Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Dec 2003 15:15:44 -0800 (PST)
From:      Nate Lawson <nate@root.org>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        arch@freebsd.org
Subject:   RE: Common device driver classes?
Message-ID:  <20031211145311.Q51054@root.org>
In-Reply-To: <XFMail.20031211164407.jhb@FreeBSD.org>
References:  <XFMail.20031211164407.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 11 Dec 2003, John Baldwin wrote:
> On 11-Dec-2003 Nate Lawson wrote:
> > I'm in the middle of implementing various drivers and all of them have the
> > same problem.  I want to have a generic set of functionality that is
> > provided in various hardware specific ways.  The two drivers I'm working
> > on are a cpu freq driver (hw-specific drivers: speedstep, longrun, acpi
> > px, amd64) and a laptop buttons/control driver (hw-specific drivers:
> > toshiba, asus, apm).
> >
> > Let's take clock frequency manipulation as an example.  There might be a
> > sysctl like "hw.cpu.0.freq" that can be set to change the clock frequency.
> > The actual transition would be handled by a hardware-specific driver that
> > would program the right registers for SpeedStep, for instance.
> >
> > The various drivers would also need to set priorities for how they attach.
> > For instance, certain drivers may implement subsets of other drivers'
> > functionality.  If so, the attach routine would return -100 for the simple
> > drivers and 0 for the full-featured ones.  If one driver returns -100 and
> > another returns 0, the sysctl function handler should point to the second
> > driver and the first should not be called since it has been superseded.
> >
> > Since this sounds like newbus, here's an example how this might work:
> >
> >     cpubusXXX
> >         cpu0
> >             cpufreq (speedstep) - hw.cpu.0.freq
> >         cpu1
> >             cpufreq (acpi performance states) - hw.cpu.1.freq
> >
> > Note that cpu0 might also support ACPI performance states but speedstep is
> > a more accurate driver for the given hardware.  The user could change the
> > frequency for each CPU through a generic sysctl without knowing the
> > underlying technology used to make the transition.
>
> Yes, you will need some sort of bus layer.  It shouldn't be impossible
> to do.  You could have a cpubus that hangs off of root0 (stick it in
> kern/subr_smp.c maybe) and then each MD arch could provide a CPU driver
> in mp_machdep.c that has an identify routine that adds cpu objects for
> each CPU in system to cpubus.  Either that or you could drop cpubus
> altogether, and just have cpuX hang directly off of root0, or off of
> something like nexus0 if that's what you want to do.  I can do a sample
> implementation for i386 that creates cpu drivers and hangs them off of
> nexus0 for i386 if you would like.

Thanks, that would be nice if you can do that in p4.  I agree there's no
need to have a cpubus.  It would be good to be able to get a pointer to
the pcpu data via an ivar in cpu0.  Also, it would be good for acpi_cpu0
to set the acpi_handle ivar for its associated cpu0 object.  That would
make it possible for the cpufreq driver in its probe routine to pull out
the acpi_handle for the associated \_PR.CPU0 object and check it for _PSS
methods, for instance.  Hmm, this part needs some more thought.

This leaves my second question, which is how to make multiple hw-dependent
drivers that implement the same interface (sysctls) such that if one
probes ok, others of the same "type" don't attach.  For instance, there
are multiple ways to control the Centrino -- both SpeedStep and ACPI
performance states.  However, if the speedstep driver has attached, it
should supersede the ACPI driver since it offers more hw-aware control.
So each CPU should have exactly one cpufreq driver attached and the one
that provides the best control.  Warner suggested making a bus driver for
cpufreq that attaches to the "winner" of the probe and provides the
generic interface like this:

   cpu0
      speedset-cpufreq0
         cpufreq0
   cpu1
      acpi-cpufreq0
         cpufreq1

Is that how miibus works?  Is that an appropriate approach here?  One
issue is that other systems in the kernel will need a generic way to
control the cpu.  For instance, passive cooling by acpi_thermal needs to
be able to use the cpufreq0 interface (through devclass_get_device) to
find what clock rates are available and adjust the clock rate without
caring about the underlying hardware.  Advice on the above approach is
welcome.

-Nate



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031211145311.Q51054>