Greg Watson gwatson@lanl.gov writes:
At 12:11 PM -0600 9/10/03, Eric W. Biederman wrote:
Greg Watson gwatson@lanl.gov writes:
Yes, I have a similar problem with the current setup. I need to be able to do
static initialization on entry to hardwaremain, but before console_init(), and also prior to pci enumeration.
The original conception was that such things would happen before hardwaremain was actually called. But regardless.
On the PPC, much of what must be done in assembly or romcc on Intel/AMD, can be done in C in hardwaremain. The architecture needs to be flexible enough to accommodate this.
I concur. And the really weird stuff either needs to happen before we enter hardwaremain or as the first function we call. I have no problem with doing that. But it should be done that way because it is weird motherboard dependent code.
Currently static device initialization can only be done during pci setup which is too late.
Why???
For example, I want to be able to configure the serial port on the superio chip so that console logging will work. This has to happen before console_init() is called. Other things that I want to be able to do that I don't want tied to PCI setup are:
- flash setup
- NVRAM setup
- on-board network interface setup
- SDRAM setup
The order goes something like this:
hardwaremain() { pre_console: superio() console_init() pre_pci: nvram() sdram() flash() pci: pci() usb() ide() pre_boot: fenet() elfboot() }
Ok. If everything is working out of ram I can see modifying things so there is both a hook before console_init, and a hook after it so generic console code can be used. It is possible to define motherboard specific console drivers but proposing that as a solution to your problem is silly.
The ethernet case is not a case I currently understand. I would be highly surprised if something is needed there. My gut feel is a simple init method should be all that is needed. Unless you are doing an ethernet device driver and that is something else again.
In addition, I probably don't want to call cpu_initialize() after PCI setup. I would prefer if the cpu (or cpu's) was treated much the same as any other static device, then I could choose where cpu_init() gets called, which may be in multiple places.
I agree they way we are currently dealing with cpus is problematic, as it does not follow the same model as the rest of the code. There has not yet been much looking given to how to handle them correctly. Doing cpu initialization late has not mattered much because if you can run the code in C generally there are no show stopper cpu bugs or cpu setup that needs to be worried about.
I've started using chip_configure() again to get around this problem, but it means I have to skip the enumerate_static_devices() step or things go to hell.
Why???
Otherwise the chip initialization happens twice: once from the call to chip_configure() and once from dev_initialize(). And it happens at the wrong place.
There are two kinds of devices. Devices that are highly motherboard centric, and no matter what you do will have special rules and generic code cannot cope with them. And then there are devices that are well factored, and can be treated as independent pieces of hardware. The generic device tree is aimed at hardware that is well factored, for the rest we do need a different mechanism.
For a well factored device having it initialized at the wrong place is almost impossible. Except in the rare cases where the devices is needed to bootstrap another say the smbus controller for memory, and in those cases it is the memory or whatever else it is that is not a standalone device.
I can feel that there is pain here. But I cannot see the source. There are two possible solutions. Either the current structure needs redesign or I need to more clearly document and explain the current structure so it can be fully taken advantage of.
The current design is too tied to PCI setup.
I have to vent at this statement. Yes the code was derived from what is needed to setup PCI devices. But no it is not tied to PCI devices, and I believe this view is part of what is limiting this conversation. In particular I see no problem setting up superio I/O devices with this code.
I try and full fill a couple of requirements with the code. 1) Enable code reuse when the hardware is tied together on another board in a different way. 2) Enable flexible resource allocation. 3) If I have multiples of the device allow the code to just work.
For an individual device knowing specifically when it is initialized inspires brittle code.
If I have multiples of the same device the code needs to be able to hand out dynamic resource assignments.
And yes this results in a little bit of duplicate setup for hardware like a serial console that is both a generic piece of code and that must be bootstrapped early.
, doesn't provide any means of doing initialization other than when PCI devices are initialized and doesn't give any control over *when* devices are initialized.
It is assumed the dependencies can be represented in the device tree. If you are higher up in the tree you are initialized first. And of devices in the same level of the device tree the order in the static tree pretty much rules.
chip_configure() allows devices to choose when in the boot sequence they want to perform some action, and allows multiple actions to occur for a single device.
It also provides no structure and it solves none of the hard problems. As for being able to do things in the boot sequence I have 6 methods to your 8. Plenty of opportunity to do weird things if need be.
I guess what I would like to avoid is representing what is essentially a motherboard dependent function call graph in a static device tree instead of just doing it straight forwardly in C.
What I don't see with chip_configure is it promoting any level of code reuse because what the calls do is not well defined. They are called in relationship to other code instead of being called to do something.
I'd be happy if the current scheme could provide this functionality, but I don't see any easy way to do it.
Hmm.
The fundamental problem I see is that Intel/AMD architectures do a lot more initialization prior to hardwaremain, so the functionality that I'm looking for is not really needed.
I agree that the current x86 ports do a substantial amount prior to hardwaremain, and so we don't have a few of your issues. That can easily be rectified.
Once you're in hardwaremain, basically all that's left to do is get PCI going.
Not at all.
This is not the case for PPC (and maybe other architectures.) The question is really: should linuxbios be Intel/AMD specific and required other architecture support grafted on, or should it be made general enough to work with any architecture. I guess I'm suggesting the latter.
I totally agree with the sentiment. And if you don't have very many devices that need their addresses programmed dynamically.
Eric