From patchwork Thu Mar 19 19:29:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 46087 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-we0-f200.google.com (mail-we0-f200.google.com [74.125.82.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 46A3221515 for ; Thu, 19 Mar 2015 19:31:57 +0000 (UTC) Received: by wevm14 with SMTP id m14sf6916495wev.0 for ; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=3Ws/MtDWN76oEmuVXvlC12ACjjcybEa1cshD87hLcwQ=; b=er7evXooRoCx+5CPO8ste7T7jD+IyDnJLKwV4Dnq+XdYJ3cQy1SK20E7AJkVtvdkOd bPN0wb3uW3bDINPZPSUWRtXioKXaycaiM3Kq7uf5lPN7hWjq9Jme49aCaZQ80AueoLpv y14DAhFo47Um506q+BkG4IV7SCdmh0n59ZkRKiAJwU4mk4DUWitVhyvkhCKCsyHENJN2 c5dBKQ4sJRqyvu6HBVOCWykvUhwc4GYlbahdb+tR1EDUVOF+dHOYh1Km4FwzMtwbJYA8 tlF9c9ImyTWhH2Q5csA2yGdh46gwrddnjLrZiRLSzfr2YzqAkV4+3ECf0/O7n56y8vCq ua/g== X-Gm-Message-State: ALoCoQkAMOed9VGq3rF8H06wqAI8j+PR/W0+nRqOZI/J+Pq+gNRFpgU1XOVwBk569WxajGH3O8p9 X-Received: by 10.112.148.10 with SMTP id to10mr7451537lbb.18.1426793516605; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.8.134 with SMTP id r6ls380435laa.59.gmail; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) X-Received: by 10.152.115.169 with SMTP id jp9mr70477551lab.121.1426793516330; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com. [209.85.217.176]) by mx.google.com with ESMTPS id wr3si1638720lac.110.2015.03.19.12.31.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Mar 2015 12:31:56 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) client-ip=209.85.217.176; Received: by lbcgn8 with SMTP id gn8so60349870lbc.2 for ; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) X-Received: by 10.152.120.134 with SMTP id lc6mr69036008lab.72.1426793516067; Thu, 19 Mar 2015 12:31:56 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp597300lbj; Thu, 19 Mar 2015 12:31:54 -0700 (PDT) X-Received: by 10.52.118.9 with SMTP id ki9mr80370249vdb.11.1426793513712; Thu, 19 Mar 2015 12:31:53 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id sd2si2018813vdc.12.2015.03.19.12.31.52 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 19 Mar 2015 12:31:53 -0700 (PDT) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YYg9R-0004Bi-TU; Thu, 19 Mar 2015 19:30:41 +0000 Received: from mail6.bemta14.messagelabs.com ([193.109.254.103]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YYg9Q-0004BB-8F for xen-devel@lists.xenproject.org; Thu, 19 Mar 2015 19:30:40 +0000 Received: from [193.109.254.147] by server-10.bemta-14.messagelabs.com id C2/61-14870-FD32B055; Thu, 19 Mar 2015 19:30:39 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-3.tower-27.messagelabs.com!1426793438!14313721!1 X-Originating-IP: [74.125.82.172] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 19587 invoked from network); 19 Mar 2015 19:30:38 -0000 Received: from mail-we0-f172.google.com (HELO mail-we0-f172.google.com) (74.125.82.172) by server-3.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 19 Mar 2015 19:30:38 -0000 Received: by wetk59 with SMTP id k59so65615477wet.3 for ; Thu, 19 Mar 2015 12:30:38 -0700 (PDT) X-Received: by 10.194.63.16 with SMTP id c16mr157585635wjs.117.1426793438045; Thu, 19 Mar 2015 12:30:38 -0700 (PDT) Received: from chilopoda.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id hl8sm3203005wjb.38.2015.03.19.12.30.36 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 19 Mar 2015 12:30:37 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Thu, 19 Mar 2015 19:29:27 +0000 Message-Id: <1426793399-6283-2-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1426793399-6283-1-git-send-email-julien.grall@linaro.org> References: <1426793399-6283-1-git-send-email-julien.grall@linaro.org> Cc: Zoltan Kiss , ian.campbell@citrix.com, Stefano Stabellini , Julien Grall , tim@xen.org, Frediano Ziglio , stefano.stabellini@citrix.com Subject: [Xen-devel] [PATCH v4 01/33] xen/arm: Divide GIC initialization in 2 parts X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: Currently the function to translate IRQ from the device tree is set unconditionally to be able to be able to retrieve serial/timer IRQ before the GIC has been initialized. It assumes that the xlate function won't ever changed. We may also need to have the primary interrupt controller very early. Rework the gic initialization in 2 parts: - gic_preinit: Get the interrupt controller device tree node and set up GIC and xlate callbacks - gic_init: Initialize the interrupt controller and the boot CPU interrupts. The former function will be called just after the IRQ subsystem as been initialized. Signed-off-by: Julien Grall Acked-by: Stefano Stabellini Acked-by: Ian Campbell Cc: Frediano Ziglio Cc: Zoltan Kiss --- Note that the HIP04 GIC driver has not been modified because I don't have a platform where I can test my changes. Although, the code is still building. I let the Hisilicon guys (Frediano and Zoltan) providing a suitable patch for there platform. Meanwhile, I think it can go upstream as it has been acked by both Ian and Stefano. Changes in v4: - Rebase on the latest staging (no functional changes) - Add Ian and Stefano's ack - Typo in the commit message Changes in v3: - Patch was previously sent in a separate series [1] - Reorder the function to avoid forward declaration - Make gic-v3 driver compliant to the new interface - Remove spurious field addition in gicv2 structure Changelog based on the separate series: Changes in v3: - Patch added. [1] https://patches.linaro.org/33313/ --- xen/arch/arm/gic-v2.c | 70 ++++++++++++++++++++++--------------------- xen/arch/arm/gic-v3.c | 75 ++++++++++++++++++++++++----------------------- xen/arch/arm/gic.c | 16 ++++++++-- xen/arch/arm/setup.c | 3 +- xen/include/asm-arm/gic.h | 8 +++++ 5 files changed, 100 insertions(+), 72 deletions(-) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index 20cdbc9..3be4ad6 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -674,37 +674,10 @@ static hw_irq_controller gicv2_guest_irq_type = { .set_affinity = gicv2_irq_set_affinity, }; -const static struct gic_hw_operations gicv2_ops = { - .info = &gicv2_info, - .secondary_init = gicv2_secondary_cpu_init, - .save_state = gicv2_save_state, - .restore_state = gicv2_restore_state, - .dump_state = gicv2_dump_state, - .gicv_setup = gicv2v_setup, - .gic_host_irq_type = &gicv2_host_irq_type, - .gic_guest_irq_type = &gicv2_guest_irq_type, - .eoi_irq = gicv2_eoi_irq, - .deactivate_irq = gicv2_dir_irq, - .read_irq = gicv2_read_irq, - .set_irq_properties = gicv2_set_irq_properties, - .send_SGI = gicv2_send_SGI, - .disable_interface = gicv2_disable_interface, - .update_lr = gicv2_update_lr, - .update_hcr_status = gicv2_hcr_status, - .clear_lr = gicv2_clear_lr, - .read_lr = gicv2_read_lr, - .write_lr = gicv2_write_lr, - .read_vmcr_priority = gicv2_read_vmcr_priority, - .read_apr = gicv2_read_apr, - .make_dt_node = gicv2_make_dt_node, -}; - -/* Set up the GIC */ -static int __init gicv2_init(struct dt_device_node *node, const void *data) +static int __init gicv2_init(void) { int res; - - dt_device_set_used_by(node, DOMID_XEN); + const struct dt_device_node *node = gicv2_info.node; res = dt_device_get_address(node, 0, &gicv2.dbase, NULL); if ( res || !gicv2.dbase || (gicv2.dbase & ~PAGE_MASK) ) @@ -727,9 +700,6 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data) panic("GICv2: Cannot find the maintenance IRQ"); gicv2_info.maintenance_irq = res; - /* Set the GIC as the primary interrupt controller */ - dt_interrupt_controller = node; - /* TODO: Add check on distributor, cpu size */ printk("GICv2 initialization:\n" @@ -774,8 +744,42 @@ static int __init gicv2_init(struct dt_device_node *node, const void *data) spin_unlock(&gicv2.lock); + return 0; +} + +const static struct gic_hw_operations gicv2_ops = { + .info = &gicv2_info, + .init = gicv2_init, + .secondary_init = gicv2_secondary_cpu_init, + .save_state = gicv2_save_state, + .restore_state = gicv2_restore_state, + .dump_state = gicv2_dump_state, + .gicv_setup = gicv2v_setup, + .gic_host_irq_type = &gicv2_host_irq_type, + .gic_guest_irq_type = &gicv2_guest_irq_type, + .eoi_irq = gicv2_eoi_irq, + .deactivate_irq = gicv2_dir_irq, + .read_irq = gicv2_read_irq, + .set_irq_properties = gicv2_set_irq_properties, + .send_SGI = gicv2_send_SGI, + .disable_interface = gicv2_disable_interface, + .update_lr = gicv2_update_lr, + .update_hcr_status = gicv2_hcr_status, + .clear_lr = gicv2_clear_lr, + .read_lr = gicv2_read_lr, + .write_lr = gicv2_write_lr, + .read_vmcr_priority = gicv2_read_vmcr_priority, + .read_apr = gicv2_read_apr, + .make_dt_node = gicv2_make_dt_node, +}; + +/* Set up the GIC */ +static int __init gicv2_preinit(struct dt_device_node *node, const void *data) +{ gicv2_info.hw_version = GIC_V2; + gicv2_info.node = node; register_gic_ops(&gicv2_ops); + dt_irq_xlate = gic_irq_xlate; return 0; } @@ -788,7 +792,7 @@ static const struct dt_device_match gicv2_dt_match[] __initconst = DT_DEVICE_START(gicv2, "GICv2", DEVICE_GIC) .dt_match = gicv2_dt_match, - .init = gicv2_init, + .init = gicv2_preinit, DT_DEVICE_END /* diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index ab80670..48772f1 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -1173,31 +1173,6 @@ static const hw_irq_controller gicv3_guest_irq_type = { .set_affinity = gicv3_irq_set_affinity, }; -static const struct gic_hw_operations gicv3_ops = { - .info = &gicv3_info, - .save_state = gicv3_save_state, - .restore_state = gicv3_restore_state, - .dump_state = gicv3_dump_state, - .gicv_setup = gicv_v3_init, - .gic_host_irq_type = &gicv3_host_irq_type, - .gic_guest_irq_type = &gicv3_guest_irq_type, - .eoi_irq = gicv3_eoi_irq, - .deactivate_irq = gicv3_dir_irq, - .read_irq = gicv3_read_irq, - .set_irq_properties = gicv3_set_irq_properties, - .send_SGI = gicv3_send_sgi, - .disable_interface = gicv3_disable_interface, - .update_lr = gicv3_update_lr, - .update_hcr_status = gicv3_hcr_status, - .clear_lr = gicv3_clear_lr, - .read_lr = gicv3_read_lr, - .write_lr = gicv3_write_lr, - .read_vmcr_priority = gicv3_read_vmcr_priority, - .read_apr = gicv3_read_apr, - .secondary_init = gicv3_secondary_cpu_init, - .make_dt_node = gicv3_make_dt_node, -}; - static int __init cmp_rdist(const void *a, const void *b) { const struct rdist_region *l = a, *r = a; @@ -1207,11 +1182,12 @@ static int __init cmp_rdist(const void *a, const void *b) } /* Set up the GIC */ -static int __init gicv3_init(struct dt_device_node *node, const void *data) +static int __init gicv3_init(void) { struct rdist_region *rdist_regs; int res, i; uint32_t reg; + const struct dt_device_node *node = gicv3_info.node; if ( !cpu_has_gicv3 ) { @@ -1219,8 +1195,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data) return -ENODEV; } - dt_device_set_used_by(node, DOMID_XEN); - res = dt_device_get_address(node, 0, &gicv3.dbase, &gicv3.dbase_size); if ( res || !gicv3.dbase ) panic("GICv3: Cannot find a valid distributor address"); @@ -1274,9 +1248,6 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data) panic("GICv3: Cannot find the maintenance IRQ"); gicv3_info.maintenance_irq = res; - /* Set the GIC as the primary interrupt controller */ - dt_interrupt_controller = node; - for ( i = 0; i < gicv3.rdist_count; i++ ) { /* map dbase & rdist regions */ @@ -1311,15 +1282,47 @@ static int __init gicv3_init(struct dt_device_node *node, const void *data) res = gicv3_cpu_init(); gicv3_hyp_init(); - gicv3_info.hw_version = GIC_V3; - /* Register hw ops*/ - register_gic_ops(&gicv3_ops); - spin_unlock(&gicv3.lock); return res; } +static const struct gic_hw_operations gicv3_ops = { + .info = &gicv3_info, + .init = gicv3_init, + .save_state = gicv3_save_state, + .restore_state = gicv3_restore_state, + .dump_state = gicv3_dump_state, + .gicv_setup = gicv_v3_init, + .gic_host_irq_type = &gicv3_host_irq_type, + .gic_guest_irq_type = &gicv3_guest_irq_type, + .eoi_irq = gicv3_eoi_irq, + .deactivate_irq = gicv3_dir_irq, + .read_irq = gicv3_read_irq, + .set_irq_properties = gicv3_set_irq_properties, + .send_SGI = gicv3_send_sgi, + .disable_interface = gicv3_disable_interface, + .update_lr = gicv3_update_lr, + .update_hcr_status = gicv3_hcr_status, + .clear_lr = gicv3_clear_lr, + .read_lr = gicv3_read_lr, + .write_lr = gicv3_write_lr, + .read_vmcr_priority = gicv3_read_vmcr_priority, + .read_apr = gicv3_read_apr, + .secondary_init = gicv3_secondary_cpu_init, + .make_dt_node = gicv3_make_dt_node, +}; + +static int __init gicv3_preinit(struct dt_device_node *node, const void *data) +{ + gicv3_info.hw_version = GIC_V3; + gicv3_info.node = node; + register_gic_ops(&gicv3_ops); + dt_irq_xlate = gic_irq_xlate; + + return 0; +} + static const struct dt_device_match gicv3_dt_match[] __initconst = { DT_MATCH_GIC_V3, @@ -1328,7 +1331,7 @@ static const struct dt_device_match gicv3_dt_match[] __initconst = DT_DEVICE_START(gicv3, "GICv3", DEVICE_GIC) .dt_match = gicv3_dt_match, - .init = gicv3_init, + .init = gicv3_preinit, DT_DEVICE_END /* diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index 940fb8e..8e7f24b 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -163,8 +163,10 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize, return 0; } -/* Set up the GIC */ -void __init gic_init(void) +/* Find the interrupt controller and set up the callback to translate + * device tree IRQ. + */ +void __init gic_preinit(void) { int rc; struct dt_device_node *node; @@ -189,6 +191,16 @@ void __init gic_init(void) if ( !num_gics ) panic("Unable to find compatible GIC in the device tree"); + /* Set the GIC as the primary interrupt controller */ + dt_interrupt_controller = node; + dt_device_set_used_by(node, DOMID_XEN); +} + +/* Set up the GIC */ +void __init gic_init(void) +{ + if ( gic_hw_ops->init() ) + panic("Failed to initialize the GIC drivers"); /* Clear LR mask for cpu0 */ clear_cpu_lr_mask(); } diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index b905c9f..4f05f57 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -752,7 +752,6 @@ void __init start_xen(unsigned long boot_phys_offset, vm_init(); dt_unflatten_host_device_tree(); - dt_irq_xlate = gic_irq_xlate; init_IRQ(); @@ -760,6 +759,8 @@ void __init start_xen(unsigned long boot_phys_offset, preinit_xen_time(); + gic_preinit(); + dt_uart_init(); console_init_preirq(); console_init_ring(); diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 89a9b6f..b16f98e 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -232,6 +232,10 @@ extern void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq); /* Accept an interrupt from the GIC and dispatch its handler */ extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq); +/* Find the interrupt controller and set up the callback to translate + * device tree IRQ. + */ +extern void gic_preinit(void); /* Bring up the interrupt controller, and report # cpus attached */ extern void gic_init(void); /* Bring up a secondary CPU's per-CPU GIC interface */ @@ -284,11 +288,15 @@ struct gic_info { uint8_t nr_lrs; /* Maintenance irq number */ unsigned int maintenance_irq; + /* Pointer to the device tree node representing the interrupt controller */ + const struct dt_device_node *node; }; struct gic_hw_operations { /* Hold GIC HW information */ const struct gic_info *info; + /* Initialize the GIC and the boot CPU */ + int (*init)(void); /* Save GIC registers */ void (*save_state)(struct vcpu *); /* Restore GIC registers */