From: Val Henson <hidden> Date: 2002-03-24 19:09:30
On Sun, Mar 24, 2002 at 01:20:48PM +0100, Benjamin Herrenschmidt wrote:
We define a special BI_DEVICE type of bi_rec that represents
a HW device for which the firmware provides some informations. Since
the firmware is free to provide whatever informations it want (that
set is not fully defined), the content of the BI_DEVICE record is itself
a list of bi_recs.
<snip>
The "standard" kernel only define a few BI_DEV_TYPE's (like PCI,
4xx OCP, 8xx OCP). Drivers define attributes they can read from the
BI_DEVICE (4xx ethernet can read a HW eth adress for example).
Board vendors are free to provide additional information in the
BI_DEVICE, and add the ability to the driver (patches welcome) to
make good use of that information ;) (Could be, for example, wiring
of the PHY since it may not use MII, etc...).
What do you think ?
I had an amazing and brilliant insight (which I'm sure everyone else
has already had). :) The kernel just ignores bi_recs it doesn't
understand. Really, you don't need any BI_DEV_TYPE's for non-core
kernel code - just a type that the kernel is guaranteed never to use
for any other bi_rec type.
How about one BI_IGNORE type, and driver writers and firmware authors
can put whatever they feel like inside that bi_rec? The BI_IGNORE
bi_rec can contain whatever you want - more bi_recs, object code,
random data - and it would be the driver and firmware writers'
responsibility to make them match up. I personally think this is an
awful idea, but it would give everyone the freedom they want while
staying within the very nice bi_rec interface. The rest of the
bi_recs, the ones that the core kernel code will interpret, can be
simple, one-dimensional bi_recs. What do you think, Ben?
I really agree with Dan Malek on this - we shouldn't use bi_recs as a
way to reimplement methods of passing information that already exist,
for example, the __setup() functions. It should be a way of passing
information that only a bootloader can know, such as the location of a
ramdisk, or the command line that the user typed into the bootloader.
People who don't agree with this philosophy can shove whatever they
like into the BI_IGNORE record type, and suffer the consequences. :)
-VAL
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2002-03-24 16:46:49
I had an amazing and brilliant insight (which I'm sure everyone else
has already had). :) The kernel just ignores bi_recs it doesn't
understand. Really, you don't need any BI_DEV_TYPE's for non-core
kernel code - just a type that the kernel is guaranteed never to use
for any other bi_rec type.
Of course you want to add whatever additional bi_recs, and among the things
I propose is the definition that the kernel will only use all-lowercase
bi_rec types for it's own use leaving any other combo for other uses.
The point is to pass informations to drivers in a bit cleaner
way than inventing a bi_rec type for each combination of driver
and attribute (expecially if a given board can decline in several
models with, for example, a different number of on-chip eth controllers,
or things like that).
How about one BI_IGNORE type, and driver writers and firmware authors
can put whatever they feel like inside that bi_rec? The BI_IGNORE
bi_rec can contain whatever you want - more bi_recs, object code,
random data - and it would be the driver and firmware writers'
responsibility to make them match up. I personally think this is an
awful idea, but it would give everyone the freedom they want while
staying within the very nice bi_rec interface. The rest of the
bi_recs, the ones that the core kernel code will interpret, can be
simple, one-dimensional bi_recs. What do you think, Ben?
Which means that as soon as you want to add more infos, you will have
to deal with all the pre-bi_rec problems when you own stuffs have to
evolve. (versionning etc...).
Again, for anything not realted to device drivers infos (things like
HW ethernet addresses, PHY IDs, eventually interrupt routing), a whole
bunch of bi_rec types will be left free by the kernel for use by your
proprietary stuff the way you want, so you can pretty much define
whatever you want (or not, it's up to you).
But, I feel it's more convenient for drivers to use this signle-level
BI_DEVICE bi_rec that contains itself bi_recs.
I really agree with Dan Malek on this - we shouldn't use bi_recs as a
way to reimplement methods of passing information that already exist,
for example, the __setup() functions. It should be a way of passing
information that only a bootloader can know, such as the location of a
ramdisk, or the command line that the user typed into the bootloader.
Which is exactly what I'm proposing. Passing generic informations like
CPU core clocks, command line, ramdisk, etc... is done via bi_recs at
the toplevel.
The BI_DEVICE bi_rec's allow to provide other informations that are
also only known by the firmware (most of the time), like eth MAC
address, PHY wiring, or other kind of wiring informations related
to a given rev. of a board, etc... provided that those infos
concern a given driver for a specific device. It's also a convenient
way to provide interrupt routing informations.
People who don't agree with this philosophy can shove whatever they
like into the BI_IGNORE record type, and suffer the consequences. :)
No. A BI_IGNORE makes no sense. A whole class of bi_rec types guaranteed
not to be used by the kernel makes sense. I don't want to fix the kernel
side of the problem just to put back the same problem on my vendor specific
infos (I have various ones; depending on the product, they can have to evolve
especially as I have to maintain different revisions of the produce, and if
possible with the same kernel / firmware). It's always a win when you don't
have to change a line of the kernel code because your HW engineer wired an
interrupt differently. That means I only have to update the tables in
the firmware and not touch the kernel version.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2002-03-24 16:55:46
Yes indeed.
BTW, I just thought of something different: some people want to keep data
stored in bi_recs for later use, after the initialization of the kernel. What
about a new tag to mark data that is to be copied and stored for later use?
Currently, I plan to keep everything. Though if we decide to put some
flag bits in the high part of the size field, we could specify what
to keep and what to strip.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2002-03-24 17:18:03
quoted
BTW, I just thought of something different: some people want to keep data
stored in bi_recs for later use, after the initialization of the
kernel. What
quoted
about a new tag to mark data that is to be copied and stored for later use?
Currently, I plan to keep everything. Though if we decide to put some
flag bits in the high part of the size field, we could specify what
to keep and what to strip.
Ok, rather that hacking flag bits, which I want to avoid, what about
that: we define an optional BI_PERSISTENT tag. Any bi_rec _before_
that tag is lost after __init (typically cmdline, initrd, informations
used in *_setup). Any bi_rec after this tag is kept around. Tyîcally,
this means those bi_recs are copied to separate pages (this will
typically be BI_DEVICE recs). If you want, you can put them before
BI_PERSISTENT and build your drivers in. If you prefer using modules,
you can put your BI_DEVICE entries after it.
An important point about bi_recs is that they shouldn't contain
pointers to other things within bi_recs. They can (and will) be
moved around, so unless explicitely defined (like initrd ptrs),
no pointers in bi_recs.
Again, all of this is just a small superset of the existing mecanism
with a few utiliy functions for kernel code and drivers to locate
bi_rec's by tag, either globally or within another bi_rec (that
is typically BI_DEVICE). The point is that once this is coded, I
expect bd_t & other various facilities used by bootloaders to go
away, or at worst be moved to the wrapper.
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2002-03-24 18:16:46
Alternatively, why not create a whole device tree for this? There already
exists a standard for device trees: IEEE 1275 Open Firmware. Then you
need only
one extra bi_rec tag: BI_OF_TREE.
Well, BI_OF_TREE may exist if we ever decide to move the OF interface
out of the kernel and to the wrapper. Though it's not well suited for
embedded platforms where we really want something as small as possible.
The device-tree has the inconvenient of duplicating a lot of informations
that we don't necessarily need. In most embedded cases, I will only
need about 2 or 3 BI_DEVICE records, those containing only a couple
of informations.
I'm still not completely sure about the BI_DEV_TYPE/BI_DEV_ID mecanism
of retreiving a given BI_DEVICE yet. I have a case here where I want to
use BI_DEVICE to carry informations about the chip select & IRQ on which
a chip is wired on the processor external bus, along with a couple of
flags related to some broken address select on some board revs, I want my
driver to be able to lookup the chip itself, not a "location", so I'm still
thinking about the best way to provide that info. Maybe an additional (and
optional as always BI_DEV_NAME).
That would give us 2 utility routines to be used by drivers to locate
BI_DEVICE bi_recs:
bi_find_device_type(ulong dev_type, void* dev_id, size_t dev_id_size)
bi_find_device_name(const char* name)
The first one compares BI_DEV_TYPE with dev_type, and if dev_id is non
NULL, matches it with the variable sized BI_DEV_ID. The second one
compares BI_DEV_NAME as a C string.
The basic function for finding a bi_rec will be
bi_find(struct bi_rec* where, ulong tag);
"where" will be NULL for a toplevel search, and will point to a bi_rec
returned by one of the 2 bi_find_device routines for looking up an
attribute within a BI_DEVICE.
Any comments ? Should I start putting this together in _2_4_devel or
only 2_5 ?
Ben.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
On Sun, Mar 24, 2002 at 01:20:48PM +0100, Benjamin Herrenschmidt wrote:
quoted
We define a special BI_DEVICE type of bi_rec that represents
a HW device for which the firmware provides some informations. Since
the firmware is free to provide whatever informations it want (that
set is not fully defined), the content of the BI_DEVICE record is itself
a list of bi_recs.
<snip>
quoted
The "standard" kernel only define a few BI_DEV_TYPE's (like PCI,
4xx OCP, 8xx OCP). Drivers define attributes they can read from the
BI_DEVICE (4xx ethernet can read a HW eth adress for example).
Board vendors are free to provide additional information in the
BI_DEVICE, and add the ability to the driver (patches welcome) to
make good use of that information ;) (Could be, for example, wiring
of the PHY since it may not use MII, etc...).
What do you think ?
I had an amazing and brilliant insight (which I'm sure everyone else
has already had). :) The kernel just ignores bi_recs it doesn't
understand. Really, you don't need any BI_DEV_TYPE's for non-core
kernel code - just a type that the kernel is guaranteed never to use
for any other bi_rec type.
Yes indeed.
BTW, I just thought of something different: some people want to keep data
stored in bi_recs for later use, after the initialization of the kernel. What
about a new tag to mark data that is to be copied and stored for later use?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
On Sun, 24 Mar 2002, Benjamin Herrenschmidt wrote:
Which means that as soon as you want to add more infos, you will have
to deal with all the pre-bi_rec problems when you own stuffs have to
evolve. (versionning etc...).
Again, for anything not realted to device drivers infos (things like
HW ethernet addresses, PHY IDs, eventually interrupt routing), a whole
bunch of bi_rec types will be left free by the kernel for use by your
proprietary stuff the way you want, so you can pretty much define
whatever you want (or not, it's up to you).
But, I feel it's more convenient for drivers to use this signle-level
BI_DEVICE bi_rec that contains itself bi_recs.
quoted
I really agree with Dan Malek on this - we shouldn't use bi_recs as a
way to reimplement methods of passing information that already exist,
for example, the __setup() functions. It should be a way of passing
information that only a bootloader can know, such as the location of a
ramdisk, or the command line that the user typed into the bootloader.
Which is exactly what I'm proposing. Passing generic informations like
CPU core clocks, command line, ramdisk, etc... is done via bi_recs at
the toplevel.
The BI_DEVICE bi_rec's allow to provide other informations that are
also only known by the firmware (most of the time), like eth MAC
address, PHY wiring, or other kind of wiring informations related
to a given rev. of a board, etc... provided that those infos
concern a given driver for a specific device. It's also a convenient
way to provide interrupt routing informations.
Alternatively, why not create a whole device tree for this? There already
exists a standard for device trees: IEEE 1275 Open Firmware. Then you need only
one extra bi_rec tag: BI_OF_TREE.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/