All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 00/20] eznps a new ARC platform
@ 2015-10-31 13:15 ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threats. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (17):
  Documentation: Add EZchip vendor to binding list
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: Mark cpu online only after it has executed the per cpu init
    hook.
  ARC: mm: use generic macros _BITUL()
  ARC: add CONFIG_CLKSRC_OF support to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: [plat-eznps] define IPI_IRQ
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (3):
  ARC: Use res_service as entry point for secondaries
  ARC: [plat-eznps] Use dedicated cpu_relax()
  ARC: [plat-eznps] replace sync with proper cpu barrier

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    9 +
 arch/arc/boot/dts/eznps.dts                        |   76 ++++++
 arch/arc/configs/nps_defconfig                     |   85 +++++++
 arch/arc/include/asm/atomic.h                      |   69 +++++
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   49 ++++
 arch/arc/include/asm/cmpxchg.h                     |   49 ++++
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   32 ++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    2 +-
 arch/arc/include/asm/spinlock.h                    |   14 +
 arch/arc/kernel/ctx_sw.c                           |   20 ++
 arch/arc/kernel/smp.c                              |    9 +-
 arch/arc/kernel/time.c                             |    4 +
 arch/arc/mm/tlb.c                                  |   12 +
 arch/arc/plat-eznps/Kconfig                        |   34 +++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   76 ++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  265 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
 arch/arc/plat-eznps/include/plat/smp.h             |   27 ++
 arch/arc/plat-eznps/mtm.c                          |  152 +++++++++++
 arch/arc/plat-eznps/platform.c                     |   40 +++
 arch/arc/plat-eznps/smp.c                          |  160 ++++++++++++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  103 ++++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
 37 files changed, 1644 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 00/20] eznps a new ARC platform
@ 2015-10-31 13:15 ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threats. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (17):
  Documentation: Add EZchip vendor to binding list
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: Mark cpu online only after it has executed the per cpu init
    hook.
  ARC: mm: use generic macros _BITUL()
  ARC: add CONFIG_CLKSRC_OF support to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: [plat-eznps] define IPI_IRQ
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (3):
  ARC: Use res_service as entry point for secondaries
  ARC: [plat-eznps] Use dedicated cpu_relax()
  ARC: [plat-eznps] replace sync with proper cpu barrier

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    9 +
 arch/arc/boot/dts/eznps.dts                        |   76 ++++++
 arch/arc/configs/nps_defconfig                     |   85 +++++++
 arch/arc/include/asm/atomic.h                      |   69 +++++
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   49 ++++
 arch/arc/include/asm/cmpxchg.h                     |   49 ++++
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   32 ++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    2 +-
 arch/arc/include/asm/spinlock.h                    |   14 +
 arch/arc/kernel/ctx_sw.c                           |   20 ++
 arch/arc/kernel/smp.c                              |    9 +-
 arch/arc/kernel/time.c                             |    4 +
 arch/arc/mm/tlb.c                                  |   12 +
 arch/arc/plat-eznps/Kconfig                        |   34 +++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   76 ++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  265 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
 arch/arc/plat-eznps/include/plat/smp.h             |   27 ++
 arch/arc/plat-eznps/mtm.c                          |  152 +++++++++++
 arch/arc/plat-eznps/platform.c                     |   40 +++
 arch/arc/plat-eznps/smp.c                          |  160 ++++++++++++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  103 ++++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
 37 files changed, 1644 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 01/20] Documentation: Add EZchip vendor to binding list
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Rob Herring,
	Pawel Moll, Mark Rutland, Kumar Gala

From: Noam Camus <noamc@ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Kumar Gala <galak@codeaurora.org>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..f8b5e9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Proccessor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82d2ac9..5a752cc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -80,6 +80,7 @@ eukrea  Eukréa Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 fsl	Freescale Semiconductor
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 01/20] Documentation: Add EZchip vendor to binding list
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Kumar Gala <galak at codeaurora.org>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..f8b5e9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Proccessor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82d2ac9..5a752cc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -80,6 +80,7 @@ eukrea  Eukr??a Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 fsl	Freescale Semiconductor
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Daniel Lezcano,
	Rob Herring

From: Noam Camus <noamc@ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  103 ++++++++++++++++++++
 3 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c5102c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,11 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer"
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+};
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5c00863..28c17dc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
 obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..83a0a9d
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_fdt.h>
+#include <plat/ctop.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+static u32 nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+	int cpu;
+	int cluster;
+	void *lower_p, *upper_p;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cpu = smp_processor_id();
+	cluster = cpu >> NPS_CLUSTER_OFFSET;
+	lower_p = (void *)nps_msu_reg_low_addr[cluster];
+	upper_p = lower_p + 4;
+	local_irq_restore(flags);
+
+	upper = ioread32be(upper_p);
+	do {
+		old_upper = upper;
+		lower = ioread32be(lower_p);
+		upper = ioread32be(upper_p);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return (cycle_t)counter;
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(64),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	unsigned long rate, dt_root;
+	int ret, cluster;
+
+	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
+		nps_msu_reg_low_addr[cluster] =
+			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
+				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
+
+	dt_root = of_get_flat_dt_root();
+	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |  103 ++++++++++++++++++++
 3 files changed, 115 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c5102c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,11 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer"
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+};
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5c00863..28c17dc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
 obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..83a0a9d
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_fdt.h>
+#include <plat/ctop.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+static u32 nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	u64 counter;
+	u32 lower;
+	u32 upper, old_upper;
+	int cpu;
+	int cluster;
+	void *lower_p, *upper_p;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	cpu = smp_processor_id();
+	cluster = cpu >> NPS_CLUSTER_OFFSET;
+	lower_p = (void *)nps_msu_reg_low_addr[cluster];
+	upper_p = lower_p + 4;
+	local_irq_restore(flags);
+
+	upper = ioread32be(upper_p);
+	do {
+		old_upper = upper;
+		lower = ioread32be(lower_p);
+		upper = ioread32be(upper_p);
+	} while (upper != old_upper);
+
+	counter = upper;
+	counter <<= 32;
+	counter |= lower;
+	return (cycle_t)counter;
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(64),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	unsigned long rate, dt_root;
+	int ret, cluster;
+
+	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
+		nps_msu_reg_low_addr[cluster] =
+			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
+				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
+
+	dt_root = of_get_flat_dt_root();
+	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 03/20] irqchip: add nps Internal and external irqchips
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Thomas Gleixner,
	Jason Cooper, Marc Zyngier

From: Noam Camus <noamc@ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++++++
 3 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index bb3048f..decfc87 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..78f3667
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define NPS_MSU_EN_CFG	0x80
+
+/* Messaging and Scheduling Unit:
+ * Provides message management for a CPU cluster.
+ */
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg {
+		union {
+			struct {
+				u32     __reserved1:11,
+				rtc_en:1, ipc_en:1, gim_1_en:1,
+				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
+				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
+				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+				buff_i_alc_bmue:1, __reserved2:1,
+				buff_e_pre_en:1, buff_i_pre_en:1,
+				pmuw_ja_en:1, pmue_ja_en:1,
+				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+			};
+			u32 value;
+		};
+	};
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* Enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+/* Global Interrupt Manager:
+ * Configures and manages up to 64 interrupts from peripherals,
+ * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
+ * Receives the interrupts and transmits them to relevant CPU.
+ */
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	 */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* Enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+}
+
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hw)
+{
+	switch (irq) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	eznps_configure_msu();
+	eznps_configure_gim();
+
+	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 03/20] irqchip: add nps Internal and external irqchips
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++++++
 3 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index bb3048f..decfc87 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..78f3667
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define NPS_MSU_EN_CFG	0x80
+
+/* Messaging and Scheduling Unit:
+ * Provides message management for a CPU cluster.
+ */
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg {
+		union {
+			struct {
+				u32     __reserved1:11,
+				rtc_en:1, ipc_en:1, gim_1_en:1,
+				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
+				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
+				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+				buff_i_alc_bmue:1, __reserved2:1,
+				buff_e_pre_en:1, buff_i_pre_en:1,
+				pmuw_ja_en:1, pmue_ja_en:1,
+				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+			};
+			u32 value;
+		};
+	};
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* Enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+/* Global Interrupt Manager:
+ * Configures and manages up to 64 interrupts from peripherals,
+ * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
+ * Receives the interrupts and transmits them to relevant CPU.
+ */
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	 */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* Enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+}
+
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hw)
+{
+	switch (irq) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	eznps_configure_msu();
+	eznps_configure_gim();
+
+	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 04/20] ARC: Set vmalloc size from configuration
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 4454535..a603301 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -113,18 +113,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0ee7398..0c75a27 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 04/20] ARC: Set vmalloc size from configuration
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 4454535..a603301 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -113,18 +113,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0ee7398..0c75a27 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Noam Camus <noamc@ezchip.com>

If we hold rw->lock_mutex and interrupt occures we may
end up spinning on it for ever during softirq.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

If we hold rw->lock_mutex and interrupt occures we may
end up spinning on it for ever during softirq.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 06/20] ARC: Mark cpu online only after it has executed the per cpu init hook.
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up() which
for ARC returns as soon as new cpu's status becomes online,
but it could still be initializing (see start_kernel_secondary())
Thus master can start cpu up for 2nd core,
while prev is still not fully up.
This can be issue for SMT system,
where first h/w thread of a core needs to be fully up before
moving on to next threads.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/smp.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..946109f 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,6 +126,10 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
+	/* Before we turn online */
+	if (machine_desc->init_cpu_smp)
+		machine_desc->init_cpu_smp(cpu);
+
 	notify_cpu_starting(cpu);
 	set_cpu_online(cpu, true);
 
@@ -135,9 +139,6 @@ void start_kernel_secondary(void)
 	if (plat_smp_ops.init_irq_cpu)
 		plat_smp_ops.init_irq_cpu(cpu);
 
-	if (machine_desc->init_cpu_smp)
-		machine_desc->init_cpu_smp(cpu);
-
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 06/20] ARC: Mark cpu online only after it has executed the per cpu init hook.
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up() which
for ARC returns as soon as new cpu's status becomes online,
but it could still be initializing (see start_kernel_secondary())
Thus master can start cpu up for 2nd core,
while prev is still not fully up.
This can be issue for SMT system,
where first h/w thread of a core needs to be fully up before
moving on to next threads.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/smp.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..946109f 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,6 +126,10 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
+	/* Before we turn online */
+	if (machine_desc->init_cpu_smp)
+		machine_desc->init_cpu_smp(cpu);
+
 	notify_cpu_starting(cpu);
 	set_cpu_online(cpu, true);
 
@@ -135,9 +139,6 @@ void start_kernel_secondary(void)
 	if (plat_smp_ops.init_irq_cpu)
 		plat_smp_ops.init_irq_cpu(cpu);
 
-	if (machine_desc->init_cpu_smp)
-		machine_desc->init_cpu_smp(cpu);
-
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

PGDIR_SIZE() cannot use "1UL" since it is called from mm/tlbex.S
by VMALLOC_START. _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/pgtable.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

PGDIR_SIZE() cannot use "1UL" since it is called from mm/tlbex.S
by VMALLOC_START. _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/pgtable.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Tal Zilcer <talz@ezchip.com>

At cpu_kick() we call res_service which can be implement by each
platform and override gerneric weak definition.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/smp.h |    2 +-
 arch/arc/kernel/smp.c      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..db05793 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
  * APIs provided by arch SMP code to rest of arch code
  */
 extern void __init smp_init_cpus(void);
-extern void first_lines_of_secondary(void);
+extern void res_service(void);
 extern const char *arc_platform_smp_cpuinfo(void);
 
 /*
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 946109f..546079f 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -167,7 +167,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 
 	if (plat_smp_ops.cpu_kick)
 		plat_smp_ops.cpu_kick(cpu,
-				(unsigned long)first_lines_of_secondary);
+				(unsigned long)res_service);
 	else
 		arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Tal Zilcer <talz@ezchip.com>

At cpu_kick() we call res_service which can be implement by each
platform and override gerneric weak definition.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/smp.h |    2 +-
 arch/arc/kernel/smp.c      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..db05793 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
  * APIs provided by arch SMP code to rest of arch code
  */
 extern void __init smp_init_cpus(void);
-extern void first_lines_of_secondary(void);
+extern void res_service(void);
 extern const char *arc_platform_smp_cpuinfo(void);
 
 /*
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 946109f..546079f 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -167,7 +167,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 
 	if (plat_smp_ops.cpu_kick)
 		plat_smp_ops.cpu_kick(cpu,
-				(unsigned long)first_lines_of_secondary);
+				(unsigned long)res_service);
 	else
 		arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 09/20] ARC: add CONFIG_CLKSRC_OF support to time_init()
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/kernel/time.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..5313961 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -283,6 +283,10 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_of_init();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 09/20] ARC: add CONFIG_CLKSRC_OF support to time_init()
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/kernel/time.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..5313961 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -283,6 +283,10 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_of_init();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 10/20] ARC: [plat-eznps] Add eznps board defconfig and dts
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   76 +++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..4d4832a
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+		};
+
+		uart@f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clock-frequency = <83333333>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		ethernet@f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# 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_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 10/20] ARC: [plat-eznps] Add eznps board defconfig and dts
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   76 +++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..4d4832a
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+		};
+
+		uart at f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clock-frequency = <83333333>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		ethernet at f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# 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_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   76 +++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  264 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   27 +++
 arch/arc/plat-eznps/mtm.c               |  152 ++++++++++++++++++
 arch/arc/plat-eznps/platform.c          |   40 +++++
 arch/arc/plat-eznps/smp.c               |  160 +++++++++++++++++++
 10 files changed, 826 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 08adb4a..c63ca18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4171,6 +4171,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc@ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
 L:	lm-sensors@lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..510354f
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_OF
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..a3dec3e
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,76 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .text, "ax",@progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	_stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; We do not have cache coherency mechanism,
+	; so D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are the huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	_stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	_stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..b708f9f
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#define NPS_HOST_REG_BASE		0xF6000000
+
+/* core auxiliary registers */
+#define CTOP_AUX_BASE			0xFFFFF800
+#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
+#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
+#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
+
+/* EZchip core instructions */
+#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
+#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
+#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
+#define CTOP_INST_SCHD_RW			0x3e6f7004
+#define CTOP_INST_SCHD_RD			0x3e6f7084
+#define CTOP_INST_ASRI_0_R3			0x3b56003e
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
+
+#ifndef __ASSEMBLY__
+#define NPS_MSU_BLKID			0x018
+#define NPS_CRG_BLKID			0x480
+#define NPS_CRG_SYNC_BIT		BIT(0)
+
+#define NPS_GIM_BLKID			0x5C0
+#define NPS_GIM_UART_LINE		BIT(7)
+#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
+#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
+
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physicaly,
+ * like can be seen in following table.
+ * Cluster ids are in format: logical (physical)
+ *
+ * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
+ * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
+ * ============================================
+ * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
+ * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
+ * --------------------------------------------
+ *   |   0     |   1     ||    2     |    3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	__asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32     base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			__reserved:4, st_cnt:4, __reserved2:8,
+			hs_cnt:8, __reserved3:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			__reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+
+/* CRG registers */
+#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+
+#endif /* __ASEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..7509443
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern struct cpumask _cpu_possible_mask;
+void eznps_smp_init_cpu(unsigned int cpu);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..802c3c8
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	switch (nat) {
+	case 1:
+		log_nat = 0;
+		break;
+	case 2:
+		log_nat = 1;
+		break;
+	case 4:
+		log_nat = 2;
+		break;
+	case 8:
+		log_nat = 3;
+		break;
+	case 16:
+		log_nat = 4;
+		break;
+	default:
+		pr_warn("BUG: got non valid NAT %d!\n", nat);
+		log_nat = 0;
+		break;
+	}
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..c84dfd9
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/mach_desc.h>
+#include <plat/smp.h>
+
+/*----------------------- Machine Descriptions ------------------------------
+ *
+ * Machine description is simply a set of platform/board specific callbacks
+ * This is not directly related to DeviceTree based dynamic device creation,
+ * however as part of early device tree scan, we also select the right
+ * callback set, by matching the DT compatible name.
+ */
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+#ifdef CONFIG_SMP
+	.init_cpu_smp	= eznps_smp_init_cpu,  /* for each CPU */
+#endif
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..0f8b51a
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+struct cpumask _cpu_possible_mask;
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Any SMP specific init any CPU does when it comes up.
+ * Here we setup the CPU to enable Inter-Processor-Interrupts
+ * Called for each CPU
+ * -Master      : init_IRQ()
+ * -Other(s)    : start_kernel_secondary()
+ */
+void eznps_smp_init_cpu(unsigned int cpu)
+{
+	unsigned int rc;
+
+	rc = smp_ipi_irq_setup(cpu, IPI_IRQ);
+	if (rc)
+		panic("IPI IRQ %d reg failed on BOOT cpu\n", IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = pc;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+};
+
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   76 +++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  264 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   27 +++
 arch/arc/plat-eznps/mtm.c               |  152 ++++++++++++++++++
 arch/arc/plat-eznps/platform.c          |   40 +++++
 arch/arc/plat-eznps/smp.c               |  160 +++++++++++++++++++
 10 files changed, 826 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 08adb4a..c63ca18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4171,6 +4171,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc at ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare at suse.com>
 L:	lm-sensors at lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..510354f
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_OF
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..a3dec3e
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,76 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .text, "ax", at progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	_stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; We do not have cache coherency mechanism,
+	; so D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are the huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	_stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	_stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..b708f9f
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#define NPS_HOST_REG_BASE		0xF6000000
+
+/* core auxiliary registers */
+#define CTOP_AUX_BASE			0xFFFFF800
+#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
+#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
+#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
+
+/* EZchip core instructions */
+#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
+#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
+#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
+#define CTOP_INST_SCHD_RW			0x3e6f7004
+#define CTOP_INST_SCHD_RD			0x3e6f7084
+#define CTOP_INST_ASRI_0_R3			0x3b56003e
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
+
+#ifndef __ASSEMBLY__
+#define NPS_MSU_BLKID			0x018
+#define NPS_CRG_BLKID			0x480
+#define NPS_CRG_SYNC_BIT		BIT(0)
+
+#define NPS_GIM_BLKID			0x5C0
+#define NPS_GIM_UART_LINE		BIT(7)
+#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
+#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
+
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physicaly,
+ * like can be seen in following table.
+ * Cluster ids are in format: logical (physical)
+ *
+ * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
+ * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
+ * ============================================
+ * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
+ * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
+ * --------------------------------------------
+ *   |   0     |   1     ||    2     |    3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	__asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32     base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			__reserved:4, st_cnt:4, __reserved2:8,
+			hs_cnt:8, __reserved3:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			__reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+
+/* CRG registers */
+#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+
+#endif /* __ASEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..7509443
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern struct cpumask _cpu_possible_mask;
+void eznps_smp_init_cpu(unsigned int cpu);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..802c3c8
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	switch (nat) {
+	case 1:
+		log_nat = 0;
+		break;
+	case 2:
+		log_nat = 1;
+		break;
+	case 4:
+		log_nat = 2;
+		break;
+	case 8:
+		log_nat = 3;
+		break;
+	case 16:
+		log_nat = 4;
+		break;
+	default:
+		pr_warn("BUG: got non valid NAT %d!\n", nat);
+		log_nat = 0;
+		break;
+	}
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..c84dfd9
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/mach_desc.h>
+#include <plat/smp.h>
+
+/*----------------------- Machine Descriptions ------------------------------
+ *
+ * Machine description is simply a set of platform/board specific callbacks
+ * This is not directly related to DeviceTree based dynamic device creation,
+ * however as part of early device tree scan, we also select the right
+ * callback set, by matching the DT compatible name.
+ */
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+#ifdef CONFIG_SMP
+	.init_cpu_smp	= eznps_smp_init_cpu,  /* for each CPU */
+#endif
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..0f8b51a
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+struct cpumask _cpu_possible_mask;
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Any SMP specific init any CPU does when it comes up.
+ * Here we setup the CPU to enable Inter-Processor-Interrupts
+ * Called for each CPU
+ * -Master      : init_IRQ()
+ * -Other(s)    : start_kernel_secondary()
+ */
+void eznps_smp_init_cpu(unsigned int cpu)
+{
+	unsigned int rc;
+
+	rc = smp_ipi_irq_setup(cpu, IPI_IRQ);
+	if (rc)
+		panic("IPI IRQ %d reg failed on BOOT cpu\n", IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = pc;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+};
+
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 12/20] ARC: [plat-eznps] Use dedicated user stack top
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index a603301..7266ede 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -126,7 +126,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0c75a27..306ee4c 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 12/20] ARC: [plat-eznps] Use dedicated user stack top
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index a603301..7266ede 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -126,7 +126,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0c75a27..306ee4c 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 13/20] ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

We need our own implementaions since we lack of LLSC.
Our extended ISA provided with optimized solution for all 32bit
operations we see in those three headers.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/atomic.h           |   69 +++++++++++++++++++++++++++++++
 arch/arc/include/asm/bitops.h           |   49 ++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h          |   49 ++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |    1 +
 4 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index c3ecda0..ca318c2 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,74 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	return v->counter;						\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define atomic_read(v)  ((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -186,6 +254,7 @@ ATOMIC_OP(xor, ^=, xor)
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..54ecbe4 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,48 @@
 #include <asm/smp.h>
 #endif
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	old = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	return (old & (1 << nr)) != 0;					\
+}
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +197,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +239,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#else
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..8578586 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,53 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	return new;
+}
+
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -158,4 +205,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index b708f9f..655a860 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -34,6 +34,7 @@
 #define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
 #define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
 #define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)
 #define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
 
 /* EZchip core instructions */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 13/20] ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

We need our own implementaions since we lack of LLSC.
Our extended ISA provided with optimized solution for all 32bit
operations we see in those three headers.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/atomic.h           |   69 +++++++++++++++++++++++++++++++
 arch/arc/include/asm/bitops.h           |   49 ++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h          |   49 ++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |    1 +
 4 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index c3ecda0..ca318c2 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,74 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	return v->counter;						\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define atomic_read(v)  ((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -186,6 +254,7 @@ ATOMIC_OP(xor, ^=, xor)
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..54ecbe4 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,48 @@
 #include <asm/smp.h>
 #endif
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	old = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	return (old & (1 << nr)) != 0;					\
+}
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +197,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +239,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#else
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..8578586 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,53 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	return new;
+}
+
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -158,4 +205,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index b708f9f..655a860 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -34,6 +34,7 @@
 #define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
 #define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
 #define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)
 #define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
 
 /* EZchip core instructions */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Noam Camus <noamc@ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..c8229b8 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,12 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#else
+
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +47,8 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..c8229b8 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,12 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#else
+
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +47,8 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 15/20] ARC: [plat-eznps] Use dedicated identity auxiliary register.
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5be..92e2e82 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -69,9 +72,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -109,6 +119,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 15/20] ARC: [plat-eznps] Use dedicated identity auxiliary register.
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5be..92e2e82 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -69,9 +72,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -109,6 +119,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Tal Zilcer <talz@ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 arch/arc/include/asm/processor.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 7266ede..f1a51a6 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -58,7 +58,12 @@ struct task_struct;
  * get optimised away by gcc
  */
 #ifdef CONFIG_SMP
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#else
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
+#endif
 #else
 #define cpu_relax()	do { } while (0)
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Tal Zilcer <talz@ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/processor.h |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 7266ede..f1a51a6 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -58,7 +58,12 @@ struct task_struct;
  * get optimised away by gcc
  */
 #ifdef CONFIG_SMP
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#else
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
+#endif
 #else
 #define cpu_relax()	do { } while (0)
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 17/20] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 17/20] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Tal Zilcer <talz@ezchip.com>

In SMT system like we have the generic "sync" is not working with
HW threads. The replacement is "schd.rw" instruction that is served
as cpu barrier for HW threads.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/kernel/ctx_sw.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 92e2e82..2a2f50e 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
+#ifdef CONFIG_EZNPS_MTM_EXT
+		".word %5   \n\t"
+#else
 		"sync   \n\t"
+#endif
 
 		/*
 		 * setup _current_task with incoming tsk.
@@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifdef CONFIG_ARC_PLAT_EZNPS
 		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
 #endif
+#ifdef CONFIG_EZNPS_MTM_EXT
+		, "i"(CTOP_INST_SCHD_RW)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Tal Zilcer <talz@ezchip.com>

In SMT system like we have the generic "sync" is not working with
HW threads. The replacement is "schd.rw" instruction that is served
as cpu barrier for HW threads.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/kernel/ctx_sw.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 92e2e82..2a2f50e 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
+#ifdef CONFIG_EZNPS_MTM_EXT
+		".word %5   \n\t"
+#else
 		"sync   \n\t"
+#endif
 
 		/*
 		 * setup _current_task with incoming tsk.
@@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifdef CONFIG_ARC_PLAT_EZNPS
 		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
 #endif
+#ifdef CONFIG_EZNPS_MTM_EXT
+		, "i"(CTOP_INST_SCHD_RW)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
  2015-10-31 13:15 ` Noam Camus
@ 2015-10-31 13:15   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    9 +++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 8a27a48..9e5928f 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,15 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+ifeq ($(KBUILD_SRC),)
+KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include
+else
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
@ 2015-10-31 13:15   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-10-31 13:15 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    9 +++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 8a27a48..9e5928f 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,15 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+ifeq ($(KBUILD_SRC),)
+KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include
+else
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 02/20] clocksource: Add NPS400 timers driver
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-01 20:44     ` Daniel Lezcano
  -1 siblings, 0 replies; 190+ messages in thread
From: Daniel Lezcano @ 2015-11-01 20:44 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Rob Herring, John Stultz,
	Thomas Gleixner

On 10/31/2015 02:15 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
>
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>

Hi Noam,

Added Thomas Gleixner and John Stultz.

> ---
>   .../bindings/timer/ezchip,nps400-timer.txt         |   11 ++
>   drivers/clocksource/Makefile                       |    1 +
>   drivers/clocksource/timer-nps.c                    |  103 ++++++++++++++++++++
>   3 files changed, 115 insertions(+), 0 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>   create mode 100644 drivers/clocksource/timer-nps.c
>
> diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> new file mode 100644
> index 0000000..c5102c2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> @@ -0,0 +1,11 @@
> +NPS Network Processor
> +
> +Required properties:
> +
> +- compatible :	should be "ezchip,nps400-timer"
> +
> +Example:
> +
> +timer {
> +	compatible = "ezchip,nps400-timer";
> +};
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 5c00863..28c17dc 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
>   obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
>   obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
>   obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
> +obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o

Please add an entry in the clocksource's Kconfig.

eg:

config NPS400_TIMER
	bool "NPS400 clocksource driver" if COMPILE_TEST
	help
	  NPS400 clocksource support.

and in the platform's Kconfig:

select NPS400_TIMER


>   obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
>   obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> new file mode 100644
> index 0000000..83a0a9d
> --- /dev/null
> +++ b/drivers/clocksource/timer-nps.c
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/irqreturn.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_fdt.h>
> +#include <plat/ctop.h>

Are you sure all the headers are needed ?

> +#define NPS_MSU_TICK_LOW	0xC8
> +#define NPS_CLUSTER_OFFSET	8
> +#define NPS_CLUSTER_NUM		16
> +
> +static u32 nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
> +
> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower;
> +	u32 upper, old_upper;
> +	int cpu;
> +	int cluster;
> +	void *lower_p, *upper_p;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);

Why do you need to disable the interrupt here ?

> +	cpu = smp_processor_id();
> +	cluster = cpu >> NPS_CLUSTER_OFFSET;
> +	lower_p = (void *)nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +	local_irq_restore(flags);
> +
> +	upper = ioread32be(upper_p);
> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = upper;
> +	counter <<= 32;
> +	counter |= lower;
> +	return (cycle_t)counter;

May be you can consider using only the 32bits. Sometimes it is faster 
than using 64bits arithmetic and reading the register three times.

https://lkml.org/lkml/2014/6/20/431

> +}
> +
> +static struct clocksource nps_counter = {
> +	.name	= "EZnps-tick",
> +	.rating = 301,
> +	.read   = nps_clksrc_read,
> +	.mask   = CLOCKSOURCE_MASK(64),
> +	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static void __init nps_setup_clocksource(struct device_node *node)
> +{
> +	struct clocksource *clksrc = &nps_counter;
> +	unsigned long rate, dt_root;
> +	int ret, cluster;
> +
> +	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
> +		nps_msu_reg_low_addr[cluster] =
> +			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
> +				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
> +
> +	dt_root = of_get_flat_dt_root();
> +	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);

Why are you using 'of_get_flat_dt_root' / 'of_get_flat_dt_prop' ?

> +	ret = clocksource_register_hz(clksrc, rate);
> +	if (ret)
> +		pr_err("Couldn't register clock source.\n");
> +}
> +
> +CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
> +		       nps_setup_clocksource);
>


-- 
  <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
@ 2015-11-01 20:44     ` Daniel Lezcano
  0 siblings, 0 replies; 190+ messages in thread
From: Daniel Lezcano @ 2015-11-01 20:44 UTC (permalink / raw)
  To: linux-snps-arc

On 10/31/2015 02:15 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>

Hi Noam,

Added Thomas Gleixner and John Stultz.

> ---
>   .../bindings/timer/ezchip,nps400-timer.txt         |   11 ++
>   drivers/clocksource/Makefile                       |    1 +
>   drivers/clocksource/timer-nps.c                    |  103 ++++++++++++++++++++
>   3 files changed, 115 insertions(+), 0 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>   create mode 100644 drivers/clocksource/timer-nps.c
>
> diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> new file mode 100644
> index 0000000..c5102c2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
> @@ -0,0 +1,11 @@
> +NPS Network Processor
> +
> +Required properties:
> +
> +- compatible :	should be "ezchip,nps400-timer"
> +
> +Example:
> +
> +timer {
> +	compatible = "ezchip,nps400-timer";
> +};
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 5c00863..28c17dc 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
>   obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
>   obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
>   obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
> +obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o

Please add an entry in the clocksource's Kconfig.

eg:

config NPS400_TIMER
	bool "NPS400 clocksource driver" if COMPILE_TEST
	help
	  NPS400 clocksource support.

and in the platform's Kconfig:

select NPS400_TIMER


>   obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
>   obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
> diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
> new file mode 100644
> index 0000000..83a0a9d
> --- /dev/null
> +++ b/drivers/clocksource/timer-nps.c
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/irqreturn.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_fdt.h>
> +#include <plat/ctop.h>

Are you sure all the headers are needed ?

> +#define NPS_MSU_TICK_LOW	0xC8
> +#define NPS_CLUSTER_OFFSET	8
> +#define NPS_CLUSTER_NUM		16
> +
> +static u32 nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
> +
> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower;
> +	u32 upper, old_upper;
> +	int cpu;
> +	int cluster;
> +	void *lower_p, *upper_p;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);

Why do you need to disable the interrupt here ?

> +	cpu = smp_processor_id();
> +	cluster = cpu >> NPS_CLUSTER_OFFSET;
> +	lower_p = (void *)nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +	local_irq_restore(flags);
> +
> +	upper = ioread32be(upper_p);
> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = upper;
> +	counter <<= 32;
> +	counter |= lower;
> +	return (cycle_t)counter;

May be you can consider using only the 32bits. Sometimes it is faster 
than using 64bits arithmetic and reading the register three times.

https://lkml.org/lkml/2014/6/20/431

> +}
> +
> +static struct clocksource nps_counter = {
> +	.name	= "EZnps-tick",
> +	.rating = 301,
> +	.read   = nps_clksrc_read,
> +	.mask   = CLOCKSOURCE_MASK(64),
> +	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static void __init nps_setup_clocksource(struct device_node *node)
> +{
> +	struct clocksource *clksrc = &nps_counter;
> +	unsigned long rate, dt_root;
> +	int ret, cluster;
> +
> +	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
> +		nps_msu_reg_low_addr[cluster] =
> +			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
> +				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
> +
> +	dt_root = of_get_flat_dt_root();
> +	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);

Why are you using 'of_get_flat_dt_root' / 'of_get_flat_dt_prop' ?

> +	ret = clocksource_register_hz(clksrc, rate);
> +	if (ret)
> +		pr_err("Couldn't register clock source.\n");
> +}
> +
> +CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
> +		       nps_setup_clocksource);
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  6:23     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:23 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: cmetcalf, gilf, talz, linux-kernel

On Saturday 31 October 2015 06:49 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
>
> PGDIR_SIZE() cannot use "1UL" since it is called from mm/tlbex.S
> by VMALLOC_START. _BITUL() solves this build error.
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/include/asm/pgtable.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
> index 57af2f0..372a282 100644
> --- a/arch/arc/include/asm/pgtable.h
> +++ b/arch/arc/include/asm/pgtable.h
> @@ -210,7 +210,7 @@
>  #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
>  
>  #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
> -#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
> +#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
>  #define PGDIR_MASK	(~(PGDIR_SIZE-1))
>  
>  #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)

For bisectability, please squash this with patch 4/20, and append the changelog of
this patch to 4/20

-Vineet


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
@ 2015-11-02  6:23     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:23 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:49 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> PGDIR_SIZE() cannot use "1UL" since it is called from mm/tlbex.S
> by VMALLOC_START. _BITUL() solves this build error.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/include/asm/pgtable.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
> index 57af2f0..372a282 100644
> --- a/arch/arc/include/asm/pgtable.h
> +++ b/arch/arc/include/asm/pgtable.h
> @@ -210,7 +210,7 @@
>  #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
>  
>  #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
> -#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
> +#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
>  #define PGDIR_MASK	(~(PGDIR_SIZE-1))
>  
>  #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)

For bisectability, please squash this with patch 4/20, and append the changelog of
this patch to 4/20

-Vineet

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
  2015-11-02  6:23     ` Vineet Gupta
@ 2015-11-02  6:27       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  6:27 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: Chris Metcalf, Gil Fruchter, Tal Zilcer, linux-kernel

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 8:24 AM

> For bisectability, please squash this with patch 4/20, and append the changelog of this patch to 4/20

OK
- Noam


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 07/20] ARC: mm: use generic macros _BITUL()
@ 2015-11-02  6:27       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  6:27 UTC (permalink / raw)
  To: linux-snps-arc

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 8:24 AM

> For bisectability, please squash this with patch 4/20, and append the changelog of this patch to 4/20

OK
- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 09/20] ARC: add CONFIG_CLKSRC_OF support to time_init()
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  6:32     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:32 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: cmetcalf, gilf, talz, linux-kernel

On Saturday 31 October 2015 06:50 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
>
> External clock source can be used if included by one of
> DTS file of a chosen platform.
> Signed-off-by: Noam Camus <noamc@ezchip.com>

Acked-by: Vineet Gupta <vgupta@synopsys.com>

> ---
>  arch/arc/kernel/time.c |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index dfad287..5313961 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -283,6 +283,10 @@ void __init time_init(void)
>  		 */
>  		clocksource_register_hz(&arc_counter, arc_get_core_freq());
>  
> +#ifdef CONFIG_CLKSRC_OF
> +	clocksource_of_init();
> +#endif
> +
>  	/* sets up the periodic event timer */
>  	arc_local_timer_setup();
>  }


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 09/20] ARC: add CONFIG_CLKSRC_OF support to time_init()
@ 2015-11-02  6:32     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:32 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:50 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> External clock source can be used if included by one of
> DTS file of a chosen platform.
> Signed-off-by: Noam Camus <noamc at ezchip.com>

Acked-by: Vineet Gupta <vgupta at synopsys.com>

> ---
>  arch/arc/kernel/time.c |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
> index dfad287..5313961 100644
> --- a/arch/arc/kernel/time.c
> +++ b/arch/arc/kernel/time.c
> @@ -283,6 +283,10 @@ void __init time_init(void)
>  		 */
>  		clocksource_register_hz(&arc_counter, arc_get_core_freq());
>  
> +#ifdef CONFIG_CLKSRC_OF
> +	clocksource_of_init();
> +#endif
> +
>  	/* sets up the periodic event timer */
>  	arc_local_timer_setup();
>  }

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  6:38     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:38 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: cmetcalf, gilf, talz, linux-kernel

