From owner-freebsd-arch@FreeBSD.ORG Wed Jul 9 10:31:48 2014 Return-Path: Delivered-To: arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 144C0F34; Wed, 9 Jul 2014 10:31:48 +0000 (UTC) Received: from mail110.syd.optusnet.com.au (mail110.syd.optusnet.com.au [211.29.132.97]) by mx1.freebsd.org (Postfix) with ESMTP id B47902BCC; Wed, 9 Jul 2014 10:31:46 +0000 (UTC) Received: from c122-106-147-133.carlnfd1.nsw.optusnet.com.au (c122-106-147-133.carlnfd1.nsw.optusnet.com.au [122.106.147.133]) by mail110.syd.optusnet.com.au (Postfix) with ESMTPS id D49DD784578; Wed, 9 Jul 2014 20:08:54 +1000 (EST) Date: Wed, 9 Jul 2014 20:08:52 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Don Lewis Subject: Re: [patch] axe RF_TIMESHARE? In-Reply-To: <201407082254.s68MsaPS028312@gw.catspoiler.org> Message-ID: <20140709200848.Q1201@besplex.bde.org> References: <201407082254.s68MsaPS028312@gw.catspoiler.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=QIpRGG7L c=1 sm=1 tr=0 a=7NqvjVvQucbO2RlWB8PEog==:117 a=PO7r1zJSAAAA:8 a=IvhbSYBuX7IA:10 a=kj9zAlcOel0A:10 a=JzwRw_2MAAAA:8 a=6I5d2MoRAAAA:8 a=23CMgkCoh3DYdGOiiSMA:9 a=Vik_ctyhMKAFVRZW:21 a=NjSdpzuRAPzGTONZ:21 a=CjuIK1q_8ugA:10 a=SV7veod9ZcQA:10 Cc: arch@freebsd.org, adrian@freebsd.org X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Jul 2014 10:31:48 -0000 yOn Tue, 8 Jul 2014, Don Lewis wrote: > On 6 Jul, Adrian Chadd wrote: >> On 6 July 2014 17:47, Don Lewis wrote: >>> On 6 Jul, Adrian Chadd wrote: >>>> Hi, >>>> >>>> What's it supposed to be used for? >>> >>> My understanding it that it is supposed to be used to allow two more >>> devices to claim the same resource, such as an I/O port range, but only >>> one device can be active at a time. >> >> Interesting. I wonder what kinds of things would want to do this. > > Not much of anything that I can think of, which is probably why this > feature was never used. The closest thing that I can think of is ISA, > as Garrett mentioned. The thing that came to mind for me when I started > looking at this is ISA attached COM ports. COM1 and COM3 both want to > use IRQ 4, and COM2 and COM4 both want to use IRQ 3. The problem is > that ISA IRQs can't be shared between slots, so it might be nice if > RF_TIMESHARE could be used to share IRQ 3 between a modem card > configured as COM4 and the COM2 serial port and then let the user pick > the device to enable through software. Unfortunately this won't work > because 16550-compatible UARTs don't have a way of disabling their IRQ > pin drivers, so this has to be done with jumpers ... No, xx50-compatible UARTs have precisely such a way of disabling their IRQ pin drivers. It is the the OUT2 pin in the modem control register. This is a general purpose pin, but in compatible systems it used to gate the IRQ pin. Its name is misspelled MCR_IENABLE in sio and MCR_IE in uart (this hard-codes its special connection in its very name, as would be correct if this were hard-wired in the xx50 itself. It probably is actually hard-wired in ASICs implementing xx50's). Correct initialization of the OUT2 pin is difficult, and is not done except in old versions of sio, only on some configurations. It is necessary to turn off the OUT2 pin for all devices that might be driving an interrupt before trying to use the interrupt. For this, it is first necessary to know all these devices. Then become the owner or otherwise lock all the devices. Then turn off OUT2 on all except the one where interrupts will be used. Then keep owning all the others so as to keep OUT2 off on them. This is needed for warm boots from another OS that used the interrupts in a different way. Sharing always worked in Linux, so rebooting while Linux is using COM3 with IRQ4 to FreeBSD configured to only use COM1 with IRQ4 will do it. At least old BIOSes don't initialize all COM ports in all cases after a warm boot, perhaps because they have the same problem as FreeBSD with knowing the complete list. Cold boots always work right for unknown xx50 devices, since the hardware reset resets the device to a known good statet. The working versions depended on config(8) being used to configure the complete lists (except it had some internal hard-coded lists, especially for the COM_ESP case). This was broken by unapproved commits for new-bus. New-bus makes it harder for drivers to hack on the lists directly, and the direct hacking on the lists just broke. New-bus doesn't provide the multiple stages of probe/attach needed to do this AFAIK. and provides even less control over the ordering than old bus. Probe shouldn't write or gain ownership of anything. That means no writing to OUT2 for even the device being probed at probe time, and no owning the device from probe to attach so as to keep OUT2 off. So the drive should claim all the devices it can without checking if their interrupts work. Then attach all devices it can, and turn off their OUT2's but still not check if interrupts work. Finally, enable interrupts for just one, provided it has been determined that enough have been claimed. The final step could be done by a second attach pass or just when devices are first really used. The latter goes well with switching on OUT2 only for one being used -- turn off OUT2 on last close and let first open gain control of the interrupt. Device interrupts can be left on for opens that _don't_ gain control of the interrupt (these interrupts are gated off by OUT2), but of i/o to actually work on these opens polled mode must be used. RF_TIMESHARE doesn't simplify this significantly. Ownership of the interrupt should be claimed somewhere so that the interrupt resource is available at first open time. That can probably be done using a super-device or some hack to own the interrupt by the first device that can share it. Then you don't need a flag for it. It seems too hard (bloated) to generalize RF_TIMESHARE so that all of the OUT2 complications can be handled at the new-bus level. Bruce