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()); }