Ron, awesome writeup! Thanks for putting it together so well!
On Thu, Feb 28, 2008 at 10:40:41AM -0800, ron minnich wrote:
> C code
>> These control variables are for very low level details of a given
> image
IMO an image is merely an instance of code. Fairly important
distinction since "image" doesn't say where code in question
came from.
> that should never change, and that should never be visible,
Details belong to components or boards, not images.
> as modifying them is very hard to get right, very easy to get
> wrong, and the right and wrong cases are very hard to distinguish.
Agree.
> A simple example is DRAM timing.
Violently disagree.
> Some boards may have pre-configured DRAM timing.
Exactly. We agree that which RAM is used and that what the PCB layout
looks like are board properties, not component properties.
> As we learned from OLPC, it is very, very hard to get this right
> if DRAMs from multiple vendors are used.
Ouch - people (and Microsoft, Xbox) could have told you before hand. :\
> It is quite easy to create timing that is optimized for one vendor
> that will fail in subtle ways on another vendor -- even if the
> DRAMs are supposed to be identical! Once the right choice is made,
> it should almost never be changed.
Right.
> In general, control variables that are not intended to be changed,
> and which can cause undetectable problems, should remain in C code.
Disagree. Or - well - variables controlling _what_ exactly?
> I am inclined to include Cache As Ram (CAR) settings here. CAR is
> very tricky. It's easy to get it slightly wrong, and not know it. I
> think CAR settings should, once they are right, remain hidden and
> hard to adjust.
>> DRAM timing that is fixed belongs here too.
Code should be used for runtime logic. I have a huge issue of
principle with code being used as data storage when there exists
another good method intended specifically for the purpose.
One example is to make a USB device look like a HID when in fact it
is a UPS, because Windows programming is easier with HIDs or whatever.
Another is a compiler/linker that generates code which doesn't use a
data segment for storage, but the code segment. Static initialized
data is compiled into move instructions that copy data from code at
runtime.
(An exception to this which I think is fine is PIC microcontrollers
which have no data storage, so code is used for lookup tables. There
are surely more exceptions. The point is that there is no option
in PICs.)
> That's not to say we can't make the details of DRAM timing
> available to payloads. The dts can be added to by coreboot, and new
> entries added as coreboot runs. It would be easy to add new entries
> for the DRAM timing as it was set up, such that these variables
> would be visible in the run time dts.
I counter with:
If data is worth having in the device tree after boot and can never
change at runtime - it belongs in the dts file at build time.
It comes down to: I would like to have zero lines of code in mainboard/
One can argue that's too ambitious for v3 but I don't think it is.
v3 is already SO close to achieving this awesome goal:
stuge at n410c ~/co/v3/mainboard/pcengines/alix1c $ ls -l
total 36
-rw-r--r-- 1 stuge stuge 1082 Feb 15 03:02 Kconfig
-rw-r--r-- 1 stuge stuge 1330 Feb 15 03:02 Makefile
-rw-r--r-- 1 stuge stuge 2517 Jan 24 04:14 cmos.layout
-rw-r--r-- 1 stuge stuge 1717 Feb 29 01:16 dts
-rw-r--r-- 1 stuge stuge 4437 Feb 29 01:16 initram.c
-rw-r--r-- 1 stuge stuge 5936 Feb 15 03:02 irq_tables.c
-rw-r--r-- 1 stuge stuge 1641 Feb 15 03:02 stage1.c
stuge at n410c ~/co/v3/mainboard/pcengines/alix1c $
Granted, K8 will be more interesting than Geode in this regard.
> Device Tree Specification (dts)
Oh! I always thought it was Device Tree Source. :)
> - include dts node for the components and set their properties
> correctly for that mainboard
I would like to have RAM components.
> - define the topology of these components, via the node hierarchy
> in the mainboard dts
Yes!
> - define the paths of each component, e.g. a southbridge might have
> path of 0000:0:1.2
RAM might have a path of 0 or 1.
> dts should be used for control variables that are per-mainboard.
Yes! I equate this with specifics of the hardware design. What is
connected where and in cases where it matters also how it is
connected. For example how interrupts are routed to PCI slots, if
those four muxed signals on the sobridge are used for COM2 or SATA
on this board, and the timing compensation constant that is needed
for the particular series resistance to RAM on this board. (for MCs
that have such settings.)
> The dts variables are currently usually static for a given
> mainboard, since they reflect the hardware of the mainboard.
Yep.
> The device tree compiler compiles dts down to C code for use by the
> image. Currently this code is initialized structures and a .h file
> with type definitions.
I agree 100% with you on the dts, but I think your reasoning around
the C code goes against it. :\
> Kconfig should rarely, if ever, be used to set device options that
> belong in the dts; or, set very low level build options such as
> DRAM timing.
It may be tempting to add (invisble) data into Kconfig. This is
presumably because it is simple to create dependencies and easy
to access in code.
That would be a testament to dts not being easy enough to deal with.
I just had another thought; I could probably be convinced that
components don't need a dts. We're currently using dtc as a C
preprocessor and there's not much point. But it doesn't do any
harm either and I do not feel at all strongly about it.
> Makefiles define how an image is built. The makefile structure is
> rarely changed.
> Makefiles should never contain settings for a single mainboard.
> Makefiles contain settings that are global to the system as a
> whole.
System meaning coreboot build system.
//Peter