On Saturday 31 October 2015 06:50 PM, Noam Camus wrote:
> From: Tal Zilcer <talz@ezchip.com>
>
> At cpu_kick() we call res_service which can be implement by each
> platform and override gerneric weak definition.
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/include/asm/smp.h |    2 +-
>  arch/arc/kernel/smp.c      |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 133c867..db05793 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
>   * APIs provided by arch SMP code to rest of arch code
>   */
>  extern void __init smp_init_cpus(void);
> -extern void first_lines_of_secondary(void);
> +extern void res_service(void);
>  extern const char *arc_platform_smp_cpuinfo(void);
>  
>  /*
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 946109f..546079f 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -167,7 +167,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  
>  	if (plat_smp_ops.cpu_kick)
>  		plat_smp_ops.cpu_kick(cpu,
> -				(unsigned long)first_lines_of_secondary);
> +				(unsigned long)res_service);

So I recently added the explicit handling of halt-on-reset vs. run-on-reset (for
non master cores)
This will cause infinite loop for non masters for run-on-reset ?

I'd suggest leave this arg alone and use whatever PC is needed inside your kick
routine

>  	else
>  		arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
>  


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
@ 2015-11-02  6:38     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  6:38 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:50 PM, Noam Camus wrote:
> From: Tal Zilcer <talz at ezchip.com>
>
> At cpu_kick() we call res_service which can be implement by each
> platform and override gerneric weak definition.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/include/asm/smp.h |    2 +-
>  arch/arc/kernel/smp.c      |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 133c867..db05793 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -30,7 +30,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
>   * APIs provided by arch SMP code to rest of arch code
>   */
>  extern void __init smp_init_cpus(void);
> -extern void first_lines_of_secondary(void);
> +extern void res_service(void);
>  extern const char *arc_platform_smp_cpuinfo(void);
>  
>  /*
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 946109f..546079f 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -167,7 +167,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  
>  	if (plat_smp_ops.cpu_kick)
>  		plat_smp_ops.cpu_kick(cpu,
> -				(unsigned long)first_lines_of_secondary);
> +				(unsigned long)res_service);

So I recently added the explicit handling of halt-on-reset vs. run-on-reset (for
non master cores)
This will cause infinite loop for non masters for run-on-reset ?

I'd suggest leave this arg alone and use whatever PC is needed inside your kick
routine

>  	else
>  		arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
>  

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  7:48     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:48 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: cmetcalf, gilf, talz, linux-kernel, Peter Zijlstra, Gilad Ben Yossef

+CC Peter.

On Saturday 31 October 2015 06:53 PM, Noam Camus wrote:
> From: Tal Zilcer <talz@ezchip.com>
>
> In SMT system like we have the generic "sync" is not working with
> HW threads. The replacement is "schd.rw" instruction that is served
> as cpu barrier for HW threads.
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/kernel/ctx_sw.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
> index 92e2e82..2a2f50e 100644
> --- a/arch/arc/kernel/ctx_sw.c
> +++ b/arch/arc/kernel/ctx_sw.c
> @@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  		"st      sp, [r24]       \n\t"
>  #endif
>  
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		".word %5   \n\t"
> +#else
>  		"sync   \n\t"
> +#endif
>  
>  		/*
>  		 * setup _current_task with incoming tsk.
> @@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  #ifdef CONFIG_ARC_PLAT_EZNPS
>  		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
>  #endif
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		, "i"(CTOP_INST_SCHD_RW)
> +#endif
>  		: "blink"
>  	);

Since u bring this up - I think we don't need the original SYNC and/or SMT thread
schedule at all.
The SYNC here is a historic relic at best and we can get rid of it per reasoning
below:

In UP context it is obviously useless, why would we want to stall the core for all
updates to stack memory of t0 to complete before loading kernel ode callee
registers from t1 stack's memory.

In SMP, we could have a potential race in which outdoing task could be
concurrently picked for running, thus the writes to stack here need to be visible
before the reads from stack on other core. But I think since this is the same rq,
there would be a taken spinlock and once a core gives it up, an smp barrier would
come naturally.

Peter do u concur ?

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-02  7:48     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:48 UTC (permalink / raw)
  To: linux-snps-arc

+CC Peter.

On Saturday 31 October 2015 06:53 PM, Noam Camus wrote:
> From: Tal Zilcer <talz at ezchip.com>
>
> In SMT system like we have the generic "sync" is not working with
> HW threads. The replacement is "schd.rw" instruction that is served
> as cpu barrier for HW threads.
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/kernel/ctx_sw.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
> index 92e2e82..2a2f50e 100644
> --- a/arch/arc/kernel/ctx_sw.c
> +++ b/arch/arc/kernel/ctx_sw.c
> @@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  		"st      sp, [r24]       \n\t"
>  #endif
>  
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		".word %5   \n\t"
> +#else
>  		"sync   \n\t"
> +#endif
>  
>  		/*
>  		 * setup _current_task with incoming tsk.
> @@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  #ifdef CONFIG_ARC_PLAT_EZNPS
>  		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
>  #endif
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		, "i"(CTOP_INST_SCHD_RW)
> +#endif
>  		: "blink"
>  	);

Since u bring this up - I think we don't need the original SYNC and/or SMT thread
schedule at all.
The SYNC here is a historic relic at best and we can get rid of it per reasoning
below:

In UP context it is obviously useless, why would we want to stall the core for all
updates to stack memory of t0 to complete before loading kernel ode callee
registers from t1 stack's memory.

In SMP, we could have a potential race in which outdoing task could be
concurrently picked for running, thus the writes to stack here need to be visible
before the reads from stack on other core. But I think since this is the same rq,
there would be a taken spinlock and once a core gives it up, an smp barrier would
come naturally.

Peter do u concur ?

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  7:52     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:52 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: cmetcalf, gilf, talz, linux-kernel

On Saturday 31 October 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
>
> We add IPI irq definition to be used later by any
> irqchip such NPS400 IC.
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>

Again this break bisectability - it needs to be placed before you use this #define
in patch 3/20.
Anyhow since you are doing stuff via DT, why not get this value from DT itself
instead of hard coding.

> ---
>  arch/arc/include/asm/irq.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
> index 4fd7d62..c5f8f0f 100644
> --- a/arch/arc/include/asm/irq.h
> +++ b/arch/arc/include/asm/irq.h
> @@ -16,7 +16,11 @@
>  #ifdef CONFIG_ISA_ARCOMPACT
>  #define TIMER0_IRQ      3
>  #define TIMER1_IRQ      4
> +#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
> +#define IPI_IRQ         5
> +#else
>  #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
> +#endif
>  #else
>  #define TIMER0_IRQ      16
>  #define TIMER1_IRQ      17


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
@ 2015-11-02  7:52     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:52 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:53 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> We add IPI irq definition to be used later by any
> irqchip such NPS400 IC.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>

Again this break bisectability - it needs to be placed before you use this #define
in patch 3/20.
Anyhow since you are doing stuff via DT, why not get this value from DT itself
instead of hard coding.

> ---
>  arch/arc/include/asm/irq.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
> index 4fd7d62..c5f8f0f 100644
> --- a/arch/arc/include/asm/irq.h
> +++ b/arch/arc/include/asm/irq.h
> @@ -16,7 +16,11 @@
>  #ifdef CONFIG_ISA_ARCOMPACT
>  #define TIMER0_IRQ      3
>  #define TIMER1_IRQ      4
> +#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
> +#define IPI_IRQ         5
> +#else
>  #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
> +#endif
>  #else
>  #define TIMER0_IRQ      16
>  #define TIMER1_IRQ      17

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  7:54     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:54 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: gilf, Peter Zijlstra, talz, linux-kernel, cmetcalf

On Saturday 31 October 2015 06:52 PM, Noam Camus wrote:
> From: Tal Zilcer <talz@ezchip.com>
>
> Since the CTOP is SMT hardware multi-threaded, we need to hint
> the HW that now will be a very good time to do a hardware
> thread context switching. This is done by issuing the schd.rw
> instruction (binary coded here so as to not require specific
> revision of GCC to build the kernel).
> sched.rw means that Thread becomes eligible for execution by
> the threads scheduler after all pending read/write
> transactions were completed.
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Peter Zijlstra <peterz@infradead.org>

Acked-by: Vineet Gupta <vgupta@synopsys.com>

> ---
>  arch/arc/include/asm/processor.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..f1a51a6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,7 +58,12 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#else
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> +#endif
>  #else
>  #define cpu_relax()	do { } while (0)
>  #endif


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-02  7:54     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  7:54 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:52 PM, Noam Camus wrote:
> From: Tal Zilcer <talz at ezchip.com>
>
> Since the CTOP is SMT hardware multi-threaded, we need to hint
> the HW that now will be a very good time to do a hardware
> thread context switching. This is done by issuing the schd.rw
> instruction (binary coded here so as to not require specific
> revision of GCC to build the kernel).
> sched.rw means that Thread becomes eligible for execution by
> the threads scheduler after all pending read/write
> transactions were completed.
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Peter Zijlstra <peterz at infradead.org>

Acked-by: Vineet Gupta <vgupta at synopsys.com>

> ---
>  arch/arc/include/asm/processor.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..f1a51a6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,7 +58,12 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#else
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> +#endif
>  #else
>  #define cpu_relax()	do { } while (0)
>  #endif

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 02/20] clocksource: Add NPS400 timers driver
  2015-11-01 20:44     ` Daniel Lezcano
@ 2015-11-02  7:57       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  7:57 UTC (permalink / raw)
  To: Daniel Lezcano, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf,
	Rob Herring, John Stultz, Thomas Gleixner

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 847 bytes --]

> From: Daniel Lezcano [mailto:daniel.lezcano@linaro.org] 
> Sent: Sunday, November 01, 2015 10:44 PM

> Please add an entry in the clocksource's Kconfig.

> eg:
OK

> Are you sure all the headers are needed ?
Thanks, will revise this part.

> Why do you need to disable the interrupt here ?
Thanks, seem like left over from past issue, I will remove.


> May be you can consider using only the 32bits. Sometimes it is faster than using 64bits arithmetic and reading the register three times.

> https://lkml.org/lkml/2014/6/20/431
Our device can reach 1000MHz.
That means that the 32-bit half of the counter rolls over every ~4 seconds.
I am not sure optimization is justified.

-Noam

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
@ 2015-11-02  7:57       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  7:57 UTC (permalink / raw)
  To: linux-snps-arc

> From: Daniel Lezcano [mailto:daniel.lezcano at linaro.org] 
> Sent: Sunday, November 01, 2015 10:44 PM

> Please add an entry in the clocksource's Kconfig.

> eg:
OK

> Are you sure all the headers are needed ?
Thanks, will revise this part.

> Why do you need to disable the interrupt here ?
Thanks, seem like left over from past issue, I will remove.


> May be you can consider using only the 32bits. Sometimes it is faster than using 64bits arithmetic and reading the register three times.

> https://lkml.org/lkml/2014/6/20/431
Our device can reach 1000MHz.
That means that the 32-bit half of the counter rolls over every ~4 seconds.
I am not sure optimization is justified.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  8:02     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  8:02 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: gilf, Peter Zijlstra, talz, linux-kernel, cmetcalf

On Saturday 31 October 2015 06:52 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
>
> NPS device got 256 cores and each got 16 HW threads (SMT).
> We use EZchip dedicated ISA to trigger HW scheduler of the
> core that current HW thread belongs to.
> This scheduling makes sure that data beyond barrier is available
> to all HW threads in core and by that to all in device (4K).
>
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> ---
>  arch/arc/include/asm/barrier.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
> index a720998..c8229b8 100644
> --- a/arch/arc/include/asm/barrier.h
> +++ b/arch/arc/include/asm/barrier.h
> @@ -34,6 +34,12 @@
>  
>  #ifdef CONFIG_ISA_ARCOMPACT
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +#include <plat/ctop.h>
> +#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")

Do u need this even for mandatory barriers whose semantics are not related to SMP
at all ? I think you need them only for smb_*

Following is a good introduction to difference between the two !
https://community.arm.com/groups/processors/blog/2011/04/11/memory-access-ordering-part-2--barriers-and-the-linux-kernel

> +#else
> +
>  /*
>   * ARCompact based cores (ARC700) only have SYNC instruction which is super
>   * heavy weight as it flushes the pipeline as well.
> @@ -41,6 +47,8 @@
>   */
>  
>  #define mb()	asm volatile("sync\n" : : : "memory")
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
> +
>  #endif
>  
>  #include <asm-generic/barrier.h>


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
@ 2015-11-02  8:02     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  8:02 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:52 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
>
> NPS device got 256 cores and each got 16 HW threads (SMT).
> We use EZchip dedicated ISA to trigger HW scheduler of the
> core that current HW thread belongs to.
> This scheduling makes sure that data beyond barrier is available
> to all HW threads in core and by that to all in device (4K).
>
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> ---
>  arch/arc/include/asm/barrier.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
> index a720998..c8229b8 100644
> --- a/arch/arc/include/asm/barrier.h
> +++ b/arch/arc/include/asm/barrier.h
> @@ -34,6 +34,12 @@
>  
>  #ifdef CONFIG_ISA_ARCOMPACT
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +#include <plat/ctop.h>
> +#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")

Do u need this even for mandatory barriers whose semantics are not related to SMP
at all ? I think you need them only for smb_*

Following is a good introduction to difference between the two !
https://community.arm.com/groups/processors/blog/2011/04/11/memory-access-ordering-part-2--barriers-and-the-linux-kernel

> +#else
> +
>  /*
>   * ARCompact based cores (ARC700) only have SYNC instruction which is super
>   * heavy weight as it flushes the pipeline as well.
> @@ -41,6 +47,8 @@
>   */
>  
>  #define mb()	asm volatile("sync\n" : : : "memory")
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
> +
>  #endif
>  
>  #include <asm-generic/barrier.h>

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
  2015-11-02  6:38     ` Vineet Gupta
@ 2015-11-02  8:05       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  8:05 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: Chris Metcalf, Gil Fruchter, Tal Zilcer, linux-kernel

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 8:38 AM

> I'd suggest leave this arg alone and use whatever PC is needed inside your kick routine
OK

- Noam 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries
@ 2015-11-02  8:05       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02  8:05 UTC (permalink / raw)
  To: linux-snps-arc

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 8:38 AM

> I'd suggest leave this arg alone and use whatever PC is needed inside your kick routine
OK

- Noam 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  9:16     ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:16 UTC (permalink / raw)
  To: Noam Camus; +Cc: linux-snps-arc, linux-kernel, talz, gilf, cmetcalf

On Sat, Oct 31, 2015 at 03:15:12PM +0200, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> If we hold rw->lock_mutex and interrupt occures we may
> end up spinning on it for ever during softirq.
> 
> Below you may see an example for interrupt we get while
> nl_table_lock is holding its rw->lock_mutex and we spinned
> on it for ever.
> 
> The concept for the fix was taken from SPARC.
> 
> [2015-05-12 19:16:12] Stack Trace:
> [2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
> [2015-05-12 19:16:12]   dump_stack+0x68/0xac
> [2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
> [2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
> [2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
> [2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
> [2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
> [2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
> [2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
> [2015-05-12 19:16:13]   process_backlog+0x92/0x154
> [2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
> [2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
> [2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
> [2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
> [2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Peter Zijlstra <peterz@infradead.org>

It might make sense to note that this is a lock internal lock and since
the lock is free to be used from any context, the lock needs to be
IRQ-safe.

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
@ 2015-11-02  9:16     ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:16 UTC (permalink / raw)
  To: linux-snps-arc

On Sat, Oct 31, 2015@03:15:12PM +0200, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> If we hold rw->lock_mutex and interrupt occures we may
> end up spinning on it for ever during softirq.
> 
> Below you may see an example for interrupt we get while
> nl_table_lock is holding its rw->lock_mutex and we spinned
> on it for ever.
> 
> The concept for the fix was taken from SPARC.
> 
> [2015-05-12 19:16:12] Stack Trace:
> [2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
> [2015-05-12 19:16:12]   dump_stack+0x68/0xac
> [2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
> [2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
> [2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
> [2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
> [2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
> [2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
> [2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
> [2015-05-12 19:16:13]   process_backlog+0x92/0x154
> [2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
> [2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
> [2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
> [2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
> [2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Peter Zijlstra <peterz at infradead.org>

It might make sense to note that this is a lock internal lock and since
the lock is free to be used from any context, the lock needs to be
IRQ-safe.

Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  9:21     ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:21 UTC (permalink / raw)
  To: Noam Camus; +Cc: linux-snps-arc, linux-kernel, talz, gilf, cmetcalf

On Sat, Oct 31, 2015 at 03:15:23PM +0200, Noam Camus wrote:
> From: Tal Zilcer <talz@ezchip.com>
> 
> Since the CTOP is SMT hardware multi-threaded, we need to hint
> the HW that now will be a very good time to do a hardware
> thread context switching. This is done by issuing the schd.rw
> instruction (binary coded here so as to not require specific
> revision of GCC to build the kernel).
> sched.rw means that Thread becomes eligible for execution by
> the threads scheduler after all pending read/write
> transactions were completed.
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> ---
>  arch/arc/include/asm/processor.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..f1a51a6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,7 +58,12 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#else
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> +#endif
>  #else
>  #define cpu_relax()	do { } while (0)
>  #endif

At which point you might want to revisit:

arch/arc/include/asm/processor.h:#define cpu_relax_lowlatency() cpu_relax()


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-02  9:21     ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:21 UTC (permalink / raw)
  To: linux-snps-arc

On Sat, Oct 31, 2015@03:15:23PM +0200, Noam Camus wrote:
> From: Tal Zilcer <talz at ezchip.com>
> 
> Since the CTOP is SMT hardware multi-threaded, we need to hint
> the HW that now will be a very good time to do a hardware
> thread context switching. This is done by issuing the schd.rw
> instruction (binary coded here so as to not require specific
> revision of GCC to build the kernel).
> sched.rw means that Thread becomes eligible for execution by
> the threads scheduler after all pending read/write
> transactions were completed.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> ---
>  arch/arc/include/asm/processor.h |    5 +++++
>  1 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..f1a51a6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,7 +58,12 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#else
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> +#endif
>  #else
>  #define cpu_relax()	do { } while (0)
>  #endif

At which point you might want to revisit:

arch/arc/include/asm/processor.h:#define cpu_relax_lowlatency() cpu_relax()

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-02  7:48     ` Vineet Gupta
@ 2015-11-02  9:26       ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:26 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: Noam Camus, linux-snps-arc, cmetcalf, gilf, talz, linux-kernel,
	Gilad Ben Yossef

On Mon, Nov 02, 2015 at 07:48:54AM +0000, Vineet Gupta wrote:
> Since u bring this up - I think we don't need the original SYNC and/or
> SMT thread schedule at all.  The SYNC here is a historic relic at best
> and we can get rid of it per reasoning below:
> 
> In UP context it is obviously useless, why would we want to stall the
> core for all updates to stack memory of t0 to complete before loading
> kernel ode callee registers from t1 stack's memory.
> 
> In SMP, we could have a potential race in which outdoing task could be
> concurrently picked for running, thus the writes to stack here need to
> be visible before the reads from stack on other core. But I think
> since this is the same rq, there would be a taken spinlock and once a
> core gives it up, an smp barrier would come naturally.
> 
> Peter do u concur ?

I'm still somewhat jet-lagged, but I think the below reference should
answer your question:

lkml.kernel.org/r/20150917130125.GL3816@twins.programming.kicks-ass.net

I (still) need to update that patch and send it out again.

But I think it answers your question; we do not rely on arch code to
provide barriers for the generic code.

Now, if for some reason the arch code has further constraints, then
maybe, but I don't think so.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-02  9:26       ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02  9:26 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Nov 02, 2015@07:48:54AM +0000, Vineet Gupta wrote:
> Since u bring this up - I think we don't need the original SYNC and/or
> SMT thread schedule at all.  The SYNC here is a historic relic at best
> and we can get rid of it per reasoning below:
> 
> In UP context it is obviously useless, why would we want to stall the
> core for all updates to stack memory of t0 to complete before loading
> kernel ode callee registers from t1 stack's memory.
> 
> In SMP, we could have a potential race in which outdoing task could be
> concurrently picked for running, thus the writes to stack here need to
> be visible before the reads from stack on other core. But I think
> since this is the same rq, there would be a taken spinlock and once a
> core gives it up, an smp barrier would come naturally.
> 
> Peter do u concur ?

I'm still somewhat jet-lagged, but I think the below reference should
answer your question:

lkml.kernel.org/r/20150917130125.GL3816 at twins.programming.kicks-ass.net

I (still) need to update that patch and send it out again.

But I think it answers your question; we do not rely on arch code to
provide barriers for the generic code.

