/*
- * C Bootstrap code for the LinuxBIOS
+ * C Bootstrap code for the coreboot
*/
-
#include <console/console.h>
-#include <cpu/cpu.h>
-#include <mem.h>
#include <version.h>
-#include <smp/start_stop.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <delay.h>
+#include <stdlib.h>
+#include <reset.h>
#include <boot/tables.h>
-#include <part/sizeram.h>
-#include <device.h>
-#include <pci.h>
-#if 0
-#include <part/mainboard.h>
-#endif
-#if 0
-#include <part/hard_reset.h>
-#endif
-#include <smp/atomic.h>
#include <boot/elf.h>
-
-
-#ifndef CONFIG_MAX_PHYSICAL_CPUS
-#define CONFIG_MAX_PHYSICAL_CPUS CONFIG_MAX_CPUS
+#include <cbfs.h>
+#if CONFIG_HAVE_ACPI_RESUME
+#include <arch/acpi.h>
+#endif
+#if CONFIG_WRITE_HIGH_TABLES
+#include <cbmem.h>
#endif
-/* The processor map.
- * Now that SMP is in linuxbios, and Linux counts on us
- * giving accurate information about processors, we need a map
- * of what processors are out there. This could be a bit mask,
- * but we will be optimistic and hope we someday run on
- * REALLY BIG SMPs. Also we may need more than one bit of
- * info per processor at some point. I hope we don't need
- * anything more complex than an int.
+/**
+ * @brief Main function of the RAM part of coreboot.
+ *
+ * Coreboot is divided into Pre-RAM part and RAM part.
+ *
+ * Device Enumeration:
+ * In the dev_enumerate() phase,
*/
-static unsigned long processor_map[MAX_CPUS];
-
-static struct mem_range *get_ramsize(void)
-{
- struct mem_range *mem = 0;
- if (!mem) {
- mem = sizeram();
- }
- if (!mem) {
- printk_err("No memory size information!\n");
- for(;;);
- }
- return mem;
-}
-
-
-#if SMP == 1
-/* Number of cpus that are currently running in linuxbios */
-static atomic_t active_cpus = ATOMIC_INIT(1);
-
-void secondary_cpu_init(void)
-{
- struct mem_range *mem;
- unsigned long id;
- int index;
-
- atomic_inc(&active_cpus);
- printk_debug(__FUNCTION__ "\n");
- mem = get_ramsize();
- id = cpu_initialize(mem);
- index = processor_index(id);
- printk_debug(__FUNCTION__ " %d/%u\n", index, id);
- processor_map[index] = CPU_ENABLED;
- atomic_dec(&active_cpus);
- stop_cpu(id);
-}
-
-static void wait_for_other_cpus(void)
-{
- int old_active_count, active_count;
- int i;
- old_active_count = 1;
-
- active_count = atomic_read(&active_cpus);
- while(active_count > 1) {
- if (active_count != old_active_count) {
- printk_info("Waiting for %d CPUS to stop\n", active_count);
- old_active_count = active_count;
- }
- active_count = atomic_read(&active_cpus);
- }
- for(i = 0; i < MAX_CPUS; i++) {
- if (!(processor_map[i] & CPU_ENABLED)) {
- printk_err("CPU %d/%u did not initialize!\n",
- i, initial_apicid[i]);
- processor_map[i] = 0;
- mainboard_cpu_fixup(i);
- }
- }
- printk_debug("All AP CPUs stopped\n");
-}
-#else /* SMP */
-#define wait_for_other_cpus() do {} while(0)
-#endif /* SMP */
+void hardwaremain(int boot_complete);
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;
struct lb_memory *lb_mem;
- unsigned long totalmem;
- post_code(0x80);
- /* displayinit MUST PRECEDE ALL PRINTK! */
+ post_code(POST_ENTRY_RAMSTAGE);
+
+ /* console_init() MUST PRECEDE ALL printk()! */
console_init();
-
- 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);
+ post_code(POST_CONSOLE_READY);
+
+ printk(BIOS_NOTICE, "coreboot-%s%s %s %s...\n",
+ coreboot_version, coreboot_extra_version, coreboot_build,
+ (boot_complete)?"rebooting":"booting");
+
+ post_code(POST_CONSOLE_BOOT_MSG);
-#if 0
/* If we have already booted attempt a hard reboot */
if (boot_complete) {
hard_reset();
}
-#endif
-#if 1
-
- // 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);
-#if 0
- enumerate_static_devices();
-#endif
+
+ /* FIXME: Is there a better way to handle this? */
+ init_timer();
+
+ /* Find the devices we don't have hard coded knowledge about. */
dev_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.
+ post_code(POST_DEVICE_ENUMERATION_COMPLETE);
+ /* Now compute and assign the bus resources. */
dev_configure();
- post_code(0x88);
-
+ post_code(POST_DEVICE_CONFIGURATION_COMPLETE);
+ /* Now actually enable devices on the bus */
dev_enable();
+ /* And of course initialize devices on the bus */
dev_initialize();
- post_code(0x89);
-#endif
-
- 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);
+ post_code(POST_DEVICES_ENABLED);
- /* make certain we are the only cpu running in linuxBIOS */
- wait_for_other_cpus();
+#if CONFIG_WRITE_HIGH_TABLES == 1
+ cbmem_initialize();
+#if CONFIG_CONSOLE_CBMEM
+ cbmemc_reinit();
+#endif
+#endif
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ suspend_resume();
+ post_code(0x8a);
+#endif
/* Now that we have collected all of our information
* write our configuration tables.
*/
- lb_mem = write_tables(mem, processor_map);
-
- elfboot(lb_mem);
+ lb_mem = write_tables();
+ cbfs_load_payload(lb_mem, CONFIG_CBFS_PREFIX "/payload");
+ printk(BIOS_ERR, "Boot failed.\n");
}