From owner-freebsd-arm@FreeBSD.ORG Sun Apr 6 17:26:40 2014 Return-Path: Delivered-To: freebsd-arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BA0015E2 for ; Sun, 6 Apr 2014 17:26:40 +0000 (UTC) Received: from mail1.uj.edu.pl (mail1.uj.edu.pl [149.156.89.193]) by mx1.freebsd.org (Postfix) with ESMTP id 76B172F9 for ; Sun, 6 Apr 2014 17:26:40 +0000 (UTC) MIME-version: 1.0 Content-transfer-encoding: 7BIT Content-type: text/plain; CHARSET=US-ASCII; format=flowed Received: from [10.10.1.20] ([83.19.65.138]) by mta.uoks.uj.edu.pl (Oracle Communications Messaging Server 7u4-27.01 (7.0.4.27.0) 64bit (built Aug 30 2012)) with ESMTPSA id <0N3M00E0UDJOGA00@mta.uoks.uj.edu.pl> for freebsd-arm@freebsd.org; Sun, 06 Apr 2014 19:21:25 +0200 (CEST) Received: from [10.10.1.20] by saiph.uoks.uj.edu.pl (Dr.Web (R) milter module ver.6.0.2.2) ; Sun, 06 Apr 2014 19:21:24 +0200 Received: from [10.10.1.20] ([83.19.65.138]) by mta.uoks.uj.edu.pl with ESMTPSA; Sun, 06 Apr 2014 19:21:24 +0200 (CEST) Date: Sun, 06 Apr 2014 19:21:23 +0200 From: Jakub Klama In-reply-to: <3e7f866f4bc774975ae3c85e0df78ec2@uj.edu.pl> Message-id: <53418D13.7030107@freebsd.org> References: <3e7f866f4bc774975ae3c85e0df78ec2@uj.edu.pl> Subject: [RFC] Refactored interrupt handling on ARM To: freebsd-arm@freebsd.org User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 X-Forwarded-Message-Id: <3e7f866f4bc774975ae3c85e0df78ec2@uj.edu.pl> X-Antivirus: Dr.Web (R) for Unix mail servers drweb plugin ver.6.0.2.2 X-Antivirus-Code: 0x100000 X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Apr 2014 17:26:40 -0000 Hello all, It has been a long time since my SoC 2012 ended. However, I've finally merged refactored interrupt handling framework to head and added SMP support (IPIs). Let's start: What is this and how does it work? It's a refactored interrupt handling code for ARM which supports multiple, stacked interrupt controllers. In particular, it creates a clean way to support IRQ multiplexers such as GPIO controllers with interrupt generation functionality. Approach used in this code is somewhat similar to one usedin powerpc port. Every interrupt controller should implement methods from pic_if.m interface - at least pic_config, pic_unmask, pic_mask and pic_eoi. It should also install IRQ handler on parent interrupt controller (specified by interrupt-parent in FDT, defaulting to nexus). The root interrupt controller is nexus - on ARM it has exactly one IRQ line (typically nexus0:0) representing core IRQ signal (on MIPS, there will be probably five of them). SoC interrupt controller, such as GIC then installs handler on nexus0:0 IRQ and exposes itself as interrupt controller by calling arm_register_pic(). When the interrupt arrives, pic driver calls arm_dispatch_irq() function. So, for example, a typical SoC interrupt tree can look like that: nexus0 (provides 1 irq) | \-- gic0 (provides 160 irqs, uses irq nexus0:0) | \-- gpio0 (provides 8 irqs, uses irq gic0:42) | | | \-- mmcsd0 (uses irqs gpio0:1, gpio0:2) | \-- spi0 (uses irq gpio0:3) | ... \-- gpio1 (provides 8 irqs, uses irq gic0:43) \-- ehci0 (uses irq gic0:109) ... Interrupt numbers used in rman are composed of two 8-bit fields: higher 8 bits are the pic index and lower 8 bits are IRQ line number inside particular pic (so there are 256 pics supported with maximum of 256 irq lines on each). These numbers are generated using FDT_MAP_IRQ() macro called from FDT code. As you can see from the provided dmesg logs, irq numbers are printed in form of "pic_name:line_number", i.e: "nexus0:0" or "gic0:109". Of course there's still support for shared interrupt handlers - on LPC3250 there are 3 pics attached to one in-core IRQ line. There's also support for IPIs. Calls to pic_ipi_get(), pic_ipi_clear(), pic_ipi_send() and ..._init_secondary() are redirected to one interrupt controller registered as capable to do IPIs. There can be only one interrupt controller with IPI support registered (and certainly not the root one). Code was tested on following platforms: * EA3250 (arm/lpc) * Pandaboard (arm/ti) (both with SMP enabled and disabled) Merging it would not require any changes in existing ARM ports (unless they will be adopted to new framework and will have ARM_INTRNG option enabled), except for adding arm/arm/intr.c to their file lists (as it's now not compiled-in by default). That was tested too. dmesg outputs can be found there: * http://people.freebsd.org/~jceel/intrng/pandaboard.dmesg.txt * http://people.freebsd.org/~jceel/intrng/ea3250.dmesg.txt diff against head as of r264192: * http://people.freebsd.org/~jceel/intrng/intrng.diff git branch containing the changes: * https://github.com/jceel/freebsd-arm-intrng/tree/intrng What do you think about that? That code probably needs some improvements, especially in IPI/SMP area, but I think it's a step further in interrupt handling on ARM. I really appreciate any comments and opinions. Regards, Jakub