Now, if for some reason the arch code has further constraints, then
maybe, but I don't think so.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02  9:42     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  9:42 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Peter Zijlstra

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> If we hold rw->lock_mutex and interrupt occures we may
> end up spinning on it for ever during softirq.
> 
> Below you may see an example for interrupt we get while
> nl_table_lock is holding its rw->lock_mutex and we spinned
> on it for ever.
> 
> The concept for the fix was taken from SPARC.
> 
> [2015-05-12 19:16:12] Stack Trace:
> [2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
> [2015-05-12 19:16:12]   dump_stack+0x68/0xac
> [2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
> [2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
> [2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
> [2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
> [2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
> [2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
> [2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
> [2015-05-12 19:16:13]   process_backlog+0x92/0x154
> [2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
> [2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
> [2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
> [2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
> [2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> ---
>  arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
>  1 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
> index db8c59d..800e7c4 100644
> --- a/arch/arc/include/asm/spinlock.h
> +++ b/arch/arc/include/asm/spinlock.h
> @@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
>  static inline int arch_read_trylock(arch_rwlock_t *rw)
>  {
>  	int ret = 0;
> +	unsigned long flags;
>  
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  
>  	/*
> @@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
>  	}
>  
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  
>  	smp_mb();
>  	return ret;
> @@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
>  static inline int arch_write_trylock(arch_rwlock_t *rw)
>  {
>  	int ret = 0;
> +	unsigned long flags;
>  
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  
>  	/*
> @@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
>  		ret = 1;
>  	}
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  
>  	return ret;
>  }
> @@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
>  
>  static inline void arch_read_unlock(arch_rwlock_t *rw)
>  {
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));


Isn't raw_spin_lock_irqsave() equivalent and more concise ?


>  	rw->counter++;
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  }
>  
>  static inline void arch_write_unlock(arch_rwlock_t *rw)
>  {
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  }
>  
>  #endif
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
@ 2015-11-02  9:42     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02  9:42 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> If we hold rw->lock_mutex and interrupt occures we may
> end up spinning on it for ever during softirq.
> 
> Below you may see an example for interrupt we get while
> nl_table_lock is holding its rw->lock_mutex and we spinned
> on it for ever.
> 
> The concept for the fix was taken from SPARC.
> 
> [2015-05-12 19:16:12] Stack Trace:
> [2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
> [2015-05-12 19:16:12]   dump_stack+0x68/0xac
> [2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
> [2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
> [2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
> [2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
> [2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
> [2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
> [2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
> [2015-05-12 19:16:13]   process_backlog+0x92/0x154
> [2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
> [2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
> [2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
> [2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
> [2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> ---
>  arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
>  1 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
> index db8c59d..800e7c4 100644
> --- a/arch/arc/include/asm/spinlock.h
> +++ b/arch/arc/include/asm/spinlock.h
> @@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
>  static inline int arch_read_trylock(arch_rwlock_t *rw)
>  {
>  	int ret = 0;
> +	unsigned long flags;
>  
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  
>  	/*
> @@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
>  	}
>  
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  
>  	smp_mb();
>  	return ret;
> @@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
>  static inline int arch_write_trylock(arch_rwlock_t *rw)
>  {
>  	int ret = 0;
> +	unsigned long flags;
>  
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  
>  	/*
> @@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
>  		ret = 1;
>  	}
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  
>  	return ret;
>  }
> @@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
>  
>  static inline void arch_read_unlock(arch_rwlock_t *rw)
>  {
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));


Isn't raw_spin_lock_irqsave() equivalent and more concise ?


>  	rw->counter++;
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  }
>  
>  static inline void arch_write_unlock(arch_rwlock_t *rw)
>  {
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
>  	arch_spin_lock(&(rw->lock_mutex));
>  	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
>  	arch_spin_unlock(&(rw->lock_mutex));
> +	local_irq_restore(flags);
>  }
>  
>  #endif
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
  2015-11-02  9:42     ` Vineet Gupta
@ 2015-11-02 10:03       ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02 10:03 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: Noam Camus, linux-snps-arc, linux-kernel, talz, gilf, cmetcalf

On Mon, Nov 02, 2015 at 03:12:49PM +0530, Vineet Gupta wrote:
> > @@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
> >  
> >  static inline void arch_read_unlock(arch_rwlock_t *rw)
> >  {
> > +	unsigned long flags;
> > +
> > +	local_irq_save(flags);
> >  	arch_spin_lock(&(rw->lock_mutex));
> 
> 
> Isn't raw_spin_lock_irqsave() equivalent and more concise ?

You might run into header file recursion issues; also raw_spinlock has
lockdep annotations added, whereas the above does not.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant
@ 2015-11-02 10:03       ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-02 10:03 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Nov 02, 2015@03:12:49PM +0530, Vineet Gupta wrote:
> > @@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
> >  
> >  static inline void arch_read_unlock(arch_rwlock_t *rw)
> >  {
> > +	unsigned long flags;
> > +
> > +	local_irq_save(flags);
> >  	arch_spin_lock(&(rw->lock_mutex));
> 
> 
> Isn't raw_spin_lock_irqsave() equivalent and more concise ?

You might run into header file recursion issues; also raw_spinlock has
lockdep annotations added, whereas the above does not.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02 10:56     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 10:56 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> This platform include boards:
> 	Hardware Emulator (HE)
> 	Simulator based upon nSIM.
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  MAINTAINERS                             |    6 +
>  arch/arc/plat-eznps/Kconfig             |   34 ++++
>  arch/arc/plat-eznps/Makefile            |    7 +
>  arch/arc/plat-eznps/entry.S             |   76 +++++++++


When trying to build with 2015.06 BE tools,

../arch/arc/plat-eznps/entry.S: Assembler messages:
../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr
(1<<28),[(0xFFFFF800+0x024)]'
make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
make[2]: *** [arch/arc/plat-eznps] Error 2

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
@ 2015-11-02 10:56     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 10:56 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This platform include boards:
> 	Hardware Emulator (HE)
> 	Simulator based upon nSIM.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  MAINTAINERS                             |    6 +
>  arch/arc/plat-eznps/Kconfig             |   34 ++++
>  arch/arc/plat-eznps/Makefile            |    7 +
>  arch/arc/plat-eznps/entry.S             |   76 +++++++++


When trying to build with 2015.06 BE tools,

../arch/arc/plat-eznps/entry.S: Assembler messages:
../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr
(1<<28),[(0xFFFFF800+0x024)]'
make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
make[2]: *** [arch/arc/plat-eznps] Error 2

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 02/20] clocksource: Add NPS400 timers driver
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02 11:03     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:03 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Daniel Lezcano, Rob Herring,
	Thomas Gleixner, John Stultz

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> ---

[snip]

> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower;
> +	u32 upper, old_upper;
> +	int cpu;
> +	int cluster;
> +	void *lower_p, *upper_p;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +	cpu = smp_processor_id();
> +	cluster = cpu >> NPS_CLUSTER_OFFSET;
> +	lower_p = (void *)nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +	local_irq_restore(flags);
> +
> +	upper = ioread32be(upper_p);

Consider using the _relaxed macros even if your platform doesn't have specific IO
barriers.

> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = upper;
> +	counter <<= 32;
> +	counter |= lower;

It is easier to read:

counter = (upper << 32) | lower;

> +	return (cycle_t)counter;
> +}
> +


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
@ 2015-11-02 11:03     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:03 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> Add internal tick generator which is shared by all cores.
> Each cluster of cores view it through dedicated address.
> This is used for SMP system where all CPUs synced by same
> clock source.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Rob Herring <robh+dt at kernel.org>
> ---

[snip]

> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower;
> +	u32 upper, old_upper;
> +	int cpu;
> +	int cluster;
> +	void *lower_p, *upper_p;
> +	unsigned long flags;
> +
> +	local_irq_save(flags);
> +	cpu = smp_processor_id();
> +	cluster = cpu >> NPS_CLUSTER_OFFSET;
> +	lower_p = (void *)nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +	local_irq_restore(flags);
> +
> +	upper = ioread32be(upper_p);

Consider using the _relaxed macros even if your platform doesn't have specific IO
barriers.

> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = upper;
> +	counter <<= 32;
> +	counter |= lower;

It is easier to read:

counter = (upper << 32) | lower;

> +	return (cycle_t)counter;
> +}
> +

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02 11:06     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:06 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> This commit should be left last since only now eznps platform
> is in state which one can actually use.
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/Kconfig  |    1 +
>  arch/arc/Makefile |    9 +++++++++
>  2 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index 689ccb3..8153b79 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
>  source "arch/arc/plat-tb10x/Kconfig"
>  source "arch/arc/plat-axs10x/Kconfig"
>  #New platform adds here
> +source "arch/arc/plat-eznps/Kconfig"
>  
>  endmenu
>  
> diff --git a/arch/arc/Makefile b/arch/arc/Makefile
> index 8a27a48..9e5928f 100644
> --- a/arch/arc/Makefile
> +++ b/arch/arc/Makefile
> @@ -99,6 +99,15 @@ core-y		+= arch/arc/boot/dts/
>  core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
>  core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
>  core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
> +core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
> +
> +ifdef CONFIG_ARC_PLAT_EZNPS
> +ifeq ($(KBUILD_SRC),)
> +KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include
> +else
> +KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
> +endif
> +endif

Are you sure you need special handling for out-of-tree build. The $srctree)
version shd work just fine for both !

>  
>  drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
>  
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
@ 2015-11-02 11:06     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:06 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This commit should be left last since only now eznps platform
> is in state which one can actually use.
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/Kconfig  |    1 +
>  arch/arc/Makefile |    9 +++++++++
>  2 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
> index 689ccb3..8153b79 100644
> --- a/arch/arc/Kconfig
> +++ b/arch/arc/Kconfig
> @@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
>  source "arch/arc/plat-tb10x/Kconfig"
>  source "arch/arc/plat-axs10x/Kconfig"
>  #New platform adds here
> +source "arch/arc/plat-eznps/Kconfig"
>  
>  endmenu
>  
> diff --git a/arch/arc/Makefile b/arch/arc/Makefile
> index 8a27a48..9e5928f 100644
> --- a/arch/arc/Makefile
> +++ b/arch/arc/Makefile
> @@ -99,6 +99,15 @@ core-y		+= arch/arc/boot/dts/
>  core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
>  core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
>  core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
> +core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
> +
> +ifdef CONFIG_ARC_PLAT_EZNPS
> +ifeq ($(KBUILD_SRC),)
> +KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include
> +else
> +KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
> +endif
> +endif

Are you sure you need special handling for out-of-tree build. The $srctree)
version shd work just fine for both !

>  
>  drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
>  
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 13/20] ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-02 11:56     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:56 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Peter Zijlstra, Gilad Ben Yossef

+CC Peter, Gilad

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> We need our own implementaions since we lack of LLSC.
> Our extended ISA provided with optimized solution for all 32bit
> operations we see in those three headers.
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/include/asm/atomic.h           |   69 +++++++++++++++++++++++++++++++
>  arch/arc/include/asm/bitops.h           |   49 ++++++++++++++++++++++
>  arch/arc/include/asm/cmpxchg.h          |   49 ++++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/ctop.h |    1 +
>  4 files changed, 168 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
> index c3ecda0..ca318c2 100644
> --- a/arch/arc/include/asm/atomic.h
> +++ b/arch/arc/include/asm/atomic.h
> @@ -17,6 +17,74 @@
>  #include <asm/barrier.h>
>  #include <asm/smp.h>
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS

Could you please move nps specific code to end in all the 3 files - just because
it is least general use case.

#ifdef CONFIG_ARC_HAS_LLSC

..
-#else	/* !CONFIG_ARC_HAS_LLSC */
+#elif !defined(CONFIG_ARC_PLAT_EZNPS)

+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+ nps code here
+
+#endif

> +static inline int atomic_read(const atomic_t *v)
> +{
> +	int temp;
> +
> +	__asm__ __volatile__(
> +	"	ld.di %0, [%1]"
> +	: "=r"(temp)
> +	: "r"(&v->counter)
> +	: "memory");
> +	return temp;
> +}
> +
> +static inline void atomic_set(atomic_t *v, int i)
> +{
> +	__asm__ __volatile__(
> +	"	st.di %0,[%1]"
> +	:
> +	: "r"(i), "r"(&v->counter)
> +	: "memory");
> +}
> +
> +#define ATOMIC_OP(op, c_op, asm_op)					\
> +static inline void atomic_##op(int i, atomic_t *v)			\
> +{									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	:								\
> +	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
> +	: "r2", "r3", "memory");					\
> +}									\
> +
> +#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
> +static inline int atomic_##op##_return(int i, atomic_t *v)		\
> +{									\
> +	unsigned int temp = i;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	"	mov %0, r2"						\
> +	: "+r"(temp)							\
> +	: "r"(&v->counter), "i"(asm_op)					\
> +	: "r2", "r3", "memory");					\
> +									\
> +	return v->counter;						\
> +}

atomic_op_return APIs require full barrier semantics (look at ARC normal
versions). So you need to add the smp_mb() calls both above and below the op
itself. This assumes that despite lack of enabling dcache for kernel, the current
hardware scheduling instructions (CTOP_INST_SCHD*) do imply some sort of barrier
semantics. If not then you don't need them as backend of smp_*() API.

> +
> +#define ATOMIC_OPS(op, c_op, asm_op)					\
> +	ATOMIC_OP(op, c_op, asm_op)					\
> +	ATOMIC_OP_RETURN(op, c_op, asm_op)
> +

+#ifndef CONFIG_ARC_PLAT_EZNPS

.... existing ATOMIC_*

+#else

> +ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
> +#define atomic_sub(i, v) atomic_add(-(i), (v))
> +#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
> +
> +ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
> +#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
> +ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
> +ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)


+#endif

> +
> +#undef ATOMIC_OPS
> +#undef ATOMIC_OP_RETURN
> +#undef ATOMIC_OP
> +#else /* CONFIG_ARC_PLAT_EZNPS */

This need not be copied.

>  #define atomic_read(v)  ((v)->counter)
>  
>  #ifdef CONFIG_ARC_HAS_LLSC
> @@ -186,6 +254,7 @@ ATOMIC_OP(xor, ^=, xor)
>  #undef SCOND_FAIL_RETRY_VAR_DEF
>  #undef SCOND_FAIL_RETRY_ASM
>  #undef SCOND_FAIL_RETRY_VARS
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
>  
>  /**
>   * __atomic_add_unless - add unless the number is a given value
> diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
> index 57c1f33..54ecbe4 100644
> --- a/arch/arc/include/asm/bitops.h
> +++ b/arch/arc/include/asm/bitops.h
> @@ -22,6 +22,48 @@
>  #include <asm/smp.h>
>  #endif
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS

Ditto - please move it to end !

> +#define BIT_OP(op, c_op, asm_op)					\
> +static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
> +{									\
> +	m += nr >> 5;							\
> +									\
> +	nr = (1UL << (nr & 0x1f));					\
> +	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
> +		nr = ~nr;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"	.word %2\n"						\
> +	:								\
> +	: "r"(nr), "r"(m), "i"(asm_op)					\
> +	: "r2", "r3", "memory");					\
> +}
> +
> +#define TEST_N_BIT_OP(op, c_op, asm_op)					\
> +static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
> +{									\
> +	unsigned long old;						\
> +									\
> +	m += nr >> 5;							\

smp_mb() needed here !

> +									\
> +	old = (1UL << (nr & 0x1f));					\

So you are reusing @old: for input bitmask as well as output value which is kind
of confusing but that's how the instructions works it seems.


> +	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
> +		old = ~old;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	"	mov %0, r2"						\
> +	: "+r"(old)							\
> +	: "r"(m), "i"(asm_op)						\
> +	: "r2", "r3", "memory");					\

smp_mb() needed here !

> +									\
> +	return (old & (1 << nr)) != 0;					\
> +}
> +#else /* CONFIG_ARC_PLAT_EZNPS */
>  #if defined(CONFIG_ARC_HAS_LLSC)
>  
>  /*
> @@ -155,6 +197,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
>  }
>  
>  #endif /* CONFIG_ARC_HAS_LLSC */
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
>  
>  /***************************************
>   * Non atomic variants
> @@ -196,9 +239,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
>  	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
>  	__TEST_N_BIT_OP(op, c_op, asm_op)
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
> +BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
> +BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
> +#else
>  BIT_OPS(set, |, bset)
>  BIT_OPS(clear, & ~, bclr)
>  BIT_OPS(change, ^, bxor)
> +#endif

Here again, please swap them around !

>  
>  /*
>   * This routine doesn't need to be atomic.
> diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
> index af7a2db..8578586 100644
> --- a/arch/arc/include/asm/cmpxchg.h
> +++ b/arch/arc/include/asm/cmpxchg.h
> @@ -14,6 +14,53 @@
>  #include <asm/barrier.h>
>  #include <asm/smp.h>
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +static inline unsigned long
> +__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
> +{
> +	write_aux_reg(CTOP_AUX_GPA1, expected);
> +

smp_mb()

> +	__asm__ __volatile__(
> +	"	mov r2, %0\n"
> +	"	mov r3, %1\n"
> +	"	.word %2\n"
> +	"	mov %0, r2"
> +	: "+r"(new)
> +	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
> +	: "r2", "r3", "memory");

smp_mb()

> +
> +	return new;
> +}
> +
> +#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
> +				(unsigned long)(o), (unsigned long)(n)))
> +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))

Do these have to be duplicated !

> +
> +static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
> +				   int size)
> +{
> +	extern unsigned long __xchg_bad_pointer(void);
> +
> +	switch (size) {
> +	case 4:

smp_mb()

> +		__asm__ __volatile__(
> +		"	mov r2, %0\n"
> +		"	mov r3, %1\n"
> +		"	.word %2\n"
> +		"	mov %0, r2\n"
> +		: "+r"(val)
> +		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
> +		: "r2", "r3", "memory");
> +

smp_mb()

> +		return val;
> +	}
> +	return __xchg_bad_pointer();
> +}
> +
> +#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
> +						 sizeof(*(ptr))))
> +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
> +#else /* CONFIG_ARC_PLAT_EZNPS */
>  #ifdef CONFIG_ARC_HAS_LLSC
>  
>  static inline unsigned long
> @@ -158,4 +205,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
>   */
>  #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
>  
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
> +
>  #endif
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> index b708f9f..655a860 100644
> --- a/arch/arc/plat-eznps/include/plat/ctop.h
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -34,6 +34,7 @@
>  #define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
>  #define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
>  #define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
> +#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)

This one is standing out - can u not squash this hunk with the patch which
introduces CTOP_INST_EXC* or one which adds various CTOP_AUX_*

>  #define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
>  
>  /* EZchip core instructions */
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 13/20] ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
@ 2015-11-02 11:56     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-02 11:56 UTC (permalink / raw)
  To: linux-snps-arc

+CC Peter, Gilad

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> We need our own implementaions since we lack of LLSC.
> Our extended ISA provided with optimized solution for all 32bit
> operations we see in those three headers.
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/include/asm/atomic.h           |   69 +++++++++++++++++++++++++++++++
>  arch/arc/include/asm/bitops.h           |   49 ++++++++++++++++++++++
>  arch/arc/include/asm/cmpxchg.h          |   49 ++++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/ctop.h |    1 +
>  4 files changed, 168 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
> index c3ecda0..ca318c2 100644
> --- a/arch/arc/include/asm/atomic.h
> +++ b/arch/arc/include/asm/atomic.h
> @@ -17,6 +17,74 @@
>  #include <asm/barrier.h>
>  #include <asm/smp.h>
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS

Could you please move nps specific code to end in all the 3 files - just because
it is least general use case.

#ifdef CONFIG_ARC_HAS_LLSC

..
-#else	/* !CONFIG_ARC_HAS_LLSC */
+#elif !defined(CONFIG_ARC_PLAT_EZNPS)

+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+ nps code here
+
+#endif

> +static inline int atomic_read(const atomic_t *v)
> +{
> +	int temp;
> +
> +	__asm__ __volatile__(
> +	"	ld.di %0, [%1]"
> +	: "=r"(temp)
> +	: "r"(&v->counter)
> +	: "memory");
> +	return temp;
> +}
> +
> +static inline void atomic_set(atomic_t *v, int i)
> +{
> +	__asm__ __volatile__(
> +	"	st.di %0,[%1]"
> +	:
> +	: "r"(i), "r"(&v->counter)
> +	: "memory");
> +}
> +
> +#define ATOMIC_OP(op, c_op, asm_op)					\
> +static inline void atomic_##op(int i, atomic_t *v)			\
> +{									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	:								\
> +	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
> +	: "r2", "r3", "memory");					\
> +}									\
> +
> +#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
> +static inline int atomic_##op##_return(int i, atomic_t *v)		\
> +{									\
> +	unsigned int temp = i;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	"	mov %0, r2"						\
> +	: "+r"(temp)							\
> +	: "r"(&v->counter), "i"(asm_op)					\
> +	: "r2", "r3", "memory");					\
> +									\
> +	return v->counter;						\
> +}

atomic_op_return APIs require full barrier semantics (look at ARC normal
versions). So you need to add the smp_mb() calls both above and below the op
itself. This assumes that despite lack of enabling dcache for kernel, the current
hardware scheduling instructions (CTOP_INST_SCHD*) do imply some sort of barrier
semantics. If not then you don't need them as backend of smp_*() API.

> +
> +#define ATOMIC_OPS(op, c_op, asm_op)					\
> +	ATOMIC_OP(op, c_op, asm_op)					\
> +	ATOMIC_OP_RETURN(op, c_op, asm_op)
> +

+#ifndef CONFIG_ARC_PLAT_EZNPS

.... existing ATOMIC_*

+#else

> +ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
> +#define atomic_sub(i, v) atomic_add(-(i), (v))
> +#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
> +
> +ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
> +#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
> +ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
> +ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)


+#endif

> +
> +#undef ATOMIC_OPS
> +#undef ATOMIC_OP_RETURN
> +#undef ATOMIC_OP
> +#else /* CONFIG_ARC_PLAT_EZNPS */

This need not be copied.

>  #define atomic_read(v)  ((v)->counter)
>  
>  #ifdef CONFIG_ARC_HAS_LLSC
> @@ -186,6 +254,7 @@ ATOMIC_OP(xor, ^=, xor)
>  #undef SCOND_FAIL_RETRY_VAR_DEF
>  #undef SCOND_FAIL_RETRY_ASM
>  #undef SCOND_FAIL_RETRY_VARS
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
>  
>  /**
>   * __atomic_add_unless - add unless the number is a given value
> diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
> index 57c1f33..54ecbe4 100644
> --- a/arch/arc/include/asm/bitops.h
> +++ b/arch/arc/include/asm/bitops.h
> @@ -22,6 +22,48 @@
>  #include <asm/smp.h>
>  #endif
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS

Ditto - please move it to end !

> +#define BIT_OP(op, c_op, asm_op)					\
> +static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
> +{									\
> +	m += nr >> 5;							\
> +									\
> +	nr = (1UL << (nr & 0x1f));					\
> +	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
> +		nr = ~nr;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"	.word %2\n"						\
> +	:								\
> +	: "r"(nr), "r"(m), "i"(asm_op)					\
> +	: "r2", "r3", "memory");					\
> +}
> +
> +#define TEST_N_BIT_OP(op, c_op, asm_op)					\
> +static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
> +{									\
> +	unsigned long old;						\
> +									\
> +	m += nr >> 5;							\

smp_mb() needed here !

> +									\
> +	old = (1UL << (nr & 0x1f));					\

So you are reusing @old: for input bitmask as well as output value which is kind
of confusing but that's how the instructions works it seems.


> +	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
> +		old = ~old;						\
> +									\
> +	__asm__ __volatile__(						\
> +	"	mov r2, %0\n"						\
> +	"	mov r3, %1\n"						\
> +	"       .word %2\n"						\
> +	"	mov %0, r2"						\
> +	: "+r"(old)							\
> +	: "r"(m), "i"(asm_op)						\
> +	: "r2", "r3", "memory");					\

smp_mb() needed here !

> +									\
> +	return (old & (1 << nr)) != 0;					\
> +}
> +#else /* CONFIG_ARC_PLAT_EZNPS */
>  #if defined(CONFIG_ARC_HAS_LLSC)
>  
>  /*
> @@ -155,6 +197,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
>  }
>  
>  #endif /* CONFIG_ARC_HAS_LLSC */
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
>  
>  /***************************************
>   * Non atomic variants
> @@ -196,9 +239,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
>  	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
>  	__TEST_N_BIT_OP(op, c_op, asm_op)
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
> +BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
> +BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
> +#else
>  BIT_OPS(set, |, bset)
>  BIT_OPS(clear, & ~, bclr)
>  BIT_OPS(change, ^, bxor)
> +#endif

Here again, please swap them around !

>  
>  /*
>   * This routine doesn't need to be atomic.
> diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
> index af7a2db..8578586 100644
> --- a/arch/arc/include/asm/cmpxchg.h
> +++ b/arch/arc/include/asm/cmpxchg.h
> @@ -14,6 +14,53 @@
>  #include <asm/barrier.h>
>  #include <asm/smp.h>
>  
> +#ifdef CONFIG_ARC_PLAT_EZNPS
> +static inline unsigned long
> +__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
> +{
> +	write_aux_reg(CTOP_AUX_GPA1, expected);
> +

smp_mb()

> +	__asm__ __volatile__(
> +	"	mov r2, %0\n"
> +	"	mov r3, %1\n"
> +	"	.word %2\n"
> +	"	mov %0, r2"
> +	: "+r"(new)
> +	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
> +	: "r2", "r3", "memory");

smp_mb()

> +
> +	return new;
> +}
> +
> +#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
> +				(unsigned long)(o), (unsigned long)(n)))
> +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))

Do these have to be duplicated !

> +
> +static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
> +				   int size)
> +{
> +	extern unsigned long __xchg_bad_pointer(void);
> +
> +	switch (size) {
> +	case 4:

smp_mb()

> +		__asm__ __volatile__(
> +		"	mov r2, %0\n"
> +		"	mov r3, %1\n"
> +		"	.word %2\n"
> +		"	mov %0, r2\n"
> +		: "+r"(val)
> +		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
> +		: "r2", "r3", "memory");
> +

smp_mb()

> +		return val;
> +	}
> +	return __xchg_bad_pointer();
> +}
> +
> +#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
> +						 sizeof(*(ptr))))
> +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
> +#else /* CONFIG_ARC_PLAT_EZNPS */
>  #ifdef CONFIG_ARC_HAS_LLSC
>  
>  static inline unsigned long
> @@ -158,4 +205,6 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
>   */
>  #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
>  
> +#endif /* CONFIG_ARC_PLAT_EZNPS */
> +
>  #endif
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> index b708f9f..655a860 100644
> --- a/arch/arc/plat-eznps/include/plat/ctop.h
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -34,6 +34,7 @@
>  #define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
>  #define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
>  #define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
> +#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)

This one is standing out - can u not squash this hunk with the patch which
introduces CTOP_INST_EXC* or one which adds various CTOP_AUX_*

>  #define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
>  
>  /* EZchip core instructions */
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
  2015-11-02  7:52     ` Vineet Gupta
@ 2015-11-02 12:16       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02 12:16 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: Chris Metcalf, Gil Fruchter, Tal Zilcer, linux-kernel

> From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
> Sent: Monday, November 02, 2015 9:53 AM

> Again this break bisectability - it needs to be placed before you use this #define in patch 3/20.
> Anyhow since you are doing stuff via DT, why not get this value from DT itself instead of hard coding.

OK I will change order.
However last commit should protect us since without it nothing will be compiled.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ
@ 2015-11-02 12:16       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02 12:16 UTC (permalink / raw)
  To: linux-snps-arc

> From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
> Sent: Monday, November 02, 2015 9:53 AM

> Again this break bisectability - it needs to be placed before you use this #define in patch 3/20.
> Anyhow since you are doing stuff via DT, why not get this value from DT itself instead of hard coding.

OK I will change order.
However last commit should protect us since without it nothing will be compiled.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
  2015-11-02  8:02     ` Vineet Gupta
@ 2015-11-02 13:08       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02 13:08 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: Gil Fruchter, Peter Zijlstra, Tal Zilcer, linux-kernel, Chris Metcalf

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 10:03 AM

> Do u need this even for mandatory barriers whose semantics are not related to SMP at all ? I think you need them only for smb_*
Yes I do.
For example it is used to proceed access to our Global Interrupt Manager (GIM) when we want to make sure that driver of some device committed all read/writes before we are acknowledging the GIM.
We are not falling to use "sync" since we prefer to have HW thread schedule in the meantime we wait for load/store to be done.

- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers
@ 2015-11-02 13:08       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-02 13:08 UTC (permalink / raw)
  To: linux-snps-arc

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 10:03 AM

> Do u need this even for mandatory barriers whose semantics are not related to SMP at all ? I think you need them only for smb_*
Yes I do.
For example it is used to proceed access to our Global Interrupt Manager (GIM) when we want to make sure that driver of some device committed all read/writes before we are acknowledging the GIM.
We are not falling to use "sync" since we prefer to have HW thread schedule in the meantime we wait for load/store to be done.

- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-02  9:21     ` Peter Zijlstra
@ 2015-11-03 14:02       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 14:02 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: linux-snps-arc, linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

From: Peter Zijlstra [mailto:peterz@infradead.org] 
Sent: Monday, November 02, 2015 11:22 AM


> At which point you might want to revisit:

> arch/arc/include/asm/processor.h:#define cpu_relax_lowlatency() cpu_relax()
Thanks, I will define this as barrier since cpu_relax() may take out current logical CPU for many cycles.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-03 14:02       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 14:02 UTC (permalink / raw)
  To: linux-snps-arc

From: Peter Zijlstra [mailto:peterz@infradead.org] 
Sent: Monday, November 02, 2015 11:22 AM


> At which point you might want to revisit:

> arch/arc/include/asm/processor.h:#define cpu_relax_lowlatency() cpu_relax()
Thanks, I will define this as barrier since cpu_relax() may take out current logical CPU for many cycles.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 02/20] clocksource: Add NPS400 timers driver
  2015-11-02 11:03     ` Vineet Gupta
@ 2015-11-03 15:18       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:18 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf,
	Daniel Lezcano, Rob Herring, Thomas Gleixner, John Stultz

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 1:04 PM

>> +
>> +	upper = ioread32be(upper_p);

>Consider using the _relaxed macros even if your platform doesn't have specific IO barriers.
[Noam Camus] What is the big endian flavor for _relaxed macros.
 
>> +	counter = upper;
>> +	counter <<= 32;
>> +	counter |= lower;

>It is easier to read:

>counter = (upper << 32) | lower;

Thanks I will update

- Noam


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 02/20] clocksource: Add NPS400 timers driver
@ 2015-11-03 15:18       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:18 UTC (permalink / raw)
  To: linux-snps-arc

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Monday, November 02, 2015 1:04 PM

>> +
>> +	upper = ioread32be(upper_p);

>Consider using the _relaxed macros even if your platform doesn't have specific IO barriers.
[Noam Camus] What is the big endian flavor for _relaxed macros.
 
>> +	counter = upper;
>> +	counter <<= 32;
>> +	counter |= lower;

>It is easier to read:

>counter = (upper << 32) | lower;

Thanks I will update

- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
  2015-11-02 11:06     ` Vineet Gupta
@ 2015-11-03 15:32       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:32 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

>From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
>Sent: Monday, November 02, 2015 1:07 PM

>> +ifdef CONFIG_ARC_PLAT_EZNPS
>> +ifeq ($(KBUILD_SRC),)
>> +KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include else KBUILD_CPPFLAGS 
>> ++= -I$(srctree)/arch/arc/plat-eznps/include
>> +endif
>> +endif

>Are you sure you need special handling for out-of-tree build. The $srctree) version shd work just fine for both !
Thanks, I will use $(srctree) for both

- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile
@ 2015-11-03 15:32       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:32 UTC (permalink / raw)
  To: linux-snps-arc

>From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
>Sent: Monday, November 02, 2015 1:07 PM

>> +ifdef CONFIG_ARC_PLAT_EZNPS
>> +ifeq ($(KBUILD_SRC),)
>> +KBUILD_CPPFLAGS += -Iarch/arc/plat-eznps/include else KBUILD_CPPFLAGS 
>> ++= -I$(srctree)/arch/arc/plat-eznps/include
>> +endif
>> +endif

>Are you sure you need special handling for out-of-tree build. The $srctree) version shd work just fine for both !
Thanks, I will use $(srctree) for both

- Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
  2015-11-02 10:56     ` Vineet Gupta
@ 2015-11-03 15:59       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:59 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

>From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
>Sent: Monday, November 02, 2015 12:57 PM


>When trying to build with 2015.06 BE tools,

>../arch/arc/plat-eznps/entry.S: Assembler messages:
>../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr (1<<28),[(0xFFFFF800+0x024)]'
>make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
>make[2]: *** [arch/arc/plat-eznps] Error 2

Need more info since I tried it locally with no success.
Can you try this single line on separate assembly test file.
I will then try such synthetic case here.
Please supply command line as well for GCC/AS. 

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
@ 2015-11-03 15:59       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-03 15:59 UTC (permalink / raw)
  To: linux-snps-arc

>From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
>Sent: Monday, November 02, 2015 12:57 PM


>When trying to build with 2015.06 BE tools,

>../arch/arc/plat-eznps/entry.S: Assembler messages:
>../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr (1<<28),[(0xFFFFF800+0x024)]'
>make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
>make[2]: *** [arch/arc/plat-eznps] Error 2

Need more info since I tried it locally with no success.
Can you try this single line on separate assembly test file.
I will then try such synthetic case here.
Please supply command line as well for GCC/AS. 

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
  2015-11-02 10:56     ` Vineet Gupta
@ 2015-11-04 12:38       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-04 12:38 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

>From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
>Sent: Monday, November 02, 2015 12:57 PM


>When trying to build with 2015.06 BE tools,

>../arch/arc/plat-eznps/entry.S: Assembler messages:
>../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr (1<<28),[(0xFFFFF800+0x024)]'
>make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
>make[2]: *** [arch/arc/plat-eznps] Error 2


I managed to reproduced this one.
The AUX address is S12 and assembler failed when I provided the address this way.
When I used (-0x800+0x024) it passed build.

Thanks
-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
@ 2015-11-04 12:38       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-04 12:38 UTC (permalink / raw)
  To: linux-snps-arc

>From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
>Sent: Monday, November 02, 2015 12:57 PM


>When trying to build with 2015.06 BE tools,

>../arch/arc/plat-eznps/entry.S: Assembler messages:
>../arch/arc/plat-eznps/entry.S:51: Error: bad instruction `sr (1<<28),[(0xFFFFF800+0x024)]'
>make[3]: *** [arch/arc/plat-eznps/entry.o] Error 1
>make[2]: *** [arch/arc/plat-eznps] Error 2


I managed to reproduced this one.
The AUX address is S12 and assembler failed when I provided the address this way.
When I used (-0x800+0x024) it passed build.

Thanks
-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 00/20] eznps a new ARC platform
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-04 15:35   ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-04 15:35 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> This set introduce new platform to ARC architecture.
> Platform name called "eznps" for working with EZchip NPS400
> Network Proccessor.
> NPS400 is targeted to service "fast path" network applications.
> 
> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
> got 16 HW threats. 

threads - although it might as well be a thread to others doing network SoC :-)

This is basically SMT core where at any point of
> time only one HW thread is active.
> Each core have HW scheduler that round robin between eligible HW
> threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
> There is no cache coherency between cores so generic user applications
> and kernel do not use D$.
> 
> Cores got special memory mappings for huge pages (8MB).
> Mapping is static and should provide application enough memory without
> any "TLB miss". This mapping is on top of TLB mapping.
> 
> This is a basic set that will later be followed with additional
> set of patches with all advanced features.
> 
> Many thanks to all people helping to make this happen.
> 
> Regards,
> Noam Camus
> 
> Noam Camus (17):
>   Documentation: Add EZchip vendor to binding list
>   clocksource: Add NPS400 timers driver
>   irqchip: add nps Internal and external irqchips
>   ARC: Set vmalloc size from configuration
>   ARC: rwlock: disable interrupts in !LLSC variant
>   ARC: Mark cpu online only after it has executed the per cpu init
>     hook.
>   ARC: mm: use generic macros _BITUL()
>   ARC: add CONFIG_CLKSRC_OF support to time_init()
>   ARC: [plat-eznps] Add eznps board defconfig and dts
>   ARC: [plat-eznps] Add eznps platform
>   ARC: [plat-eznps] Use dedicated user stack top
>   ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
>   ARC: [plat-eznps] Use dedicated SMP barriers
>   ARC: [plat-eznps] Use dedicated identity auxiliary register.
>   ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
>   ARC: [plat-eznps] define IPI_IRQ
>   ARC: Add eznps platform to Kconfig and Makefile
> 
> Tal Zilcer (3):
>   ARC: Use res_service as entry point for secondaries
>   ARC: [plat-eznps] Use dedicated cpu_relax()
>   ARC: [plat-eznps] replace sync with proper cpu barrier
> 
>  Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
>  .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
>  .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
>  .../devicetree/bindings/vendor-prefixes.txt        |    1 +
>  MAINTAINERS                                        |    6 +
>  arch/arc/Kconfig                                   |    9 +
>  arch/arc/Makefile                                  |    9 +
>  arch/arc/boot/dts/eznps.dts                        |   76 ++++++
>  arch/arc/configs/nps_defconfig                     |   85 +++++++
>  arch/arc/include/asm/atomic.h                      |   69 +++++
>  arch/arc/include/asm/barrier.h                     |    8 +
>  arch/arc/include/asm/bitops.h                      |   49 ++++
>  arch/arc/include/asm/cmpxchg.h                     |   49 ++++
>  arch/arc/include/asm/entry-compact.h               |    8 +
>  arch/arc/include/asm/irq.h                         |    4 +
>  arch/arc/include/asm/pgtable.h                     |    2 +-
>  arch/arc/include/asm/processor.h                   |   32 ++-
>  arch/arc/include/asm/setup.h                       |    4 +
>  arch/arc/include/asm/smp.h                         |    2 +-
>  arch/arc/include/asm/spinlock.h                    |   14 +
>  arch/arc/kernel/ctx_sw.c                           |   20 ++
>  arch/arc/kernel/smp.c                              |    9 +-
>  arch/arc/kernel/time.c                             |    4 +
>  arch/arc/mm/tlb.c                                  |   12 +
>  arch/arc/plat-eznps/Kconfig                        |   34 +++
>  arch/arc/plat-eznps/Makefile                       |    7 +
>  arch/arc/plat-eznps/entry.S                        |   76 ++++++
>  arch/arc/plat-eznps/include/plat/ctop.h            |  265 ++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
>  arch/arc/plat-eznps/include/plat/smp.h             |   27 ++
>  arch/arc/plat-eznps/mtm.c                          |  152 +++++++++++
>  arch/arc/plat-eznps/platform.c                     |   40 +++
>  arch/arc/plat-eznps/smp.c                          |  160 ++++++++++++
>  drivers/clocksource/Makefile                       |    1 +
>  drivers/clocksource/timer-nps.c                    |  103 ++++++++
>  drivers/irqchip/Makefile                           |    1 +
>  drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
>  37 files changed, 1644 insertions(+), 11 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>  create mode 100644 arch/arc/boot/dts/eznps.dts
>  create mode 100644 arch/arc/configs/nps_defconfig
>  create mode 100644 arch/arc/plat-eznps/Kconfig
>  create mode 100644 arch/arc/plat-eznps/Makefile
>  create mode 100644 arch/arc/plat-eznps/entry.S
>  create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
>  create mode 100644 arch/arc/plat-eznps/mtm.c
>  create mode 100644 arch/arc/plat-eznps/platform.c
>  create mode 100644 arch/arc/plat-eznps/smp.c
>  create mode 100644 drivers/clocksource/timer-nps.c
>  create mode 100644 drivers/irqchip/irq-eznps.c
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 00/20] eznps a new ARC platform
@ 2015-11-04 15:35   ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-04 15:35 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This set introduce new platform to ARC architecture.
> Platform name called "eznps" for working with EZchip NPS400
> Network Proccessor.
> NPS400 is targeted to service "fast path" network applications.
> 
> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
> got 16 HW threats. 

threads - although it might as well be a thread to others doing network SoC :-)

This is basically SMT core where at any point of
> time only one HW thread is active.
> Each core have HW scheduler that round robin between eligible HW
> threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
> There is no cache coherency between cores so generic user applications
> and kernel do not use D$.
> 
> Cores got special memory mappings for huge pages (8MB).
> Mapping is static and should provide application enough memory without
> any "TLB miss". This mapping is on top of TLB mapping.
> 
> This is a basic set that will later be followed with additional
> set of patches with all advanced features.
> 
> Many thanks to all people helping to make this happen.
> 
> Regards,
> Noam Camus
> 
> Noam Camus (17):
>   Documentation: Add EZchip vendor to binding list
>   clocksource: Add NPS400 timers driver
>   irqchip: add nps Internal and external irqchips
>   ARC: Set vmalloc size from configuration
>   ARC: rwlock: disable interrupts in !LLSC variant
>   ARC: Mark cpu online only after it has executed the per cpu init
>     hook.
>   ARC: mm: use generic macros _BITUL()
>   ARC: add CONFIG_CLKSRC_OF support to time_init()
>   ARC: [plat-eznps] Add eznps board defconfig and dts
>   ARC: [plat-eznps] Add eznps platform
>   ARC: [plat-eznps] Use dedicated user stack top
>   ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg
>   ARC: [plat-eznps] Use dedicated SMP barriers
>   ARC: [plat-eznps] Use dedicated identity auxiliary register.
>   ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
>   ARC: [plat-eznps] define IPI_IRQ
>   ARC: Add eznps platform to Kconfig and Makefile
> 
> Tal Zilcer (3):
>   ARC: Use res_service as entry point for secondaries
>   ARC: [plat-eznps] Use dedicated cpu_relax()
>   ARC: [plat-eznps] replace sync with proper cpu barrier
> 
>  Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
>  .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
>  .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
>  .../devicetree/bindings/vendor-prefixes.txt        |    1 +
>  MAINTAINERS                                        |    6 +
>  arch/arc/Kconfig                                   |    9 +
>  arch/arc/Makefile                                  |    9 +
>  arch/arc/boot/dts/eznps.dts                        |   76 ++++++
>  arch/arc/configs/nps_defconfig                     |   85 +++++++
>  arch/arc/include/asm/atomic.h                      |   69 +++++
>  arch/arc/include/asm/barrier.h                     |    8 +
>  arch/arc/include/asm/bitops.h                      |   49 ++++
>  arch/arc/include/asm/cmpxchg.h                     |   49 ++++
>  arch/arc/include/asm/entry-compact.h               |    8 +
>  arch/arc/include/asm/irq.h                         |    4 +
>  arch/arc/include/asm/pgtable.h                     |    2 +-
>  arch/arc/include/asm/processor.h                   |   32 ++-
>  arch/arc/include/asm/setup.h                       |    4 +
>  arch/arc/include/asm/smp.h                         |    2 +-
>  arch/arc/include/asm/spinlock.h                    |   14 +
>  arch/arc/kernel/ctx_sw.c                           |   20 ++
>  arch/arc/kernel/smp.c                              |    9 +-
>  arch/arc/kernel/time.c                             |    4 +
>  arch/arc/mm/tlb.c                                  |   12 +
>  arch/arc/plat-eznps/Kconfig                        |   34 +++
>  arch/arc/plat-eznps/Makefile                       |    7 +
>  arch/arc/plat-eznps/entry.S                        |   76 ++++++
>  arch/arc/plat-eznps/include/plat/ctop.h            |  265 ++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
>  arch/arc/plat-eznps/include/plat/smp.h             |   27 ++
>  arch/arc/plat-eznps/mtm.c                          |  152 +++++++++++
>  arch/arc/plat-eznps/platform.c                     |   40 +++
>  arch/arc/plat-eznps/smp.c                          |  160 ++++++++++++
>  drivers/clocksource/Makefile                       |    1 +
>  drivers/clocksource/timer-nps.c                    |  103 ++++++++
>  drivers/irqchip/Makefile                           |    1 +
>  drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
>  37 files changed, 1644 insertions(+), 11 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
>  create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
>  create mode 100644 arch/arc/boot/dts/eznps.dts
>  create mode 100644 arch/arc/configs/nps_defconfig
>  create mode 100644 arch/arc/plat-eznps/Kconfig
>  create mode 100644 arch/arc/plat-eznps/Makefile
>  create mode 100644 arch/arc/plat-eznps/entry.S
>  create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
>  create mode 100644 arch/arc/plat-eznps/mtm.c
>  create mode 100644 arch/arc/plat-eznps/platform.c
>  create mode 100644 arch/arc/plat-eznps/smp.c
>  create mode 100644 drivers/clocksource/timer-nps.c
>  create mode 100644 drivers/irqchip/irq-eznps.c
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 00/20] eznps a new ARC platform
  2015-11-04 15:35   ` Vineet Gupta
@ 2015-11-04 15:53     ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-04 15:53 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

>From: Vineet Gupta [mailto:vineetg76@gmail.com] On Behalf Of Vineet Gupta
>Sent: Wednesday, November 04, 2015 5:35 PM

>> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core got 16 
>> HW threats.

>threads - although it might as well be a thread to others doing network SoC :-)
Thanks

V2 is ready :)

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 00/20] eznps a new ARC platform
@ 2015-11-04 15:53     ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-04 15:53 UTC (permalink / raw)
  To: linux-snps-arc

>From: Vineet Gupta [mailto:vineetg76 at gmail.com] On Behalf Of Vineet Gupta
>Sent: Wednesday, November 04, 2015 5:35 PM

>> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core got 16 
>> HW threats.

>threads - although it might as well be a thread to others doing network SoC :-)
Thanks

V2 is ready :)

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v1 00/20] eznps a new ARC platform
  2015-11-04 15:53     ` Noam Camus
@ 2015-11-04 17:42       ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-04 17:42 UTC (permalink / raw)
  To: Noam Camus, Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

don't post it yet - im yet to finish the review of mail patch !

________________________________________
From: Noam Camus [noamc@ezchip.com]
Sent: Wednesday, November 04, 2015 9:23 PM
To: Vineet Gupta; linux-snps-arc@lists.infradead.org
Cc: linux-kernel@vger.kernel.org; Tal Zilcer; Gil Fruchter; Chris Metcalf
Subject: RE: [PATCH v1 00/20] eznps a new ARC platform

>From: Vineet Gupta [mailto:vineetg76@gmail.com] On Behalf Of Vineet Gupta
>Sent: Wednesday, November 04, 2015 5:35 PM

>> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core got 16
>> HW threats.

>threads - although it might as well be a thread to others doing network SoC :-)
Thanks

V2 is ready :)

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 00/20] eznps a new ARC platform
@ 2015-11-04 17:42       ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-04 17:42 UTC (permalink / raw)
  To: linux-snps-arc

don't post it yet - im yet to finish the review of mail patch !

________________________________________
From: Noam Camus [noamc@ezchip.com]
Sent: Wednesday, November 04, 2015 9:23 PM
To: Vineet Gupta; linux-snps-arc at lists.infradead.org
Cc: linux-kernel at vger.kernel.org; Tal Zilcer; Gil Fruchter; Chris Metcalf
Subject: RE: [PATCH v1 00/20] eznps a new ARC platform

>From: Vineet Gupta [mailto:vineetg76 at gmail.com] On Behalf Of Vineet Gupta
>Sent: Wednesday, November 04, 2015 5:35 PM

>> NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core got 16
>> HW threats.

>threads - although it might as well be a thread to others doing network SoC :-)
Thanks

