From: Andre Przywara <andre.przywara@arm.com>
To: Julien Grall <julien.grall@arm.com>,
Stefano Stabellini <sstabellini@kernel.org>
Cc: xen-devel@lists.xenproject.org
Subject: [RFC PATCH 05/24] ARM: GICv3 ITS: introduce ITS command handling
Date: Wed, 28 Sep 2016 19:24:38 +0100 [thread overview]
Message-ID: <20160928182457.12433-6-andre.przywara@arm.com> (raw)
In-Reply-To: <20160928182457.12433-1-andre.przywara@arm.com>
To be able to easily send commands to the ITS, create the respective
wrapper functions, which take care of the ring buffer.
The first two commands we implement provide methods to map a collection
to a redistributor (aka host core) and to flush the command queue (SYNC).
Start using these commands for mapping one collection to each host CPU.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
xen/arch/arm/gic-its.c | 101 ++++++++++++++++++++++++++++++++++++++++++
xen/arch/arm/gic-v3.c | 17 +++++++
xen/include/asm-arm/gic-its.h | 32 +++++++++++++
3 files changed, 150 insertions(+)
diff --git a/xen/arch/arm/gic-its.c b/xen/arch/arm/gic-its.c
index c8a7a7e..88397bc 100644
--- a/xen/arch/arm/gic-its.c
+++ b/xen/arch/arm/gic-its.c
@@ -33,6 +33,10 @@ static struct {
int host_lpi_bits;
} lpi_data;
+/* Physical redistributor address */
+static DEFINE_PER_CPU(uint64_t, rdist_addr);
+/* Redistributor ID */
+static DEFINE_PER_CPU(uint64_t, rdist_id);
/* Pending table for each redistributor */
static DEFINE_PER_CPU(void *, pending_table);
@@ -40,6 +44,86 @@ static DEFINE_PER_CPU(void *, pending_table);
min_t(unsigned int, lpi_data.host_lpi_bits, CONFIG_HOST_LPI_BITS)
#define MAX_HOST_LPIS (BIT(MAX_HOST_LPI_BITS) - 8192)
+#define ITS_COMMAND_SIZE 32
+
+static int its_send_command(struct host_its *hw_its, void *its_cmd)
+{
+ int readp, writep;
+
+ spin_lock(&hw_its->cmd_lock);
+
+ readp = readl_relaxed(hw_its->its_base + GITS_CREADR) & GENMASK(19, 5);
+ writep = readl_relaxed(hw_its->its_base + GITS_CWRITER) & GENMASK(19, 5);
+
+ if ( ((writep + ITS_COMMAND_SIZE) % PAGE_SIZE) == readp )
+ {
+ spin_unlock(&hw_its->cmd_lock);
+ return -EBUSY;
+ }
+
+ memcpy(hw_its->cmd_buf + writep, its_cmd, ITS_COMMAND_SIZE);
+ __flush_dcache_area(hw_its->cmd_buf + writep, ITS_COMMAND_SIZE);
+ writep = (writep + ITS_COMMAND_SIZE) % PAGE_SIZE;
+
+ writeq_relaxed(writep & GENMASK(19, 5), hw_its->its_base + GITS_CWRITER);
+
+ spin_unlock(&hw_its->cmd_lock);
+
+ return 0;
+}
+
+static uint64_t encode_rdbase(struct host_its *hw_its, int cpu, uint64_t reg)
+{
+ reg &= ~GENMASK(51, 16);
+
+ if ( hw_its->pta )
+ reg |= per_cpu(rdist_addr, cpu) & GENMASK(51, 16);
+ else
+ reg |= per_cpu(rdist_id, cpu) << 16;
+
+ return reg;
+}
+
+static int its_send_cmd_sync(struct host_its *its, int cpu)
+{
+ uint64_t cmd[4];
+
+ cmd[0] = GITS_CMD_SYNC;
+ cmd[1] = 0x00;
+ cmd[2] = encode_rdbase(its, cpu, 0x0);
+ cmd[3] = 0x00;
+
+ return its_send_command(its, cmd);
+}
+
+static int its_send_cmd_mapc(struct host_its *its, int collection_id, int cpu)
+{
+ uint64_t cmd[4];
+
+ cmd[0] = GITS_CMD_MAPC;
+ cmd[1] = 0x00;
+ cmd[2] = encode_rdbase(its, cpu, (collection_id & GENMASK(15, 0)) | BIT(63));
+ cmd[3] = 0x00;
+
+ return its_send_command(its, cmd);
+}
+
+/* Set up the (1:1) collection mapping for the given host CPU. */
+void gicv3_its_setup_collection(int cpu)
+{
+ struct host_its *its;
+
+ list_for_each_entry(its, &host_its_list, entry)
+ {
+ /* Only send commands to ITS that have been initialized already. */
+ if ( !its->cmd_buf )
+ continue;
+
+ its_send_cmd_mapc(its, cpu, cpu);
+ its_send_cmd_sync(its, cpu);
+ }
+}
+
#define BASER_ATTR_MASK \
((0x3UL << GITS_BASER_SHAREABILITY_SHIFT) | \
(0x7UL << GITS_BASER_OUTER_CACHEABILITY_SHIFT) | \
@@ -147,6 +231,13 @@ int gicv3_its_init(struct host_its *hw_its)
if ( !hw_its->its_base )
return -ENOMEM;
+ /* Make sure the ITS is disabled before programming the BASE registers. */
+ reg = readl_relaxed(hw_its->its_base + GITS_CTLR);
+ writel_relaxed(reg & ~GITS_CTLR_ENABLE, hw_its->its_base + GITS_CTLR);
+
+ reg = readq_relaxed(hw_its->its_base + GITS_TYPER);
+ hw_its->pta = reg & GITS_TYPER_PTA;
+
for (i = 0; i < 8; i++)
{
void __iomem *basereg = hw_its->its_base + GITS_BASER0 + i * 8;
@@ -174,9 +265,18 @@ int gicv3_its_init(struct host_its *hw_its)
if ( IS_ERR(hw_its->cmd_buf) )
return PTR_ERR(hw_its->cmd_buf);
+ its_send_cmd_mapc(hw_its, smp_processor_id(), smp_processor_id());
+ its_send_cmd_sync(hw_its, smp_processor_id());
+
return 0;
}
+void gicv3_set_redist_addr(paddr_t address, int redist_id)
+{
+ this_cpu(rdist_addr) = address;
+ this_cpu(rdist_id) = redist_id;
+}
+
uint64_t gicv3_lpi_allocate_pendtable(void)
{
uint64_t reg, attr;
@@ -265,6 +365,7 @@ void gicv3_its_dt_init(const struct dt_device_node *node)
its_data->addr = addr;
its_data->size = size;
its_data->dt_node = its;
+ spin_lock_init(&its_data->cmd_lock);
printk("GICv3: Found ITS @0x%lx\n", addr);
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 5cf4618..b9387a3 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -638,6 +638,8 @@ static void gicv3_rdist_init_lpis(void __iomem * rdist_base)
table_reg = gicv3_lpi_get_proptable();
if ( table_reg )
writeq_relaxed(table_reg, rdist_base + GICR_PROPBASER);
+
+ gicv3_its_setup_collection(smp_processor_id());
}
static int __init gicv3_populate_rdist(void)
@@ -684,7 +686,22 @@ static int __init gicv3_populate_rdist(void)
this_cpu(rbase) = ptr;
if ( typer & GICR_TYPER_PLPIS )
+ {
+ paddr_t rdist_addr;
+
+ rdist_addr = gicv3.rdist_regions[i].base;
+ rdist_addr += ptr - gicv3.rdist_regions[i].map_base;
+
+ /* The ITS refers to redistributors either by their physical
+ * address or by their ID. Determine those two values and
+ * let the ITS code store them in per host CPU variables to
+ * later be able to address those redistributors.
+ */
+ gicv3_set_redist_addr(rdist_addr,
+ (typer >> 8) & GENMASK(15, 0));
+
gicv3_rdist_init_lpis(ptr);
+ }
printk("GICv3: CPU%d: Found redistributor in region %d @%p\n",
smp_processor_id(), i, ptr);
diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
index b2a003f..b49d274 100644
--- a/xen/include/asm-arm/gic-its.h
+++ b/xen/include/asm-arm/gic-its.h
@@ -37,6 +37,7 @@
/* Register bits */
#define GITS_CTLR_ENABLE 0x1
+#define GITS_TYPER_PTA BIT(19)
#define GITS_IIDR_VALUE 0x34c
#define GITS_BASER_VALID BIT(63)
@@ -59,6 +60,22 @@
(31UL << GITS_BASER_ENTRY_SIZE_SHIFT) |\
GITS_BASER_INDIRECT)
+/* ITS command definitions */
+#define ITS_CMD_SIZE 32
+
+#define GITS_CMD_MOVI 0x01
+#define GITS_CMD_INT 0x03
+#define GITS_CMD_CLEAR 0x04
+#define GITS_CMD_SYNC 0x05
+#define GITS_CMD_MAPD 0x08
+#define GITS_CMD_MAPC 0x09
+#define GITS_CMD_MAPTI 0x0a
+#define GITS_CMD_MAPI 0x0b
+#define GITS_CMD_INV 0x0c
+#define GITS_CMD_INVALL 0x0d
+#define GITS_CMD_MOVALL 0x0e
+#define GITS_CMD_DISCARD 0x0f
+
#ifndef __ASSEMBLY__
#include <xen/device_tree.h>
@@ -69,7 +86,9 @@ struct host_its {
paddr_t addr;
paddr_t size;
void __iomem *its_base;
+ spinlock_t cmd_lock;
void *cmd_buf;
+ bool pta;
};
extern struct list_head host_its_list;
@@ -89,6 +108,12 @@ uint64_t gicv3_lpi_allocate_pendtable(void);
int gicv3_lpi_init_host_lpis(int nr_lpis);
int gicv3_its_init(struct host_its *hw_its);
+/* Set the physical address and ID for each redistributor as read from DT. */
+void gicv3_set_redist_addr(paddr_t address, int redist_id);
+
+/* Map a collection for this host CPU to each host ITS. */
+void gicv3_its_setup_collection(int cpu);
+
#else
static inline void gicv3_its_dt_init(const struct dt_device_node *node)
@@ -110,6 +135,13 @@ static inline int gicv3_its_init(struct host_its *hw_its)
{
return 0;
}
+static inline void gicv3_set_redist_addr(paddr_t address, int redist_id)
+{
+}
+static inline void gicv3_its_setup_collection(int cpu)
+{
+}
+
#endif /* CONFIG_HAS_ITS */
#endif /* __ASSEMBLY__ */
--
2.9.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2016-09-28 18:25 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-28 18:24 [RFC PATCH 00/24] [FOR 4.9] arm64: Dom0 ITS emulation Andre Przywara
2016-09-28 18:24 ` [RFC PATCH 01/24] ARM: GICv3 ITS: parse and store ITS subnodes from hardware DT Andre Przywara
2016-10-26 1:11 ` Stefano Stabellini
2016-11-01 15:13 ` Julien Grall
2016-11-14 17:35 ` Andre Przywara
2016-11-23 15:39 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 02/24] ARM: GICv3: allocate LPI pending and property table Andre Przywara
2016-10-24 14:28 ` Vijay Kilari
2016-11-02 16:22 ` Andre Przywara
2016-10-26 1:10 ` Stefano Stabellini
2016-11-10 15:29 ` Andre Przywara
2016-11-10 21:00 ` Stefano Stabellini
2016-11-01 17:22 ` Julien Grall
2016-11-15 11:32 ` Andre Przywara
2016-11-23 15:58 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 03/24] ARM: GICv3 ITS: allocate device and collection table Andre Przywara
2016-10-09 13:55 ` Vijay Kilari
2016-10-10 9:05 ` Andre Przywara
2016-10-24 14:30 ` Vijay Kilari
2016-11-02 17:51 ` Andre Przywara
2016-10-26 22:57 ` Stefano Stabellini
2016-11-01 17:34 ` Julien Grall
2016-11-10 15:32 ` Andre Przywara
2016-11-10 21:06 ` Stefano Stabellini
2016-11-01 18:19 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 04/24] ARM: GICv3 ITS: map ITS command buffer Andre Przywara
2016-10-24 14:31 ` Vijay Kilari
2016-10-26 23:03 ` Stefano Stabellini
2016-11-10 16:04 ` Andre Przywara
2016-11-02 13:38 ` Julien Grall
2016-09-28 18:24 ` Andre Przywara [this message]
2016-10-26 23:55 ` [RFC PATCH 05/24] ARM: GICv3 ITS: introduce ITS command handling Stefano Stabellini
2016-10-27 21:52 ` Stefano Stabellini
2016-11-10 15:57 ` Andre Przywara
2016-11-02 15:05 ` Julien Grall
2017-01-31 9:10 ` Andre Przywara
2017-01-31 10:23 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 06/24] ARM: GICv3 ITS: introduce host LPI array Andre Przywara
2016-10-27 22:59 ` Stefano Stabellini
2016-11-02 15:14 ` Julien Grall
2016-11-10 17:22 ` Andre Przywara
2016-11-10 21:48 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 07/24] ARM: GICv3 ITS: introduce device mapping Andre Przywara
2016-10-24 15:31 ` Vijay Kilari
2016-11-03 19:33 ` Andre Przywara
2016-10-28 0:08 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 08/24] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2016-10-24 15:31 ` Vijay Kilari
2016-11-03 19:47 ` Andre Przywara
2016-10-28 1:04 ` Stefano Stabellini
2017-01-12 19:14 ` Andre Przywara
2017-01-13 19:37 ` Stefano Stabellini
2017-01-16 9:44 ` André Przywara
2017-01-16 19:16 ` Stefano Stabellini
2016-11-04 15:46 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 09/24] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2016-10-28 1:51 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 10/24] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2016-10-28 23:07 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 11/24] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2016-10-24 15:32 ` Vijay Kilari
2016-11-03 20:21 ` Andre Przywara
2016-11-04 11:53 ` Julien Grall
2016-10-29 0:39 ` Stefano Stabellini
2017-03-29 15:47 ` Andre Przywara
2016-11-02 17:18 ` Julien Grall
2016-11-02 17:41 ` Stefano Stabellini
2016-11-02 18:03 ` Julien Grall
2016-11-02 18:09 ` Stefano Stabellini
2017-01-31 9:10 ` Andre Przywara
2017-01-31 10:38 ` Julien Grall
2017-01-31 12:04 ` Andre Przywara
2016-09-28 18:24 ` [RFC PATCH 12/24] ARM: vGICv3: introduce basic ITS emulation bits Andre Przywara
2016-10-09 14:20 ` Vijay Kilari
2016-10-10 10:38 ` Andre Przywara
2016-10-24 15:31 ` Vijay Kilari
2016-11-03 19:26 ` Andre Przywara
2016-11-04 12:07 ` Julien Grall
2016-11-03 17:50 ` Julien Grall
2016-11-08 23:54 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 13/24] ARM: vITS: handle CLEAR command Andre Przywara
2016-11-04 15:48 ` Julien Grall
2016-11-09 0:39 ` Stefano Stabellini
2016-11-09 13:32 ` Julien Grall
2016-09-28 18:24 ` [RFC PATCH 14/24] ARM: vITS: handle INT command Andre Przywara
2016-11-09 0:42 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 15/24] ARM: vITS: handle MAPC command Andre Przywara
2016-11-09 0:48 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 16/24] ARM: vITS: handle MAPD command Andre Przywara
2016-11-09 0:54 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 17/24] ARM: vITS: handle MAPTI command Andre Przywara
2016-11-09 1:07 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 18/24] ARM: vITS: handle MOVI command Andre Przywara
2016-11-09 1:13 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 19/24] ARM: vITS: handle DISCARD command Andre Przywara
2016-11-09 1:28 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 20/24] ARM: vITS: handle INV command Andre Przywara
2016-11-09 1:49 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 21/24] ARM: vITS: handle INVALL command Andre Przywara
2016-10-24 15:32 ` Vijay Kilari
2016-11-04 9:22 ` Andre Przywara
2016-11-10 0:21 ` Stefano Stabellini
2016-11-10 11:57 ` Julien Grall
2016-11-10 20:42 ` Stefano Stabellini
2016-11-11 15:53 ` Julien Grall
2016-11-11 20:31 ` Stefano Stabellini
2016-11-18 18:39 ` Stefano Stabellini
2016-11-25 16:10 ` Julien Grall
2016-12-01 1:19 ` Stefano Stabellini
2016-12-02 16:18 ` Andre Przywara
2016-12-03 0:46 ` Stefano Stabellini
2016-12-05 13:36 ` Julien Grall
2016-12-05 19:51 ` Stefano Stabellini
2016-12-06 15:56 ` Julien Grall
2016-12-06 19:36 ` Stefano Stabellini
2016-12-06 21:32 ` Dario Faggioli
2016-12-06 21:53 ` Stefano Stabellini
2016-12-06 22:01 ` Stefano Stabellini
2016-12-06 22:12 ` Dario Faggioli
2016-12-06 23:13 ` Julien Grall
2016-12-07 20:20 ` Stefano Stabellini
2016-12-09 18:01 ` Julien Grall
2016-12-09 20:13 ` Stefano Stabellini
2016-12-09 18:07 ` Andre Przywara
2016-12-09 20:18 ` Stefano Stabellini
2016-12-14 2:39 ` George Dunlap
2016-12-16 1:30 ` Dario Faggioli
2016-12-06 22:39 ` Dario Faggioli
2016-12-06 23:24 ` Julien Grall
2016-12-07 0:17 ` Dario Faggioli
2016-12-07 20:21 ` Stefano Stabellini
2016-12-09 10:14 ` Dario Faggioli
2016-12-06 21:36 ` Dario Faggioli
2016-12-09 19:00 ` Andre Przywara
2016-12-10 0:30 ` Stefano Stabellini
2016-12-12 10:38 ` Andre Przywara
2016-12-14 0:38 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 22/24] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2016-11-10 0:38 ` Stefano Stabellini
2016-09-28 18:24 ` [RFC PATCH 23/24] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2016-09-28 18:24 ` [RFC PATCH 24/24] ARM: vGIC: advertising LPI support Andre Przywara
2016-11-10 0:49 ` Stefano Stabellini
2016-11-10 11:22 ` Julien Grall
2016-11-02 13:56 ` [RFC PATCH 00/24] [FOR 4.9] arm64: Dom0 ITS emulation Julien Grall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160928182457.12433-6-andre.przywara@arm.com \
--to=andre.przywara@arm.com \
--cc=julien.grall@arm.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.