Greetings,
Thinking about initialization where one device's init is required to make others show up:
In the cases I have seen, any devices that require another device's setup, the new device either has a higher device or function number, or it is on a subordinate bus. The mose common case is the superIO devices which require both southbridge and PnP setup.
Perhaps the best thing is a provision for a function call upon scanning a device. That function would init it far enough to reveal anything behind it and no further. It could then either scan any subordinate busses and dependant devices, or just return and let the scan that found it continue to higher dev/fn numbers.
G'day, sjames
steven james pyro@linuxlabs.com writes:
Greetings,
Thinking about initialization where one device's init is required to make others show up:
In the cases I have seen, any devices that require another device's setup, the new device either has a higher device or function number, or it is on a subordinate bus. The mose common case is the superIO devices which require both southbridge and PnP setup.
Perhaps the best thing is a provision for a function call upon scanning a device. That function would init it far enough to reveal anything behind it and no further. It could then either scan any subordinate busses and dependant devices, or just return and let the scan that found it continue to higher dev/fn numbers.
So the scan_bus function in pch.h should work then, and it seems to be a reasonable match.
Eric
On Mon, 17 Feb 2003, steven james wrote:
In the cases I have seen, any devices that require another device's setup, the new device either has a higher device or function number, or it is on a subordinate bus. The mose common case is the superIO devices which require both southbridge and PnP setup.
Perhaps the best thing is a provision for a function call upon scanning a device. That function would init it far enough to reveal anything behind it and no further. It could then either scan any subordinate busses and dependant devices, or just return and let the scan that found it continue to higher dev/fn numbers.
on some devices (e.g. the acer southbridge) I think it is too late by that point.
ron
Greetings,
I just looked at that code. I see what you mean.
A question there, we are still going to want early serial output. It's ugly, but could special cases like that go into preram init? That does look like a step back to what we have now, but it may be hard to help in corner cases, and would allow for a neat and clean init for most chipsets.
The question is, it thats's done, would the exception become the rule?
G'day, sjames
On Mon, 17 Feb 2003, Ronald G. Minnich wrote:
On Mon, 17 Feb 2003, steven james wrote:
In the cases I have seen, any devices that require another device's setup, the new device either has a higher device or function number, or it is on a subordinate bus. The mose common case is the superIO devices which require both southbridge and PnP setup.
Perhaps the best thing is a provision for a function call upon scanning a device. That function would init it far enough to reveal anything behind it and no further. It could then either scan any subordinate busses and dependant devices, or just return and let the scan that found it continue to higher dev/fn numbers.
on some devices (e.g. the acer southbridge) I think it is too late by that point.
ron
Linuxbios mailing list Linuxbios@clustermatic.org http://www.clustermatic.org/mailman/listinfo/linuxbios
On Tue, 18 Feb 2003, steven james wrote:
A question there, we are still going to want early serial output. It's ugly, but could special cases like that go into preram init? That does look like a step back to what we have now, but it may be hard to help in corner cases, and would allow for a neat and clean init for most chipsets.
yes, but I think the way we do it now is ok. You always need this strange early stuff to get going.
ron
"Ronald G. Minnich" rminnich@lanl.gov writes:
On Tue, 18 Feb 2003, steven james wrote:
A question there, we are still going to want early serial output. It's ugly, but could special cases like that go into preram init? That does look like a step back to what we have now, but it may be hard to help in corner cases, and would allow for a neat and clean init for most chipsets.
yes, but I think the way we do it now is ok. You always need this strange early stuff to get going.
There are and always will be 2 specials cases. - Ram initialization - Console initialization.
Both of those will always need to be handled early in strange special ways.
The goal is to cleanup all of the rest of the code as much as possible. Especially at the point of making the code more reuseable.
Right now I have a larger number of initialization functions being called from mainboard_fixup. Those are the real functions that need to be tackled. The superio model comes close to handling those cases cleanly. The big issue with superio code is that we use one structure for all possible static values, that is silly.
Another issue is irq allocation. Currently if a card is plugged in with a pci bridge on it we have broken pirq, and mptables. So those tables need to be generated a little more dynamically then we do now.
For each device if we have a linked list of structures listing configuration information, we should have a clean model. A linked list may be overkill but it allows fairly generic things like irq routing to be attached, which the device driver does not need to process. An alternative would be to have parallel trees of information.
In addition as this settles out we want to export the entire device tree in the LinuxBIOS table so the OS can do something with it, if it feels like it.
Eric
On 18 Feb 2003, Eric W. Biederman wrote:
Right now I have a larger number of initialization functions being called from mainboard_fixup. Those are the real functions that need to be tackled. The superio model comes close to handling those cases cleanly. The big issue with superio code is that we use one structure for all possible static values, that is silly.
There are two static structures in there, and I think I know which one you mean, but want to clarify.
This one, I assume, is OK
struct superio_control { void (*pre_pci_init)(struct superio *s); void (*init)(struct superio *s); void (*finishup)(struct superio *s); unsigned int defaultport; /* the defaultport. Can be overridden * by commands in config */ // This is the print name for debugging char *name; };
Fairly generic and represents how to attack a superio. Universal to all superios.
This one, I think is the mistake:
struct superio { struct superio_control *super; // the ops for the device. unsigned int port; // if non-zero, overrides the default port // com ports. This is not done as an array (yet). // We think it's easier to set up from python if it is not an array. struct com_ports com1, com2, com3, com4; // DMA, if it exists. struct lpt_ports lpt1, lpt2; /* flags for each device type. Unsigned int. */ // low order bit ALWAYS means enable. Next bit means to enable // LPT is in transition, so we leave this here for the moment. // The winbond chips really stretched the way this works. // so many functions! unsigned int ide, floppy, lpt; unsigned int keyboard, cir, game; unsigned int gpio1, gpio2, gpio3; unsigned int acpi,hwmonitor; };
because all the superios are so different (I never realized how different!) this struct is a mess and we don't want to repeat this for the south and north bridge hardware.
Make sense?
ron
"Ronald G. Minnich" rminnich@lanl.gov writes:
On 18 Feb 2003, Eric W. Biederman wrote:
Right now I have a larger number of initialization functions being called from mainboard_fixup. Those are the real functions that need to be tackled. The superio model comes close to handling those cases cleanly. The big issue with superio code is that we use one structure for all possible static values, that is silly.
There are two static structures in there, and I think I know which one you mean, but want to clarify.
This one, I assume, is OK
struct superio_control { void (*pre_pci_init)(struct superio *s); void (*init)(struct superio *s); void (*finishup)(struct superio *s); unsigned int defaultport; /* the defaultport. Can be overridden * by commands in config */ // This is the print name for debugging char *name; };
Fairly generic and represents how to attack a superio. Universal to all superios.
Right. The one I have for pci is a little different but roughly equivalent.
This one, I think is the mistake:
I would just call it in need of a better abstraction. Not a really a mistake.
struct superio { struct superio_control *super; // the ops for the device. unsigned int port; // if non-zero, overrides the default port // com ports. This is not done as an array (yet). // We think it's easier to set up from python if it is not an array. struct com_ports com1, com2, com3, com4; // DMA, if it exists. struct lpt_ports lpt1, lpt2; /* flags for each device type. Unsigned int. */ // low order bit ALWAYS means enable. Next bit means to enable // LPT is in transition, so we leave this here for the moment. // The winbond chips really stretched the way this works. // so many functions! unsigned int ide, floppy, lpt; unsigned int keyboard, cir, game; unsigned int gpio1, gpio2, gpio3; unsigned int acpi,hwmonitor; };
because all the superios are so different (I never realized how different!) this struct is a mess and we don't want to repeat this for the south and north bridge hardware.
Correct.
Make sense?
Yes.
I am thinking of something like:
struct setup_info { struct setup_info *next; int type; };
struct irq_routing { struct setup_info info; /* Flesh this out... */ };
struct static_resources { struct setup_info info; /* Flesh this out... */ };
struct old_superio { struct setup_info info; struct com_ports com1, com2, com3, com4; struct lpt_ports lpt1,lpt2; unsigned int ide, floppy, lpt; unsigned int keyboard, cir, game; unsigned int gpio1, gpio2, gpio3; unsigned int acpi,hwmonitor; /* Don't use this for real.. */ };
The important characteristics are:
- Any developer can add new structure types and they can be motherboard or device specific
- There is a way for generic code to access configuration settings information about a device.
Eric
Greetings,
Given the many permutations of com lpt, and other devices from (possibly multiple) superios, I wonder if a linked list of single device structs might not be a better abstraction.
I've certainly seen enough cases where various chips provide the same class of device, such as e750[01] where ICH3 provides IDE and Intel puts a Promise IDE-RAID (really just IDE with soft raid in firmware) on the board.
Then there's the SiS630 boards that have an rtl8139 and a disconnected SiS900 ethernet on board.
G'day, sjames
On 18 Feb 2003, Eric W. Biederman wrote:
"Ronald G. Minnich" rminnich@lanl.gov writes:
On 18 Feb 2003, Eric W. Biederman wrote:
Right now I have a larger number of initialization functions being called from mainboard_fixup. Those are the real functions that need to be tackled. The superio model comes close to handling those cases cleanly. The big issue with superio code is that we use one structure for all possible static values, that is silly.
There are two static structures in there, and I think I know which one you mean, but want to clarify.
This one, I assume, is OK
struct superio_control { void (*pre_pci_init)(struct superio *s); void (*init)(struct superio *s); void (*finishup)(struct superio *s); unsigned int defaultport; /* the defaultport. Can be overridden * by commands in config */ // This is the print name for debugging char *name; };
Fairly generic and represents how to attack a superio. Universal to all superios.
Right. The one I have for pci is a little different but roughly equivalent.
This one, I think is the mistake:
I would just call it in need of a better abstraction. Not a really a mistake.
struct superio { struct superio_control *super; // the ops for the device. unsigned int port; // if non-zero, overrides the default port // com ports. This is not done as an array (yet). // We think it's easier to set up from python if it is not an array. struct com_ports com1, com2, com3, com4; // DMA, if it exists. struct lpt_ports lpt1, lpt2; /* flags for each device type. Unsigned int. */ // low order bit ALWAYS means enable. Next bit means to enable // LPT is in transition, so we leave this here for the moment. // The winbond chips really stretched the way this works. // so many functions! unsigned int ide, floppy, lpt; unsigned int keyboard, cir, game; unsigned int gpio1, gpio2, gpio3; unsigned int acpi,hwmonitor; };
because all the superios are so different (I never realized how different!) this struct is a mess and we don't want to repeat this for the south and north bridge hardware.
Correct.
Make sense?
Yes.
I am thinking of something like:
struct setup_info { struct setup_info *next; int type; };
struct irq_routing { struct setup_info info; /* Flesh this out... */ };
struct static_resources { struct setup_info info; /* Flesh this out... */ };
struct old_superio { struct setup_info info; struct com_ports com1, com2, com3, com4; struct lpt_ports lpt1,lpt2; unsigned int ide, floppy, lpt; unsigned int keyboard, cir, game; unsigned int gpio1, gpio2, gpio3; unsigned int acpi,hwmonitor; /* Don't use this for real.. */ };
The important characteristics are:
Any developer can add new structure types and they can be motherboard or device specific
There is a way for generic code to access configuration settings information about a device.
Eric
steven james pyro@linuxlabs.com writes:
Greetings,
Given the many permutations of com lpt, and other devices from (possibly multiple) superios, I wonder if a linked list of single device structs might not be a better abstraction.
I agree. The more I look at the more I like the linked list idea. Being able to have structures for the common things like ide/serial/parallel ports sounds very good.
I've certainly seen enough cases where various chips provide the same class of device, such as e750[01] where ICH3 provides IDE and Intel puts a Promise IDE-RAID (really just IDE with soft raid in firmware) on the board.
Then there's the SiS630 boards that have an rtl8139 and a disconnected SiS900 ethernet on board.
Yep. We have to know which chips are on the board and which ones to enable.
Eric