V2 is ready :)

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
  2015-10-31 13:15   ` Noam Camus
@ 2015-11-05  5:09     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-05  5:09 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> This platform include boards:
> 	Hardware Emulator (HE)
> 	Simulator based upon nSIM.
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  MAINTAINERS                             |    6 +
>  arch/arc/plat-eznps/Kconfig             |   34 ++++
>  arch/arc/plat-eznps/Makefile            |    7 +
>  arch/arc/plat-eznps/entry.S             |   76 +++++++++
>  arch/arc/plat-eznps/include/plat/ctop.h |  264 +++++++++++++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
>  arch/arc/plat-eznps/include/plat/smp.h  |   27 +++
>  arch/arc/plat-eznps/mtm.c               |  152 ++++++++++++++++++
>  arch/arc/plat-eznps/platform.c          |   40 +++++
>  arch/arc/plat-eznps/smp.c               |  160 +++++++++++++++++++
>  10 files changed, 826 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arc/plat-eznps/Kconfig
>  create mode 100644 arch/arc/plat-eznps/Makefile
>  create mode 100644 arch/arc/plat-eznps/entry.S
>  create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
>  create mode 100644 arch/arc/plat-eznps/mtm.c
>  create mode 100644 arch/arc/plat-eznps/platform.c
>  create mode 100644 arch/arc/plat-eznps/smp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 08adb4a..c63ca18 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4171,6 +4171,12 @@ S:	Maintained
>  F:	drivers/video/fbdev/exynos/exynos_mipi*
>  F:	include/video/exynos_mipi*
>  
> +EZchip NPS platform support
> +M:	Noam Camus <noamc@ezchip.com>
> +S:	Supported
> +F:	arch/arc/plat-eznps
> +F:	arch/arc/boot/dts/eznps.dts
> +
>  F71805F HARDWARE MONITORING DRIVER
>  M:	Jean Delvare <jdelvare@suse.com>
>  L:	lm-sensors@lm-sensors.org
> diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
> new file mode 100644
> index 0000000..510354f
> --- /dev/null
> +++ b/arch/arc/plat-eznps/Kconfig
> @@ -0,0 +1,34 @@
> +#
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +#
> +
> +menuconfig ARC_PLAT_EZNPS
> +	bool "\"EZchip\" ARC dev platform"
> +	select ARC_HAS_COH_CACHES if SMP
> +	select CPU_BIG_ENDIAN
> +	select CLKSRC_OF
> +	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
> +	help
> +	  Support for EZchip development platforms,
> +	  based on ARC700 cores.
> +	  We handle few flavours:
> +	    - Hardware Emulator AKA HE which is FPGA based chasis
> +	    - Simulator based on MetaWare nSIM
> +	    - NPS400 chip based on ASIC
> +
> +config EZNPS_MTM_EXT
> +	bool "ARC-EZchip MTM Extensions"
> +	select CPUMASK_OFFSTACK
> +	depends on ARC_PLAT_EZNPS && SMP
> +	default y
> +	help
> +	  Here we add new hierarchy for CPUs topology.
> +	  We got:
> +		Core
> +		Thread
> +	  At the new thread level each CPU represent one HW thread.
> +	  At highest hierarchy each core contain 16 threads,
> +	  any of them seem like CPU from Linux point of view.
> +	  All threads within same core share the execution unit of the
> +	  core and HW scheduler round robin between them.
> diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
> new file mode 100644
> index 0000000..21091b1
> --- /dev/null
> +++ b/arch/arc/plat-eznps/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Makefile for the linux kernel.
> +#
> +
> +obj-y := entry.o platform.o
> +obj-$(CONFIG_SMP) += smp.o
> +obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
> diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
> new file mode 100644
> index 0000000..a3dec3e
> --- /dev/null
> +++ b/arch/arc/plat-eznps/entry.S
> @@ -0,0 +1,76 @@
> +/*******************************************************************************
> +
> +  EZNPS CPU startup Code
> +  Copyright(c) 2012 EZchip Technologies.
> +
> +  This program is free software; you can redistribute it and/or modify it
> +  under the terms and conditions of the GNU General Public License,
> +  version 2, as published by the Free Software Foundation.
> +
> +  This program is distributed in the hope it will be useful, but WITHOUT
> +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> +  more details.
> +
> +  The full GNU General Public License is included in this distribution in
> +  the file called "COPYING".
> +
> +*******************************************************************************/
> +#include <linux/linkage.h>
> +#include <asm/entry.h>
> +#include <asm/cache.h>
> +#include <plat/ctop.h>
> +
> +	.cpu A7
> +
> +	.section .text, "ax",@progbits
> +	.align 1024	; HW requierment for restart first PC
> +
> +ENTRY(res_service)
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +	; For HW thread != 0 there is no work.
> +	lr	r3, [CTOP_AUX_THREAD_ID]
> +	cmp	r3, 0
> +	jne	_stext

Don't use _stext - it new rols is to simply demarcate where kernel code starts and
not guaranteed to be code you want to jump to. Per latest head.S, it is stext

> +#endif
> +
> +#ifdef CONFIG_ARC_HAS_DCACHE
> +	; We do not have cache coherency mechanism,
> +	; so D$ need to be used very carefully.

Can these go in same line

> +	; Address space:
> +	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
> +	; 2G-3G: We disable D$ by setting this bit.
> +	; 3G-4G: D$ is disabled by architecture.
> +	; FMT are the huge pages for user application reside at 0-2G.
> +	; Only FMT left as one who can use D$ where each such page got
> +	; disable/enable bit for cachability.
> +	; Programmer will use FMT pages for private data so cache coherency
> +	; would not be a problem.
> +	; First thing we invalidate D$
> +	sr	1, [ARC_REG_DC_IVDC]
> +	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
> +#endif
> +
> +#ifdef CONFIG_SMP
> +	; check for boot CPU
> +	lr	r3, [CTOP_AUX_GLOBAL_ID]
> +	cmp	r3, 0
> +	jeq	_stext
> +
> +	; We set logical cpuid to be used by GET_CPUID
> +	; We do not use physical cpuid since we want ids to be continious when
> +	; it comes to cpus on the same quad cluster.
> +	; This is useful for applications that used shared resources of a quad
> +	; cluster such SRAMS.
> +	lr 	r3, [CTOP_AUX_CORE_ID]
> +	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
> +	lr	r3, [CTOP_AUX_CLUSTER_ID]
> +	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
> +	; r3 is used since we use short instruction and we need q-class reg
> +	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
> +	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
> +	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
> +#endif
> +
> +	j	_stext
> +END(res_service)
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> new file mode 100644
> index 0000000..b708f9f
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -0,0 +1,264 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef _PLAT_EZNPS_CTOP_H
> +#define _PLAT_EZNPS_CTOP_H
> +
> +#define NPS_HOST_REG_BASE		0xF6000000
> +
> +/* core auxiliary registers */
> +#define CTOP_AUX_BASE			0xFFFFF800
> +#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
> +#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
> +#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
> +#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
> +#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
> +#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
> +#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
> +#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
> +#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
> +#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
> +#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
> +#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
> +#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
> +#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
> +
> +/* EZchip core instructions */
> +#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
> +#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
> +#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
> +#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
> +#define CTOP_INST_SCHD_RW			0x3e6f7004
> +#define CTOP_INST_SCHD_RD			0x3e6f7084
> +#define CTOP_INST_ASRI_0_R3			0x3b56003e
> +#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
> +#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
> +#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
> +#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
> +#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
> +#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
> +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
> +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
> +#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
> +
> +/* Do not use D$ for address in 2G-3G */
> +#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
> +
> +#ifndef __ASSEMBLY__
> +#define NPS_MSU_BLKID			0x018
> +#define NPS_CRG_BLKID			0x480
> +#define NPS_CRG_SYNC_BIT		BIT(0)
> +
> +#define NPS_GIM_BLKID			0x5C0
> +#define NPS_GIM_UART_LINE		BIT(7)
> +#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
> +#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
> +
> +/* CPU global ID */
> +struct global_id {
> +	union {
> +		struct {
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +			u32 __reserved:20, cluster:4, core:4, thread:4;
> +#else
> +			u32 __reserved:24, cluster:4, core:4;
> +#endif
> +		};
> +		u32 value;
> +	};
> +};
> +
> +/*
> + * Convert logical to physical CPU IDs
> + *
> + * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
> + * Now quad of logical clusters id's are adjacent physicaly,

physically

> + * like can be seen in following table.
> + * Cluster ids are in format: logical (physical)
> + *
> + * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
> + * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
> + * ============================================
> + * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
> + * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
> + * --------------------------------------------
> + *   |   0     |   1     ||    2     |    3

I can't quite understand how to read this table !

> + */
> +static inline int nps_cluster_logic_to_phys(int cluster)
> +{
> +	__asm__ __volatile__(
> +	"       mov r3,%0\n"
> +	"       .short %1\n"
> +	"       .word %2\n"
> +	"       mov %0,r3\n"
> +	: "+r"(cluster)
> +	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
> +	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
> +	: "r3");
> +
> +	return cluster;
> +}
> +
> +#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
> +	({ struct global_id gid; gid.value = cpu; \
> +		nps_cluster_logic_to_phys(gid.cluster); })
> +
> +struct nps_host_reg_address {
> +	union {
> +		struct {
> +			u32     base:8, cl_x:4, cl_y:4,
> +			blkid:6, reg:8, __reserved:2;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_mtm_cfg {
> +	union {
> +		struct {
> +			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
> +			__reserved:9, nat:3, ten:16;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_mtm_cpu_cfg {
> +	union {
> +		struct {
> +			u32 csa:22, dmsid:6, __reserved:3, cs:1;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_thr_init {
> +	union {
> +		struct {
> +			u32 str:1, __reserved:27, thr_id:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_thr_init_sts {
> +	union {
> +		struct {
> +			u32 bsy:1, err:1, __reserved:26, thr_id:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_udmc {
> +	union {
> +		struct {
> +			u32 dcp:1, cme:1, __reserved:20, nat:3,
> +			__reserved2:5, dcas:3;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_mt_ctrl {
> +	union {
> +		struct {
> +			u32 mten:1, hsen:1, scd:1, sten:1,
> +			__reserved:4, st_cnt:4, __reserved2:8,
> +			hs_cnt:8, __reserved3:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_hw_comply {
> +	union {
> +		struct {
> +			u32 me:1, le:1, te:1, knc:1, __reserved:28;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_lpc {
> +	union {
> +		struct {
> +			u32 mep:1, __reserved:31;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_address_non_cl {
> +	union {
> +		struct {
> +			u32 base:7, blkid:11, reg:12, __reserved:2;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_gim_p_int_dst {
> +	union {
> +		struct {
> +			u32 int_out_en:1, __reserved1:4,
> +			is:1, intm:2, __reserved2:4,
> +			nid:4, __reserved3:4, cid:4,
> +			__reserved4:4, tid:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
> +{
> +	struct nps_host_reg_address_non_cl reg_address;
> +
> +	reg_address.value = NPS_HOST_REG_BASE;
> +	reg_address.blkid = blkid;
> +	reg_address.reg = reg;
> +
> +	return (void *)reg_address.value;
> +}
> +
> +static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
> +{
> +	struct nps_host_reg_address reg_address;
> +	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
> +
> +	reg_address.value = NPS_HOST_REG_BASE;
> +	reg_address.cl_x  = (cl >> 2) & 0x3;
> +	reg_address.cl_y  = cl & 0x3;
> +	reg_address.blkid = blkid;
> +	reg_address.reg   = reg;
> +
> +	return (void *)reg_address.value;
> +}
> +
> +/* CRG registers */
> +#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
> +
> +/* GIM registers */
> +#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
> +#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
> +#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
> +#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
> +#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
> +#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
> +
> +#endif /* __ASEMBLY__ */
> +
> +#endif /* _PLAT_EZNPS_CTOP_H */
> diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
> new file mode 100644
> index 0000000..29b91b5
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/mtm.h
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef _PLAT_EZNPS_MTM_H
> +#define _PLAT_EZNPS_MTM_H
> +
> +#include <plat/ctop.h>
> +
> +static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
> +{
> +	struct global_id gid;
> +	u32 core, blkid;
> +
> +	gid.value = cpu;
> +	core = gid.core;
> +	blkid = (((core & 0x0C) << 2) | (core & 0x03));
> +
> +	return nps_host_reg(cpu, blkid, reg);
> +}
> +
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define NPS_CPU_TO_THREAD_NUM(cpu) \
> +	({ struct global_id gid; gid.value = cpu; gid.thread; })
> +
> +/* MTM registers */
> +#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
> +#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
> +#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
> +
> +#define get_thread(map) map.thread
> +#define eznps_max_cpus 4096
> +#define eznps_cpus_per_cluster	256
> +
> +void mtm_enable_core(unsigned int cpu);
> +int mtm_enable_thread(int cpu);
> +#else /* !CONFIG_EZNPS_MTM_EXT */
> +
> +#define get_thread(map) 0
> +#define eznps_max_cpus 256
> +#define eznps_cpus_per_cluster	16
> +#define mtm_enable_core(cpu)
> +#define mtm_enable_thread(cpu) 1
> +#define NPS_CPU_TO_THREAD_NUM(cpu) 0
> +
> +#endif /* CONFIG_EZNPS_MTM_EXT */
> +
> +#endif /* _PLAT_EZNPS_MTM_H */
> diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
> new file mode 100644
> index 0000000..7509443
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/smp.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef __PLAT_EZNPS_SMP_H
> +#define __PLAT_EZNPS_SMP_H
> +
> +#ifdef CONFIG_SMP
> +
> +extern struct cpumask _cpu_possible_mask;

Is this needed ?

> +void eznps_smp_init_cpu(unsigned int cpu);

You don't need this either - see below !

> +
> +#endif /* CONFIG_SMP */
> +
> +#endif
> diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
> new file mode 100644
> index 0000000..802c3c8
> --- /dev/null
> +++ b/arch/arc/plat-eznps/mtm.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/smp.h>
> +#include <linux/io.h>
> +#include <asm/arcregs.h>
> +#include <plat/mtm.h>
> +#include <plat/smp.h>
> +
> +#define MT_CTRL_HS_CNT		0xFF
> +#define MT_CTRL_ST_CNT		0xF
> +#define NPS_NUM_HW_THREADS	0x10
> +
> +static void mtm_init_nat(int cpu)
> +{
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +	struct nps_host_reg_aux_udmc udmc;
> +	int log_nat, nat = 0, i, t;
> +
> +	/* Iterate core threads and update nat */
> +	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
> +		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
> +
> +	switch (nat) {
> +	case 1:
> +		log_nat = 0;
> +		break;
> +	case 2:
> +		log_nat = 1;
> +		break;
> +	case 4:
> +		log_nat = 2;
> +		break;
> +	case 8:
> +		log_nat = 3;
> +		break;
> +	case 16:
> +		log_nat = 4;
> +		break;

Can u use a some ilog function do do this ?

> +	default:
> +		pr_warn("BUG: got non valid NAT %d!\n", nat);
> +		log_nat = 0;
> +		break;
> +	}
> +
> +	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
> +	udmc.nat = log_nat;
> +	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
> +
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.nat = log_nat;
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +}
> +
> +static void mtm_init_thread(int cpu)
> +{
> +	int i, tries = 5;
> +	struct nps_host_reg_thr_init thr_init;
> +	struct nps_host_reg_thr_init_sts thr_init_sts;
> +
> +	/* Set thread init register */
> +	thr_init.value = 0;
> +	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
> +	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
> +	thr_init.str = 1;
> +	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
> +
> +	/* Poll till thread init is done */
> +	for (i = 0; i < tries; i++) {
> +		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
> +		if (thr_init_sts.thr_id == thr_init.thr_id) {
> +			if (thr_init_sts.bsy)
> +				continue;
> +			else if (thr_init_sts.err)
> +				pr_warn("Failed to thread init cpu %u\n", cpu);
> +			break;
> +		}
> +
> +		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
> +		break;
> +	}
> +
> +	if (i == tries)
> +		pr_warn("Got thread init timeout for cpu %u\n", cpu);
> +}
> +
> +int mtm_enable_thread(int cpu)
> +{
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
> +		return 1;
> +
> +	/* Enable thread in mtm */
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +
> +	return 0;
> +}
> +
> +void mtm_enable_core(unsigned int cpu)
> +{
> +	int i;
> +	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
> +		return;
> +
> +	/* Initialize Number of Active Threads */
> +	mtm_init_nat(cpu);
> +
> +	/* Initialize mtm_cfg */
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.ten = 1;
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +
> +	/* Initialize all other threads in core */
> +	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
> +		mtm_init_thread(cpu + i);
> +
> +
> +	/* Enable HW schedule, stall counter, mtm */
> +	mt_ctrl.value = 0;
> +	mt_ctrl.hsen = 1;
> +	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
> +	mt_ctrl.sten = 1;
> +	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
> +	mt_ctrl.mten = 1;
> +	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
> +
> +	/*
> +	 * HW scheduling mechanism will start working
> +	 * Only after call to instruction "schd.rw".
> +	 * cpu_relax() calls "schd.rw" instruction.
> +	 */
> +	cpu_relax();
> +}
> diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
> new file mode 100644
> index 0000000..c84dfd9
> --- /dev/null
> +++ b/arch/arc/plat-eznps/platform.c
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/init.h>
> +#include <asm/io.h>
> +#include <asm/mach_desc.h>
> +#include <plat/smp.h>

This will go away

> +
> +/*----------------------- Machine Descriptions ------------------------------
> + *
> + * Machine description is simply a set of platform/board specific callbacks
> + * This is not directly related to DeviceTree based dynamic device creation,
> + * however as part of early device tree scan, we also select the right
> + * callback set, by matching the DT compatible name.
> + */

No Cargo Culting please. Delete this comment !

> +
> +static const char *eznps_compat[] __initconst = {
> +	"ezchip,arc-nps",
> +	NULL,
> +};
> +
> +MACHINE_START(NPS, "nps")
> +	.dt_compat	= eznps_compat,
> +#ifdef CONFIG_SMP
> +	.init_cpu_smp	= eznps_smp_init_cpu,  /* for each CPU */
> +#endif

This is not needed. See below !

> +MACHINE_END
> diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
> new file mode 100644
> index 0000000..0f8b51a
> --- /dev/null
> +++ b/arch/arc/plat-eznps/smp.c
> @@ -0,0 +1,160 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/smp.h>
> +#include <linux/of_fdt.h>
> +#include <linux/io.h>
> +#include <asm/irq.h>
> +#include <plat/ctop.h>
> +#include <plat/smp.h>
> +#include <plat/mtm.h>
> +
> +#define NPS_DEFAULT_MSID	0x34
> +#define NPS_MTM_CPU_CFG		0x90
> +
> +struct cpumask _cpu_possible_mask;
> +static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
> +
> +/* Get cpu map from device tree */
> +static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
> +{
> +	unsigned long dt_root = of_get_flat_dt_root();
> +	const char *buf;
> +
> +	buf = of_get_flat_dt_prop(dt_root, name, NULL);
> +	if (!buf)
> +		return 1;
> +
> +	cpulist_parse(buf, cpumask);
> +
> +	return 0;
> +}
> +
> +/* Update board cpu maps */
> +static void __init eznps_init_cpumasks(void)
> +{
> +	struct cpumask cpumask;
> +
> +	if (eznps_get_map("present-cpus", &cpumask)) {
> +		pr_err("Failed to get present-cpus from dtb");
> +		return;
> +	}
> +	init_cpu_present(&cpumask);
> +
> +	if (eznps_get_map("possible-cpus", &cpumask)) {
> +		pr_err("Failed to get possible-cpus from dtb");
> +		return;
> +	}
> +	init_cpu_possible(&cpumask);
> +}
> +
> +static void eznps_init_core(unsigned int cpu)
> +{
> +	u32 sync_value;
> +	struct nps_host_reg_aux_hw_comply hw_comply;
> +	struct nps_host_reg_aux_lpc lpc;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
> +		return;
> +
> +	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
> +	hw_comply.me  = 1;
> +	hw_comply.le  = 1;
> +	hw_comply.te  = 1;
> +	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
> +
> +	/* Enable MMU clock */
> +	lpc.mep = 1;
> +	write_aux_reg(CTOP_AUX_LPC, lpc.value);
> +
> +	/* Boot CPU only */
> +	if (!cpu) {
> +		/* Write to general purpose register in CRG */
> +		sync_value = ioread32be(REG_GEN_PURP_0);
> +		sync_value |= NPS_CRG_SYNC_BIT;
> +		iowrite32be(sync_value, REG_GEN_PURP_0);
> +	}
> +}
> +
> +/*
> + * Any SMP specific init any CPU does when it comes up.
> + * Here we setup the CPU to enable Inter-Processor-Interrupts
> + * Called for each CPU
> + * -Master      : init_IRQ()
> + * -Other(s)    : start_kernel_secondary()
> + */

This comment is no longer accurate, please get rid of it

> +void eznps_smp_init_cpu(unsigned int cpu)
> +{
> +	unsigned int rc;
> +
> +	rc = smp_ipi_irq_setup(cpu, IPI_IRQ);
> +	if (rc)
> +		panic("IPI IRQ %d reg failed on BOOT cpu\n", IPI_IRQ);

This is not just BOOT cpu ?

> +
> +	eznps_init_core(cpu);
> +	mtm_enable_core(cpu);
> +}
> +
> +/*
> + * Master kick starting another CPU
> + */
> +static void eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
> +{
> +	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
> +
> +	if (mtm_enable_thread(cpu) == 0)
> +		return;
> +
> +	/* set PC, dmsid, and start CPU */
> +	cpu_cfg.value = pc;
> +	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
> +	cpu_cfg.cs = 1;
> +	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
> +}
> +
> +static void eznps_ipi_send(int cpu)
> +{
> +	struct global_id gid;
> +	struct {
> +		union {
> +			struct {
> +				u32 num:8, cluster:8, core:8, thread:8;
> +			};
> +			u32 value;
> +		};
> +	} ipi;
> +
> +	gid.value = cpu;
> +	ipi.thread = get_thread(gid);
> +	ipi.core = gid.core;
> +	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
> +	ipi.num = IPI_IRQ;
> +
> +	__asm__ __volatile__(
> +	"	mov r3, %0\n"
> +	"	.word %1\n"
> +	:
> +	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
> +	: "r3");
> +}
> +
> +struct plat_smp_ops plat_smp_ops = {
> +	.info		= smp_cpuinfo_buf,
> +	.init_early_smp	= eznps_init_cpumasks,
> +	.cpu_kick	= eznps_smp_wakeup_cpu,
> +	.ipi_send	= eznps_ipi_send,

look at mcip.c to add eznps_smp_init_cpu() as smp op callback !

commit 286130ebf196d9643800977d57bdb7cda266b49e
Author: Vineet Gupta <vgupta@synopsys.com>
Date:   Wed Oct 14 14:38:02 2015 +0530

    ARC: smp: Introduce smp hook @init_irq_cpu called for all cores

    Note this is not part of platform owned static machine_desc,
    but more of device owned plat_smp_ops (rather misnamed) which a IPI
    provider or some such typically defines.

    This will help us seperate out the IPI registration from platform
    specific init_cpu_smp() into device specific init_irq_cpu()



^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform
@ 2015-11-05  5:09     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-05  5:09 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 31 October 2015 06:45 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This platform include boards:
> 	Hardware Emulator (HE)
> 	Simulator based upon nSIM.
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  MAINTAINERS                             |    6 +
>  arch/arc/plat-eznps/Kconfig             |   34 ++++
>  arch/arc/plat-eznps/Makefile            |    7 +
>  arch/arc/plat-eznps/entry.S             |   76 +++++++++
>  arch/arc/plat-eznps/include/plat/ctop.h |  264 +++++++++++++++++++++++++++++++
>  arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
>  arch/arc/plat-eznps/include/plat/smp.h  |   27 +++
>  arch/arc/plat-eznps/mtm.c               |  152 ++++++++++++++++++
>  arch/arc/plat-eznps/platform.c          |   40 +++++
>  arch/arc/plat-eznps/smp.c               |  160 +++++++++++++++++++
>  10 files changed, 826 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arc/plat-eznps/Kconfig
>  create mode 100644 arch/arc/plat-eznps/Makefile
>  create mode 100644 arch/arc/plat-eznps/entry.S
>  create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
>  create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
>  create mode 100644 arch/arc/plat-eznps/mtm.c
>  create mode 100644 arch/arc/plat-eznps/platform.c
>  create mode 100644 arch/arc/plat-eznps/smp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 08adb4a..c63ca18 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4171,6 +4171,12 @@ S:	Maintained
>  F:	drivers/video/fbdev/exynos/exynos_mipi*
>  F:	include/video/exynos_mipi*
>  
> +EZchip NPS platform support
> +M:	Noam Camus <noamc at ezchip.com>
> +S:	Supported
> +F:	arch/arc/plat-eznps
> +F:	arch/arc/boot/dts/eznps.dts
> +
>  F71805F HARDWARE MONITORING DRIVER
>  M:	Jean Delvare <jdelvare at suse.com>
>  L:	lm-sensors at lm-sensors.org
> diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
> new file mode 100644
> index 0000000..510354f
> --- /dev/null
> +++ b/arch/arc/plat-eznps/Kconfig
> @@ -0,0 +1,34 @@
> +#
> +# For a description of the syntax of this configuration file,
> +# see Documentation/kbuild/kconfig-language.txt.
> +#
> +
> +menuconfig ARC_PLAT_EZNPS
> +	bool "\"EZchip\" ARC dev platform"
> +	select ARC_HAS_COH_CACHES if SMP
> +	select CPU_BIG_ENDIAN
> +	select CLKSRC_OF
> +	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
> +	help
> +	  Support for EZchip development platforms,
> +	  based on ARC700 cores.
> +	  We handle few flavours:
> +	    - Hardware Emulator AKA HE which is FPGA based chasis
> +	    - Simulator based on MetaWare nSIM
> +	    - NPS400 chip based on ASIC
> +
> +config EZNPS_MTM_EXT
> +	bool "ARC-EZchip MTM Extensions"
> +	select CPUMASK_OFFSTACK
> +	depends on ARC_PLAT_EZNPS && SMP
> +	default y
> +	help
> +	  Here we add new hierarchy for CPUs topology.
> +	  We got:
> +		Core
> +		Thread
> +	  At the new thread level each CPU represent one HW thread.
> +	  At highest hierarchy each core contain 16 threads,
> +	  any of them seem like CPU from Linux point of view.
> +	  All threads within same core share the execution unit of the
> +	  core and HW scheduler round robin between them.
> diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
> new file mode 100644
> index 0000000..21091b1
> --- /dev/null
> +++ b/arch/arc/plat-eznps/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# Makefile for the linux kernel.
> +#
> +
> +obj-y := entry.o platform.o
> +obj-$(CONFIG_SMP) += smp.o
> +obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
> diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
> new file mode 100644
> index 0000000..a3dec3e
> --- /dev/null
> +++ b/arch/arc/plat-eznps/entry.S
> @@ -0,0 +1,76 @@
> +/*******************************************************************************
> +
> +  EZNPS CPU startup Code
> +  Copyright(c) 2012 EZchip Technologies.
> +
> +  This program is free software; you can redistribute it and/or modify it
> +  under the terms and conditions of the GNU General Public License,
> +  version 2, as published by the Free Software Foundation.
> +
> +  This program is distributed in the hope it will be useful, but WITHOUT
> +  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> +  more details.
> +
> +  The full GNU General Public License is included in this distribution in
> +  the file called "COPYING".
> +
> +*******************************************************************************/
> +#include <linux/linkage.h>
> +#include <asm/entry.h>
> +#include <asm/cache.h>
> +#include <plat/ctop.h>
> +
> +	.cpu A7
> +
> +	.section .text, "ax", at progbits
> +	.align 1024	; HW requierment for restart first PC
> +
> +ENTRY(res_service)
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +	; For HW thread != 0 there is no work.
> +	lr	r3, [CTOP_AUX_THREAD_ID]
> +	cmp	r3, 0
> +	jne	_stext

Don't use _stext - it new rols is to simply demarcate where kernel code starts and
not guaranteed to be code you want to jump to. Per latest head.S, it is stext

> +#endif
> +
> +#ifdef CONFIG_ARC_HAS_DCACHE
> +	; We do not have cache coherency mechanism,
> +	; so D$ need to be used very carefully.

Can these go in same line

> +	; Address space:
> +	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
> +	; 2G-3G: We disable D$ by setting this bit.
> +	; 3G-4G: D$ is disabled by architecture.
> +	; FMT are the huge pages for user application reside at 0-2G.
> +	; Only FMT left as one who can use D$ where each such page got
> +	; disable/enable bit for cachability.
> +	; Programmer will use FMT pages for private data so cache coherency
> +	; would not be a problem.
> +	; First thing we invalidate D$
> +	sr	1, [ARC_REG_DC_IVDC]
> +	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
> +#endif
> +
> +#ifdef CONFIG_SMP
> +	; check for boot CPU
> +	lr	r3, [CTOP_AUX_GLOBAL_ID]
> +	cmp	r3, 0
> +	jeq	_stext
> +
> +	; We set logical cpuid to be used by GET_CPUID
> +	; We do not use physical cpuid since we want ids to be continious when
> +	; it comes to cpus on the same quad cluster.
> +	; This is useful for applications that used shared resources of a quad
> +	; cluster such SRAMS.
> +	lr 	r3, [CTOP_AUX_CORE_ID]
> +	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
> +	lr	r3, [CTOP_AUX_CLUSTER_ID]
> +	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
> +	; r3 is used since we use short instruction and we need q-class reg
> +	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
> +	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
> +	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
> +#endif
> +
> +	j	_stext
> +END(res_service)
> diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
> new file mode 100644
> index 0000000..b708f9f
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/ctop.h
> @@ -0,0 +1,264 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef _PLAT_EZNPS_CTOP_H
> +#define _PLAT_EZNPS_CTOP_H
> +
> +#define NPS_HOST_REG_BASE		0xF6000000
> +
> +/* core auxiliary registers */
> +#define CTOP_AUX_BASE			0xFFFFF800
> +#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
> +#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
> +#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
> +#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
> +#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
> +#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
> +#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
> +#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
> +#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
> +#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
> +#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
> +#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
> +#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
> +#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
> +
> +/* EZchip core instructions */
> +#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
> +#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
> +#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
> +#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
> +#define CTOP_INST_SCHD_RW			0x3e6f7004
> +#define CTOP_INST_SCHD_RD			0x3e6f7084
> +#define CTOP_INST_ASRI_0_R3			0x3b56003e
> +#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
> +#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
> +#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
> +#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
> +#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
> +#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
> +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
> +#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
> +#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
> +
> +/* Do not use D$ for address in 2G-3G */
> +#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
> +
> +#ifndef __ASSEMBLY__
> +#define NPS_MSU_BLKID			0x018
> +#define NPS_CRG_BLKID			0x480
> +#define NPS_CRG_SYNC_BIT		BIT(0)
> +
> +#define NPS_GIM_BLKID			0x5C0
> +#define NPS_GIM_UART_LINE		BIT(7)
> +#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
> +#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
> +
> +/* CPU global ID */
> +struct global_id {
> +	union {
> +		struct {
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +			u32 __reserved:20, cluster:4, core:4, thread:4;
> +#else
> +			u32 __reserved:24, cluster:4, core:4;
> +#endif
> +		};
> +		u32 value;
> +	};
> +};
> +
> +/*
> + * Convert logical to physical CPU IDs
> + *
> + * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
> + * Now quad of logical clusters id's are adjacent physicaly,

physically

> + * like can be seen in following table.
> + * Cluster ids are in format: logical (physical)
> + *
> + * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
> + * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
> + * ============================================
> + * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
> + * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
> + * --------------------------------------------
> + *   |   0     |   1     ||    2     |    3

I can't quite understand how to read this table !

> + */
> +static inline int nps_cluster_logic_to_phys(int cluster)
> +{
> +	__asm__ __volatile__(
> +	"       mov r3,%0\n"
> +	"       .short %1\n"
> +	"       .word %2\n"
> +	"       mov %0,r3\n"
> +	: "+r"(cluster)
> +	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
> +	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
> +	: "r3");
> +
> +	return cluster;
> +}
> +
> +#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
> +	({ struct global_id gid; gid.value = cpu; \
> +		nps_cluster_logic_to_phys(gid.cluster); })
> +
> +struct nps_host_reg_address {
> +	union {
> +		struct {
> +			u32     base:8, cl_x:4, cl_y:4,
> +			blkid:6, reg:8, __reserved:2;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_mtm_cfg {
> +	union {
> +		struct {
> +			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
> +			__reserved:9, nat:3, ten:16;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_mtm_cpu_cfg {
> +	union {
> +		struct {
> +			u32 csa:22, dmsid:6, __reserved:3, cs:1;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_thr_init {
> +	union {
> +		struct {
> +			u32 str:1, __reserved:27, thr_id:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_thr_init_sts {
> +	union {
> +		struct {
> +			u32 bsy:1, err:1, __reserved:26, thr_id:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_udmc {
> +	union {
> +		struct {
> +			u32 dcp:1, cme:1, __reserved:20, nat:3,
> +			__reserved2:5, dcas:3;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_mt_ctrl {
> +	union {
> +		struct {
> +			u32 mten:1, hsen:1, scd:1, sten:1,
> +			__reserved:4, st_cnt:4, __reserved2:8,
> +			hs_cnt:8, __reserved3:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_hw_comply {
> +	union {
> +		struct {
> +			u32 me:1, le:1, te:1, knc:1, __reserved:28;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_aux_lpc {
> +	union {
> +		struct {
> +			u32 mep:1, __reserved:31;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_address_non_cl {
> +	union {
> +		struct {
> +			u32 base:7, blkid:11, reg:12, __reserved:2;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +struct nps_host_reg_gim_p_int_dst {
> +	union {
> +		struct {
> +			u32 int_out_en:1, __reserved1:4,
> +			is:1, intm:2, __reserved2:4,
> +			nid:4, __reserved3:4, cid:4,
> +			__reserved4:4, tid:4;
> +		};
> +		u32 value;
> +	};
> +};
> +
> +static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
> +{
> +	struct nps_host_reg_address_non_cl reg_address;
> +
> +	reg_address.value = NPS_HOST_REG_BASE;
> +	reg_address.blkid = blkid;
> +	reg_address.reg = reg;
> +
> +	return (void *)reg_address.value;
> +}
> +
> +static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
> +{
> +	struct nps_host_reg_address reg_address;
> +	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
> +
> +	reg_address.value = NPS_HOST_REG_BASE;
> +	reg_address.cl_x  = (cl >> 2) & 0x3;
> +	reg_address.cl_y  = cl & 0x3;
> +	reg_address.blkid = blkid;
> +	reg_address.reg   = reg;
> +
> +	return (void *)reg_address.value;
> +}
> +
> +/* CRG registers */
> +#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
> +
> +/* GIM registers */
> +#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
> +#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
> +#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
> +#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
> +#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
> +#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
> +
> +#endif /* __ASEMBLY__ */
> +
> +#endif /* _PLAT_EZNPS_CTOP_H */
> diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
> new file mode 100644
> index 0000000..29b91b5
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/mtm.h
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef _PLAT_EZNPS_MTM_H
> +#define _PLAT_EZNPS_MTM_H
> +
> +#include <plat/ctop.h>
> +
> +static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
> +{
> +	struct global_id gid;
> +	u32 core, blkid;
> +
> +	gid.value = cpu;
> +	core = gid.core;
> +	blkid = (((core & 0x0C) << 2) | (core & 0x03));
> +
> +	return nps_host_reg(cpu, blkid, reg);
> +}
> +
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +#define NPS_CPU_TO_THREAD_NUM(cpu) \
> +	({ struct global_id gid; gid.value = cpu; gid.thread; })
> +
> +/* MTM registers */
> +#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
> +#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
> +#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
> +
> +#define get_thread(map) map.thread
> +#define eznps_max_cpus 4096
> +#define eznps_cpus_per_cluster	256
> +
> +void mtm_enable_core(unsigned int cpu);
> +int mtm_enable_thread(int cpu);
> +#else /* !CONFIG_EZNPS_MTM_EXT */
> +
> +#define get_thread(map) 0
> +#define eznps_max_cpus 256
> +#define eznps_cpus_per_cluster	16
> +#define mtm_enable_core(cpu)
> +#define mtm_enable_thread(cpu) 1
> +#define NPS_CPU_TO_THREAD_NUM(cpu) 0
> +
> +#endif /* CONFIG_EZNPS_MTM_EXT */
> +
> +#endif /* _PLAT_EZNPS_MTM_H */
> diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
> new file mode 100644
> index 0000000..7509443
> --- /dev/null
> +++ b/arch/arc/plat-eznps/include/plat/smp.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#ifndef __PLAT_EZNPS_SMP_H
> +#define __PLAT_EZNPS_SMP_H
> +
> +#ifdef CONFIG_SMP
> +
> +extern struct cpumask _cpu_possible_mask;

Is this needed ?

> +void eznps_smp_init_cpu(unsigned int cpu);

You don't need this either - see below !

> +
> +#endif /* CONFIG_SMP */
> +
> +#endif
> diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
> new file mode 100644
> index 0000000..802c3c8
> --- /dev/null
> +++ b/arch/arc/plat-eznps/mtm.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/smp.h>
> +#include <linux/io.h>
> +#include <asm/arcregs.h>
> +#include <plat/mtm.h>
> +#include <plat/smp.h>
> +
> +#define MT_CTRL_HS_CNT		0xFF
> +#define MT_CTRL_ST_CNT		0xF
> +#define NPS_NUM_HW_THREADS	0x10
> +
> +static void mtm_init_nat(int cpu)
> +{
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +	struct nps_host_reg_aux_udmc udmc;
> +	int log_nat, nat = 0, i, t;
> +
> +	/* Iterate core threads and update nat */
> +	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
> +		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
> +
> +	switch (nat) {
> +	case 1:
> +		log_nat = 0;
> +		break;
> +	case 2:
> +		log_nat = 1;
> +		break;
> +	case 4:
> +		log_nat = 2;
> +		break;
> +	case 8:
> +		log_nat = 3;
> +		break;
> +	case 16:
> +		log_nat = 4;
> +		break;

Can u use a some ilog function do do this ?

> +	default:
> +		pr_warn("BUG: got non valid NAT %d!\n", nat);
> +		log_nat = 0;
> +		break;
> +	}
> +
> +	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
> +	udmc.nat = log_nat;
> +	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
> +
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.nat = log_nat;
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +}
> +
> +static void mtm_init_thread(int cpu)
> +{
> +	int i, tries = 5;
> +	struct nps_host_reg_thr_init thr_init;
> +	struct nps_host_reg_thr_init_sts thr_init_sts;
> +
> +	/* Set thread init register */
> +	thr_init.value = 0;
> +	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
> +	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
> +	thr_init.str = 1;
> +	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
> +
> +	/* Poll till thread init is done */
> +	for (i = 0; i < tries; i++) {
> +		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
> +		if (thr_init_sts.thr_id == thr_init.thr_id) {
> +			if (thr_init_sts.bsy)
> +				continue;
> +			else if (thr_init_sts.err)
> +				pr_warn("Failed to thread init cpu %u\n", cpu);
> +			break;
> +		}
> +
> +		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
> +		break;
> +	}
> +
> +	if (i == tries)
> +		pr_warn("Got thread init timeout for cpu %u\n", cpu);
> +}
> +
> +int mtm_enable_thread(int cpu)
> +{
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
> +		return 1;
> +
> +	/* Enable thread in mtm */
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +
> +	return 0;
> +}
> +
> +void mtm_enable_core(unsigned int cpu)
> +{
> +	int i;
> +	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
> +	struct nps_host_reg_mtm_cfg mtm_cfg;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
> +		return;
> +
> +	/* Initialize Number of Active Threads */
> +	mtm_init_nat(cpu);
> +
> +	/* Initialize mtm_cfg */
> +	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
> +	mtm_cfg.ten = 1;
> +	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
> +
> +	/* Initialize all other threads in core */
> +	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
> +		mtm_init_thread(cpu + i);
> +
> +
> +	/* Enable HW schedule, stall counter, mtm */
> +	mt_ctrl.value = 0;
> +	mt_ctrl.hsen = 1;
> +	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
> +	mt_ctrl.sten = 1;
> +	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
> +	mt_ctrl.mten = 1;
> +	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
> +
> +	/*
> +	 * HW scheduling mechanism will start working
> +	 * Only after call to instruction "schd.rw".
> +	 * cpu_relax() calls "schd.rw" instruction.
> +	 */
> +	cpu_relax();
> +}
> diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
> new file mode 100644
> index 0000000..c84dfd9
> --- /dev/null
> +++ b/arch/arc/plat-eznps/platform.c
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/init.h>
> +#include <asm/io.h>
> +#include <asm/mach_desc.h>
> +#include <plat/smp.h>

This will go away

> +
> +/*----------------------- Machine Descriptions ------------------------------
> + *
> + * Machine description is simply a set of platform/board specific callbacks
> + * This is not directly related to DeviceTree based dynamic device creation,
> + * however as part of early device tree scan, we also select the right
> + * callback set, by matching the DT compatible name.
> + */

No Cargo Culting please. Delete this comment !

> +
> +static const char *eznps_compat[] __initconst = {
> +	"ezchip,arc-nps",
> +	NULL,
> +};
> +
> +MACHINE_START(NPS, "nps")
> +	.dt_compat	= eznps_compat,
> +#ifdef CONFIG_SMP
> +	.init_cpu_smp	= eznps_smp_init_cpu,  /* for each CPU */
> +#endif

This is not needed. See below !

> +MACHINE_END
> diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
> new file mode 100644
> index 0000000..0f8b51a
> --- /dev/null
> +++ b/arch/arc/plat-eznps/smp.c
> @@ -0,0 +1,160 @@
> +/*
> + * Copyright(c) 2015 EZchip Technologies.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * The full GNU General Public License is included in this distribution in
> + * the file called "COPYING".
> + */
> +
> +#include <linux/smp.h>
> +#include <linux/of_fdt.h>
> +#include <linux/io.h>
> +#include <asm/irq.h>
> +#include <plat/ctop.h>
> +#include <plat/smp.h>
> +#include <plat/mtm.h>
> +
> +#define NPS_DEFAULT_MSID	0x34
> +#define NPS_MTM_CPU_CFG		0x90
> +
> +struct cpumask _cpu_possible_mask;
> +static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
> +
> +/* Get cpu map from device tree */
> +static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
> +{
> +	unsigned long dt_root = of_get_flat_dt_root();
> +	const char *buf;
> +
> +	buf = of_get_flat_dt_prop(dt_root, name, NULL);
> +	if (!buf)
> +		return 1;
> +
> +	cpulist_parse(buf, cpumask);
> +
> +	return 0;
> +}
> +
> +/* Update board cpu maps */
> +static void __init eznps_init_cpumasks(void)
> +{
> +	struct cpumask cpumask;
> +
> +	if (eznps_get_map("present-cpus", &cpumask)) {
> +		pr_err("Failed to get present-cpus from dtb");
> +		return;
> +	}
> +	init_cpu_present(&cpumask);
> +
> +	if (eznps_get_map("possible-cpus", &cpumask)) {
> +		pr_err("Failed to get possible-cpus from dtb");
> +		return;
> +	}
> +	init_cpu_possible(&cpumask);
> +}
> +
> +static void eznps_init_core(unsigned int cpu)
> +{
> +	u32 sync_value;
> +	struct nps_host_reg_aux_hw_comply hw_comply;
> +	struct nps_host_reg_aux_lpc lpc;
> +
> +	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
> +		return;
> +
> +	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
> +	hw_comply.me  = 1;
> +	hw_comply.le  = 1;
> +	hw_comply.te  = 1;
> +	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
> +
> +	/* Enable MMU clock */
> +	lpc.mep = 1;
> +	write_aux_reg(CTOP_AUX_LPC, lpc.value);
> +
> +	/* Boot CPU only */
> +	if (!cpu) {
> +		/* Write to general purpose register in CRG */
> +		sync_value = ioread32be(REG_GEN_PURP_0);
> +		sync_value |= NPS_CRG_SYNC_BIT;
> +		iowrite32be(sync_value, REG_GEN_PURP_0);
> +	}
> +}
> +
> +/*
> + * Any SMP specific init any CPU does when it comes up.
> + * Here we setup the CPU to enable Inter-Processor-Interrupts
> + * Called for each CPU
> + * -Master      : init_IRQ()
> + * -Other(s)    : start_kernel_secondary()
> + */

This comment is no longer accurate, please get rid of it

> +void eznps_smp_init_cpu(unsigned int cpu)
> +{
> +	unsigned int rc;
> +
> +	rc = smp_ipi_irq_setup(cpu, IPI_IRQ);
> +	if (rc)
> +		panic("IPI IRQ %d reg failed on BOOT cpu\n", IPI_IRQ);

This is not just BOOT cpu ?

> +
> +	eznps_init_core(cpu);
> +	mtm_enable_core(cpu);
> +}
> +
> +/*
> + * Master kick starting another CPU
> + */
> +static void eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
> +{
> +	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
> +
> +	if (mtm_enable_thread(cpu) == 0)
> +		return;
> +
> +	/* set PC, dmsid, and start CPU */
> +	cpu_cfg.value = pc;
> +	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
> +	cpu_cfg.cs = 1;
> +	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
> +}
> +
> +static void eznps_ipi_send(int cpu)
> +{
> +	struct global_id gid;
> +	struct {
> +		union {
> +			struct {
> +				u32 num:8, cluster:8, core:8, thread:8;
> +			};
> +			u32 value;
> +		};
> +	} ipi;
> +
> +	gid.value = cpu;
> +	ipi.thread = get_thread(gid);
> +	ipi.core = gid.core;
> +	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
> +	ipi.num = IPI_IRQ;
> +
> +	__asm__ __volatile__(
> +	"	mov r3, %0\n"
> +	"	.word %1\n"
> +	:
> +	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
> +	: "r3");
> +}
> +
> +struct plat_smp_ops plat_smp_ops = {
> +	.info		= smp_cpuinfo_buf,
> +	.init_early_smp	= eznps_init_cpumasks,
> +	.cpu_kick	= eznps_smp_wakeup_cpu,
> +	.ipi_send	= eznps_ipi_send,

look at mcip.c to add eznps_smp_init_cpu() as smp op callback !

commit 286130ebf196d9643800977d57bdb7cda266b49e
Author: Vineet Gupta <vgupta at synopsys.com>
Date:   Wed Oct 14 14:38:02 2015 +0530

    ARC: smp: Introduce smp hook @init_irq_cpu called for all cores

    Note this is not part of platform owned static machine_desc,
    but more of device owned plat_smp_ops (rather misnamed) which a IPI
    provider or some such typically defines.

    This will help us seperate out the IPI registration from platform
    specific init_cpu_smp() into device specific init_irq_cpu()

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 00/19] eznps a new ARC platform
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

v2:
1)	Remove out of tree platform include path
2)	Move atomic/bitop/cmpxchg for platform to end.
	Remove macro duplication.
	Fix some bad implementation.
3)	define cpu_relax_lowlatency() for platform.
4)	rename init_irq_cpu() to init_per_cpu()
	reorder call to init_per_cpu() for secondary
	use it instead of init_cpu_smp().
5)	set res_service to call stext
6)	fix build failure for CTOP_AUX_BASE at assembly code
7)	Use ilog2 for mtm_init_nat()
8)	Add CLKSRC_NPS option to Kconfig
	change nps_clksrc_read() to be more readable.

General summay:
This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threads. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (17):
  Documentation: Add EZchip vendor to binding list
  ARC: [plat-eznps] define IPI_IRQ
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  ARC: Mark secondary cpu online only after all HW setup is done
  ARC: add CONFIG_CLKSRC_OF support to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (2):
  ARC: [plat-eznps] Use dedicated cpu_relax()
  ARC: [plat-eznps] replace sync with proper cpu barrier

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    5 +
 arch/arc/boot/dts/eznps.dts                        |   76 ++++++
 arch/arc/configs/nps_defconfig                     |   85 ++++++
 arch/arc/include/asm/atomic.h                      |   79 ++++++-
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   54 ++++
 arch/arc/include/asm/cmpxchg.h                     |   87 +++++-
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   36 +++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    4 +-
 arch/arc/include/asm/spinlock.h                    |   14 +
 arch/arc/kernel/ctx_sw.c                           |   20 ++
 arch/arc/kernel/irq.c                              |    4 +-
 arch/arc/kernel/mcip.c                             |    2 +-
 arch/arc/kernel/smp.c                              |   14 +-
 arch/arc/kernel/time.c                             |    4 +
 arch/arc/mm/tlb.c                                  |   12 +
 arch/arc/plat-eznps/Kconfig                        |   34 +++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   75 ++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  271 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
 arch/arc/plat-eznps/include/plat/smp.h             |   26 ++
 arch/arc/plat-eznps/mtm.c                          |  133 ++++++++++
 arch/arc/plat-eznps/platform.c                     |   27 ++
 arch/arc/plat-eznps/smp.c                          |  149 +++++++++++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   85 ++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
 40 files changed, 1635 insertions(+), 36 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 00/19] eznps a new ARC platform
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

v2:
1)	Remove out of tree platform include path
2)	Move atomic/bitop/cmpxchg for platform to end.
	Remove macro duplication.
	Fix some bad implementation.
3)	define cpu_relax_lowlatency() for platform.
4)	rename init_irq_cpu() to init_per_cpu()
	reorder call to init_per_cpu() for secondary
	use it instead of init_cpu_smp().
5)	set res_service to call stext
6)	fix build failure for CTOP_AUX_BASE at assembly code
7)	Use ilog2 for mtm_init_nat()
8)	Add CLKSRC_NPS option to Kconfig
	change nps_clksrc_read() to be more readable.

General summay:
This set introduce new platform to ARC architecture.
Platform name called "eznps" for working with EZchip NPS400
Network Proccessor.
NPS400 is targeted to service "fast path" network applications.

NPS400 got mesh of 256 extended ARC cores (AKA CTOP), each core
got 16 HW threads. This is basically SMT core where at any point of
time only one HW thread is active.
Each core have HW scheduler that round robin between eligible HW
threads. Totaly, kernel sees 4096 CPUs which I belive is a high record.
There is no cache coherency between cores so generic user applications
and kernel do not use D$.

Cores got special memory mappings for huge pages (8MB).
Mapping is static and should provide application enough memory without
any "TLB miss". This mapping is on top of TLB mapping.

This is a basic set that will later be followed with additional
set of patches with all advanced features.

Many thanks to all people helping to make this happen.

Regards,
Noam Camus

Noam Camus (17):
  Documentation: Add EZchip vendor to binding list
  ARC: [plat-eznps] define IPI_IRQ
  clocksource: Add NPS400 timers driver
  irqchip: add nps Internal and external irqchips
  ARC: Set vmalloc size from configuration
  ARC: rwlock: disable interrupts in !LLSC variant
  ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  ARC: Mark secondary cpu online only after all HW setup is done
  ARC: add CONFIG_CLKSRC_OF support to time_init()
  ARC: [plat-eznps] Add eznps board defconfig and dts
  ARC: [plat-eznps] Add eznps platform
  ARC: [plat-eznps] Use dedicated user stack top
  ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  ARC: [plat-eznps] Use dedicated SMP barriers
  ARC: [plat-eznps] Use dedicated identity auxiliary register.
  ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  ARC: Add eznps platform to Kconfig and Makefile

Tal Zilcer (2):
  ARC: [plat-eznps] Use dedicated cpu_relax()
  ARC: [plat-eznps] replace sync with proper cpu barrier

 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 MAINTAINERS                                        |    6 +
 arch/arc/Kconfig                                   |    9 +
 arch/arc/Makefile                                  |    5 +
 arch/arc/boot/dts/eznps.dts                        |   76 ++++++
 arch/arc/configs/nps_defconfig                     |   85 ++++++
 arch/arc/include/asm/atomic.h                      |   79 ++++++-
 arch/arc/include/asm/barrier.h                     |    8 +
 arch/arc/include/asm/bitops.h                      |   54 ++++
 arch/arc/include/asm/cmpxchg.h                     |   87 +++++-
 arch/arc/include/asm/entry-compact.h               |    8 +
 arch/arc/include/asm/irq.h                         |    4 +
 arch/arc/include/asm/pgtable.h                     |    2 +-
 arch/arc/include/asm/processor.h                   |   36 +++-
 arch/arc/include/asm/setup.h                       |    4 +
 arch/arc/include/asm/smp.h                         |    4 +-
 arch/arc/include/asm/spinlock.h                    |   14 +
 arch/arc/kernel/ctx_sw.c                           |   20 ++
 arch/arc/kernel/irq.c                              |    4 +-
 arch/arc/kernel/mcip.c                             |    2 +-
 arch/arc/kernel/smp.c                              |   14 +-
 arch/arc/kernel/time.c                             |    4 +
 arch/arc/mm/tlb.c                                  |   12 +
 arch/arc/plat-eznps/Kconfig                        |   34 +++
 arch/arc/plat-eznps/Makefile                       |    7 +
 arch/arc/plat-eznps/entry.S                        |   75 ++++++
 arch/arc/plat-eznps/include/plat/ctop.h            |  271 ++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h             |   60 +++++
 arch/arc/plat-eznps/include/plat/smp.h             |   26 ++
 arch/arc/plat-eznps/mtm.c                          |  133 ++++++++++
 arch/arc/plat-eznps/platform.c                     |   27 ++
 arch/arc/plat-eznps/smp.c                          |  149 +++++++++++
 drivers/clocksource/Kconfig                        |    7 +
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   85 ++++++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++
 40 files changed, 1635 insertions(+), 36 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c
 create mode 100644 drivers/clocksource/timer-nps.c
 create mode 100644 drivers/irqchip/irq-eznps.c

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 01/19] Documentation: Add EZchip vendor to binding list
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Rob Herring,
	Pawel Moll, Mark Rutland, Kumar Gala

From: Noam Camus <noamc@ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Kumar Gala <galak@codeaurora.org>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..f8b5e9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Proccessor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82d2ac9..5a752cc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -80,6 +80,7 @@ eukrea  Eukréa Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 fsl	Freescale Semiconductor
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 01/19] Documentation: Add EZchip vendor to binding list
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Add EZchip to vendor prefixes list.
EZchip introduce the NPS platform for the ARC architecture.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Kumar Gala <galak at codeaurora.org>
---
 Documentation/devicetree/bindings/arc/eznps.txt    |    7 +++++++
 .../devicetree/bindings/vendor-prefixes.txt        |    1 +
 2 files changed, 8 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arc/eznps.txt

diff --git a/Documentation/devicetree/bindings/arc/eznps.txt b/Documentation/devicetree/bindings/arc/eznps.txt
new file mode 100644
index 0000000..f8b5e9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arc/eznps.txt
@@ -0,0 +1,7 @@
+EZchip NPS Network Proccessor Platforms Device Tree Bindings
+---------------------------------------------------------------------------
+
+Appliance main board with NPS400 ASIC.
+
+Required root node properties:
+    - compatible = "ezchip,arc-nps";
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82d2ac9..5a752cc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -80,6 +80,7 @@ eukrea  Eukr??a Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 excito	Excito
+ezchip	EZchip Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 fsl	Freescale Semiconductor
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 02/19] ARC: [plat-eznps] define IPI_IRQ
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 02/19] ARC: [plat-eznps] define IPI_IRQ
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

We add IPI irq definition to be used later by any
irqchip such NPS400 IC.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/irq.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/irq.h b/arch/arc/include/asm/irq.h
index 4fd7d62..c5f8f0f 100644
--- a/arch/arc/include/asm/irq.h
+++ b/arch/arc/include/asm/irq.h
@@ -16,7 +16,11 @@
 #ifdef CONFIG_ISA_ARCOMPACT
 #define TIMER0_IRQ      3
 #define TIMER1_IRQ      4
+#if defined(CONFIG_SMP) && defined(CONFIG_ARC_PLAT_EZNPS)
+#define IPI_IRQ         5
+#else
 #define IPI_IRQ		(NR_CPU_IRQS-1) /* dummy to enable SMP build for up hardware */
+#endif
 #else
 #define TIMER0_IRQ      16
 #define TIMER1_IRQ      17
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 03/19] clocksource: Add NPS400 timers driver
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Daniel Lezcano,
	Rob Herring, Thomas Gleixner, John Stultz

From: Noam Camus <noamc@ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +++
 drivers/clocksource/Kconfig                        |    7 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   85 ++++++++++++++++++++
 4 files changed, 104 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c5102c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,11 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer"
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a7726db..8437113 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -115,6 +115,13 @@ config CLKSRC_PISTACHIO
 	bool
 	select CLKSRC_OF
 
+config CLKSRC_NPS
+	bool "NPS400 clocksource driver" if COMPILE_TEST
+	select CLKSRC_OF
+	help
+	  NPS400 clocksource support.
+	  Got 64 bit counter with update rate up to 1000MHz.
+
 config CLKSRC_STM32
 	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
 	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5c00863..28c17dc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
 obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..7abde9e
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clocksource.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <plat/ctop.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	u64 counter;
+	u32 lower, upper, old_upper;
+	void *lower_p, *upper_p;
+	int cluster = (smp_processor_id() >> NPS_CLUSTER_OFFSET);
+
+	lower_p = nps_msu_reg_low_addr[cluster];
+	upper_p = lower_p + 4;
+
+	upper = ioread32be(upper_p);
+	do {
+		old_upper = upper;
+		lower = ioread32be(lower_p);
+		upper = ioread32be(upper_p);
+	} while (upper != old_upper);
+
+	counter = (upper << 32) | lower;
+	return (cycle_t)counter;
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(64),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	unsigned long rate, dt_root;
+	int ret, cluster;
+
+	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
+		nps_msu_reg_low_addr[cluster] =
+			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
+				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
+
+	dt_root = of_get_flat_dt_root();
+	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 03/19] clocksource: Add NPS400 timers driver
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Add internal tick generator which is shared by all cores.
Each cluster of cores view it through dedicated address.
This is used for SMP system where all CPUs synced by same
clock source.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: John Stultz <john.stultz at linaro.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 .../bindings/timer/ezchip,nps400-timer.txt         |   11 +++
 drivers/clocksource/Kconfig                        |    7 ++
 drivers/clocksource/Makefile                       |    1 +
 drivers/clocksource/timer-nps.c                    |   85 ++++++++++++++++++++
 4 files changed, 104 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
 create mode 100644 drivers/clocksource/timer-nps.c

diff --git a/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
new file mode 100644
index 0000000..c5102c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/ezchip,nps400-timer.txt
@@ -0,0 +1,11 @@
+NPS Network Processor
+
+Required properties:
+
+- compatible :	should be "ezchip,nps400-timer"
+
+Example:
+
+timer {
+	compatible = "ezchip,nps400-timer";
+};
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a7726db..8437113 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -115,6 +115,13 @@ config CLKSRC_PISTACHIO
 	bool
 	select CLKSRC_OF
 
+config CLKSRC_NPS
+	bool "NPS400 clocksource driver" if COMPILE_TEST
+	select CLKSRC_OF
+	help
+	  NPS400 clocksource support.
+	  Got 64 bit counter with update rate up to 1000MHz.
+
 config CLKSRC_STM32
 	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
 	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5c00863..28c17dc 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VF_PIT_TIMER)	+= vf_pit_timer.o
 obj-$(CONFIG_CLKSRC_QCOM)	+= qcom-timer.o
 obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)	+= timer-nps.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
diff --git a/drivers/clocksource/timer-nps.c b/drivers/clocksource/timer-nps.c
new file mode 100644
index 0000000..7abde9e
--- /dev/null
+++ b/drivers/clocksource/timer-nps.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/clocksource.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <plat/ctop.h>
+
+#define NPS_MSU_TICK_LOW	0xC8
+#define NPS_CLUSTER_OFFSET	8
+#define NPS_CLUSTER_NUM		16
+
+static void *nps_msu_reg_low_addr[NPS_CLUSTER_NUM] __read_mostly;
+
+/*
+ * To get the value from the Global Timer Counter register proceed as follows:
+ * 1. Read the upper 32-bit timer counter register
+ * 2. Read the lower 32-bit timer counter register
+ * 3. Read the upper 32-bit timer counter register again. If the value is
+ *  different to the 32-bit upper value read previously, go back to step 2.
+ *  Otherwise the 64-bit timer counter value is correct.
+ */
+static cycle_t nps_clksrc_read(struct clocksource *clksrc)
+{
+	u64 counter;
+	u32 lower, upper, old_upper;
+	void *lower_p, *upper_p;
+	int cluster = (smp_processor_id() >> NPS_CLUSTER_OFFSET);
+
+	lower_p = nps_msu_reg_low_addr[cluster];
+	upper_p = lower_p + 4;
+
+	upper = ioread32be(upper_p);
+	do {
+		old_upper = upper;
+		lower = ioread32be(lower_p);
+		upper = ioread32be(upper_p);
+	} while (upper != old_upper);
+
+	counter = (upper << 32) | lower;
+	return (cycle_t)counter;
+}
+
+static struct clocksource nps_counter = {
+	.name	= "EZnps-tick",
+	.rating = 301,
+	.read   = nps_clksrc_read,
+	.mask   = CLOCKSOURCE_MASK(64),
+	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nps_setup_clocksource(struct device_node *node)
+{
+	struct clocksource *clksrc = &nps_counter;
+	unsigned long rate, dt_root;
+	int ret, cluster;
+
+	for (cluster = 0; cluster < NPS_CLUSTER_NUM; cluster++)
+		nps_msu_reg_low_addr[cluster] =
+			nps_host_reg((cluster << NPS_CLUSTER_OFFSET),
+				 NPS_MSU_BLKID, NPS_MSU_TICK_LOW);
+
+	dt_root = of_get_flat_dt_root();
+	rate = (u32)of_get_flat_dt_prop(dt_root, "clock-frequency", NULL);
+
+	ret = clocksource_register_hz(clksrc, rate);
+	if (ret)
+		pr_err("Couldn't register clock source.\n");
+}
+
+CLOCKSOURCE_OF_DECLARE(nps_400, "nps,400-timer",
+		       nps_setup_clocksource);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Thomas Gleixner,
	Jason Cooper, Marc Zyngier

From: Noam Camus <noamc@ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++++++
 3 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index bb3048f..decfc87 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..78f3667
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define NPS_MSU_EN_CFG	0x80
+
+/* Messaging and Scheduling Unit:
+ * Provides message management for a CPU cluster.
+ */
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg {
+		union {
+			struct {
+				u32     __reserved1:11,
+				rtc_en:1, ipc_en:1, gim_1_en:1,
+				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
+				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
+				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+				buff_i_alc_bmue:1, __reserved2:1,
+				buff_e_pre_en:1, buff_i_pre_en:1,
+				pmuw_ja_en:1, pmue_ja_en:1,
+				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+			};
+			u32 value;
+		};
+	};
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* Enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+/* Global Interrupt Manager:
+ * Configures and manages up to 64 interrupts from peripherals,
+ * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
+ * Receives the interrupts and transmits them to relevant CPU.
+ */
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	 */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* Enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+}
+
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hw)
+{
+	switch (irq) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	eznps_configure_msu();
+	eznps_configure_gim();
+
+	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Adding EZchip NPS400 support.
NPS internal interrupts are internally handled at
Multi Thread Manager (MTM) that is signaled for deactivating
an interrupt.
External interrupts is handled also at Global Interrupt
Controller (GIC) e.g. serial and network devices.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 .../interrupt-controller/ezchip,nps400-ic.txt      |   17 ++
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-eznps.c                        |  222 ++++++++++++++++++++
 3 files changed, 240 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
 create mode 100644 drivers/irqchip/irq-eznps.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
new file mode 100644
index 0000000..888b2b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ezchip,nps400-ic.txt
@@ -0,0 +1,17 @@
+EZchip NPS Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ezchip,nps400-ic"
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+
+
+Example:
+
+intc: interrupt-controller {
+	compatible = "ezchip,nps400-ic";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+};
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index bb3048f..decfc87 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -55,3 +55,4 @@ obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
+obj-$(CONFIG_ARC_PLAT_EZNPS)		+= irq-eznps.o
diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
new file mode 100644
index 0000000..78f3667
--- /dev/null
+++ b/drivers/irqchip/irq-eznps.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <asm/irq.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define NPS_MSU_EN_CFG	0x80
+
+/* Messaging and Scheduling Unit:
+ * Provides message management for a CPU cluster.
+ */
+static void __init eznps_configure_msu(void)
+{
+	int cpu;
+	struct nps_host_reg_msu_en_cfg {
+		union {
+			struct {
+				u32     __reserved1:11,
+				rtc_en:1, ipc_en:1, gim_1_en:1,
+				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
+				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
+				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
+				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
+				buff_i_alc_bmue:1, __reserved2:1,
+				buff_e_pre_en:1, buff_i_pre_en:1,
+				pmuw_ja_en:1, pmue_ja_en:1,
+				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
+			};
+			u32 value;
+		};
+	};
+	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
+
+	msu_en_cfg.msu_en = 1;
+	msu_en_cfg.ipi_en = 1;
+	msu_en_cfg.gim_0_en = 1;
+	msu_en_cfg.gim_1_en = 1;
+
+	/* Enable IPI and GIM messages on all clusters */
+	for (cpu = 0 ; cpu < eznps_max_cpus; cpu += eznps_cpus_per_cluster)
+		iowrite32be(msu_en_cfg.value,
+			    nps_host_reg(cpu, NPS_MSU_BLKID, NPS_MSU_EN_CFG));
+}
+
+/* Global Interrupt Manager:
+ * Configures and manages up to 64 interrupts from peripherals,
+ * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
+ * Receives the interrupts and transmits them to relevant CPU.
+ */
+static void __init eznps_configure_gim(void)
+{
+	u32 reg_value;
+	u32 gim_int_lines;
+	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
+
+	gim_int_lines = NPS_GIM_UART_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
+
+	/*
+	 * IRQ polarity
+	 * low or high level
+	 * negative or positive edge
+	 */
+	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
+	reg_value &= ~gim_int_lines;
+	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
+
+	/* IRQ type level or edge */
+	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
+	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
+	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
+
+	/*
+	 * GIM interrupt select type for
+	 * dbg_lan TX and RX interrupts
+	 * should be type 1
+	 * type 0 = IRQ line 6
+	 * type 1 = IRQ line 7
+	 */
+	gim_p_int_dst.is = 1;
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_10);
+	iowrite32be(gim_p_int_dst.value, REG_GIM_P_INT_DST_11);
+
+	/*
+	 * CTOP IRQ lines should be defined
+	 * as blocking in GIM
+	 */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_BLK_0);
+
+	/* Enable CTOP IRQ lines in GIM */
+	iowrite32be(gim_int_lines, REG_GIM_P_INT_EN_0);
+}
+
+/*
+ * NPS400 core includes a Interrupt Controller (IC) support.
+ * All cores can deactivate level irqs at first level control
+ * at cores mesh layer called MTM.
+ * For devices out side chip e.g. uart, network there is another
+ * level called Global Interrupt Manager (GIM).
+ * This second level can control level and edge interrupt.
+ */
+
+static void nps400_irq_mask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb &= ~(1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_unmask(struct irq_data *data)
+{
+	unsigned int ienb;
+
+	ienb = read_aux_reg(AUX_IENABLE);
+	ienb |= (1 << data->irq);
+	write_aux_reg(AUX_IENABLE, ienb);
+}
+
+static void nps400_irq_eoi_global(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+
+	/* Don't ack before all device access is done */
+	mb();
+
+	__asm__ __volatile__ (
+	"       .word %0\n"
+	:
+	: "i"(CTOP_INST_RSPI_GIC_0_R12)
+	: "memory");
+}
+
+static void nps400_irq_eoi(struct irq_data *data)
+{
+	write_aux_reg(CTOP_AUX_IACK, 1 << data->irq);
+}
+
+
+static struct irq_chip nps400_irq_chip_fasteoi = {
+	.name		= "NPS400 IC Global",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi_global,
+};
+
+static struct irq_chip nps400_irq_chip_percpu = {
+	.name		= "NPS400 IC",
+	.irq_mask	= nps400_irq_mask,
+	.irq_unmask	= nps400_irq_unmask,
+	.irq_eoi	= nps400_irq_eoi,
+};
+
+static int nps400_irq_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hw)
+{
+	switch (irq) {
+	case TIMER0_IRQ:
+#if defined(CONFIG_SMP)
+	case IPI_IRQ:
+#endif
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_percpu,
+					 handle_percpu_irq);
+	break;
+	default:
+		irq_set_chip_and_handler(irq, &nps400_irq_chip_fasteoi,
+					 handle_fasteoi_irq);
+	break;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops nps400_irq_ops = {
+	.xlate = irq_domain_xlate_onecell,
+	.map = nps400_irq_map,
+};
+
+static struct irq_domain *nps400_root_domain;
+
+static int __init nps400_of_init(struct device_node *node,
+				 struct device_node *parent)
+{
+	if (parent)
+		panic("DeviceTree incore ic not a root irq controller\n");
+
+	eznps_configure_msu();
+	eznps_configure_gim();
+
+	nps400_root_domain = irq_domain_add_legacy(node, NR_CPU_IRQS, 0, 0,
+						   &nps400_irq_ops, NULL);
+
+	if (!nps400_root_domain)
+		panic("nps400 root irq domain not avail\n");
+
+	/* with this we don't need to export nps400_root_domain */
+	irq_set_default_host(nps400_root_domain);
+
+	return 0;
+}
+IRQCHIP_DECLARE(ezchip_nps400_ic, "ezchip,nps400-ic", nps400_of_init);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 05/19] ARC: Set vmalloc size from configuration
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

This introduce build error since PGDIR_SIZE() cannot use "1UL"
ibecause it is called from mm/tlbex.S by VMALLOC_START.
Using _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/pgtable.h   |    2 +-
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 4454535..a603301 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -113,18 +113,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0ee7398..0c75a27 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 05/19] ARC: Set vmalloc size from configuration
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

User space use lower 2G of the virtual address space.
However kernel steals upper 512M of this space.
This stolen space is used partially for vmalloc and the rest
serves as gutter between kernel and user space.
The vmalloc size is depend on NR_CPUS since "per cpu" mechanism
use vmalloc to allocate chunks for its use.

Historically vmalloc size was 256M however it is not enough in
case of many CPUs e.g. 4K CPUs. For such case an extra 192M is
allocated.
We are setting default vmalloc size to be 256M, any addtional
space will be taken from kernel/user gutter.

This introduce build error since PGDIR_SIZE() cannot use "1UL"
ibecause it is called from mm/tlbex.S by VMALLOC_START.
Using _BITUL() solves this build error.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/Kconfig                 |    8 ++++++++
 arch/arc/include/asm/pgtable.h   |    2 +-
 arch/arc/include/asm/processor.h |   10 +++++-----
 arch/arc/mm/tlb.c                |    6 ++++++
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 2c2ac3f..689ccb3 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -468,6 +468,14 @@ config ARCH_PHYS_ADDR_T_64BIT
 config ARCH_DMA_ADDR_T_64BIT
 	bool
 
+config ARC_VMALLOC_SIZE
+	hex "Vmalloc size (MB)"
+	range 0 512
+	default "256"
+	help
+	  By default equals to 256MB and the rest of 512MB is
+	  left for gutter between kernel and user space.
+
 config ARC_CURR_IN_REG
 	bool "Dedicate Register r25 for current_task pointer"
 	default y
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 57af2f0..372a282 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -210,7 +210,7 @@
 #define BITS_FOR_PGD	(32 - BITS_FOR_PTE - BITS_IN_PAGE)
 
 #define PGDIR_SHIFT	(32 - BITS_FOR_PGD)
-#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)	/* vaddr span, not PDG sz */
+#define PGDIR_SIZE	_BITUL(PGDIR_SHIFT)	/* vaddr span, not PDG sz */
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #define	PTRS_PER_PTE	_BITUL(BITS_FOR_PTE)
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 4454535..a603301 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -113,18 +113,18 @@ extern unsigned int get_wchan(struct task_struct *p);
  * 0xC000_0000		0xFFFF_FFFF	(peripheral uncached space)
  * -----------------------------------------------------------------------------
  */
-#define VMALLOC_START	0x70000000
 
 /*
  * 1 PGDIR_SIZE each for fixmap/pkmap, 2 PGDIR_SIZE gutter
  * See asm/highmem.h for details
  */
-#define VMALLOC_SIZE	(PAGE_OFFSET - VMALLOC_START - PGDIR_SIZE * 4)
-#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_END	(PAGE_OFFSET - PGDIR_SIZE * 4)
+#define VMALLOC_SIZE	(CONFIG_ARC_VMALLOC_SIZE << 20)
+#define VMALLOC_START	(VMALLOC_END - VMALLOC_SIZE)
 
-#define USER_KERNEL_GUTTER    0x10000000
+#define TASK_SIZE	0x60000000
 
-#define TASK_SIZE	(VMALLOC_START - USER_KERNEL_GUTTER)
+#define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
 #define STACK_TOP       TASK_SIZE
 #define STACK_TOP_MAX   STACK_TOP
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0ee7398..0c75a27 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -814,6 +814,12 @@ void arc_mmu_init(void)
 
 	printk(arc_mmu_mumbojumbo(0, str, sizeof(str)));
 
+	/*
+	 * vmalloc size (in MB) sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 06/19] ARC: rwlock: disable interrupts in !LLSC variant
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Noam Camus <noamc@ezchip.com>

If we hold rwlock and interrupt occures we may
end up spinning on it for ever during softirq.
Note that this lock is an internal lock
and since the lock is free to be used from any context,
the lock needs to be IRQ-safe.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 06/19] ARC: rwlock: disable interrupts in !LLSC variant
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

If we hold rwlock and interrupt occures we may
end up spinning on it for ever during softirq.
Note that this lock is an internal lock
and since the lock is free to be used from any context,
the lock needs to be IRQ-safe.

Below you may see an example for interrupt we get while
nl_table_lock is holding its rw->lock_mutex and we spinned
on it for ever.

The concept for the fix was taken from SPARC.

[2015-05-12 19:16:12] Stack Trace:
[2015-05-12 19:16:12]   arc_unwind_core+0xb8/0x11c
[2015-05-12 19:16:12]   dump_stack+0x68/0xac
[2015-05-12 19:16:12]   _raw_read_lock+0xa8/0xac
[2015-05-12 19:16:12]   netlink_broadcast_filtered+0x56/0x35c
[2015-05-12 19:16:12]   nlmsg_notify+0x42/0xa4
[2015-05-12 19:16:13]   neigh_update+0x1fe/0x44c
[2015-05-12 19:16:13]   neigh_event_ns+0x40/0xa4
[2015-05-12 19:16:13]   arp_process+0x46e/0x5a8
[2015-05-12 19:16:13]   __netif_receive_skb_core+0x358/0x500
[2015-05-12 19:16:13]   process_backlog+0x92/0x154
[2015-05-12 19:16:13]   net_rx_action+0xb8/0x188
[2015-05-12 19:16:13]   __do_softirq+0xda/0x1d8
[2015-05-12 19:16:14]   irq_exit+0x8a/0x8c
[2015-05-12 19:16:14]   arch_do_IRQ+0x6c/0xa8
[2015-05-12 19:16:14]   handle_interrupt_level1+0xe4/0xf0

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/spinlock.h |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h
index db8c59d..800e7c4 100644
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -610,7 +610,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 static inline int arch_read_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -623,6 +625,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 	}
 
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	smp_mb();
 	return ret;
@@ -632,7 +635,9 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
 static inline int arch_write_trylock(arch_rwlock_t *rw)
 {
 	int ret = 0;
+	unsigned long flags;
 
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 
 	/*
@@ -646,6 +651,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
 		ret = 1;
 	}
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 
 	return ret;
 }
@@ -664,16 +670,24 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_read_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter++;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
 	arch_spin_lock(&(rw->lock_mutex));
 	rw->counter = __ARCH_RW_LOCK_UNLOCKED__;
 	arch_spin_unlock(&(rw->lock_mutex));
+	local_irq_restore(flags);
 }
 
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This will better reflect its description i.e. "any needed setup..."
and not just do an "IPI request".

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/smp.h |    4 ++--
 arch/arc/kernel/irq.c      |    4 ++--
 arch/arc/kernel/mcip.c     |    2 +-
 arch/arc/kernel/smp.c      |    4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..9913804 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:	A SMP specific h/w block can init itself
  * 			Could be common across platforms so not covered by
  * 			mach_desc->init_early()
- * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:	Called for each core so SMP h/w block driver can do
  * 			any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:		To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
 	const char 	*info;
 	void		(*init_early_smp)(void);
-	void		(*init_irq_cpu)(int cpu);
+	void		(*init_per_cpu)(int cpu);
 	void		(*cpu_kick)(int cpu, unsigned long pc);
 	void		(*ipi_send)(int cpu);
 	void		(*ipi_clear)(int irq);
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2ee2265..a650650 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -29,8 +29,8 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
 	/* a SMP H/w block could do IPI IRQ request here */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(smp_processor_id());
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(smp_processor_id());
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(smp_processor_id());
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 74a9b07..bd237ac 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
 	.info		= smp_cpuinfo_buf,
 	.init_early_smp	= mcip_probe_n_setup,
-	.init_irq_cpu	= mcip_setup_per_cpu,
+	.init_per_cpu	= mcip_setup_per_cpu,
 	.ipi_send	= mcip_ipi_send,
 	.ipi_clear	= mcip_ipi_clear,
 };
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..0b061a4 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -132,8 +132,8 @@ void start_kernel_secondary(void)
 	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
 	/* Some SMP H/w setup - for each cpu */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(cpu);
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(cpu);
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This will better reflect its description i.e. "any needed setup..."
and not just do an "IPI request".

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/smp.h |    4 ++--
 arch/arc/kernel/irq.c      |    4 ++--
 arch/arc/kernel/mcip.c     |    2 +-
 arch/arc/kernel/smp.c      |    4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
index 133c867..9913804 100644
--- a/arch/arc/include/asm/smp.h
+++ b/arch/arc/include/asm/smp.h
@@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
  * @init_early_smp:	A SMP specific h/w block can init itself
  * 			Could be common across platforms so not covered by
  * 			mach_desc->init_early()
- * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
+ * @init_per_cpu:	Called for each core so SMP h/w block driver can do
  * 			any needed setup per cpu (e.g. IPI request)
  * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
  * @ipi_send:		To send IPI to a @cpu
@@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
 struct plat_smp_ops {
 	const char 	*info;
 	void		(*init_early_smp)(void);
-	void		(*init_irq_cpu)(int cpu);
+	void		(*init_per_cpu)(int cpu);
 	void		(*cpu_kick)(int cpu, unsigned long pc);
 	void		(*ipi_send)(int cpu);
 	void		(*ipi_clear)(int irq);
diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
index 2ee2265..a650650 100644
--- a/arch/arc/kernel/irq.c
+++ b/arch/arc/kernel/irq.c
@@ -29,8 +29,8 @@ void __init init_IRQ(void)
 
 #ifdef CONFIG_SMP
 	/* a SMP H/w block could do IPI IRQ request here */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(smp_processor_id());
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(smp_processor_id());
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(smp_processor_id());
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index 74a9b07..bd237ac 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
 struct plat_smp_ops plat_smp_ops = {
 	.info		= smp_cpuinfo_buf,
 	.init_early_smp	= mcip_probe_n_setup,
-	.init_irq_cpu	= mcip_setup_per_cpu,
+	.init_per_cpu	= mcip_setup_per_cpu,
 	.ipi_send	= mcip_ipi_send,
 	.ipi_clear	= mcip_ipi_clear,
 };
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 5805878..0b061a4 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -132,8 +132,8 @@ void start_kernel_secondary(void)
 	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
 
 	/* Some SMP H/w setup - for each cpu */
-	if (plat_smp_ops.init_irq_cpu)
-		plat_smp_ops.init_irq_cpu(cpu);
+	if (plat_smp_ops.init_per_cpu)
+		plat_smp_ops.init_per_cpu(cpu);
 
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 08/19] ARC: Mark secondary cpu online only after all HW setup is done
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up().
For ARC it returns as soon as new cpu's status becomes online,
However secondary may still do HW initializing,
machine or platform hook level.

So turn secondary online only after all HW setup is done.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/kernel/smp.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 0b061a4..bc0e4f6 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
-
-	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
-
 	/* Some SMP H/w setup - for each cpu */
 	if (plat_smp_ops.init_per_cpu)
 		plat_smp_ops.init_per_cpu(cpu);
@@ -138,6 +133,11 @@ void start_kernel_secondary(void)
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
 
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
+	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 08/19] ARC: Mark secondary cpu online only after all HW setup is done
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

In SMP setup, master loops for each_present_cpu calling cpu_up().
For ARC it returns as soon as new cpu's status becomes online,
However secondary may still do HW initializing,
machine or platform hook level.

So turn secondary online only after all HW setup is done.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/kernel/smp.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index 0b061a4..bc0e4f6 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -126,11 +126,6 @@ void start_kernel_secondary(void)
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 
-	notify_cpu_starting(cpu);
-	set_cpu_online(cpu, true);
-
-	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
-
 	/* Some SMP H/w setup - for each cpu */
 	if (plat_smp_ops.init_per_cpu)
 		plat_smp_ops.init_per_cpu(cpu);
@@ -138,6 +133,11 @@ void start_kernel_secondary(void)
 	if (machine_desc->init_cpu_smp)
 		machine_desc->init_cpu_smp(cpu);
 
+	notify_cpu_starting(cpu);
+	set_cpu_online(cpu, true);
+
+	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
+
 	arc_local_timer_setup();
 
 	local_irq_enable();
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 09/19] ARC: add CONFIG_CLKSRC_OF support to time_init()
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/kernel/time.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..5313961 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -283,6 +283,10 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_of_init();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 09/19] ARC: add CONFIG_CLKSRC_OF support to time_init()
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

External clock source can be used if included by one of
DTS file of a chosen platform.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/kernel/time.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dfad287..5313961 100644
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -283,6 +283,10 @@ void __init time_init(void)
 		 */
 		clocksource_register_hz(&arc_counter, arc_get_core_freq());
 
+#ifdef CONFIG_CLKSRC_OF
+	clocksource_of_init();
+#endif
+
 	/* sets up the periodic event timer */
 	arc_local_timer_setup();
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 10/19] ARC: [plat-eznps] Add eznps board defconfig and dts
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   76 +++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..4d4832a
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+		};
+
+		uart@f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clock-frequency = <83333333>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		ethernet@f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# 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_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 10/19] ARC: [plat-eznps] Add eznps board defconfig and dts
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

Adding default configuration file and DTS file

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/boot/dts/eznps.dts    |   76 +++++++++++++++++++++++++++++++++++
 arch/arc/configs/nps_defconfig |   85 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/boot/dts/eznps.dts
 create mode 100644 arch/arc/configs/nps_defconfig

diff --git a/arch/arc/boot/dts/eznps.dts b/arch/arc/boot/dts/eznps.dts
new file mode 100644
index 0000000..4d4832a
--- /dev/null
+++ b/arch/arc/boot/dts/eznps.dts
@@ -0,0 +1,76 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "ezchip,arc-nps";
+	clock-frequency = <83333333>;	/* 83.333333 MHZ */
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&intc>;
+	present-cpus = "0-1,16-17";
+	possible-cpus = "0-4095";
+
+	chosen {
+		bootargs = "earlycon=uart8250,mmio32be,0xf7209000,115200n8 console=ttyS0,115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	/* 512M */
+	};
+
+	fpga {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* child and parent address space 1:1 mapped */
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "ezchip,nps400-ic";
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer {
+			compatible = "ezchip,nps400-timer";
+		};
+
+		uart at f7209000 {
+			compatible = "snps,dw-apb-uart";
+			device_type = "serial";
+			reg = <0xf7209000 0x100>;
+			interrupts = <6>;
+			clock-frequency = <83333333>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			native-endian;
+		};
+
+		ethernet at f7470000 {
+			compatible = "ezchip,nps-mgt-enet";
+			reg = <0xf7470000 0x1940>;
+			interrupts = <7>;
+			mac-address = [ 00 C0 00 F0 04 03 ];
+		};
+	};
+};
diff --git a/arch/arc/configs/nps_defconfig b/arch/arc/configs/nps_defconfig
new file mode 100644
index 0000000..13a67ac
--- /dev/null
+++ b/arch/arc/configs/nps_defconfig
@@ -0,0 +1,85 @@
+CONFIG_CROSS_COMPILE="arceb-linux-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARC_PLAT_EZNPS=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4096
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_CACHE_PAGES is not set
+# CONFIG_ARC_HAS_LLSC is not set
+CONFIG_ARC_VMALLOC_SIZE=192
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_PREEMPT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=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_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=2048
+CONFIG_NETDEVICES=y
+CONFIG_NETCONSOLE=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# 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_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 11/19] ARC: [plat-eznps] Add eznps platform
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   75 +++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  271 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   26 +++
 arch/arc/plat-eznps/mtm.c               |  133 +++++++++++++++
 arch/arc/plat-eznps/platform.c          |   27 +++
 arch/arc/plat-eznps/smp.c               |  149 +++++++++++++++++
 10 files changed, 788 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 08adb4a..c63ca18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4171,6 +4171,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc@ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare@suse.com>
 L:	lm-sensors@lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..051fdca
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_NPS
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..b4dee38
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .init.text, "ax",@progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; With no cache coherency mechanism D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..774fe9c
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#define NPS_HOST_REG_BASE		0xF6000000
+
+/* core auxiliary registers */
+#ifdef __ASSEMBLY__
+#define CTOP_AUX_BASE			(-0x800)
+#else
+#define CTOP_AUX_BASE			0xFFFFF800
+#endif
+
+#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
+#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
+#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)
+#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
+
+/* EZchip core instructions */
+#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
+#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
+#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
+#define CTOP_INST_SCHD_RW			0x3e6f7004
+#define CTOP_INST_SCHD_RD			0x3e6f7084
+#define CTOP_INST_ASRI_0_R3			0x3b56003e
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
+
+#ifndef __ASSEMBLY__
+#define NPS_MSU_BLKID			0x018
+#define NPS_CRG_BLKID			0x480
+#define NPS_CRG_SYNC_BIT		BIT(0)
+
+#define NPS_GIM_BLKID			0x5C0
+#define NPS_GIM_UART_LINE		BIT(7)
+#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
+#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
+
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physically,
+ * and not like the id's physically came with each cluster.
+ * Below table is 4x4 mesh of core clusters as it layout on chip.
+ * Cluster ids are in format: logical (physical)
+ *
+ * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
+ * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
+ * ============================================
+ * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
+ * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
+ * --------------------------------------------
+ *   |   0     |   1     ||    2     |    3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	__asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32     base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			__reserved:4, st_cnt:4, __reserved2:8,
+			hs_cnt:8, __reserved3:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			__reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+
+/* CRG registers */
+#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+
+#endif /* __ASEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..06b59bd
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern void res_service(void);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..aaaaffd
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	log_nat = ilog2(nat);
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..12efeb6
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <asm/mach_desc.h>
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..87849a3
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = (u32)res_service;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+static void eznps_init_per_cpu(int cpu)
+{
+	smp_ipi_irq_setup(cpu, IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+	.init_per_cpu	= eznps_init_per_cpu,
+};
+
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 11/19] ARC: [plat-eznps] Add eznps platform
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This platform include boards:
	Hardware Emulator (HE)
	Simulator based upon nSIM.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 MAINTAINERS                             |    6 +
 arch/arc/plat-eznps/Kconfig             |   34 ++++
 arch/arc/plat-eznps/Makefile            |    7 +
 arch/arc/plat-eznps/entry.S             |   75 +++++++++
 arch/arc/plat-eznps/include/plat/ctop.h |  271 +++++++++++++++++++++++++++++++
 arch/arc/plat-eznps/include/plat/mtm.h  |   60 +++++++
 arch/arc/plat-eznps/include/plat/smp.h  |   26 +++
 arch/arc/plat-eznps/mtm.c               |  133 +++++++++++++++
 arch/arc/plat-eznps/platform.c          |   27 +++
 arch/arc/plat-eznps/smp.c               |  149 +++++++++++++++++
 10 files changed, 788 insertions(+), 0 deletions(-)
 create mode 100644 arch/arc/plat-eznps/Kconfig
 create mode 100644 arch/arc/plat-eznps/Makefile
 create mode 100644 arch/arc/plat-eznps/entry.S
 create mode 100644 arch/arc/plat-eznps/include/plat/ctop.h
 create mode 100644 arch/arc/plat-eznps/include/plat/mtm.h
 create mode 100644 arch/arc/plat-eznps/include/plat/smp.h
 create mode 100644 arch/arc/plat-eznps/mtm.c
 create mode 100644 arch/arc/plat-eznps/platform.c
 create mode 100644 arch/arc/plat-eznps/smp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 08adb4a..c63ca18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4171,6 +4171,12 @@ S:	Maintained
 F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
+EZchip NPS platform support
+M:	Noam Camus <noamc at ezchip.com>
+S:	Supported
+F:	arch/arc/plat-eznps
+F:	arch/arc/boot/dts/eznps.dts
+
 F71805F HARDWARE MONITORING DRIVER
 M:	Jean Delvare <jdelvare at suse.com>
 L:	lm-sensors at lm-sensors.org
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
new file mode 100644
index 0000000..051fdca
--- /dev/null
+++ b/arch/arc/plat-eznps/Kconfig
@@ -0,0 +1,34 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+menuconfig ARC_PLAT_EZNPS
+	bool "\"EZchip\" ARC dev platform"
+	select ARC_HAS_COH_CACHES if SMP
+	select CPU_BIG_ENDIAN
+	select CLKSRC_NPS
+	select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
+	help
+	  Support for EZchip development platforms,
+	  based on ARC700 cores.
+	  We handle few flavours:
+	    - Hardware Emulator AKA HE which is FPGA based chasis
+	    - Simulator based on MetaWare nSIM
+	    - NPS400 chip based on ASIC
+
+config EZNPS_MTM_EXT
+	bool "ARC-EZchip MTM Extensions"
+	select CPUMASK_OFFSTACK
+	depends on ARC_PLAT_EZNPS && SMP
+	default y
+	help
+	  Here we add new hierarchy for CPUs topology.
+	  We got:
+		Core
+		Thread
+	  At the new thread level each CPU represent one HW thread.
+	  At highest hierarchy each core contain 16 threads,
+	  any of them seem like CPU from Linux point of view.
+	  All threads within same core share the execution unit of the
+	  core and HW scheduler round robin between them.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
new file mode 100644
index 0000000..21091b1
--- /dev/null
+++ b/arch/arc/plat-eznps/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := entry.o platform.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
new file mode 100644
index 0000000..b4dee38
--- /dev/null
+++ b/arch/arc/plat-eznps/entry.S
@@ -0,0 +1,75 @@
+/*******************************************************************************
+
+  EZNPS CPU startup Code
+  Copyright(c) 2012 EZchip Technologies.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+  more details.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/cache.h>
+#include <plat/ctop.h>
+
+	.cpu A7
+
+	.section .init.text, "ax", at progbits
+	.align 1024	; HW requierment for restart first PC
+
+ENTRY(res_service)
+#ifdef CONFIG_EZNPS_MTM_EXT
+	; For HW thread != 0 there is no work.
+	lr	r3, [CTOP_AUX_THREAD_ID]
+	cmp	r3, 0
+	jne	stext
+#endif
+
+#ifdef CONFIG_ARC_HAS_DCACHE
+	; With no cache coherency mechanism D$ need to be used very carefully.
+	; Address space:
+	; 0G-2G: We disable CONFIG_ARC_CACHE_PAGES.
+	; 2G-3G: We disable D$ by setting this bit.
+	; 3G-4G: D$ is disabled by architecture.
+	; FMT are huge pages for user application reside at 0-2G.
+	; Only FMT left as one who can use D$ where each such page got
+	; disable/enable bit for cachability.
+	; Programmer will use FMT pages for private data so cache coherency
+	; would not be a problem.
+	; First thing we invalidate D$
+	sr	1, [ARC_REG_DC_IVDC]
+	sr	HW_COMPLY_KRN_NOT_D_CACHED, [CTOP_AUX_HW_COMPLY]
+#endif
+
+#ifdef CONFIG_SMP
+	; check for boot CPU
+	lr	r3, [CTOP_AUX_GLOBAL_ID]
+	cmp	r3, 0
+	jeq	stext
+
+	; We set logical cpuid to be used by GET_CPUID
+	; We do not use physical cpuid since we want ids to be continious when
+	; it comes to cpus on the same quad cluster.
+	; This is useful for applications that used shared resources of a quad
+	; cluster such SRAMS.
+	lr 	r3, [CTOP_AUX_CORE_ID]
+	sr	r3, [CTOP_AUX_LOGIC_CORE_ID]
+	lr	r3, [CTOP_AUX_CLUSTER_ID]
+	; Set logical is acheived by swap of 2 middle bits of cluster id (4 bit)
+	; r3 is used since we use short instruction and we need q-class reg
+	.short	CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST
+	.word 	CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM
+	 sr	r3, [CTOP_AUX_LOGIC_CLUSTER_ID]
+#endif
+
+	j	stext
+END(res_service)
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
new file mode 100644
index 0000000..774fe9c
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_CTOP_H
+#define _PLAT_EZNPS_CTOP_H
+
+#define NPS_HOST_REG_BASE		0xF6000000
+
+/* core auxiliary registers */
+#ifdef __ASSEMBLY__
+#define CTOP_AUX_BASE			(-0x800)
+#else
+#define CTOP_AUX_BASE			0xFFFFF800
+#endif
+
+#define CTOP_AUX_GLOBAL_ID		(CTOP_AUX_BASE + 0x000)
+#define CTOP_AUX_CLUSTER_ID		(CTOP_AUX_BASE + 0x004)
+#define CTOP_AUX_CORE_ID		(CTOP_AUX_BASE + 0x008)
+#define CTOP_AUX_THREAD_ID		(CTOP_AUX_BASE + 0x00C)
+#define CTOP_AUX_LOGIC_GLOBAL_ID	(CTOP_AUX_BASE + 0x010)
+#define CTOP_AUX_LOGIC_CLUSTER_ID	(CTOP_AUX_BASE + 0x014)
+#define CTOP_AUX_LOGIC_CORE_ID		(CTOP_AUX_BASE + 0x018)
+#define CTOP_AUX_MT_CTRL		(CTOP_AUX_BASE + 0x020)
+#define CTOP_AUX_HW_COMPLY		(CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_LPC			(CTOP_AUX_BASE + 0x030)
+#define AUX_REG_TSI1			(CTOP_AUX_BASE + 0x050)
+#define CTOP_AUX_EFLAGS			(CTOP_AUX_BASE + 0x080)
+#define CTOP_AUX_IACK			(CTOP_AUX_BASE + 0x088)
+#define CTOP_AUX_GPA1			(CTOP_AUX_BASE + 0x08C)
+#define CTOP_AUX_UDMC			(CTOP_AUX_BASE + 0x300)
+
+/* EZchip core instructions */
+#define CTOP_INST_HWSCHD_OFF_R3			0x3b6f00bf
+#define CTOP_INST_HWSCHD_OFF_R4			0x3c6f00bf
+#define CTOP_INST_HWSCHD_RESTORE_R3		0x3e6f7083
+#define CTOP_INST_HWSCHD_RESTORE_R4		0x3e6f7103
+#define CTOP_INST_SCHD_RW			0x3e6f7004
+#define CTOP_INST_SCHD_RD			0x3e6f7084
+#define CTOP_INST_ASRI_0_R3			0x3b56003e
+#define CTOP_INST_XEX_DI_R2_R2_R3		0x4a664c00
+#define CTOP_INST_EXC_DI_R2_R2_R3		0x4a664c01
+#define CTOP_INST_AADD_DI_R2_R2_R3		0x4a664c02
+#define CTOP_INST_AAND_DI_R2_R2_R3		0x4a664c04
+#define CTOP_INST_AOR_DI_R2_R2_R3		0x4a664c05
+#define CTOP_INST_AXOR_DI_R2_R2_R3		0x4a664c06
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST	0x5b60
+#define CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM	0x00010422
+#define CTOP_INST_RSPI_GIC_0_R12		0x3c56117e
+
+/* Do not use D$ for address in 2G-3G */
+#define HW_COMPLY_KRN_NOT_D_CACHED	(1 << 28)
+
+#ifndef __ASSEMBLY__
+#define NPS_MSU_BLKID			0x018
+#define NPS_CRG_BLKID			0x480
+#define NPS_CRG_SYNC_BIT		BIT(0)
+
+#define NPS_GIM_BLKID			0x5C0
+#define NPS_GIM_UART_LINE		BIT(7)
+#define NPS_GIM_DBG_LAN_TX_DONE_LINE	BIT(10)
+#define NPS_GIM_DBG_LAN_RX_RDY_LINE	BIT(11)
+
+/* CPU global ID */
+struct global_id {
+	union {
+		struct {
+#ifdef CONFIG_EZNPS_MTM_EXT
+			u32 __reserved:20, cluster:4, core:4, thread:4;
+#else
+			u32 __reserved:24, cluster:4, core:4;
+#endif
+		};
+		u32 value;
+	};
+};
+
+/*
+ * Convert logical to physical CPU IDs
+ *
+ * The conversion swap bits 1 and 2 of cluster id (out of 4 bits)
+ * Now quad of logical clusters id's are adjacent physically,
+ * and not like the id's physically came with each cluster.
+ * Below table is 4x4 mesh of core clusters as it layout on chip.
+ * Cluster ids are in format: logical (physical)
+ *
+ * 3 |  5 (3)  |  7 (7)  ||  13 (11) |  15 (15)
+ * 2 |  4 (2)  |  6 (6)  ||  12 (10) |  14 (14)
+ * ============================================
+ * 1 |  1 (1)  |  3 (5)  ||  9  (9)  |  11 (13)
+ * 0 |  0 (0)  |  2 (4)  ||  8  (8)  |  10 (12)
+ * --------------------------------------------
+ *   |   0     |   1     ||    2     |    3
+ */
+static inline int nps_cluster_logic_to_phys(int cluster)
+{
+	__asm__ __volatile__(
+	"       mov r3,%0\n"
+	"       .short %1\n"
+	"       .word %2\n"
+	"       mov %0,r3\n"
+	: "+r"(cluster)
+	: "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_INST),
+	  "i"(CTOP_INST_MOV2B_FLIP_R3_B1_B2_LIMM)
+	: "r3");
+
+	return cluster;
+}
+
+#define NPS_CPU_TO_CLUSTER_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; \
+		nps_cluster_logic_to_phys(gid.cluster); })
+
+struct nps_host_reg_address {
+	union {
+		struct {
+			u32     base:8, cl_x:4, cl_y:4,
+			blkid:6, reg:8, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cfg {
+	union {
+		struct {
+			u32 gen:1, gdis:1, clk_gate_dis:1, asb:1,
+			__reserved:9, nat:3, ten:16;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_mtm_cpu_cfg {
+	union {
+		struct {
+			u32 csa:22, dmsid:6, __reserved:3, cs:1;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init {
+	union {
+		struct {
+			u32 str:1, __reserved:27, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_thr_init_sts {
+	union {
+		struct {
+			u32 bsy:1, err:1, __reserved:26, thr_id:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_udmc {
+	union {
+		struct {
+			u32 dcp:1, cme:1, __reserved:20, nat:3,
+			__reserved2:5, dcas:3;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_mt_ctrl {
+	union {
+		struct {
+			u32 mten:1, hsen:1, scd:1, sten:1,
+			__reserved:4, st_cnt:4, __reserved2:8,
+			hs_cnt:8, __reserved3:4;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_hw_comply {
+	union {
+		struct {
+			u32 me:1, le:1, te:1, knc:1, __reserved:28;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_aux_lpc {
+	union {
+		struct {
+			u32 mep:1, __reserved:31;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_address_non_cl {
+	union {
+		struct {
+			u32 base:7, blkid:11, reg:12, __reserved:2;
+		};
+		u32 value;
+	};
+};
+
+struct nps_host_reg_gim_p_int_dst {
+	union {
+		struct {
+			u32 int_out_en:1, __reserved1:4,
+			is:1, intm:2, __reserved2:4,
+			nid:4, __reserved3:4, cid:4,
+			__reserved4:4, tid:4;
+		};
+		u32 value;
+	};
+};
+
+static inline void *nps_host_reg_non_cl(u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address_non_cl reg_address;
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.blkid = blkid;
+	reg_address.reg = reg;
+
+	return (void *)reg_address.value;
+}
+
+static inline void *nps_host_reg(u32 cpu, u32 blkid, u32 reg)
+{
+	struct nps_host_reg_address reg_address;
+	u32 cl = NPS_CPU_TO_CLUSTER_NUM(cpu);
+
+	reg_address.value = NPS_HOST_REG_BASE;
+	reg_address.cl_x  = (cl >> 2) & 0x3;
+	reg_address.cl_y  = cl & 0x3;
+	reg_address.blkid = blkid;
+	reg_address.reg   = reg;
+
+	return (void *)reg_address.value;
+}
+
+/* CRG registers */
+#define REG_GEN_PURP_0	nps_host_reg_non_cl(NPS_CRG_BLKID, 0x1BF)
+
+/* GIM registers */
+#define REG_GIM_P_INT_EN_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x100)
+#define REG_GIM_P_INT_POL_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x110)
+#define REG_GIM_P_INT_SENS_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x114)
+#define REG_GIM_P_INT_BLK_0	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x118)
+#define REG_GIM_P_INT_DST_10	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13A)
+#define REG_GIM_P_INT_DST_11	nps_host_reg_non_cl(NPS_GIM_BLKID, 0x13B)
+
+#endif /* __ASEMBLY__ */
+
+#endif /* _PLAT_EZNPS_CTOP_H */
diff --git a/arch/arc/plat-eznps/include/plat/mtm.h b/arch/arc/plat-eznps/include/plat/mtm.h
new file mode 100644
index 0000000..29b91b5
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/mtm.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef _PLAT_EZNPS_MTM_H
+#define _PLAT_EZNPS_MTM_H
+
+#include <plat/ctop.h>
+
+static inline void *nps_mtm_reg_addr(u32 cpu, u32 reg)
+{
+	struct global_id gid;
+	u32 core, blkid;
+
+	gid.value = cpu;
+	core = gid.core;
+	blkid = (((core & 0x0C) << 2) | (core & 0x03));
+
+	return nps_host_reg(cpu, blkid, reg);
+}
+
+#ifdef CONFIG_EZNPS_MTM_EXT
+#define NPS_CPU_TO_THREAD_NUM(cpu) \
+	({ struct global_id gid; gid.value = cpu; gid.thread; })
+
+/* MTM registers */
+#define MTM_CFG(cpu)			nps_mtm_reg_addr(cpu, 0x81)
+#define MTM_THR_INIT(cpu)		nps_mtm_reg_addr(cpu, 0x92)
+#define MTM_THR_INIT_STS(cpu)		nps_mtm_reg_addr(cpu, 0x93)
+
+#define get_thread(map) map.thread
+#define eznps_max_cpus 4096
+#define eznps_cpus_per_cluster	256
+
+void mtm_enable_core(unsigned int cpu);
+int mtm_enable_thread(int cpu);
+#else /* !CONFIG_EZNPS_MTM_EXT */
+
+#define get_thread(map) 0
+#define eznps_max_cpus 256
+#define eznps_cpus_per_cluster	16
+#define mtm_enable_core(cpu)
+#define mtm_enable_thread(cpu) 1
+#define NPS_CPU_TO_THREAD_NUM(cpu) 0
+
+#endif /* CONFIG_EZNPS_MTM_EXT */
+
+#endif /* _PLAT_EZNPS_MTM_H */
diff --git a/arch/arc/plat-eznps/include/plat/smp.h b/arch/arc/plat-eznps/include/plat/smp.h
new file mode 100644
index 0000000..06b59bd
--- /dev/null
+++ b/arch/arc/plat-eznps/include/plat/smp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#ifndef __PLAT_EZNPS_SMP_H
+#define __PLAT_EZNPS_SMP_H
+
+#ifdef CONFIG_SMP
+
+extern void res_service(void);
+
+#endif /* CONFIG_SMP */
+
+#endif
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
new file mode 100644
index 0000000..aaaaffd
--- /dev/null
+++ b/arch/arc/plat-eznps/mtm.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <asm/arcregs.h>
+#include <plat/mtm.h>
+#include <plat/smp.h>
+
+#define MT_CTRL_HS_CNT		0xFF
+#define MT_CTRL_ST_CNT		0xF
+#define NPS_NUM_HW_THREADS	0x10
+
+static void mtm_init_nat(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+	struct nps_host_reg_aux_udmc udmc;
+	int log_nat, nat = 0, i, t;
+
+	/* Iterate core threads and update nat */
+	for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
+		nat += test_bit(t, cpumask_bits(cpu_possible_mask));
+
+	log_nat = ilog2(nat);
+
+	udmc.value = read_aux_reg(CTOP_AUX_UDMC);
+	udmc.nat = log_nat;
+	write_aux_reg(CTOP_AUX_UDMC, udmc.value);
+
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.nat = log_nat;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+}
+
+static void mtm_init_thread(int cpu)
+{
+	int i, tries = 5;
+	struct nps_host_reg_thr_init thr_init;
+	struct nps_host_reg_thr_init_sts thr_init_sts;
+
+	/* Set thread init register */
+	thr_init.value = 0;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+	thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
+	thr_init.str = 1;
+	iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
+
+	/* Poll till thread init is done */
+	for (i = 0; i < tries; i++) {
+		thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
+		if (thr_init_sts.thr_id == thr_init.thr_id) {
+			if (thr_init_sts.bsy)
+				continue;
+			else if (thr_init_sts.err)
+				pr_warn("Failed to thread init cpu %u\n", cpu);
+			break;
+		}
+
+		pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
+		break;
+	}
+
+	if (i == tries)
+		pr_warn("Got thread init timeout for cpu %u\n", cpu);
+}
+
+int mtm_enable_thread(int cpu)
+{
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
+		return 1;
+
+	/* Enable thread in mtm */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	return 0;
+}
+
+void mtm_enable_core(unsigned int cpu)
+{
+	int i;
+	struct nps_host_reg_aux_mt_ctrl mt_ctrl;
+	struct nps_host_reg_mtm_cfg mtm_cfg;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	/* Initialize Number of Active Threads */
+	mtm_init_nat(cpu);
+
+	/* Initialize mtm_cfg */
+	mtm_cfg.value = ioread32be(MTM_CFG(cpu));
+	mtm_cfg.ten = 1;
+	iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
+
+	/* Initialize all other threads in core */
+	for (i = 1; i < NPS_NUM_HW_THREADS; i++)
+		mtm_init_thread(cpu + i);
+
+
+	/* Enable HW schedule, stall counter, mtm */
+	mt_ctrl.value = 0;
+	mt_ctrl.hsen = 1;
+	mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
+	mt_ctrl.sten = 1;
+	mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+	mt_ctrl.mten = 1;
+	write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
+
+	/*
+	 * HW scheduling mechanism will start working
+	 * Only after call to instruction "schd.rw".
+	 * cpu_relax() calls "schd.rw" instruction.
+	 */
+	cpu_relax();
+}
diff --git a/arch/arc/plat-eznps/platform.c b/arch/arc/plat-eznps/platform.c
new file mode 100644
index 0000000..12efeb6
--- /dev/null
+++ b/arch/arc/plat-eznps/platform.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/init.h>
+#include <asm/mach_desc.h>
+
+static const char *eznps_compat[] __initconst = {
+	"ezchip,arc-nps",
+	NULL,
+};
+
+MACHINE_START(NPS, "nps")
+	.dt_compat	= eznps_compat,
+MACHINE_END
diff --git a/arch/arc/plat-eznps/smp.c b/arch/arc/plat-eznps/smp.c
new file mode 100644
index 0000000..87849a3
--- /dev/null
+++ b/arch/arc/plat-eznps/smp.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/smp.h>
+#include <linux/of_fdt.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <plat/ctop.h>
+#include <plat/smp.h>
+#include <plat/mtm.h>
+
+#define NPS_DEFAULT_MSID	0x34
+#define NPS_MTM_CPU_CFG		0x90
+
+static char smp_cpuinfo_buf[128] = {"Extn [EZNPS-SMP]\t: On\n"};
+
+/* Get cpu map from device tree */
+static int __init eznps_get_map(const char *name, struct cpumask *cpumask)
+{
+	unsigned long dt_root = of_get_flat_dt_root();
+	const char *buf;
+
+	buf = of_get_flat_dt_prop(dt_root, name, NULL);
+	if (!buf)
+		return 1;
+
+	cpulist_parse(buf, cpumask);
+
+	return 0;
+}
+
+/* Update board cpu maps */
+static void __init eznps_init_cpumasks(void)
+{
+	struct cpumask cpumask;
+
+	if (eznps_get_map("present-cpus", &cpumask)) {
+		pr_err("Failed to get present-cpus from dtb");
+		return;
+	}
+	init_cpu_present(&cpumask);
+
+	if (eznps_get_map("possible-cpus", &cpumask)) {
+		pr_err("Failed to get possible-cpus from dtb");
+		return;
+	}
+	init_cpu_possible(&cpumask);
+}
+
+static void eznps_init_core(unsigned int cpu)
+{
+	u32 sync_value;
+	struct nps_host_reg_aux_hw_comply hw_comply;
+	struct nps_host_reg_aux_lpc lpc;
+
+	if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
+		return;
+
+	hw_comply.value = read_aux_reg(CTOP_AUX_HW_COMPLY);
+	hw_comply.me  = 1;
+	hw_comply.le  = 1;
+	hw_comply.te  = 1;
+	write_aux_reg(CTOP_AUX_HW_COMPLY, hw_comply.value);
+
+	/* Enable MMU clock */
+	lpc.mep = 1;
+	write_aux_reg(CTOP_AUX_LPC, lpc.value);
+
+	/* Boot CPU only */
+	if (!cpu) {
+		/* Write to general purpose register in CRG */
+		sync_value = ioread32be(REG_GEN_PURP_0);
+		sync_value |= NPS_CRG_SYNC_BIT;
+		iowrite32be(sync_value, REG_GEN_PURP_0);
+	}
+}
+
+/*
+ * Master kick starting another CPU
+ */
+static void __init eznps_smp_wakeup_cpu(int cpu, unsigned long pc)
+{
+	struct nps_host_reg_mtm_cpu_cfg cpu_cfg;
+
+	if (mtm_enable_thread(cpu) == 0)
+		return;
+
+	/* set PC, dmsid, and start CPU */
+	cpu_cfg.value = (u32)res_service;
+	cpu_cfg.dmsid = NPS_DEFAULT_MSID;
+	cpu_cfg.cs = 1;
+	iowrite32be(cpu_cfg.value, nps_mtm_reg_addr(cpu, NPS_MTM_CPU_CFG));
+}
+
+static void eznps_ipi_send(int cpu)
+{
+	struct global_id gid;
+	struct {
+		union {
+			struct {
+				u32 num:8, cluster:8, core:8, thread:8;
+			};
+			u32 value;
+		};
+	} ipi;
+
+	gid.value = cpu;
+	ipi.thread = get_thread(gid);
+	ipi.core = gid.core;
+	ipi.cluster = nps_cluster_logic_to_phys(gid.cluster);
+	ipi.num = IPI_IRQ;
+
+	__asm__ __volatile__(
+	"	mov r3, %0\n"
+	"	.word %1\n"
+	:
+	: "r"(ipi.value), "i"(CTOP_INST_ASRI_0_R3)
+	: "r3");
+}
+
+static void eznps_init_per_cpu(int cpu)
+{
+	smp_ipi_irq_setup(cpu, IPI_IRQ);
+
+	eznps_init_core(cpu);
+	mtm_enable_core(cpu);
+}
+
+struct plat_smp_ops plat_smp_ops = {
+	.info		= smp_cpuinfo_buf,
+	.init_early_smp	= eznps_init_cpumasks,
+	.cpu_kick	= eznps_smp_wakeup_cpu,
+	.ipi_send	= eznps_ipi_send,
+	.init_per_cpu	= eznps_init_per_cpu,
+};
+
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 12/19] ARC: [plat-eznps] Use dedicated user stack top
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index a603301..7266ede 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -126,7 +126,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0c75a27..306ee4c 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 12/19] ARC: [plat-eznps] Use dedicated user stack top
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

NPS use special mapping right below TASK_SIZE.
Hence we need to lower STACK_TOP so that user stack won't
overlap NPS special mapping.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |   17 +++++++++++++++++
 arch/arc/mm/tlb.c                |    6 ++++++
 2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index a603301..7266ede 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -126,7 +126,24 @@ extern unsigned int get_wchan(struct task_struct *p);
 
 #define USER_KERNEL_GUTTER    (VMALLOC_START - TASK_SIZE)
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+/* NPS architecture defines special window of 129M in user address space for
+ * special memory areas, when accessing this window the MMU do not use TLB.
+ * Instead MMU direct the access to:
+ * 0x57f00000:0x57ffffff -- 1M of closely coupled memory (aka CMEM)
+ * 0x58000000:0x5fffffff -- 16 huge pages, 8M each, with fixed map (aka FMTs)
+ *
+ * CMEM - is the fastest memory we got and its size is 16K.
+ * FMT  - is used to map either to internal/external memory.
+ * Internal memory is the second fast memory and its size is 16M
+ * External memory is the biggest memory (16G) and also the slowest.
+ *
+ * STACK_TOP need to be PMD align (21bit) that is why we supply 0x57e00000.
+ */
+#define STACK_TOP       0x57e00000
+#else /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP       TASK_SIZE
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 #define STACK_TOP_MAX   STACK_TOP
 
 /* This decides where the kernel will search for a free chunk of vm
diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c
index 0c75a27..306ee4c 100644
--- a/arch/arc/mm/tlb.c
+++ b/arch/arc/mm/tlb.c
@@ -820,6 +820,12 @@ void arc_mmu_init(void)
 	 */
 	BUILD_BUG_ON(!IS_ALIGNED((CONFIG_ARC_VMALLOC_SIZE << 20), PMD_SIZE));
 
+	/*
+	 * stack top size sanity check,
+	 * Can't be done in processor.h due to header include depenedencies
+	 */
+	BUILD_BUG_ON(!IS_ALIGNED(STACK_TOP, PMD_SIZE));
+
 	/* For efficiency sake, kernel is compile time built for a MMU ver
 	 * This must match the hardware it is running on.
 	 * Linux built for MMU V2, if run on MMU V1 will break down because V1
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 13/19] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

We need our own implementaions since we lack LLSC support.
Our extended ISA provided with optimized solution for all 32bit
operations we see in these three headers.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/atomic.h  |   79 +++++++++++++++++++++++++++++++++++-
 arch/arc/include/asm/bitops.h  |   54 +++++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h |   87 +++++++++++++++++++++++++++++++++-------
 3 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index c3ecda0..1b2e78a 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #define atomic_read(v)  ((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic)
 ATOMIC_OP(or, |=, or)
 ATOMIC_OP(xor, ^=, xor)
 
-#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	temp c_op i;							\
+									\
+	return temp;							\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..5a29185 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,7 @@
 #include <asm/smp.h>
 #endif
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#else /* CONFIG_ARC_PLAT_EZNPS */
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	nr = old = (1UL << (nr & 0x1f));				\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	return (old & nr) != 0;					\
+}
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#else
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..6d320d3 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
 
 #endif /* CONFIG_ARC_HAS_LLSC */
 
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
-				(unsigned long)(o), (unsigned long)(n)))
-
-/*
- * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
- * just to gaurantee semantics.
- * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
- * which also happens to be atomic_ops_lock.
- *
- * Thus despite semantically being different, implementation of atomic_cmpxchg()
- * is same as cmpxchg().
- */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-
-
 /*
  * xchg (reg with memory) based on "Native atomic" EX insn
  */
@@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
 
 #endif
 
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	/*
+	 * Explicit full memory barrier needed before/after
+	 */
+	smp_mb();
+
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	smp_mb();
+
+	return new;
+}
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		/*
+		 * Explicit full memory barrier needed before/after
+		 */
+		smp_mb();
+
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		smp_mb();
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 /*
  * "atomic" variant of xchg()
  * REQ: It needs to follow the same serialization rules as other atomic_xxx()
@@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+
+/*
+ * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
+ * just to gaurantee semantics.
+ * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
+ * which also happens to be atomic_ops_lock.
+ *
+ * Thus despite semantically being different, implementation of atomic_cmpxchg()
+ * is same as cmpxchg().
+ */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
 #endif
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 13/19] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

We need our own implementaions since we lack LLSC support.
Our extended ISA provided with optimized solution for all 32bit
operations we see in these three headers.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/atomic.h  |   79 +++++++++++++++++++++++++++++++++++-
 arch/arc/include/asm/bitops.h  |   54 +++++++++++++++++++++++++
 arch/arc/include/asm/cmpxchg.h |   87 +++++++++++++++++++++++++++++++++-------
 3 files changed, 202 insertions(+), 18 deletions(-)

diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h
index c3ecda0..1b2e78a 100644
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -17,6 +17,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #define atomic_read(v)  ((v)->counter)
 
 #ifdef CONFIG_ARC_HAS_LLSC
@@ -180,12 +181,84 @@ ATOMIC_OP(andnot, &= ~, bic)
 ATOMIC_OP(or, |=, or)
 ATOMIC_OP(xor, ^=, xor)
 
-#undef ATOMIC_OPS
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
 #undef SCOND_FAIL_RETRY_VAR_DEF
 #undef SCOND_FAIL_RETRY_ASM
 #undef SCOND_FAIL_RETRY_VARS
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline int atomic_read(const atomic_t *v)
+{
+	int temp;
+
+	__asm__ __volatile__(
+	"	ld.di %0, [%1]"
+	: "=r"(temp)
+	: "r"(&v->counter)
+	: "memory");
+	return temp;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+	__asm__ __volatile__(
+	"	st.di %0,[%1]"
+	:
+	: "r"(i), "r"(&v->counter)
+	: "memory");
+}
+
+#define ATOMIC_OP(op, c_op, asm_op)					\
+static inline void atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	:								\
+	: "r"(i), "r"(&v->counter), "i"(asm_op)				\
+	: "r2", "r3", "memory");					\
+}									\
+
+#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
+static inline int atomic_##op##_return(int i, atomic_t *v)		\
+{									\
+	unsigned int temp = i;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(temp)							\
+	: "r"(&v->counter), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	temp c_op i;							\
+									\
+	return temp;							\
+}
+
+#define ATOMIC_OPS(op, c_op, asm_op)					\
+	ATOMIC_OP(op, c_op, asm_op)					\
+	ATOMIC_OP_RETURN(op, c_op, asm_op)
+
+ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
+#define atomic_sub(i, v) atomic_add(-(i), (v))
+#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
+
+ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
+#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
+ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
+ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
+#undef ATOMIC_OPS
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
 
 /**
  * __atomic_add_unless - add unless the number is a given value
diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 57c1f33..5a29185 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -22,6 +22,7 @@
 #include <asm/smp.h>
 #endif
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #if defined(CONFIG_ARC_HAS_LLSC)
 
 /*
@@ -155,6 +156,53 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
 }
 
 #endif /* CONFIG_ARC_HAS_LLSC */
+#else /* CONFIG_ARC_PLAT_EZNPS */
+#define BIT_OP(op, c_op, asm_op)					\
+static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	m += nr >> 5;							\
+									\
+	nr = (1UL << (nr & 0x1f));					\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		nr = ~nr;						\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"	.word %2\n"						\
+	:								\
+	: "r"(nr), "r"(m), "i"(asm_op)					\
+	: "r2", "r3", "memory");					\
+}
+
+#define TEST_N_BIT_OP(op, c_op, asm_op)					\
+static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *m)\
+{									\
+	unsigned long old;						\
+									\
+	m += nr >> 5;							\
+									\
+	nr = old = (1UL << (nr & 0x1f));				\
+	if (asm_op == CTOP_INST_AAND_DI_R2_R2_R3)			\
+		old = ~old;						\
+									\
+	/* Explicit full memory barrier needed before/after */		\
+	smp_mb();							\
+									\
+	__asm__ __volatile__(						\
+	"	mov r2, %0\n"						\
+	"	mov r3, %1\n"						\
+	"       .word %2\n"						\
+	"	mov %0, r2"						\
+	: "+r"(old)							\
+	: "r"(m), "i"(asm_op)						\
+	: "r2", "r3", "memory");					\
+									\
+	smp_mb();							\
+									\
+	return (old & nr) != 0;					\
+}
+#endif /* CONFIG_ARC_PLAT_EZNPS */
 
 /***************************************
  * Non atomic variants
@@ -196,9 +244,15 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
 	/* __test_and_set_bit(), __test_and_clear_bit(), __test_and_change_bit() */\
 	__TEST_N_BIT_OP(op, c_op, asm_op)
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 BIT_OPS(set, |, bset)
 BIT_OPS(clear, & ~, bclr)
 BIT_OPS(change, ^, bxor)
+#else
+BIT_OPS(set, |, CTOP_INST_AOR_DI_R2_R2_R3)
+BIT_OPS(clear, & ~, CTOP_INST_AAND_DI_R2_R2_R3)
+BIT_OPS(change, ^, CTOP_INST_AXOR_DI_R2_R2_R3)
+#endif
 
 /*
  * This routine doesn't need to be atomic.
diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h
index af7a2db..6d320d3 100644
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -14,6 +14,7 @@
 #include <asm/barrier.h>
 #include <asm/smp.h>
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 #ifdef CONFIG_ARC_HAS_LLSC
 
 static inline unsigned long
@@ -66,21 +67,6 @@ __cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
 
 #endif /* CONFIG_ARC_HAS_LLSC */
 
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
-				(unsigned long)(o), (unsigned long)(n)))
-
-/*
- * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
- * just to gaurantee semantics.
- * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
- * which also happens to be atomic_ops_lock.
- *
- * Thus despite semantically being different, implementation of atomic_cmpxchg()
- * is same as cmpxchg().
- */
-#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
-
-
 /*
  * xchg (reg with memory) based on "Native atomic" EX insn
  */
@@ -143,6 +129,63 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
 
 #endif
 
+#else /* CONFIG_ARC_PLAT_EZNPS */
+static inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long expected, unsigned long new)
+{
+	/*
+	 * Explicit full memory barrier needed before/after
+	 */
+	smp_mb();
+
+	write_aux_reg(CTOP_AUX_GPA1, expected);
+
+	__asm__ __volatile__(
+	"	mov r2, %0\n"
+	"	mov r3, %1\n"
+	"	.word %2\n"
+	"	mov %0, r2"
+	: "+r"(new)
+	: "r"(ptr), "i"(CTOP_INST_EXC_DI_R2_R2_R3)
+	: "r2", "r3", "memory");
+
+	smp_mb();
+
+	return new;
+}
+
+static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
+				   int size)
+{
+	extern unsigned long __xchg_bad_pointer(void);
+
+	switch (size) {
+	case 4:
+		/*
+		 * Explicit full memory barrier needed before/after
+		 */
+		smp_mb();
+
+		__asm__ __volatile__(
+		"	mov r2, %0\n"
+		"	mov r3, %1\n"
+		"	.word %2\n"
+		"	mov %0, r2\n"
+		: "+r"(val)
+		: "r"(ptr), "i"(CTOP_INST_XEX_DI_R2_R2_R3)
+		: "r2", "r3", "memory");
+
+		smp_mb();
+
+		return val;
+	}
+	return __xchg_bad_pointer();
+}
+
+#define xchg(ptr, with) ((typeof(*(ptr)))__xchg((unsigned long)(with), (ptr), \
+						 sizeof(*(ptr))))
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 /*
  * "atomic" variant of xchg()
  * REQ: It needs to follow the same serialization rules as other atomic_xxx()
@@ -158,4 +201,18 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr,
  */
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr)))__cmpxchg((ptr), \
+				(unsigned long)(o), (unsigned long)(n)))
+
+/*
+ * Since not supported natively, ARC cmpxchg() uses atomic_ops_lock (UP/SMP)
+ * just to gaurantee semantics.
+ * atomic_cmpxchg() needs to use the same locks as it's other atomic siblings
+ * which also happens to be atomic_ops_lock.
+ *
+ * Thus despite semantically being different, implementation of atomic_cmpxchg()
+ * is same as cmpxchg().
+ */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 14/19] ARC: [plat-eznps] Use dedicated SMP barriers
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Noam Camus <noamc@ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..a559732 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +42,13 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 14/19] ARC: [plat-eznps] Use dedicated SMP barriers
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

NPS device got 256 cores and each got 16 HW threads (SMT).
We use EZchip dedicated ISA to trigger HW scheduler of the
core that current HW thread belongs to.
This scheduling makes sure that data beyond barrier is available
to all HW threads in core and by that to all in device (4K).

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 arch/arc/include/asm/barrier.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
index a720998..a559732 100644
--- a/arch/arc/include/asm/barrier.h
+++ b/arch/arc/include/asm/barrier.h
@@ -34,6 +34,7 @@
 
 #ifdef CONFIG_ISA_ARCOMPACT
 
+#ifndef CONFIG_ARC_PLAT_EZNPS
 /*
  * ARCompact based cores (ARC700) only have SYNC instruction which is super
  * heavy weight as it flushes the pipeline as well.
@@ -41,6 +42,13 @@
  */
 
 #define mb()	asm volatile("sync\n" : : : "memory")
+#else /* CONFIG_ARC_PLAT_EZNPS */
+
+#include <plat/ctop.h>
+#define mb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#define rmb()	asm volatile (".word %0" : : "i"(CTOP_INST_SCHD_RD) : "memory")
+#endif /* CONFIG_ARC_PLAT_EZNPS */
+
 #endif
 
 #include <asm-generic/barrier.h>
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 15/19] ARC: [plat-eznps] Use dedicated identity auxiliary register.
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5be..92e2e82 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -69,9 +72,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -109,6 +119,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 15/19] ARC: [plat-eznps] Use dedicated identity auxiliary register.
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

With generic "identity" num of CPUs is limited to 256 (8 bit).
We use our alternative AUX register GLOBAL_ID (12 bit).
Now we can support up to 4096 CPUs.

Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/include/asm/entry-compact.h |    8 ++++++++
 arch/arc/kernel/ctx_sw.c             |   13 +++++++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h
index 1aff3be..bf9a6a1 100644
--- a/arch/arc/include/asm/entry-compact.h
+++ b/arch/arc/include/asm/entry-compact.h
@@ -35,6 +35,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/irqflags-compact.h>
 #include <asm/thread_info.h>	/* For THREAD_SIZE */
+#include <plat/ctop.h>
 
 /*--------------------------------------------------------------
  * Switch to Kernel Mode stack if SP points to User Mode stack
@@ -298,9 +299,16 @@
 
 /* Get CPU-ID of this core */
 .macro  GET_CPU_ID  reg
+#ifdef CONFIG_ARC_PLAT_EZNPS
+	lr  \reg, [CTOP_AUX_LOGIC_GLOBAL_ID]
+#ifndef CONFIG_EZNPS_MTM_EXT
+	lsr \reg, \reg, 4
+#endif
+#else
 	lr  \reg, [identity]
 	lsr \reg, \reg, 8
 	bmsk \reg, \reg, 7
+#endif
 .endm
 
 #endif  /* __ASM_ARC_ENTRY_COMPACT_H */
diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5be..92e2e82 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -16,6 +16,9 @@
 
 #include <asm/asm-offsets.h>
 #include <linux/sched.h>
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#include <plat/ctop.h>
+#endif
 
 #define KSP_WORD_OFF 	((TASK_THREAD + THREAD_KSP) / 4)
 
@@ -69,9 +72,16 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifndef CONFIG_SMP
 		"st  %2, [@_current_task]	\n\t"
 #else
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		"lr   r24, [%4]		\n\t"
+#ifndef CONFIG_EZNPS_MTM_EXT
+		"lsr  r24, r24, 4		\n\t"
+#endif
+#else
 		"lr   r24, [identity]		\n\t"
 		"lsr  r24, r24, 8		\n\t"
 		"bmsk r24, r24, 7		\n\t"
+#endif
 		"add2 r24, @_current_task, r24	\n\t"
 		"st   %2,  [r24]		\n\t"
 #endif
@@ -109,6 +119,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 
 		: "=r"(tmp)
 		: "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
+#ifdef CONFIG_ARC_PLAT_EZNPS
+		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus, Peter Zijlstra

From: Tal Zilcer <talz@ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Implementing cpu_relax_lowlatency() with barrier()
Since with current semantics of cpu_relax() it may take a
while till yielded CPU will get back.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 7266ede..50f9bae 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -58,12 +58,21 @@ struct task_struct;
  * get optimised away by gcc
  */
 #ifdef CONFIG_SMP
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
 #else
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#endif
+#else
 #define cpu_relax()	do { } while (0)
 #endif
 
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax_lowlatency() cpu_relax()
+#else
+#define cpu_relax_lowlatency() barrier()
+#endif
 
 #define copy_segments(tsk, mm)      do { } while (0)
 #define release_segments(mm)        do { } while (0)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Tal Zilcer <talz@ezchip.com>

Since the CTOP is SMT hardware multi-threaded, we need to hint
the HW that now will be a very good time to do a hardware
thread context switching. This is done by issuing the schd.rw
instruction (binary coded here so as to not require specific
revision of GCC to build the kernel).
sched.rw means that Thread becomes eligible for execution by
the threads scheduler after all pending read/write
transactions were completed.

Implementing cpu_relax_lowlatency() with barrier()
Since with current semantics of cpu_relax() it may take a
while till yielded CPU will get back.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 7266ede..50f9bae 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -58,12 +58,21 @@ struct task_struct;
  * get optimised away by gcc
  */
 #ifdef CONFIG_SMP
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
 #else
+#define cpu_relax()     \
+	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
+#endif
+#else
 #define cpu_relax()	do { } while (0)
 #endif
 
+#ifndef CONFIG_EZNPS_MTM_EXT
 #define cpu_relax_lowlatency() cpu_relax()
+#else
+#define cpu_relax_lowlatency() barrier()
+#endif
 
 #define copy_segments(tsk, mm)      do { } while (0)
 #define release_segments(mm)        do { } while (0)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 17/19] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc@ezchip.com>
Acked-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 17/19] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

The default 256 bytes sometimes is just not enough.
We usually provide earlycon=... and console=... and ip=...
All this and more may need more room.

Signed-off-by: Noam Camus <noamc at ezchip.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/setup.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arc/include/asm/setup.h b/arch/arc/include/asm/setup.h
index 3078466..48b37c6 100644
--- a/arch/arc/include/asm/setup.h
+++ b/arch/arc/include/asm/setup.h
@@ -12,7 +12,11 @@
 #include <linux/types.h>
 #include <uapi/asm/setup.h>
 
+#ifdef CONFIG_ARC_PLAT_EZNPS
+#define COMMAND_LINE_SIZE 2048
+#else
 #define COMMAND_LINE_SIZE 256
+#endif
 
 /*
  * Data structure to map a ID to string
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Tal Zilcer <talz@ezchip.com>

In SMT system like we have the generic "sync" is not working with
HW threads. The replacement is "schd.rw" instruction that is served
as cpu barrier for HW threads.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/kernel/ctx_sw.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 92e2e82..2a2f50e 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
+#ifdef CONFIG_EZNPS_MTM_EXT
+		".word %5   \n\t"
+#else
 		"sync   \n\t"
+#endif
 
 		/*
 		 * setup _current_task with incoming tsk.
@@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifdef CONFIG_ARC_PLAT_EZNPS
 		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
 #endif
+#ifdef CONFIG_EZNPS_MTM_EXT
+		, "i"(CTOP_INST_SCHD_RW)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Tal Zilcer <talz@ezchip.com>

In SMT system like we have the generic "sync" is not working with
HW threads. The replacement is "schd.rw" instruction that is served
as cpu barrier for HW threads.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/kernel/ctx_sw.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index 92e2e82..2a2f50e 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
+#ifdef CONFIG_EZNPS_MTM_EXT
+		".word %5   \n\t"
+#else
 		"sync   \n\t"
+#endif
 
 		/*
 		 * setup _current_task with incoming tsk.
@@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 #ifdef CONFIG_ARC_PLAT_EZNPS
 		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
 #endif
+#ifdef CONFIG_EZNPS_MTM_EXT
+		, "i"(CTOP_INST_SCHD_RW)
+#endif
 		: "blink"
 	);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 19/19] ARC: Add eznps platform to Kconfig and Makefile
  2015-10-31 13:15 ` Noam Camus
