linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: Tomasz Nowicki <tn@semihalf.com>,
	tglx@linutronix.de, jason@lakedaemon.net, rjw@rjwysocki.net,
	lorenzo.pieralisi@arm.com, robert.richter@caviumnetworks.com,
	shijie.huang@arm.com, guohanjun@huawei.com,
	Suravee.Suthikulpanit@amd.com
Cc: mw@semihalf.com, graeme.gregory@linaro.org,
	Catalin.Marinas@arm.com, will.deacon@arm.com,
	linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
	hanjun.guo@linaro.org, linux-arm-kernel@lists.infradead.org,
	ddaney.cavm@gmail.com
Subject: Re: [PATCH V2 03/10] irqchip,GICv3,ACPI: Add redistributor support via GICC structures.
Date: Tue, 12 Jan 2016 12:03:30 +0000	[thread overview]
Message-ID: <5694EB92.9030109@arm.com> (raw)
In-Reply-To: <1450353133-15992-4-git-send-email-tn@semihalf.com>

On 17/12/15 11:52, Tomasz Nowicki wrote:
> On systems supporting GICv3 and above, in MADT GICC structures, the
> field of GICR Base Address holds the 64-bit physical address of the
> associated Redistributor if the GIC Redistributors are not in the
> always-on power domain, so instead of init GICR regions via GIC
> redistributor structure(s), init it with GICR base address in GICC
> structures in that case.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 98 ++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 89 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c4b929c..0528e82 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -39,6 +39,7 @@
>  struct redist_region {
>  	void __iomem		*redist_base;
>  	phys_addr_t		phys_base;
> +	bool			single_redist;
>  };
>  
>  struct gic_chip_data {
> @@ -435,6 +436,9 @@ static int gic_populate_rdist(void)
>  				return 0;
>  			}
>  
> +			if (gic_data.redist_regions[i].single_redist)
> +				break;
> +
>  			if (gic_data.redist_stride) {
>  				ptr += gic_data.redist_stride;
>  			} else {
> @@ -965,6 +969,7 @@ IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>  #ifdef CONFIG_ACPI
>  static struct redist_region *redist_regs __initdata;
>  static u32 nr_redist_regions __initdata;
> +static bool single_redist;
>  
>  static int __init
>  gic_acpi_register_redist(phys_addr_t phys_base, u64 size)
> @@ -979,7 +984,8 @@ gic_acpi_register_redist(phys_addr_t phys_base, u64 size)
>  	}
>  
>  	redist_regs[count].phys_base = phys_base;
> -	redist_regs[count++].redist_base = redist_base;
> +	redist_regs[count].redist_base = redist_base;

nit: move the count++ out of the access in the previous patch, this will
make this series a bit easier to follow.

> +	redist_regs[count++].single_redist = single_redist;

What is that single_redist for? Is that because you can't rely on
GICR_TYPER.Last?

>  	return 0;
>  }
>  
> @@ -993,6 +999,48 @@ gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>  	return gic_acpi_register_redist(redist->base_address, redist->length);
>  }
>  
> +static int __init
> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
> +			 const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *gicc;
> +	void __iomem *redist_base;
> +	u64 typer;
> +	u32 size;
> +
> +	gicc = (struct acpi_madt_generic_interrupt *)header;
> +	redist_base = ioremap(gicc->gicr_base_address, SZ_64K * 2);
> +	if (!redist_base)
> +		return -ENOMEM;
> +
> +	typer = readq_relaxed(redist_base + GICR_TYPER);
> +	/* don't map reserved page as it's buggy to access it */
> +	size = (typer & GICR_TYPER_VLPIS) ? SZ_64K * 3 : SZ_64K * 2;
> +	iounmap(redist_base);

What a mess. If you discover a !VLPIS redistributor, why do you have to
unmap it to remap it again? Also, please map the whole region for the
redistributor as we have on the DT side (4 64kB pages for VLPIS capable
redistributors).

Also, the spec says:

"On systems supporting GICv3 and above, this field holds the 64-bit
physical address of the associated Redistributor. If all of the GIC
Redistributors are in the always-on power domain, GICR structures should
be used to describe the Redistributors instead, and this field must be
set to 0."

which triggers two questions:
- Can you access always the GICR_TYPER register without waking the
redistributor up?
- How do you cope with situations where some redistributors are in the
always-on domain, and some are not?

