Development in the current LinuxBIOS tree is starting to get
difficult because of the sheer number of backward compatible
interfaces we retain even when better code is introduced
into the tree.
For the 1.1.x development branch leading to the stable
2.0.x series it is my intention remove all of the old interfaces
and put LinuxBIOS back together using the current best of breed
techniques.
- Use the elf bootloader
- Use romcc so we can remove most of the assembly.
- Use the generic pci setup mechanism. It needs a little work
to make initialization as easy as the superio case but it should
work for everything.
- Make hardwaremain architecture independent.
- Native interrupt routing. (We don't have code but...)
- Documented interfaces (I suck at doing this but it needs to happen)...
I am still in the final stages of prototyping the cleanups to hardwaremain.
But my first draft is below.
The function that still needs things worked out is enumerate static
devices. One or two boards need to be ported and the issues worked
out before everything else comes along. The goal is a
hardwaremain() function that does not change.
Once there is a stable port in the 1.1. development branch my goal
is to call that enough development make it the 2.0 branch and any
future disruptive work needs to go on a new development branch. When
the 2.0 branch can continue to accumulate working ports.
To implement this I have started a freebios2 tree at sourceforge
and I will gradually populating this tree. I am taking the expedient
of copying old code over as needed. Leaving old code for now
unneeded functionality to just fade away. It is the only easy
incremental way I can see to make the sweeping changes I want to see
in the LinuxBIOS tree.
I am going to start with the Hammer port and possibly with the p4dpr,
to seed the tree and work out most of the issues with the new
infrastructure. After that it is moving to 2.0 and collecting
additional ports, I suspect.
Eric
void hardwaremain(int boot_complete)
{
/* Processor ID of the BOOT cpu (i.e. the one running this code) */
unsigned long boot_cpu;
int boot_index;
/* the order here is a bit tricky. We don't want to do much of
* anything that uses config registers until after PciAllocateResources
* since that function also figures out what kind of config strategy
* to use (type 1 or type 2).
* so we turn on cache, then worry about PCI setup, then do other
* things, so that the other work can use the PciRead* and PciWrite*
* functions.
*/
struct mem_range *mem, *tmem;
unsigned long totalmem;
// we don't call post code for this one -- since serial post could cause
real
// trouble.
outb(0x38, 0x80);
/* displayinit MUST PRECEDE ALL PRINTK! */
displayinit();
post_code(0x39);
printk_notice("LinuxBIOS-%s%s %s %s...\n",
linuxbios_version, linuxbios_extra_version, linuxbios_build,
(boot_complete)?"rebooting":"booting");
post_code(0x40);
/* If we have already booted attempt a hard reboot */
if (boot_complete) {
hard_reset();
}
// pick how to scan the bus. This is first so we can get at memory size.
printk_info("Finding PCI configuration type.\n");
pci_set_method();
post_code(0x5f);
enumerate_static_devices();
pci_enumerate();
post_code(0x66);
// Now do the real bus
// we round the total ram up a lot for thing like the SISFB, which
// shares high memory with the CPU.
pci_configure();
post_code(0x88);
pci_enable();
pci_initialize();
post_code(0x89);
mem = get_ramsize();
post_code(0x70);
totalmem = 0;
for(tmem = mem; tmem->sizek; tmem++) {
totalmem += tmem->sizek;
}
printk_info("totalram: %ldM\n",
(totalmem + 512) >> 10); /* Round to the nearest meg */
/* Fully initialize the cpu before configuring the bus */
boot_cpu = cpu_initialize(mem);
boot_index = processor_index(boot_cpu);
printk_spew("BOOT CPU is %d\n", boot_cpu);
processor_map[boot_index] = CPU_BOOTPROCESSOR|CPU_ENABLED;
/* Now start the other cpus initializing
* The sooner they start the sooner they stop.
*/
post_code(0x75);
startup_other_cpus(processor_map);
post_code(0x77);
/* make certain we are the only cpu running in linuxBIOS */
wait_for_other_cpus();
/* Now that we have collected all of our information
* write our configuration tables.
*/
write_tables(mem);
elfboot(streams, get_lb_mem());
}