@ 2015-11-07 10:52   ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf, Noam Camus

From: Noam Camus <noamc@ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc@ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 8a27a48..ebaab13 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,11 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 19/19] ARC: Add eznps platform to Kconfig and Makefile
@ 2015-11-07 10:52   ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 10:52 UTC (permalink / raw)
  To: linux-snps-arc

From: Noam Camus <noamc@ezchip.com>

This commit should be left last since only now eznps platform
is in state which one can actually use.
Signed-off-by: Noam Camus <noamc at ezchip.com>
---
 arch/arc/Kconfig  |    1 +
 arch/arc/Makefile |    5 +++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 689ccb3..8153b79 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -91,6 +91,7 @@ source "arch/arc/plat-sim/Kconfig"
 source "arch/arc/plat-tb10x/Kconfig"
 source "arch/arc/plat-axs10x/Kconfig"
 #New platform adds here
+source "arch/arc/plat-eznps/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index 8a27a48..ebaab13 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -99,6 +99,11 @@ core-y		+= arch/arc/boot/dts/
 core-$(CONFIG_ARC_PLAT_SIM)	+= arch/arc/plat-sim/
 core-$(CONFIG_ARC_PLAT_TB10X)	+= arch/arc/plat-tb10x/
 core-$(CONFIG_ARC_PLAT_AXS10X)	+= arch/arc/plat-axs10x/
