From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 02/20] arm64: initial support for GICv3
Date: Wed, 11 Jun 2014 17:16:05 +0100 [thread overview]
Message-ID: <539880C5.6020203@arm.com> (raw)
In-Reply-To: <CALicx6vz6JZsMDmEVUMarsTd67xK1r+HjVTD0Jg94U6LD9bk3w@mail.gmail.com>
Hi Vijay,
On 11/06/14 16:52, Vijay Kilari wrote:
> Hi Marc,
>
> [...]
>> +
>> +static void gic_write_pmr(u64 val)
>> +{
>> + asm volatile("msr " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
>> +}
>> +
>> +static void gic_write_ctlr(u64 val)
>> +{
>> + asm volatile("msr " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val));
>> + isb();
>> +}
>> +
>> +static void gic_write_grpen1(u64 val)
>> +{
>> + asm volatile("msr " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val));
>> + isb();
>
> As per 4.4.11 of PRD03-GENC-010745 17.0 specification
First thing (not relevant to your question), I'd suggest you upgrade to
a *recent* version of the spec.
> execution of DSB after write to ICC_{PMR,IAR, EOI, IGRPEN} etc will
> ensure the observability of GIC register access. However here you are using
> isb(). Is that ok?
I think it depends whether or not you want all effects to be
synchronously observable in the whole system. We already have barriers
on exception returns that will ensure the observability of all these.
Adding them on a per access basis is likely to degrade performance.
>> +}
> [...]
>
>> +static int gic_populate_rdist(void)
>> +{
>> + u64 mpidr = cpu_logical_map(smp_processor_id());
>> + u64 typer;
>> + u32 aff;
>> + int i;
>> +
>> + /*
>> + * Convert affinity to a 32bit value that can be matched to
>> + * GICR_TYPER bits [63:32].
>> + */
>> + aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 |
>> + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 |
>> + MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 |
>> + MPIDR_AFFINITY_LEVEL(mpidr, 0));
>> +
>> + for (i = 0; i < gic_data.redist_regions; i++) {
>> + void __iomem *ptr = gic_data.redist_base[i];
>> + u32 reg;
>> +
>> + reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> + if (reg != 0x30 && reg != 0x40) { /* We're in trouble... */
>> + pr_warn("No redistributor present @%p\n", ptr);
>> + break;
>> + }
>> +
>> + do {
>> + typer = readq_relaxed(ptr + GICR_TYPER);
>> + if ((typer >> 32) == aff) {
>> + gic_data_rdist_rd_base() = ptr;
>> + pr_info("CPU%d: found redistributor %llx @%p\n",
>> + smp_processor_id(),
>> + (unsigned long long)mpidr, ptr);
>> + return 0;
>> + }
>> +
>> + if (gic_data.redist_stride) {
>> + ptr += gic_data.redist_stride;
>> + } else {
>> + ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */
>> + if (typer & GICR_TYPER_VLPIS)
>> + ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */
>> + }
>> + } while (!(typer & GICR_TYPER_LAST));
>> + }
>> +
> [...]
>
>> +
> [...]
>> +
>> +static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>> +{
>> + void __iomem *dist_base;
>> + void __iomem **redist_base;
>> + u64 redist_stride;
>> + u32 redist_regions;
>> + u32 reg;
>> + int gic_irqs;
>> + int err;
>> + int i;
>> +
>> + dist_base = of_iomap(node, 0);
>> + if (!dist_base) {
>> + pr_err("%s: unable to map gic dist registers\n",
>> + node->full_name);
>> + return -ENXIO;
>> + }
>> +
>> + reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> + if (reg != 0x30 && reg != 0x40) {
>> + pr_err("%s: no distributor detected, giving up\n",
>> + node->full_name);
>> + err = -ENODEV;
>> + goto out_unmap_dist;
>> + }
>> +
>> + if (of_property_read_u32(node, "#redistributor-regions", &redist_regions))
>> + redist_regions = 1;
>> +
>> + redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL);
>> + if (!redist_base) {
>> + err = -ENOMEM;
>> + goto out_unmap_dist;
>> + }
>> +
>> + for (i = 0; i < redist_regions; i++) {
>> + redist_base[i] = of_iomap(node, 1 + i);
>> + if (!redist_base[i]) {
>> + pr_err("%s: couldn't map region %d\n",
>> + node->full_name, i);
>> + err = -ENODEV;
>> + goto out_unmap_rdist;
>> + }
>> + }
>> +
>> + if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
>> + redist_stride = 0;
>
> why can't redist_stride be set to 2 * SZ_64K by default if redist_stride is not
> available in dt? Because in populate_redist() if stride is set to 0,
> the redistributor search
> pointer is incremented by 2 * SZ_64K?
Because redist_stride is supposed to give you the absolute stride,
irrespective of the GIC implementing VLPIs or not.
If you read again the code in populate_redist(), you'll see that the
default (with redist_stride == 0) is to adapt to what TYPER says about
the features your GIC supports.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
next parent reply other threads:[~2014-06-11 16:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CALicx6vz6JZsMDmEVUMarsTd67xK1r+HjVTD0Jg94U6LD9bk3w@mail.gmail.com>
2014-06-11 16:16 ` Marc Zyngier [this message]
2014-05-15 17:58 [PATCH v4 00/20] arm64: GICv3 support Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 02/20] arm64: initial support for GICv3 Marc Zyngier
2014-05-23 16:40 ` Jean-Philippe Brucker
2014-05-27 8:17 ` Marc Zyngier
2014-06-05 7:47 ` Abel
2014-06-05 8:44 ` Marc Zyngier
2014-06-09 4:10 ` Abel
2014-06-09 8:41 ` Marc Zyngier
2014-06-10 3:57 ` Abel
2014-06-10 10:43 ` Marc Zyngier
2014-06-11 1:15 ` Abel
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=539880C5.6020203@arm.com \
--to=marc.zyngier@arm.com \
--cc=linux-arm-kernel@lists.infradead.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.