> +	return gic_acpi_register_redist(gicc->gicr_base_address, size);
> +}
> +
> +static int __init gic_acpi_collect_gicr_base(void)
> +{
> +	acpi_tbl_entry_handler redist_parser;
> +	enum acpi_madt_type type;
> +
> +	if (single_redist) {
> +		type = ACPI_MADT_TYPE_GENERIC_INTERRUPT;
> +		redist_parser = gic_acpi_parse_madt_gicc;
> +	} else {
> +		type = ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR;
> +		redist_parser = gic_acpi_parse_madt_redist;
> +	}
> +
> +	/* Collect redistributor base addresses in GICR entries */
> +	if (acpi_table_parse_madt(type, redist_parser, 0) > 0)
> +		return 0;
> +
> +	pr_info("No valid GICR entries exist\n");
> +	return -ENODEV;
> +}
> +
>  static int __init gic_acpi_match_gicr(struct acpi_subtable_header *header,
>  				  const unsigned long end)
>  {
> @@ -1000,6 +1048,42 @@ static int __init gic_acpi_match_gicr(struct acpi_subtable_header *header,
>  	return 0;
>  }
>  
> +static int __init gic_acpi_match_gicc(struct acpi_subtable_header *header,
> +				      const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +				(struct acpi_madt_generic_interrupt *)header;
> +
> +	/*
> +	 * If GICC is enabled and has valid gicr base address, then it means
> +	 * GICR base is presented via GICC
> +	 */
> +	if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
> +		return 0;
> +
> +	return -ENODEV;
> +}
> +
> +static int __init gic_acpi_count_gicr_regions(void)
> +{
> +	int count;
> +
> +	/* Count how many redistributor regions we have */
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
> +				      gic_acpi_match_gicr, 0);
> +	if (count > 0) {
> +		single_redist = false;
> +		return count;
> +	}
> +
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
> +				      gic_acpi_match_gicc, 0);
> +	if (count > 0)
> +		single_redist = true;
> +
> +	return count;
> +}
> +

Here, you seem to consider GICR and GICC tables to be mutually
exclusive. I don't think the spec says so.

>  static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header,
>  					   struct acpi_probe_entry *ape)
>  {
> @@ -1011,8 +1095,7 @@ static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header,
>  		return false;
>  
>  	/* We need to do that exercise anyway, the sooner the better */
> -	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
> -				      gic_acpi_match_gicr, 0);
> +	count = gic_acpi_count_gicr_regions();
>  	if (count <= 0)
>  		return false;
>  
> @@ -1028,7 +1111,7 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
>  	struct acpi_madt_generic_distributor *dist;
>  	struct fwnode_handle *domain_handle;
>  	void __iomem *dist_base;
> -	int i, err, count;
> +	int i, err;
>  
>  	/* Get distributor base address */
>  	dist = (struct acpi_madt_generic_distributor *)header;
> @@ -1051,12 +1134,9 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
>  		goto out_dist_unmap;
>  	}
>  
> -	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
> -				      gic_acpi_parse_madt_redist, 0);
> -	if (count <= 0) {
> -		err = -ENODEV;
> +	err = gic_acpi_collect_gicr_base();
> +	if (err)
>  		goto out_redist_unmap;
> -	}
>  
>  	domain_handle = irq_domain_alloc_fwnode(dist_base);
>  	if (!domain_handle) {
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2016-01-12 12:03 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-17 11:52 [PATCH V2 00/10] Introduce ACPI world to GICv3 & ITS irqchip Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 01/10] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 02/10] irqchip / GICv3: Add ACPI support for GICv3+ initialization Tomasz Nowicki
2015-12-17 13:44   ` kbuild test robot
2015-12-17 15:12     ` Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 03/10] irqchip,GICv3,ACPI: Add redistributor support via GICC structures Tomasz Nowicki
2016-01-12 12:03   ` Marc Zyngier [this message]
2016-01-12 15:05     ` Hanjun Guo
2016-01-12 16:16       ` Marc Zyngier
2016-01-12 17:14         ` Tomasz Nowicki
2016-01-12 16:45     ` Tomasz Nowicki
2016-01-13  1:52       ` Hanjun Guo
2016-01-13  8:35         ` Marc Zyngier
2016-01-13  9:15           ` Hanjun Guo
2015-12-17 11:52 ` [PATCH V2 04/10] irqchip / GICv3: remove gic root node in ITS Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 05/10] irqchip, gicv3, its: Mark its_init() and its children as __init Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 06/10] irqchip/GICv3/ITS: Refator ITS dt init code to prepare for ACPI Tomasz Nowicki
2015-12-18 10:57   ` Hanjun Guo
2015-12-18 11:14     ` Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 07/10] ARM64, ACPI, PCI: I/O Remapping Table (IORT) initial support Tomasz Nowicki
2015-12-17 13:24   ` Tomasz Nowicki
2015-12-18 12:11     ` Hanjun Guo
2015-12-18 11:18   ` Hanjun Guo
2015-12-17 11:52 ` [PATCH V2 08/10] irqchip, gicv3, its: Probe ITS in the ACPI way Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 09/10] acpi, gicv3, msi: Factor out code that might be reused for ACPI equivalent Tomasz Nowicki
2015-12-17 11:52 ` [PATCH V2 10/10] acpi, gicv3, its: Use MADT ITS subtable to do PCI/MSI domain initialization Tomasz Nowicki
2015-12-17 12:46   ` kbuild test robot

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=5694EB92.9030109@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=Catalin.Marinas@arm.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=ddaney.cavm@gmail.com \
    --cc=graeme.gregory@linaro.org \
    --cc=guohanjun@huawei.com \
    --cc=hanjun.guo@linaro.org \
    --cc=jason@lakedaemon.net \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=mw@semihalf.com \
    --cc=rjw@rjwysocki.net \
    --cc=robert.richter@caviumnetworks.com \
    --cc=shijie.huang@arm.com \
    --cc=tglx@linutronix.de \
    --cc=tn@semihalf.com \
    --cc=will.deacon@arm.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).