+core-$(CONFIG_ARC_PLAT_EZNPS)	+= arch/arc/plat-eznps/
+
+ifdef CONFIG_ARC_PLAT_EZNPS
+KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include
+endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 03/19] clocksource: Add NPS400 timers driver
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-07 11:26     ` Thomas Gleixner
  -1 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 11:26 UTC (permalink / raw)
  To: Noam Camus
  Cc: linux-snps-arc, linux-kernel, talz, gilf, cmetcalf,
	Daniel Lezcano, Rob Herring, John Stultz

On Sat, 7 Nov 2015, Noam Camus wrote:
> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower, upper, old_upper;
> +	void *lower_p, *upper_p;
> +	int cluster = (smp_processor_id() >> NPS_CLUSTER_OFFSET);
> +
> +	lower_p = nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +
> +	upper = ioread32be(upper_p);
> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = (upper << 32) | lower;
> +	return (cycle_t)counter;

So that clocksource goes up to 1GHz. That means u32 fits ~4.29
seconds. Unless you are striving for NOHZ idle sleep times above that
there is no point in doing that 64bit dance.

The timekeeping code is perfectly fine with a 32bit value. You just
have to set the proper mask.

Thanks,

	tglx



^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 03/19] clocksource: Add NPS400 timers driver
@ 2015-11-07 11:26     ` Thomas Gleixner
  0 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 11:26 UTC (permalink / raw)
  To: linux-snps-arc

On Sat, 7 Nov 2015, Noam Camus wrote:
> +/*
> + * To get the value from the Global Timer Counter register proceed as follows:
> + * 1. Read the upper 32-bit timer counter register
> + * 2. Read the lower 32-bit timer counter register
> + * 3. Read the upper 32-bit timer counter register again. If the value is
> + *  different to the 32-bit upper value read previously, go back to step 2.
> + *  Otherwise the 64-bit timer counter value is correct.
> + */
> +static cycle_t nps_clksrc_read(struct clocksource *clksrc)
> +{
> +	u64 counter;
> +	u32 lower, upper, old_upper;
> +	void *lower_p, *upper_p;
> +	int cluster = (smp_processor_id() >> NPS_CLUSTER_OFFSET);
> +
> +	lower_p = nps_msu_reg_low_addr[cluster];
> +	upper_p = lower_p + 4;
> +
> +	upper = ioread32be(upper_p);
> +	do {
> +		old_upper = upper;
> +		lower = ioread32be(lower_p);
> +		upper = ioread32be(upper_p);
> +	} while (upper != old_upper);
> +
> +	counter = (upper << 32) | lower;
> +	return (cycle_t)counter;

So that clocksource goes up to 1GHz. That means u32 fits ~4.29
seconds. Unless you are striving for NOHZ idle sleep times above that
there is no point in doing that 64bit dance.

The timekeeping code is perfectly fine with a 32bit value. You just
have to set the proper mask.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-07 11:38     ` Thomas Gleixner
  -1 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 11:38 UTC (permalink / raw)
  To: Noam Camus
  Cc: linux-snps-arc, linux-kernel, talz, gilf, cmetcalf, Jason Cooper,
	Marc Zyngier

On Sat, 7 Nov 2015, Noam Camus wrote:
> +#define NPS_MSU_EN_CFG	0x80
> +
> +/* Messaging and Scheduling Unit:
> + * Provides message management for a CPU cluster.
> + */
> +static void __init eznps_configure_msu(void)
> +{
> +	int cpu;
> +	struct nps_host_reg_msu_en_cfg {
> +		union {
> +			struct {
> +				u32     __reserved1:11,
> +				rtc_en:1, ipc_en:1, gim_1_en:1,
> +				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
> +				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
> +				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
> +				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
> +				buff_i_alc_bmue:1, __reserved2:1,
> +				buff_e_pre_en:1, buff_i_pre_en:1,
> +				pmuw_ja_en:1, pmue_ja_en:1,
> +				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
> +			};
> +			u32 value;
> +		};
> +	};
> +	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
> +
> +	msu_en_cfg.msu_en = 1;
> +	msu_en_cfg.ipi_en = 1;
> +	msu_en_cfg.gim_0_en = 1;
> +	msu_en_cfg.gim_1_en = 1;

Yuck. What's wrong with:

#define GIM_1_EN	(1 << 13)
#define GIM_0_EN	(1 << 14)
#define IPI_EN		(1 << 15)
#define MSU_EN		(1 << 31)

	u32 val = GIM_1_EN | GIM_0_EN | IPI_EN | MSU_EN;

Hmm?

> +/* Global Interrupt Manager:
> + * Configures and manages up to 64 interrupts from peripherals,
> + * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
> + * Receives the interrupts and transmits them to relevant CPU.
> + */
> +static void __init eznps_configure_gim(void)
> +{
> +	u32 reg_value;
> +	u32 gim_int_lines;
> +	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
> +
> +	gim_int_lines = NPS_GIM_UART_LINE;
> +	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
> +	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
> +
> +	/*
> +	 * IRQ polarity
> +	 * low or high level
> +	 * negative or positive edge
> +	 */
> +	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
> +	reg_value &= ~gim_int_lines;
> +	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
> +
> +	/* IRQ type level or edge */
> +	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
> +	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
> +	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
> +
> +	/*
> +	 * GIM interrupt select type for
> +	 * dbg_lan TX and RX interrupts
> +	 * should be type 1
> +	 * type 0 = IRQ line 6
> +	 * type 1 = IRQ line 7
> +	 */
> +	gim_p_int_dst.is = 1;

More magic structs to set a single bit, right?

> +/*
> + * NPS400 core includes a Interrupt Controller (IC) support.
> + * All cores can deactivate level irqs at first level control
> + * at cores mesh layer called MTM.
> + * For devices out side chip e.g. uart, network there is another
> + * level called Global Interrupt Manager (GIM).
> + * This second level can control level and edge interrupt.
> + */
> +
> +static void nps400_irq_mask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb &= ~(1 << data->irq);

You should not rely on data->irq ever. It's the Linux interrupt number
and it does not necessarily have a 1:1 mapping to the hardware
interrupt number. Its working for legacy domains, but there
data->hwirq is set up for you as well.

> +	write_aux_reg(AUX_IENABLE, ienb);

I can see how that works for per cpu interrupts, but what happens if
two cpus run that concurrent for two different interrupts?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
@ 2015-11-07 11:38     ` Thomas Gleixner
  0 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 11:38 UTC (permalink / raw)
  To: linux-snps-arc

On Sat, 7 Nov 2015, Noam Camus wrote:
> +#define NPS_MSU_EN_CFG	0x80
> +
> +/* Messaging and Scheduling Unit:
> + * Provides message management for a CPU cluster.
> + */
> +static void __init eznps_configure_msu(void)
> +{
> +	int cpu;
> +	struct nps_host_reg_msu_en_cfg {
> +		union {
> +			struct {
> +				u32     __reserved1:11,
> +				rtc_en:1, ipc_en:1, gim_1_en:1,
> +				gim_0_en:1, ipi_en:1, buff_e_rls_bmuw:1,
> +				buff_e_alc_bmuw:1, buff_i_rls_bmuw:1,
> +				buff_i_alc_bmuw:1, buff_e_rls_bmue:1,
> +				buff_e_alc_bmue:1, buff_i_rls_bmue:1,
> +				buff_i_alc_bmue:1, __reserved2:1,
> +				buff_e_pre_en:1, buff_i_pre_en:1,
> +				pmuw_ja_en:1, pmue_ja_en:1,
> +				pmuw_nj_en:1, pmue_nj_en:1, msu_en:1;
> +			};
> +			u32 value;
> +		};
> +	};
> +	struct nps_host_reg_msu_en_cfg msu_en_cfg = {.value = 0};
> +
> +	msu_en_cfg.msu_en = 1;
> +	msu_en_cfg.ipi_en = 1;
> +	msu_en_cfg.gim_0_en = 1;
> +	msu_en_cfg.gim_1_en = 1;

Yuck. What's wrong with:

#define GIM_1_EN	(1 << 13)
#define GIM_0_EN	(1 << 14)
#define IPI_EN		(1 << 15)
#define MSU_EN		(1 << 31)

	u32 val = GIM_1_EN | GIM_0_EN | IPI_EN | MSU_EN;

Hmm?

> +/* Global Interrupt Manager:
> + * Configures and manages up to 64 interrupts from peripherals,
> + * 16 interrupts from CPUs (virtual interrupts) and ECC interrupts.
> + * Receives the interrupts and transmits them to relevant CPU.
> + */
> +static void __init eznps_configure_gim(void)
> +{
> +	u32 reg_value;
> +	u32 gim_int_lines;
> +	struct nps_host_reg_gim_p_int_dst gim_p_int_dst = {.value = 0};
> +
> +	gim_int_lines = NPS_GIM_UART_LINE;
> +	gim_int_lines |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
> +	gim_int_lines |= NPS_GIM_DBG_LAN_RX_RDY_LINE;
> +
> +	/*
> +	 * IRQ polarity
> +	 * low or high level
> +	 * negative or positive edge
> +	 */
> +	reg_value = ioread32be(REG_GIM_P_INT_POL_0);
> +	reg_value &= ~gim_int_lines;
> +	iowrite32be(reg_value, REG_GIM_P_INT_POL_0);
> +
> +	/* IRQ type level or edge */
> +	reg_value = ioread32be(REG_GIM_P_INT_SENS_0);
> +	reg_value |= NPS_GIM_DBG_LAN_TX_DONE_LINE;
> +	iowrite32be(reg_value, REG_GIM_P_INT_SENS_0);
> +
> +	/*
> +	 * GIM interrupt select type for
> +	 * dbg_lan TX and RX interrupts
> +	 * should be type 1
> +	 * type 0 = IRQ line 6
> +	 * type 1 = IRQ line 7
> +	 */
> +	gim_p_int_dst.is = 1;

More magic structs to set a single bit, right?

> +/*
> + * NPS400 core includes a Interrupt Controller (IC) support.
> + * All cores can deactivate level irqs at first level control
> + * at cores mesh layer called MTM.
> + * For devices out side chip e.g. uart, network there is another
> + * level called Global Interrupt Manager (GIM).
> + * This second level can control level and edge interrupt.
> + */
> +
> +static void nps400_irq_mask(struct irq_data *data)
> +{
> +	unsigned int ienb;
> +
> +	ienb = read_aux_reg(AUX_IENABLE);
> +	ienb &= ~(1 << data->irq);

You should not rely on data->irq ever. It's the Linux interrupt number
and it does not necessarily have a 1:1 mapping to the hardware
interrupt number. Its working for legacy domains, but there
data->hwirq is set up for you as well.

> +	write_aux_reg(AUX_IENABLE, ienb);

I can see how that works for per cpu interrupts, but what happens if
two cpus run that concurrent for two different interrupts?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
  2015-11-07 11:38     ` Thomas Gleixner
@ 2015-11-07 20:52       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 20:52 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-snps-arc, linux-kernel, Tal Zilcer, Gil Fruchter,
	Chris Metcalf, Jason Cooper, Marc Zyngier

>From: Thomas Gleixner <tglx@linutronix.de>
>Sent: Saturday, November 7, 2015 1:38 PM

>> +     /*
>> +      * GIM interrupt select type for
>> +      * dbg_lan TX and RX interrupts
>> +      * should be type 1
>> +      * type 0 = IRQ line 6
>> +      * type 1 = IRQ line 7
>> +      */
>> +     gim_p_int_dst.is = 1;

>More magic structs to set a single bit, right?
I will replace all such magic with macros.

>> +     ienb &= ~(1 << data->irq);

>You should not rely on data->irq ever. It's the Linux interrupt number
>and it does not necessarily have a 1:1 mapping to the hardware
>nterrupt number. Its working for legacy domains, but there
>data->hwirq is set up for you as well.
Thanks, I will use data->hwirq instead of data->irq.


>> +     write_aux_reg(AUX_IENABLE, ienb);

>I can see how that works for per cpu interrupts, but what happens if
>two cpus run that concurrent for two different interrupts?

Each CPU got its own HW copy of auxiliary register IENABLE, so concurrent access won't be a trouble.
 
-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
@ 2015-11-07 20:52       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-07 20:52 UTC (permalink / raw)
  To: linux-snps-arc

>From: Thomas Gleixner <tglx at linutronix.de>
>Sent: Saturday, November 7, 2015 1:38 PM

>> +     /*
>> +      * GIM interrupt select type for
>> +      * dbg_lan TX and RX interrupts
>> +      * should be type 1
>> +      * type 0 = IRQ line 6
>> +      * type 1 = IRQ line 7
>> +      */
>> +     gim_p_int_dst.is = 1;

>More magic structs to set a single bit, right?
I will replace all such magic with macros.

>> +     ienb &= ~(1 << data->irq);

>You should not rely on data->irq ever. It's the Linux interrupt number
>and it does not necessarily have a 1:1 mapping to the hardware
>nterrupt number. Its working for legacy domains, but there
>data->hwirq is set up for you as well.
Thanks, I will use data->hwirq instead of data->irq.


>> +     write_aux_reg(AUX_IENABLE, ienb);

>I can see how that works for per cpu interrupts, but what happens if
>two cpus run that concurrent for two different interrupts?

Each CPU got its own HW copy of auxiliary register IENABLE, so concurrent access won't be a trouble.
 
-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
  2015-11-07 20:52       ` Noam Camus
@ 2015-11-07 23:52         ` Thomas Gleixner
  -1 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 23:52 UTC (permalink / raw)
  To: Noam Camus
  Cc: linux-snps-arc, linux-kernel, Tal Zilcer, Gil Fruchter,
	Chris Metcalf, Jason Cooper, Marc Zyngier

Noam,

On Sat, 7 Nov 2015, Noam Camus wrote:
> >From: Thomas Gleixner <tglx@linutronix.de>
> >> +     write_aux_reg(AUX_IENABLE, ienb);
> 
> >I can see how that works for per cpu interrupts, but what happens if
> >two cpus run that concurrent for two different interrupts?
> 
> Each CPU got its own HW copy of auxiliary register IENABLE, so
> concurrent access won't be a trouble.

Please put a comment into the code explaining it.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 04/19] irqchip: add nps Internal and external irqchips
@ 2015-11-07 23:52         ` Thomas Gleixner
  0 siblings, 0 replies; 190+ messages in thread
From: Thomas Gleixner @ 2015-11-07 23:52 UTC (permalink / raw)
  To: linux-snps-arc

Noam,

On Sat, 7 Nov 2015, Noam Camus wrote:
> >From: Thomas Gleixner <tglx at linutronix.de>
> >> +     write_aux_reg(AUX_IENABLE, ienb);
> 
> >I can see how that works for per cpu interrupts, but what happens if
> >two cpus run that concurrent for two different interrupts?
> 
> Each CPU got its own HW copy of auxiliary register IENABLE, so
> concurrent access won't be a trouble.

Please put a comment into the code explaining it.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-09 10:05     ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 10:05 UTC (permalink / raw)
  To: Noam Camus; +Cc: linux-snps-arc, linux-kernel, talz, gilf, cmetcalf

On Sat, Nov 07, 2015 at 12:52:34PM +0200, Noam Camus wrote:
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..50f9bae 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,12 +58,21 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifndef CONFIG_EZNPS_MTM_EXT
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>  #else
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#endif
> +#else
>  #define cpu_relax()	do { } while (0)

I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
be a compiler barrier.

>  #endif
>  
> +#ifndef CONFIG_EZNPS_MTM_EXT
>  #define cpu_relax_lowlatency() cpu_relax()
> +#else
> +#define cpu_relax_lowlatency() barrier()
> +#endif

At which point you can unconditionally use that definition.

>  
>  #define copy_segments(tsk, mm)      do { } while (0)
>  #define release_segments(mm)        do { } while (0)
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-09 10:05     ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 10:05 UTC (permalink / raw)
  To: linux-snps-arc

On Sat, Nov 07, 2015@12:52:34PM +0200, Noam Camus wrote:
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 7266ede..50f9bae 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -58,12 +58,21 @@ struct task_struct;
>   * get optimised away by gcc
>   */
>  #ifdef CONFIG_SMP
> +#ifndef CONFIG_EZNPS_MTM_EXT
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>  #else
> +#define cpu_relax()     \
> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> +#endif
> +#else
>  #define cpu_relax()	do { } while (0)

I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
be a compiler barrier.

>  #endif
>  
> +#ifndef CONFIG_EZNPS_MTM_EXT
>  #define cpu_relax_lowlatency() cpu_relax()
> +#else
> +#define cpu_relax_lowlatency() barrier()
> +#endif

At which point you can unconditionally use that definition.

>  
>  #define copy_segments(tsk, mm)      do { } while (0)
>  #define release_segments(mm)        do { } while (0)
> -- 
> 1.7.1
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-09 10:05     ` Peter Zijlstra
@ 2015-11-09 10:22       ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-09 10:22 UTC (permalink / raw)
  To: Peter Zijlstra, Noam Camus
  Cc: gilf, linux-snps-arc, talz, linux-kernel, cmetcalf

On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
> On Sat, Nov 07, 2015 at 12:52:34PM +0200, Noam Camus wrote:
>> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
>> index 7266ede..50f9bae 100644
>> --- a/arch/arc/include/asm/processor.h
>> +++ b/arch/arc/include/asm/processor.h
>> @@ -58,12 +58,21 @@ struct task_struct;
>>   * get optimised away by gcc
>>   */
>>  #ifdef CONFIG_SMP
>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>>  #else
>> +#define cpu_relax()     \
>> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
>> +#endif
>> +#else
>>  #define cpu_relax()	do { } while (0)
> I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
> be a compiler barrier.

We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
psuedo randomly)

http://marc.info/?l=linux-kernel&m=140350765530113


>
>>  #endif
>>  
>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>  #define cpu_relax_lowlatency() cpu_relax()
>> +#else
>> +#define cpu_relax_lowlatency() barrier()
>> +#endif
> At which point you can unconditionally use that definition.
>
>>  
>>  #define copy_segments(tsk, mm)      do { } while (0)
>>  #define release_segments(mm)        do { } while (0)
>> -- 
>> 1.7.1
>>
> _______________________________________________
> linux-snps-arc mailing list
> linux-snps-arc@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-snps-arc
>


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-09 10:22       ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-09 10:22 UTC (permalink / raw)
  To: linux-snps-arc

On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
> On Sat, Nov 07, 2015@12:52:34PM +0200, Noam Camus wrote:
>> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
>> index 7266ede..50f9bae 100644
>> --- a/arch/arc/include/asm/processor.h
>> +++ b/arch/arc/include/asm/processor.h
>> @@ -58,12 +58,21 @@ struct task_struct;
>>   * get optimised away by gcc
>>   */
>>  #ifdef CONFIG_SMP
>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>>  #else
>> +#define cpu_relax()     \
>> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
>> +#endif
>> +#else
>>  #define cpu_relax()	do { } while (0)
> I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
> be a compiler barrier.

We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
psuedo randomly)

http://marc.info/?l=linux-kernel&m=140350765530113


>
>>  #endif
>>  
>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>  #define cpu_relax_lowlatency() cpu_relax()
>> +#else
>> +#define cpu_relax_lowlatency() barrier()
>> +#endif
> At which point you can unconditionally use that definition.
>
>>  
>>  #define copy_segments(tsk, mm)      do { } while (0)
>>  #define release_segments(mm)        do { } while (0)
>> -- 
>> 1.7.1
>>
> _______________________________________________
> linux-snps-arc mailing list
> linux-snps-arc at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-snps-arc
>

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-09 10:22       ` Vineet Gupta
@ 2015-11-09 10:45         ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 10:45 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: Noam Camus, gilf, linux-snps-arc, talz, linux-kernel, cmetcalf

On Mon, Nov 09, 2015 at 10:22:27AM +0000, Vineet Gupta wrote:
> On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
> > On Sat, Nov 07, 2015 at 12:52:34PM +0200, Noam Camus wrote:
> >> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> >> index 7266ede..50f9bae 100644
> >> --- a/arch/arc/include/asm/processor.h
> >> +++ b/arch/arc/include/asm/processor.h
> >> @@ -58,12 +58,21 @@ struct task_struct;
> >>   * get optimised away by gcc
> >>   */
> >>  #ifdef CONFIG_SMP
> >> +#ifndef CONFIG_EZNPS_MTM_EXT
> >>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> >>  #else
> >> +#define cpu_relax()     \
> >> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> >> +#endif
> >> +#else
> >>  #define cpu_relax()	do { } while (0)
> > I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
> > be a compiler barrier.
> 
> We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
> psuedo randomly)
> 
> http://marc.info/?l=linux-kernel&m=140350765530113

Hurm.. you have a better memory than me ;-)

So in general we assume cpu_relax() implies a barrier() and I think we
have loops like:

	while (!var)
		cpu_relax();

where var isn't volatile (or casted using READ_ONCE etc).

See for instance: kernel/time/timer.c:lock_timer_base() which has:

	for (;;) {
		u32 tf = timer->flags;

		if (!(tf & TIMER_MIGRATING)) {
		 ...
		}

		cpu_relax();
	}

So while TIMER_MIGRATING is set, it will only ever do regular loads,
which GCC is permitted to lift out if cpu_relax() is not a barrier.



^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-09 10:45         ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 10:45 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Nov 09, 2015@10:22:27AM +0000, Vineet Gupta wrote:
> On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
> > On Sat, Nov 07, 2015@12:52:34PM +0200, Noam Camus wrote:
> >> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> >> index 7266ede..50f9bae 100644
> >> --- a/arch/arc/include/asm/processor.h
> >> +++ b/arch/arc/include/asm/processor.h
> >> @@ -58,12 +58,21 @@ struct task_struct;
> >>   * get optimised away by gcc
> >>   */
> >>  #ifdef CONFIG_SMP
> >> +#ifndef CONFIG_EZNPS_MTM_EXT
> >>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> >>  #else
> >> +#define cpu_relax()     \
> >> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
> >> +#endif
> >> +#else
> >>  #define cpu_relax()	do { } while (0)
> > I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
> > be a compiler barrier.
> 
> We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
> psuedo randomly)
> 
> http://marc.info/?l=linux-kernel&m=140350765530113

Hurm.. you have a better memory than me ;-)

So in general we assume cpu_relax() implies a barrier() and I think we
have loops like:

	while (!var)
		cpu_relax();

where var isn't volatile (or casted using READ_ONCE etc).

See for instance: kernel/time/timer.c:lock_timer_base() which has:

	for (;;) {
		u32 tf = timer->flags;

		if (!(tf & TIMER_MIGRATING)) {
		 ...
		}

		cpu_relax();
	}

So while TIMER_MIGRATING is set, it will only ever do regular loads,
which GCC is permitted to lift out if cpu_relax() is not a barrier.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-09 10:45         ` Peter Zijlstra
@ 2015-11-09 12:27           ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-09 12:27 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Monday 09 November 2015 04:15 PM, Peter Zijlstra wrote:
> On Mon, Nov 09, 2015 at 10:22:27AM +0000, Vineet Gupta wrote:
>> On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
>>> On Sat, Nov 07, 2015 at 12:52:34PM +0200, Noam Camus wrote:
>>>> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
>>>> index 7266ede..50f9bae 100644
>>>> --- a/arch/arc/include/asm/processor.h
>>>> +++ b/arch/arc/include/asm/processor.h
>>>> @@ -58,12 +58,21 @@ struct task_struct;
>>>>   * get optimised away by gcc
>>>>   */
>>>>  #ifdef CONFIG_SMP
>>>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>>>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>>>>  #else
>>>> +#define cpu_relax()     \
>>>> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
>>>> +#endif
>>>> +#else
>>>>  #define cpu_relax()	do { } while (0)
>>> I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
>>> be a compiler barrier.
>>
>> We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
>> psuedo randomly)
>>
>> http://marc.info/?l=linux-kernel&m=140350765530113
> 
> Hurm.. you have a better memory than me ;-)
> 
> So in general we assume cpu_relax() implies a barrier() and I think we
> have loops like:
> 
> 	while (!var)
> 		cpu_relax();
> 
> where var isn't volatile (or casted using READ_ONCE etc).
> 
> See for instance: kernel/time/timer.c:lock_timer_base() which has:
> 
> 	for (;;) {
> 		u32 tf = timer->flags;
> 
> 		if (!(tf & TIMER_MIGRATING)) {
> 		 ...
> 		}
> 
> 		cpu_relax();
> 	}
> 
> So while TIMER_MIGRATING is set, it will only ever do regular loads,
> which GCC is permitted to lift out if cpu_relax() is not a barrier.

I'll just bite the bullet and make it a compiler barrier and send Linus way in
4.4. Care to provide an Ack or some such.

-------------------->
>From e29de8efa621b825891dcc744c84965b38f6b868 Mon Sep 17 00:00:00 2001
From: Vineet Gupta <vgupta@synopsys.com>
Date: Mon, 9 Nov 2015 17:48:34 +0530
Subject: [PATCH] ARC: cpu_relax() to be compiler barrier even for UP

cpu_relax() on ARC has been barrier only for SMP (and no-op for UP). Per
recent discussions, it is safer to make it a compiler barrier
unconditionally.

Link: http://lkml.kernel.org/r/53A7D3AA.9020100@synopsys.com
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/include/asm/processor.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 44545354e9e8..1d694c1ef6d6 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,11 +57,7 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
-#ifdef CONFIG_SMP
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
-#else
-#define cpu_relax()	do { } while (0)
-#endif

 #define cpu_relax_lowlatency() cpu_relax()

-- 
1.9.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-09 12:27           ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-09 12:27 UTC (permalink / raw)
  To: linux-snps-arc

On Monday 09 November 2015 04:15 PM, Peter Zijlstra wrote:
> On Mon, Nov 09, 2015@10:22:27AM +0000, Vineet Gupta wrote:
>> On Monday 09 November 2015 03:35 PM, Peter Zijlstra wrote:
>>> On Sat, Nov 07, 2015@12:52:34PM +0200, Noam Camus wrote:
>>>> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
>>>> index 7266ede..50f9bae 100644
>>>> --- a/arch/arc/include/asm/processor.h
>>>> +++ b/arch/arc/include/asm/processor.h
>>>> @@ -58,12 +58,21 @@ struct task_struct;
>>>>   * get optimised away by gcc
>>>>   */
>>>>  #ifdef CONFIG_SMP
>>>> +#ifndef CONFIG_EZNPS_MTM_EXT
>>>>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
>>>>  #else
>>>> +#define cpu_relax()     \
>>>> +	__asm__ __volatile__ (".word %0" : : "i"(CTOP_INST_SCHD_RW) : "memory")
>>>> +#endif
>>>> +#else
>>>>  #define cpu_relax()	do { } while (0)
>>> I'm fairly sure this is incorrect. Even on UP we expect cpu_relax() to
>>> be a compiler barrier.
>>
>> We discussed this a while back (why do https:/lkml.org/lkml/<year>/.... links work
>> psuedo randomly)
>>
>> http://marc.info/?l=linux-kernel&m=140350765530113
> 
> Hurm.. you have a better memory than me ;-)
> 
> So in general we assume cpu_relax() implies a barrier() and I think we
> have loops like:
> 
> 	while (!var)
> 		cpu_relax();
> 
> where var isn't volatile (or casted using READ_ONCE etc).
> 
> See for instance: kernel/time/timer.c:lock_timer_base() which has:
> 
> 	for (;;) {
> 		u32 tf = timer->flags;
> 
> 		if (!(tf & TIMER_MIGRATING)) {
> 		 ...
> 		}
> 
> 		cpu_relax();
> 	}
> 
> So while TIMER_MIGRATING is set, it will only ever do regular loads,
> which GCC is permitted to lift out if cpu_relax() is not a barrier.

I'll just bite the bullet and make it a compiler barrier and send Linus way in
4.4. Care to provide an Ack or some such.

-------------------->
>From e29de8efa621b825891dcc744c84965b38f6b868 Mon Sep 17 00:00:00 2001
From: Vineet Gupta <vgupta@synopsys.com>
Date: Mon, 9 Nov 2015 17:48:34 +0530
Subject: [PATCH] ARC: cpu_relax() to be compiler barrier even for UP

cpu_relax() on ARC has been barrier only for SMP (and no-op for UP). Per
recent discussions, it is safer to make it a compiler barrier
unconditionally.

Link: http://lkml.kernel.org/r/53A7D3AA.9020100 at synopsys.com
Cc: Peter Zijlstra <peterz at infradead.org>
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/include/asm/processor.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 44545354e9e8..1d694c1ef6d6 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -57,11 +57,7 @@ struct task_struct;
  * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
  * get optimised away by gcc
  */
-#ifdef CONFIG_SMP
 #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
-#else
-#define cpu_relax()	do { } while (0)
-#endif

 #define cpu_relax_lowlatency() cpu_relax()

-- 
1.9.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
  2015-11-09 12:27           ` Vineet Gupta
@ 2015-11-09 12:51             ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 12:51 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Mon, Nov 09, 2015 at 05:57:25PM +0530, Vineet Gupta wrote:
> From e29de8efa621b825891dcc744c84965b38f6b868 Mon Sep 17 00:00:00 2001
> From: Vineet Gupta <vgupta@synopsys.com>
> Date: Mon, 9 Nov 2015 17:48:34 +0530
> Subject: [PATCH] ARC: cpu_relax() to be compiler barrier even for UP
> 
> cpu_relax() on ARC has been barrier only for SMP (and no-op for UP). Per
> recent discussions, it is safer to make it a compiler barrier
> unconditionally.
> 
> Link: http://lkml.kernel.org/r/53A7D3AA.9020100@synopsys.com

Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>

> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
> ---
>  arch/arc/include/asm/processor.h | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 44545354e9e8..1d694c1ef6d6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -57,11 +57,7 @@ struct task_struct;
>   * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
>   * get optimised away by gcc
>   */
> -#ifdef CONFIG_SMP
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> -#else
> -#define cpu_relax()	do { } while (0)
> -#endif
> 
>  #define cpu_relax_lowlatency() cpu_relax()
> 
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax()
@ 2015-11-09 12:51             ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-09 12:51 UTC (permalink / raw)
  To: linux-snps-arc

On Mon, Nov 09, 2015@05:57:25PM +0530, Vineet Gupta wrote:
> From e29de8efa621b825891dcc744c84965b38f6b868 Mon Sep 17 00:00:00 2001
> From: Vineet Gupta <vgupta at synopsys.com>
> Date: Mon, 9 Nov 2015 17:48:34 +0530
> Subject: [PATCH] ARC: cpu_relax() to be compiler barrier even for UP
> 
> cpu_relax() on ARC has been barrier only for SMP (and no-op for UP). Per
> recent discussions, it is safer to make it a compiler barrier
> unconditionally.
> 
> Link: http://lkml.kernel.org/r/53A7D3AA.9020100 at synopsys.com

Acked-by: Peter Zijlstra (Intel) <peterz at infradead.org>

> Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
> ---
>  arch/arc/include/asm/processor.h | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
> index 44545354e9e8..1d694c1ef6d6 100644
> --- a/arch/arc/include/asm/processor.h
> +++ b/arch/arc/include/asm/processor.h
> @@ -57,11 +57,7 @@ struct task_struct;
>   * A lot of busy-wait loops in SMP are based off of non-volatile data otherwise
>   * get optimised away by gcc
>   */
> -#ifdef CONFIG_SMP
>  #define cpu_relax()	__asm__ __volatile__ ("" : : : "memory")
> -#else
> -#define cpu_relax()	do { } while (0)
> -#endif
> 
>  #define cpu_relax_lowlatency() cpu_relax()
> 
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-17 11:12     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:12 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, talz, gilf, cmetcalf, Peter Zijlstra

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Tal Zilcer <talz@ezchip.com>
> 
> In SMT system like we have the generic "sync" is not working with
> HW threads. The replacement is "schd.rw" instruction that is served
> as cpu barrier for HW threads.

As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
superfluous. We don't need this patch, you may instead wanna submit a patch which
removes the sync. Also please do that in assembler version of this file as well !

> Signed-off-by: Noam Camus <noamc@ezchip.com>
> ---
>  arch/arc/kernel/ctx_sw.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
> index 92e2e82..2a2f50e 100644
> --- a/arch/arc/kernel/ctx_sw.c
> +++ b/arch/arc/kernel/ctx_sw.c
> @@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  		"st      sp, [r24]       \n\t"
>  #endif
>  
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		".word %5   \n\t"
> +#else
>  		"sync   \n\t"
> +#endif
>  
>  		/*
>  		 * setup _current_task with incoming tsk.
> @@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  #ifdef CONFIG_ARC_PLAT_EZNPS
>  		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
>  #endif
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		, "i"(CTOP_INST_SCHD_RW)
> +#endif
>  		: "blink"
>  	);
>  
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 11:12     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:12 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Tal Zilcer <talz at ezchip.com>
> 
> In SMT system like we have the generic "sync" is not working with
> HW threads. The replacement is "schd.rw" instruction that is served
> as cpu barrier for HW threads.

As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
superfluous. We don't need this patch, you may instead wanna submit a patch which
removes the sync. Also please do that in assembler version of this file as well !

> Signed-off-by: Noam Camus <noamc at ezchip.com>
> ---
>  arch/arc/kernel/ctx_sw.c |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
> index 92e2e82..2a2f50e 100644
> --- a/arch/arc/kernel/ctx_sw.c
> +++ b/arch/arc/kernel/ctx_sw.c
> @@ -61,7 +61,11 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  		"st      sp, [r24]       \n\t"
>  #endif
>  
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		".word %5   \n\t"
> +#else
>  		"sync   \n\t"
> +#endif
>  
>  		/*
>  		 * setup _current_task with incoming tsk.
> @@ -122,6 +126,9 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
>  #ifdef CONFIG_ARC_PLAT_EZNPS
>  		, "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
>  #endif
> +#ifdef CONFIG_EZNPS_MTM_EXT
> +		, "i"(CTOP_INST_SCHD_RW)
> +#endif
>  		: "blink"
>  	);
>  
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-17 11:15     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:15 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> This will better reflect its description i.e. "any needed setup..."
> and not just do an "IPI request".
> 
> Signed-off-by: Noam Camus <noamc@ezchip.com>

Acked-by: Vineet Gupta <vgupta@synopsys.com>

Per our disccussion were you also going to rename the similar op in machine_desc ?

> ---
>  arch/arc/include/asm/smp.h |    4 ++--
>  arch/arc/kernel/irq.c      |    4 ++--
>  arch/arc/kernel/mcip.c     |    2 +-
>  arch/arc/kernel/smp.c      |    4 ++--
>  4 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 133c867..9913804 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
>   * @init_early_smp:	A SMP specific h/w block can init itself
>   * 			Could be common across platforms so not covered by
>   * 			mach_desc->init_early()
> - * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
> + * @init_per_cpu:	Called for each core so SMP h/w block driver can do
>   * 			any needed setup per cpu (e.g. IPI request)
>   * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
>   * @ipi_send:		To send IPI to a @cpu
> @@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
>  struct plat_smp_ops {
>  	const char 	*info;
>  	void		(*init_early_smp)(void);
> -	void		(*init_irq_cpu)(int cpu);
> +	void		(*init_per_cpu)(int cpu);
>  	void		(*cpu_kick)(int cpu, unsigned long pc);
>  	void		(*ipi_send)(int cpu);
>  	void		(*ipi_clear)(int irq);
> diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
> index 2ee2265..a650650 100644
> --- a/arch/arc/kernel/irq.c
> +++ b/arch/arc/kernel/irq.c
> @@ -29,8 +29,8 @@ void __init init_IRQ(void)
>  
>  #ifdef CONFIG_SMP
>  	/* a SMP H/w block could do IPI IRQ request here */
> -	if (plat_smp_ops.init_irq_cpu)
> -		plat_smp_ops.init_irq_cpu(smp_processor_id());
> +	if (plat_smp_ops.init_per_cpu)
> +		plat_smp_ops.init_per_cpu(smp_processor_id());
>  
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(smp_processor_id());
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index 74a9b07..bd237ac 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
>  struct plat_smp_ops plat_smp_ops = {
>  	.info		= smp_cpuinfo_buf,
>  	.init_early_smp	= mcip_probe_n_setup,
> -	.init_irq_cpu	= mcip_setup_per_cpu,
> +	.init_per_cpu	= mcip_setup_per_cpu,
>  	.ipi_send	= mcip_ipi_send,
>  	.ipi_clear	= mcip_ipi_clear,
>  };
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 5805878..0b061a4 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -132,8 +132,8 @@ void start_kernel_secondary(void)
>  	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
>  
>  	/* Some SMP H/w setup - for each cpu */
> -	if (plat_smp_ops.init_irq_cpu)
> -		plat_smp_ops.init_irq_cpu(cpu);
> +	if (plat_smp_ops.init_per_cpu)
> +		plat_smp_ops.init_per_cpu(cpu);
>  
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(cpu);
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
@ 2015-11-17 11:15     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:15 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> This will better reflect its description i.e. "any needed setup..."
> and not just do an "IPI request".
> 
> Signed-off-by: Noam Camus <noamc at ezchip.com>

Acked-by: Vineet Gupta <vgupta at synopsys.com>

Per our disccussion were you also going to rename the similar op in machine_desc ?

> ---
>  arch/arc/include/asm/smp.h |    4 ++--
>  arch/arc/kernel/irq.c      |    4 ++--
>  arch/arc/kernel/mcip.c     |    2 +-
>  arch/arc/kernel/smp.c      |    4 ++--
>  4 files changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h
> index 133c867..9913804 100644
> --- a/arch/arc/include/asm/smp.h
> +++ b/arch/arc/include/asm/smp.h
> @@ -48,7 +48,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
>   * @init_early_smp:	A SMP specific h/w block can init itself
>   * 			Could be common across platforms so not covered by
>   * 			mach_desc->init_early()
> - * @init_irq_cpu:	Called for each core so SMP h/w block driver can do
> + * @init_per_cpu:	Called for each core so SMP h/w block driver can do
>   * 			any needed setup per cpu (e.g. IPI request)
>   * @cpu_kick:		For Master to kickstart a cpu (optionally at a PC)
>   * @ipi_send:		To send IPI to a @cpu
> @@ -57,7 +57,7 @@ extern int smp_ipi_irq_setup(int cpu, int irq);
>  struct plat_smp_ops {
>  	const char 	*info;
>  	void		(*init_early_smp)(void);
> -	void		(*init_irq_cpu)(int cpu);
> +	void		(*init_per_cpu)(int cpu);
>  	void		(*cpu_kick)(int cpu, unsigned long pc);
>  	void		(*ipi_send)(int cpu);
>  	void		(*ipi_clear)(int irq);
> diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c
> index 2ee2265..a650650 100644
> --- a/arch/arc/kernel/irq.c
> +++ b/arch/arc/kernel/irq.c
> @@ -29,8 +29,8 @@ void __init init_IRQ(void)
>  
>  #ifdef CONFIG_SMP
>  	/* a SMP H/w block could do IPI IRQ request here */
> -	if (plat_smp_ops.init_irq_cpu)
> -		plat_smp_ops.init_irq_cpu(smp_processor_id());
> +	if (plat_smp_ops.init_per_cpu)
> +		plat_smp_ops.init_per_cpu(smp_processor_id());
>  
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(smp_processor_id());
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index 74a9b07..bd237ac 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -132,7 +132,7 @@ static void mcip_probe_n_setup(void)
>  struct plat_smp_ops plat_smp_ops = {
>  	.info		= smp_cpuinfo_buf,
>  	.init_early_smp	= mcip_probe_n_setup,
> -	.init_irq_cpu	= mcip_setup_per_cpu,
> +	.init_per_cpu	= mcip_setup_per_cpu,
>  	.ipi_send	= mcip_ipi_send,
>  	.ipi_clear	= mcip_ipi_clear,
>  };
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 5805878..0b061a4 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -132,8 +132,8 @@ void start_kernel_secondary(void)
>  	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
>  
>  	/* Some SMP H/w setup - for each cpu */
> -	if (plat_smp_ops.init_irq_cpu)
> -		plat_smp_ops.init_irq_cpu(cpu);
> +	if (plat_smp_ops.init_per_cpu)
> +		plat_smp_ops.init_per_cpu(cpu);
>  
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(cpu);
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 08/19] ARC: Mark secondary cpu online only after all HW setup is done
  2015-11-07 10:52   ` Noam Camus
@ 2015-11-17 11:17     ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:17 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc; +Cc: linux-kernel, talz, gilf, cmetcalf

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Noam Camus <noamc@ezchip.com>
> 
> In SMP setup, master loops for each_present_cpu calling cpu_up().
> For ARC it returns as soon as new cpu's status becomes online,
> However secondary may still do HW initializing,
> machine or platform hook level.
> 
> So turn secondary online only after all HW setup is done.
> Signed-off-by: Noam Camus <noamc@ezchip.com>

Acked-by: Vineet Gupta <vgupta@synopsys.com>

> ---
>  arch/arc/kernel/smp.c |   10 +++++-----
>  1 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 0b061a4..bc0e4f6 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -126,11 +126,6 @@ void start_kernel_secondary(void)
>  	current->active_mm = mm;
>  	cpumask_set_cpu(cpu, mm_cpumask(mm));
>  
> -	notify_cpu_starting(cpu);
> -	set_cpu_online(cpu, true);
> -
> -	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
> -
>  	/* Some SMP H/w setup - for each cpu */
>  	if (plat_smp_ops.init_per_cpu)
>  		plat_smp_ops.init_per_cpu(cpu);
> @@ -138,6 +133,11 @@ void start_kernel_secondary(void)
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(cpu);
>  
> +	notify_cpu_starting(cpu);
> +	set_cpu_online(cpu, true);
> +
> +	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
> +
>  	arc_local_timer_setup();
>  
>  	local_irq_enable();
> 


^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 08/19] ARC: Mark secondary cpu online only after all HW setup is done
@ 2015-11-17 11:17     ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:17 UTC (permalink / raw)
  To: linux-snps-arc

On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> From: Noam Camus <noamc at ezchip.com>
> 
> In SMP setup, master loops for each_present_cpu calling cpu_up().
> For ARC it returns as soon as new cpu's status becomes online,
> However secondary may still do HW initializing,
> machine or platform hook level.
> 
> So turn secondary online only after all HW setup is done.
> Signed-off-by: Noam Camus <noamc at ezchip.com>

Acked-by: Vineet Gupta <vgupta at synopsys.com>

> ---
>  arch/arc/kernel/smp.c |   10 +++++-----
>  1 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
> index 0b061a4..bc0e4f6 100644
> --- a/arch/arc/kernel/smp.c
> +++ b/arch/arc/kernel/smp.c
> @@ -126,11 +126,6 @@ void start_kernel_secondary(void)
>  	current->active_mm = mm;
>  	cpumask_set_cpu(cpu, mm_cpumask(mm));
>  
> -	notify_cpu_starting(cpu);
> -	set_cpu_online(cpu, true);
> -
> -	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
> -
>  	/* Some SMP H/w setup - for each cpu */
>  	if (plat_smp_ops.init_per_cpu)
>  		plat_smp_ops.init_per_cpu(cpu);
> @@ -138,6 +133,11 @@ void start_kernel_secondary(void)
>  	if (machine_desc->init_cpu_smp)
>  		machine_desc->init_cpu_smp(cpu);
>  
> +	notify_cpu_starting(cpu);
> +	set_cpu_online(cpu, true);
> +
> +	pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);
> +
>  	arc_local_timer_setup();
>  
>  	local_irq_enable();
> 

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 11:12     ` Vineet Gupta
@ 2015-11-17 11:23       ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 11:23 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: Noam Camus, linux-snps-arc, linux-kernel, talz, gilf, cmetcalf

On Tue, Nov 17, 2015 at 04:42:49PM +0530, Vineet Gupta wrote:
> On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> > From: Tal Zilcer <talz@ezchip.com>
> > 
> > In SMT system like we have the generic "sync" is not working with
> > HW threads. The replacement is "schd.rw" instruction that is served
> > as cpu barrier for HW threads.
> 
> As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
> superfluous. We don't need this patch, you may instead wanna submit a patch which
> removes the sync. Also please do that in assembler version of this file as well !

Do test it though; as is ARC-SMP seems to have a _lot_ of superfluous
barriers many of which have no explanation yet (I'm thinking of those
extra smp_mb()s in the lock primitives).

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 11:23       ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 11:23 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 17, 2015@04:42:49PM +0530, Vineet Gupta wrote:
> On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
> > From: Tal Zilcer <talz at ezchip.com>
> > 
> > In SMT system like we have the generic "sync" is not working with
> > HW threads. The replacement is "schd.rw" instruction that is served
> > as cpu barrier for HW threads.
> 
> As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
> superfluous. We don't need this patch, you may instead wanna submit a patch which
> removes the sync. Also please do that in assembler version of this file as well !

Do test it though; as is ARC-SMP seems to have a _lot_ of superfluous
barriers many of which have no explanation yet (I'm thinking of those
extra smp_mb()s in the lock primitives).

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 11:23       ` Peter Zijlstra
@ 2015-11-17 11:37         ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:37 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tuesday 17 November 2015 04:53 PM, Peter Zijlstra wrote:
> On Tue, Nov 17, 2015 at 04:42:49PM +0530, Vineet Gupta wrote:
>> On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
>>> From: Tal Zilcer <talz@ezchip.com>
>>>
>>> In SMT system like we have the generic "sync" is not working with
>>> HW threads. The replacement is "schd.rw" instruction that is served
>>> as cpu barrier for HW threads.
>>
>> As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
>> superfluous. We don't need this patch, you may instead wanna submit a patch which
>> removes the sync. Also please do that in assembler version of this file as well !
> 
> Do test it though; 

Certainly !

> as is ARC-SMP seems to have a _lot_ of superfluous
> barriers many of which have no explanation yet (I'm thinking of those
> extra smp_mb()s in the lock primitives).

Other than the lock primitives can u think of any more.

I verified that with llock/scond based spinlocks, those smp_mb() can be safely
removed. I didn't send that patch over yet as part of puzzle is why removing them
in EX based locks causes hackbench to jitter on quad core builds. This required
some perf investigation but that seems to be causing some sort of livelock with
callgraph profiling which is what I'm debugging currently :-)

BTW since we are on the topic we have this loop in stack unwinder which can
potentially cause RCU stalls, actual lockups etc. I was planning to add the
following - does that seem fine to you.

------------------>

diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index 573ac469f68b..e887f6df7ac9 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -138,6 +138,10 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
 		if (consumer_fn(address, arg) == -1)
 			break;

+		cond_resched();
+		if (fatal_signal_pending(current))
+			return -ERESTARTNOHAND;
+
 		ret = arc_unwind(&frame_info);
 		if (ret)
 			break;


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 11:37         ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:37 UTC (permalink / raw)
  To: linux-snps-arc

On Tuesday 17 November 2015 04:53 PM, Peter Zijlstra wrote:
> On Tue, Nov 17, 2015@04:42:49PM +0530, Vineet Gupta wrote:
>> On Saturday 07 November 2015 04:22 PM, Noam Camus wrote:
>>> From: Tal Zilcer <talz at ezchip.com>
>>>
>>> In SMT system like we have the generic "sync" is not working with
>>> HW threads. The replacement is "schd.rw" instruction that is served
>>> as cpu barrier for HW threads.
>>
>> As discussed in v2 of this patch, SYNC or some such in __switch_to is completely
>> superfluous. We don't need this patch, you may instead wanna submit a patch which
>> removes the sync. Also please do that in assembler version of this file as well !
> 
> Do test it though; 

Certainly !

> as is ARC-SMP seems to have a _lot_ of superfluous
> barriers many of which have no explanation yet (I'm thinking of those
> extra smp_mb()s in the lock primitives).

Other than the lock primitives can u think of any more.

I verified that with llock/scond based spinlocks, those smp_mb() can be safely
removed. I didn't send that patch over yet as part of puzzle is why removing them
in EX based locks causes hackbench to jitter on quad core builds. This required
some perf investigation but that seems to be causing some sort of livelock with
callgraph profiling which is what I'm debugging currently :-)

BTW since we are on the topic we have this loop in stack unwinder which can
potentially cause RCU stalls, actual lockups etc. I was planning to add the
following - does that seem fine to you.

------------------>

diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index 573ac469f68b..e887f6df7ac9 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -138,6 +138,10 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
 		if (consumer_fn(address, arg) == -1)
 			break;

+		cond_resched();
+		if (fatal_signal_pending(current))
+			return -ERESTARTNOHAND;
+
 		ret = arc_unwind(&frame_info);
 		if (ret)
 			break;

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* RE: [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  2015-11-17 11:15     ` Vineet Gupta
@ 2015-11-17 11:38       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-17 11:38 UTC (permalink / raw)
  To: Vineet Gupta, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Tuesday, November 17, 2015 1:16 PM
>
>
>Acked-by: Vineet Gupta <vgupta@synopsys.com>
>
>Per our disccussion were you also going to rename the similar op in machine_desc ?

No, Just rename the plat_smp_ops.
About machine_desc, I believe that now init_cpu_smp is not needed.
I will remove it if you wish to.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
@ 2015-11-17 11:38       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-17 11:38 UTC (permalink / raw)
  To: linux-snps-arc

From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
Sent: Tuesday, November 17, 2015 1:16 PM
>
>
>Acked-by: Vineet Gupta <vgupta at synopsys.com>
>
>Per our disccussion were you also going to rename the similar op in machine_desc ?

No, Just rename the plat_smp_ops.
About machine_desc, I believe that now init_cpu_smp is not needed.
I will remove it if you wish to.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
  2015-11-17 11:38       ` Noam Camus
@ 2015-11-17 11:42         ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:42 UTC (permalink / raw)
  To: Noam Camus, linux-snps-arc
  Cc: linux-kernel, Tal Zilcer, Gil Fruchter, Chris Metcalf

On Tuesday 17 November 2015 05:08 PM, Noam Camus wrote:
> From: Vineet Gupta [mailto:Vineet.Gupta1@synopsys.com] 
> Sent: Tuesday, November 17, 2015 1:16 PM
>> >
>> >
>> >Acked-by: Vineet Gupta <vgupta@synopsys.com>
>> >
>> >Per our disccussion were you also going to rename the similar op in machine_desc ?
> No, Just rename the plat_smp_ops.
> About machine_desc, I believe that now init_cpu_smp is not needed.
> I will remove it if you wish to.
> 
> -Noam

No let us keep it - I think axs platform will need it soon !

-Vineet

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu()
@ 2015-11-17 11:42         ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 11:42 UTC (permalink / raw)
  To: linux-snps-arc

On Tuesday 17 November 2015 05:08 PM, Noam Camus wrote:
> From: Vineet Gupta [mailto:Vineet.Gupta1 at synopsys.com] 
> Sent: Tuesday, November 17, 2015 1:16 PM
>> >
>> >
>> >Acked-by: Vineet Gupta <vgupta at synopsys.com>
>> >
>> >Per our disccussion were you also going to rename the similar op in machine_desc ?
> No, Just rename the plat_smp_ops.
> About machine_desc, I believe that now init_cpu_smp is not needed.
> I will remove it if you wish to.
> 
> -Noam

No let us keep it - I think axs platform will need it soon !

-Vineet

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 11:37         ` Vineet Gupta
@ 2015-11-17 12:22           ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 12:22 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tue, Nov 17, 2015 at 05:07:38PM +0530, Vineet Gupta wrote:
> > as is ARC-SMP seems to have a _lot_ of superfluous
> > barriers many of which have no explanation yet (I'm thinking of those
> > extra smp_mb()s in the lock primitives).
> 
> Other than the lock primitives can u think of any more.

Not of the top of my head.

> I verified that with llock/scond based spinlocks, those smp_mb() can be safely
> removed.

Good!

> I didn't send that patch over yet as part of puzzle is why removing them
> in EX based locks causes hackbench to jitter on quad core builds. This required
> some perf investigation but that seems to be causing some sort of livelock with
> callgraph profiling which is what I'm debugging currently :-)

So there's two superfluous barriers right; the one before LOCK and the
one after UNLOCK. Does removing either cause the jitter? I'm thinking
that maybe its the smp_mb after UNLOCK that force flushes the store
buffer that helps (MIPS has something similar).

> BTW since we are on the topic we have this loop in stack unwinder which can
> potentially cause RCU stalls, actual lockups etc. I was planning to add the
> following - does that seem fine to you.

Worries me more than anything. How could you get stuck in there?

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 12:22           ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 12:22 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 17, 2015@05:07:38PM +0530, Vineet Gupta wrote:
> > as is ARC-SMP seems to have a _lot_ of superfluous
> > barriers many of which have no explanation yet (I'm thinking of those
> > extra smp_mb()s in the lock primitives).
> 
> Other than the lock primitives can u think of any more.

Not of the top of my head.

> I verified that with llock/scond based spinlocks, those smp_mb() can be safely
> removed.

Good!

> I didn't send that patch over yet as part of puzzle is why removing them
> in EX based locks causes hackbench to jitter on quad core builds. This required
> some perf investigation but that seems to be causing some sort of livelock with
> callgraph profiling which is what I'm debugging currently :-)

So there's two superfluous barriers right; the one before LOCK and the
one after UNLOCK. Does removing either cause the jitter? I'm thinking
that maybe its the smp_mb after UNLOCK that force flushes the store
buffer that helps (MIPS has something similar).

> BTW since we are on the topic we have this loop in stack unwinder which can
> potentially cause RCU stalls, actual lockups etc. I was planning to add the
> following - does that seem fine to you.

Worries me more than anything. How could you get stuck in there?

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 12:22           ` Peter Zijlstra
@ 2015-11-17 12:37             ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 12:37 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
>> > BTW since we are on the topic we have this loop in stack unwinder which can
>> > potentially cause RCU stalls, actual lockups etc. I was planning to add the
>> > following - does that seem fine to you.
> Worries me more than anything. How could you get stuck in there?

No we not getting stuck in there - but this has potential to - if say unwind info
were corrupt (not seen that ever though).

The old code won't even respond to say a Ctrl+C if it were stuck !
Plus the reschedule there will keeps sched happy when say unraveling deep stack
frames with perf ?



^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 12:37             ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 12:37 UTC (permalink / raw)
  To: linux-snps-arc

On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
>> > BTW since we are on the topic we have this loop in stack unwinder which can
>> > potentially cause RCU stalls, actual lockups etc. I was planning to add the
>> > following - does that seem fine to you.
> Worries me more than anything. How could you get stuck in there?

No we not getting stuck in there - but this has potential to - if say unwind info
were corrupt (not seen that ever though).

The old code won't even respond to say a Ctrl+C if it were stuck !
Plus the reschedule there will keeps sched happy when say unraveling deep stack
frames with perf ?

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 12:37             ` Vineet Gupta
@ 2015-11-17 12:44               ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 12:44 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tue, Nov 17, 2015 at 06:07:08PM +0530, Vineet Gupta wrote:
> On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
> >> > BTW since we are on the topic we have this loop in stack unwinder which can
> >> > potentially cause RCU stalls, actual lockups etc. I was planning to add the
> >> > following - does that seem fine to you.
> > Worries me more than anything. How could you get stuck in there?
> 
> No we not getting stuck in there - but this has potential to - if say unwind info
> were corrupt (not seen that ever though).

Better put in a failsafe for that anyway, just out of sheer paranoia :-)

You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
so once you've done that many loops, you're good to bail, right?

> The old code won't even respond to say a Ctrl+C if it were stuck !
> Plus the reschedule there will keeps sched happy when say unraveling deep stack
> frames with perf ?

You're likely to call this code from interrupt/NMI context, there is no
^C or scheduling going to help you there.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 12:44               ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 12:44 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 17, 2015@06:07:08PM +0530, Vineet Gupta wrote:
> On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
> >> > BTW since we are on the topic we have this loop in stack unwinder which can
> >> > potentially cause RCU stalls, actual lockups etc. I was planning to add the
> >> > following - does that seem fine to you.
> > Worries me more than anything. How could you get stuck in there?
> 
> No we not getting stuck in there - but this has potential to - if say unwind info
> were corrupt (not seen that ever though).

Better put in a failsafe for that anyway, just out of sheer paranoia :-)

You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
so once you've done that many loops, you're good to bail, right?

> The old code won't even respond to say a Ctrl+C if it were stuck !
> Plus the reschedule there will keeps sched happy when say unraveling deep stack
> frames with perf ?

You're likely to call this code from interrupt/NMI context, there is no
^C or scheduling going to help you there.

^ permalink raw reply	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 12:44               ` Peter Zijlstra
@ 2015-11-17 13:32                 ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 13:32 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tuesday 17 November 2015 06:14 PM, Peter Zijlstra wrote:
> On Tue, Nov 17, 2015 at 06:07:08PM +0530, Vineet Gupta wrote:
>> On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
>>>>> BTW since we are on the topic we have this loop in stack unwinder which can
>>>>> potentially cause RCU stalls, actual lockups etc. I was planning to add the
>>>>> following - does that seem fine to you.
>>> Worries me more than anything. How could you get stuck in there?
>>
>> No we not getting stuck in there - but this has potential to - if say unwind info
>> were corrupt (not seen that ever though).
> 
> Better put in a failsafe for that anyway, just out of sheer paranoia :-)

Indeed, loop for say 32 times at max or some such.


> You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
> so once you've done that many loops, you're good to bail, right?

Yeah, although I need to ensure if arch code needs to check that. Plus the
unwinder is also used for things like ps wchan, /proc/<pid>/stack, crash dump etc.

>> The old code won't even respond to say a Ctrl+C if it were stuck !
>> Plus the reschedule there will keeps sched happy when say unraveling deep stack
>> frames with perf ?
> 
> You're likely to call this code from interrupt/NMI context, there is no
> ^C or scheduling going to help you there.

For perf case, but there are other uses of unwinder as described above.

So in light of above, do u think that the cond_resched() + signal_pending check is
not needed and the bail if over N iters will be fine !

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 13:32                 ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 13:32 UTC (permalink / raw)
  To: linux-snps-arc

On Tuesday 17 November 2015 06:14 PM, Peter Zijlstra wrote:
> On Tue, Nov 17, 2015@06:07:08PM +0530, Vineet Gupta wrote:
>> On Tuesday 17 November 2015 05:52 PM, Peter Zijlstra wrote:
>>>>> BTW since we are on the topic we have this loop in stack unwinder which can
>>>>> potentially cause RCU stalls, actual lockups etc. I was planning to add the
>>>>> following - does that seem fine to you.
>>> Worries me more than anything. How could you get stuck in there?
>>
>> No we not getting stuck in there - but this has potential to - if say unwind info
>> were corrupt (not seen that ever though).
> 
> Better put in a failsafe for that anyway, just out of sheer paranoia :-)

Indeed, loop for say 32 times at max or some such.


> You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
> so once you've done that many loops, you're good to bail, right?

Yeah, although I need to ensure if arch code needs to check that. Plus the
unwinder is also used for things like ps wchan, /proc/<pid>/stack, crash dump etc.

>> The old code won't even respond to say a Ctrl+C if it were stuck !
>> Plus the reschedule there will keeps sched happy when say unraveling deep stack
>> frames with perf ?
> 
> You're likely to call this code from interrupt/NMI context, there is no
> ^C or scheduling going to help you there.

For perf case, but there are other uses of unwinder as described above.

So in light of above, do u think that the cond_resched() + signal_pending check is
not needed and the bail if over N iters will be fine !

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH] ARC: remove SYNC from __switch_to()
  2015-11-02  9:26       ` Peter Zijlstra
@ 2015-11-17 13:48         ` Vineet Gupta
  -1 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 13:48 UTC (permalink / raw)
  To: linux-snps-arc; +Cc: Vineet Gupta, Peter Zijlstra, linux-kernel, Noam Camus

SYNC in __switch_to() is a historic relic and not needed at all.

 - In UP context it is obviously useless, why would we want to stall
   the core for all updates to stack memory of t0 to complete before
   loading kernel mode callee registers from t1 stack's memory.

 - In SMP, there could be potential race in which outgoing task could
   be concurrently picked for running on a different core, thus writes
   to stack here need to be visible before the reads from stack on
   other core. Peter confirmed that generic schedular already has needed
   barriers (by way of rq lock) so there is no need for additional arch
   barrier.

This came up when Noam was tryign to replace this SYNC with EZChip
specific hardware thread scheduling instruction for their platform support.

Link: http://lkml.kernel.org/r/20151102092654.GM17308@twins.programming.kicks-ass.net
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org
Cc: Noam Camus <noamc@ezchip.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
---
 arch/arc/kernel/ctx_sw.c     | 2 --
 arch/arc/kernel/ctx_sw_asm.S | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5bea0c76..5d446df2c413 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -58,8 +58,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
-		"sync   \n\t"
-
 		/*
 		 * setup _current_task with incoming tsk.
 		 * optionally, set r25 to that as well
diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S
index e248594097e7..e6890b1f8650 100644
--- a/arch/arc/kernel/ctx_sw_asm.S
+++ b/arch/arc/kernel/ctx_sw_asm.S
@@ -44,9 +44,6 @@ __switch_to:
 	* don't need to do anything special to return it
 	*/
 
-	/* hardware memory barrier */
-	sync
-
 	/*
 	 * switch to new task, contained in r1
 	 * Temp reg r3 is required to get the ptr to store val
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 190+ messages in thread

* [PATCH] ARC: remove SYNC from __switch_to()
@ 2015-11-17 13:48         ` Vineet Gupta
  0 siblings, 0 replies; 190+ messages in thread
From: Vineet Gupta @ 2015-11-17 13:48 UTC (permalink / raw)
  To: linux-snps-arc

SYNC in __switch_to() is a historic relic and not needed at all.

 - In UP context it is obviously useless, why would we want to stall
   the core for all updates to stack memory of t0 to complete before
   loading kernel mode callee registers from t1 stack's memory.

 - In SMP, there could be potential race in which outgoing task could
   be concurrently picked for running on a different core, thus writes
   to stack here need to be visible before the reads from stack on
   other core. Peter confirmed that generic schedular already has needed
   barriers (by way of rq lock) so there is no need for additional arch
   barrier.

This came up when Noam was tryign to replace this SYNC with EZChip
specific hardware thread scheduling instruction for their platform support.

Link: http://lkml.kernel.org/r/20151102092654.GM17308 at twins.programming.kicks-ass.net
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: linux-kernel at vger.kernel.org
Cc: Noam Camus <noamc at ezchip.com>
Signed-off-by: Vineet Gupta <vgupta at synopsys.com>
---
 arch/arc/kernel/ctx_sw.c     | 2 --
 arch/arc/kernel/ctx_sw_asm.S | 3 ---
 2 files changed, 5 deletions(-)

diff --git a/arch/arc/kernel/ctx_sw.c b/arch/arc/kernel/ctx_sw.c
index c14a5bea0c76..5d446df2c413 100644
--- a/arch/arc/kernel/ctx_sw.c
+++ b/arch/arc/kernel/ctx_sw.c
@@ -58,8 +58,6 @@ __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
 		"st      sp, [r24]       \n\t"
 #endif
 
-		"sync   \n\t"
-
 		/*
 		 * setup _current_task with incoming tsk.
 		 * optionally, set r25 to that as well
diff --git a/arch/arc/kernel/ctx_sw_asm.S b/arch/arc/kernel/ctx_sw_asm.S
index e248594097e7..e6890b1f8650 100644
--- a/arch/arc/kernel/ctx_sw_asm.S
+++ b/arch/arc/kernel/ctx_sw_asm.S
@@ -44,9 +44,6 @@ __switch_to:
 	* don't need to do anything special to return it
 	*/
 
-	/* hardware memory barrier */
-	sync
-
 	/*
 	 * switch to new task, contained in r1
 	 * Temp reg r3 is required to get the ptr to store val
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 190+ messages in thread

* Re: [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
  2015-11-17 13:32                 ` Vineet Gupta
@ 2015-11-17 13:59                   ` Peter Zijlstra
  -1 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 13:59 UTC (permalink / raw)
  To: Vineet Gupta
  Cc: gilf, talz, linux-kernel, cmetcalf, Noam Camus, linux-snps-arc

On Tue, Nov 17, 2015 at 07:02:00PM +0530, Vineet Gupta wrote:
> > You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
> > so once you've done that many loops, you're good to bail, right?
> 
> Yeah, although I need to ensure if arch code needs to check that. Plus the
> unwinder is also used for things like ps wchan, /proc/<pid>/stack, crash dump etc.

Ah, ok. On x86 we have a separate unwinder for perf. Trying to touch
userspace memory from NMI context is a tad tricky.

(imagine the NMI interrupting a page-fault and then itself triggering a
page-fault again)

> > You're likely to call this code from interrupt/NMI context, there is no
> > ^C or scheduling going to help you there.
> 
> For perf case, but there are other uses of unwinder as described above.
> 
> So in light of above, do u think that the cond_resched() + signal_pending check is
> not needed and the bail if over N iters will be fine !

It can't hurt, but you want to engineer it to be robust for the most
constrained environment, so I would say the bail over N iters had
better be robust, otherwise you're screwed anyhow ;-)

^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier
@ 2015-11-17 13:59                   ` Peter Zijlstra
  0 siblings, 0 replies; 190+ messages in thread
From: Peter Zijlstra @ 2015-11-17 13:59 UTC (permalink / raw)
  To: linux-snps-arc

On Tue, Nov 17, 2015@07:02:00PM +0530, Vineet Gupta wrote:
> > You should never report more than PERF_MAX_STACK_DEPTH thingies anyway,
> > so once you've done that many loops, you're good to bail, right?
> 
> Yeah, although I need to ensure if arch code needs to check that. Plus the
> unwinder is also used for things like ps wchan, /proc/<pid>/stack, crash dump etc.

Ah, ok. On x86 we have a separate unwinder for perf. Trying to touch
userspace memory from NMI context is a tad tricky.

(imagine the NMI interrupting a page-fault and then itself triggering a
page-fault again)

> > You're likely to call this code from interrupt/NMI context, there is no
> > ^C or scheduling going to help you there.
> 
> For perf case, but there are other uses of unwinder as described above.
> 
> So in light of above, do u think that the cond_resched() + signal_pending check is
> not needed and the bail if over N iters will be fine !

It can't hurt, but you want to engineer it to be robust for the most
constrained environment, so I would say the bail over N iters had
better be robust, otherwise you're screwed anyhow ;-)

^ permalink raw reply	[flat|nested] 190+ messages in thread

* RE: [PATCH v2 03/19] clocksource: Add NPS400 timers driver
  2015-11-07 11:26     ` Thomas Gleixner
@ 2015-11-20 11:59       ` Noam Camus
  -1 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-20 11:59 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-snps-arc, linux-kernel, Tal Zilcer, Gil Fruchter,
	Chris Metcalf, Daniel Lezcano, Rob Herring, John Stultz

>From: Thomas Gleixner [mailto:tglx@linutronix.de] 
>Sent: Saturday, November 07, 2015 1:26 PM


>So that clocksource goes up to 1GHz. That means u32 fits ~4.29 seconds. Unless you are striving for NOHZ idle sleep times above that there is no point in doing that 64bit dance.
>
>The timekeeping code is perfectly fine with a 32bit value. You just have to set the proper mask.

We do it because we do indeed care very much for long NOHZ idle (and full) times on NPS, hence the song and dance.

-Noam



^ permalink raw reply	[flat|nested] 190+ messages in thread

* [PATCH v2 03/19] clocksource: Add NPS400 timers driver
@ 2015-11-20 11:59       ` Noam Camus
  0 siblings, 0 replies; 190+ messages in thread
From: Noam Camus @ 2015-11-20 11:59 UTC (permalink / raw)
  To: linux-snps-arc

>From: Thomas Gleixner [mailto:tglx at linutronix.de] 
>Sent: Saturday, November 07, 2015 1:26 PM


>So that clocksource goes up to 1GHz. That means u32 fits ~4.29 seconds. Unless you are striving for NOHZ idle sleep times above that there is no point in doing that 64bit dance.
>
>The timekeeping code is perfectly fine with a 32bit value. You just have to set the proper mask.

We do it because we do indeed care very much for long NOHZ idle (and full) times on NPS, hence the song and dance.

-Noam

^ permalink raw reply	[flat|nested] 190+ messages in thread

end of thread, other threads:[~2015-11-20 11:59 UTC | newest]

Thread overview: 190+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-31 13:15 [PATCH v1 00/20] eznps a new ARC platform Noam Camus
2015-10-31 13:15 ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 01/20] Documentation: Add EZchip vendor to binding list Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 02/20] clocksource: Add NPS400 timers driver Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-01 20:44   ` Daniel Lezcano
2015-11-01 20:44     ` Daniel Lezcano
2015-11-02  7:57     ` Noam Camus
2015-11-02  7:57       ` Noam Camus
2015-11-02 11:03   ` Vineet Gupta
2015-11-02 11:03     ` Vineet Gupta
2015-11-03 15:18     ` Noam Camus
2015-11-03 15:18       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 03/20] irqchip: add nps Internal and external irqchips Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 04/20] ARC: Set vmalloc size from configuration Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 05/20] ARC: rwlock: disable interrupts in !LLSC variant Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  9:16   ` Peter Zijlstra
2015-11-02  9:16     ` Peter Zijlstra
2015-11-02  9:42   ` Vineet Gupta
2015-11-02  9:42     ` Vineet Gupta
2015-11-02 10:03     ` Peter Zijlstra
2015-11-02 10:03       ` Peter Zijlstra
2015-10-31 13:15 ` [PATCH v1 06/20] ARC: Mark cpu online only after it has executed the per cpu init hook Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 07/20] ARC: mm: use generic macros _BITUL() Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  6:23   ` Vineet Gupta
2015-11-02  6:23     ` Vineet Gupta
2015-11-02  6:27     ` Noam Camus
2015-11-02  6:27       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 08/20] ARC: Use res_service as entry point for secondaries Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  6:38   ` Vineet Gupta
2015-11-02  6:38     ` Vineet Gupta
2015-11-02  8:05     ` Noam Camus
2015-11-02  8:05       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 09/20] ARC: add CONFIG_CLKSRC_OF support to time_init() Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  6:32   ` Vineet Gupta
2015-11-02  6:32     ` Vineet Gupta
2015-10-31 13:15 ` [PATCH v1 10/20] ARC: [plat-eznps] Add eznps board defconfig and dts Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 11/20] ARC: [plat-eznps] Add eznps platform Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02 10:56   ` Vineet Gupta
2015-11-02 10:56     ` Vineet Gupta
2015-11-03 15:59     ` Noam Camus
2015-11-03 15:59       ` Noam Camus
2015-11-04 12:38     ` Noam Camus
2015-11-04 12:38       ` Noam Camus
2015-11-05  5:09   ` Vineet Gupta
2015-11-05  5:09     ` Vineet Gupta
2015-10-31 13:15 ` [PATCH v1 12/20] ARC: [plat-eznps] Use dedicated user stack top Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 13/20] ARC: [plat-eznps] Use dedicated bitops/atomic/cmpxchg Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02 11:56   ` Vineet Gupta
2015-11-02 11:56     ` Vineet Gupta
2015-10-31 13:15 ` [PATCH v1 14/20] ARC: [plat-eznps] Use dedicated SMP barriers Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  8:02   ` Vineet Gupta
2015-11-02  8:02     ` Vineet Gupta
2015-11-02 13:08     ` Noam Camus
2015-11-02 13:08       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 15/20] ARC: [plat-eznps] Use dedicated identity auxiliary register Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 16/20] ARC: [plat-eznps] Use dedicated cpu_relax() Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  7:54   ` Vineet Gupta
2015-11-02  7:54     ` Vineet Gupta
2015-11-02  9:21   ` Peter Zijlstra
2015-11-02  9:21     ` Peter Zijlstra
2015-11-03 14:02     ` Noam Camus
2015-11-03 14:02       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 17/20] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 18/20] ARC: [plat-eznps] define IPI_IRQ Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  7:52   ` Vineet Gupta
2015-11-02  7:52     ` Vineet Gupta
2015-11-02 12:16     ` Noam Camus
2015-11-02 12:16       ` Noam Camus
2015-10-31 13:15 ` [PATCH v1 19/20] ARC: [plat-eznps] replace sync with proper cpu barrier Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02  7:48   ` Vineet Gupta
2015-11-02  7:48     ` Vineet Gupta
2015-11-02  9:26     ` Peter Zijlstra
2015-11-02  9:26       ` Peter Zijlstra
2015-11-17 13:48       ` [PATCH] ARC: remove SYNC from __switch_to() Vineet Gupta
2015-11-17 13:48         ` Vineet Gupta
2015-10-31 13:15 ` [PATCH v1 20/20] ARC: Add eznps platform to Kconfig and Makefile Noam Camus
2015-10-31 13:15   ` Noam Camus
2015-11-02 11:06   ` Vineet Gupta
2015-11-02 11:06     ` Vineet Gupta
2015-11-03 15:32     ` Noam Camus
2015-11-03 15:32       ` Noam Camus
2015-11-04 15:35 ` [PATCH v1 00/20] eznps a new ARC platform Vineet Gupta
2015-11-04 15:35   ` Vineet Gupta
2015-11-04 15:53   ` Noam Camus
2015-11-04 15:53     ` Noam Camus
2015-11-04 17:42     ` Vineet Gupta
2015-11-04 17:42       ` Vineet Gupta
2015-11-07 10:52 ` [PATCH v2 00/19] " Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 01/19] Documentation: Add EZchip vendor to binding list Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 02/19] ARC: [plat-eznps] define IPI_IRQ Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 03/19] clocksource: Add NPS400 timers driver Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 11:26   ` Thomas Gleixner
2015-11-07 11:26     ` Thomas Gleixner
2015-11-20 11:59     ` Noam Camus
2015-11-20 11:59       ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 04/19] irqchip: add nps Internal and external irqchips Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 11:38   ` Thomas Gleixner
2015-11-07 11:38     ` Thomas Gleixner
2015-11-07 20:52     ` Noam Camus
2015-11-07 20:52       ` Noam Camus
2015-11-07 23:52       ` Thomas Gleixner
2015-11-07 23:52         ` Thomas Gleixner
2015-11-07 10:52 ` [PATCH v2 05/19] ARC: Set vmalloc size from configuration Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 06/19] ARC: rwlock: disable interrupts in !LLSC variant Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 07/19] ARC: rename smp operation init_irq_cpu() to init_per_cpu() Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-17 11:15   ` Vineet Gupta
2015-11-17 11:15     ` Vineet Gupta
2015-11-17 11:38     ` Noam Camus
2015-11-17 11:38       ` Noam Camus
2015-11-17 11:42       ` Vineet Gupta
2015-11-17 11:42         ` Vineet Gupta
2015-11-07 10:52 ` [PATCH v2 08/19] ARC: Mark secondary cpu online only after all HW setup is done Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-17 11:17   ` Vineet Gupta
2015-11-17 11:17     ` Vineet Gupta
2015-11-07 10:52 ` [PATCH v2 09/19] ARC: add CONFIG_CLKSRC_OF support to time_init() Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 10/19] ARC: [plat-eznps] Add eznps board defconfig and dts Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 11/19] ARC: [plat-eznps] Add eznps platform Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 12/19] ARC: [plat-eznps] Use dedicated user stack top Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 13/19] ARC: [plat-eznps] Use dedicated atomic/bitops/cmpxchg Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 14/19] ARC: [plat-eznps] Use dedicated SMP barriers Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 15/19] ARC: [plat-eznps] Use dedicated identity auxiliary register Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 16/19] ARC: [plat-eznps] Use dedicated cpu_relax() Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-09 10:05   ` Peter Zijlstra
2015-11-09 10:05     ` Peter Zijlstra
2015-11-09 10:22     ` Vineet Gupta
2015-11-09 10:22       ` Vineet Gupta
2015-11-09 10:45       ` Peter Zijlstra
2015-11-09 10:45         ` Peter Zijlstra
2015-11-09 12:27         ` Vineet Gupta
2015-11-09 12:27           ` Vineet Gupta
2015-11-09 12:51           ` Peter Zijlstra
2015-11-09 12:51             ` Peter Zijlstra
2015-11-07 10:52 ` [PATCH v2 17/19] ARC: [plat-eznps] Use dedicated COMMAND_LINE_SIZE Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-07 10:52 ` [PATCH v2 18/19] ARC: [plat-eznps] replace sync with proper cpu barrier Noam Camus
2015-11-07 10:52   ` Noam Camus
2015-11-17 11:12   ` Vineet Gupta
2015-11-17 11:12     ` Vineet Gupta
2015-11-17 11:23     ` Peter Zijlstra
2015-11-17 11:23       ` Peter Zijlstra
2015-11-17 11:37       ` Vineet Gupta
2015-11-17 11:37         ` Vineet Gupta
2015-11-17 12:22         ` Peter Zijlstra
2015-11-17 12:22           ` Peter Zijlstra
2015-11-17 12:37           ` Vineet Gupta
2015-11-17 12:37             ` Vineet Gupta
2015-11-17 12:44             ` Peter Zijlstra
2015-11-17 12:44               ` Peter Zijlstra
2015-11-17 13:32               ` Vineet Gupta
2015-11-17 13:32                 ` Vineet Gupta
2015-11-17 13:59                 ` Peter Zijlstra
2015-11-17 13:59                   ` Peter Zijlstra
2015-11-07 10:52 ` [PATCH v2 19/19] ARC: Add eznps platform to Kconfig and Makefile Noam Camus
2015-11-07 10:52   ` Noam Camus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.