X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fcbmem.c;h=b09b070d7afe99f8c8f632e9c32bbb021a16affc;hb=be25a4ded0957a0ca31f94d32857f1cb03aa42ff;hp=83779a7ee823cb90cd96e3692cf43120d620d5c5;hpb=a8888bd1d236af51dae1b39a5d7bc9dd8b9b4f2e;p=coreboot.git diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c index 83779a7ee..b09b070d7 100644 --- a/src/lib/cbmem.c +++ b/src/lib/cbmem.c @@ -21,11 +21,8 @@ #include #include #include - -#if 1 -#define debug(x...) printk_debug(x) -#else -#define debug(x...) +#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__) +#include #endif // The CBMEM TOC reserves 512 bytes to keep @@ -35,9 +32,6 @@ #define MAX_CBMEM_ENTRIES 16 #define CBMEM_MAGIC 0x434f5245 -static void *cbmem_base; -static int cbmem_size; - struct cbmem_entry { u32 magic; u32 id; @@ -45,8 +39,26 @@ struct cbmem_entry { u64 size; } __attribute__((packed)); -#ifndef __ROMCC__ -struct cbmem_entry *bss_cbmem_toc; +#ifndef __PRE_RAM__ +static struct cbmem_entry *bss_cbmem_toc; + +struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void) +{ + return bss_cbmem_toc; +} + +void __attribute__((weak)) set_cbmem_toc(struct cbmem_entry * x) +{ + /* do nothing, this should be called by chipset to save TOC in NVRAM */ +} +#else + +struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void) +{ + printk(BIOS_WARNING, "WARNING: you need to define get_cbmem_toc() for your chipset\n"); + return NULL; +} + #endif /** @@ -64,17 +76,22 @@ void cbmem_init(u64 baseaddr, u64 size) struct cbmem_entry *cbmem_toc; cbmem_toc = (struct cbmem_entry *)(unsigned long)baseaddr; -#ifndef __ROMCC__ +#ifndef __PRE_RAM__ bss_cbmem_toc = cbmem_toc; #endif - - debug("Initializing CBMEM area to 0x%llx (%lld bytes)\n", baseaddr, size); + + printk(BIOS_DEBUG, "Initializing CBMEM area to 0x%llx (%lld bytes)\n", + baseaddr, size); if (size < (64 * 1024)) { - debug("Increase CBMEM size!!\n"); + printk(BIOS_DEBUG, "Increase CBMEM size!\n"); for (;;) ; } + /* we don't need to call this in romstage, usefull only from ramstage */ +#ifndef __PRE_RAM__ + set_cbmem_toc((struct cbmem_entry *)(unsigned long)baseaddr); +#endif memset(cbmem_toc, 0, CBMEM_TOC_RESERVED); cbmem_toc[0] = (struct cbmem_entry) { @@ -90,8 +107,10 @@ int cbmem_reinit(u64 baseaddr) struct cbmem_entry *cbmem_toc; cbmem_toc = (struct cbmem_entry *)(unsigned long)baseaddr; - debug("Re-Initializing CBMEM area to 0x%lx\n", (unsigned long)baseaddr); -#ifndef __ROMCC__ + printk(BIOS_DEBUG, "Re-Initializing CBMEM area to 0x%lx\n", + (unsigned long)baseaddr); + +#ifndef __PRE_RAM__ bss_cbmem_toc = cbmem_toc; #endif @@ -102,30 +121,42 @@ void *cbmem_add(u32 id, u64 size) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __ROMCC__ - cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE); -#else - cbmem_toc = bss_cbmem_toc; -#endif - + void *p; + + /* + * This could be a restart, check if the section is there already. It + * is remotely possible that the dram contents persisted over the + * bootloader upgrade AND the same section now needs more room, but + * this is quite a remote possibility and it is ignored here. + */ + p = cbmem_find(id); + if (p) { + printk(BIOS_NOTICE, + "CBMEM section %x: using existing location at %p.\n", + id, p); + return p; + } + + cbmem_toc = get_cbmem_toc(); + if (cbmem_toc == NULL) { return NULL; } if (cbmem_toc[0].magic != CBMEM_MAGIC) { - printk_err("ERROR: CBMEM was not initialized yet.\n"); + printk(BIOS_ERR, "ERROR: CBMEM was not initialized yet.\n"); return NULL; } /* Will the entry fit at all? */ if (size > cbmem_toc[0].size) { - printk_err("ERROR: Not enough memory for table %x\n", id); + printk(BIOS_ERR, "ERROR: Not enough memory for table %x\n", id); return NULL; } /* Align size to 512 byte blocks */ - size = ALIGN(size, 512) < cbmem_toc[0].size ? + size = ALIGN(size, 512) < cbmem_toc[0].size ? ALIGN(size, 512) : cbmem_toc[0].size; /* Now look for the first free/usable TOC entry */ @@ -135,11 +166,11 @@ void *cbmem_add(u32 id, u64 size) } if (i >= MAX_CBMEM_ENTRIES) { - printk_err("ERROR: No more CBMEM entries available.\n"); + printk(BIOS_ERR, "ERROR: No more CBMEM entries available.\n"); return NULL; } - debug("Adding CBMEM entry as no. %d\n", i); + printk(BIOS_DEBUG, "Adding CBMEM entry as no. %d\n", i); cbmem_toc[i] = (struct cbmem_entry) { .magic = CBMEM_MAGIC, @@ -151,19 +182,15 @@ void *cbmem_add(u32 id, u64 size) cbmem_toc[0].base += size; cbmem_toc[0].size -= size; - return (void *)cbmem_toc[i].base; + return (void *)(u32)cbmem_toc[i].base; } void *cbmem_find(u32 id) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __ROMCC__ - cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE); -#else - cbmem_toc = bss_cbmem_toc; -#endif - + cbmem_toc = get_cbmem_toc(); + if (cbmem_toc == NULL) return NULL; @@ -175,41 +202,42 @@ void *cbmem_find(u32 id) return (void *)NULL; } -#ifndef __ROMCC__ -#if CONFIG_HAVE_ACPI_RESUME -extern u8 acpi_slp_type; +#if CONFIG_EARLY_CBMEM_INIT || !defined(__PRE_RAM__) +/* Returns True if it was not intialized before. */ +int cbmem_initialize(void) +{ + int rv = 0; + +#ifdef __PRE_RAM__ + extern unsigned long get_top_of_ram(void); + uint64_t high_tables_base = get_top_of_ram() - HIGH_MEMORY_SIZE; + uint64_t high_tables_size = HIGH_MEMORY_SIZE; #endif -extern uint64_t high_tables_base, high_tables_size; -void cbmem_initialize(void) -{ -#if CONFIG_HAVE_ACPI_RESUME - if (acpi_slp_type == 3) { - if (!cbmem_reinit(high_tables_base)) { - /* Something went wrong, our high memory area got wiped */ - acpi_slp_type == 0; - cbmem_init(high_tables_base, high_tables_size); - } - } else { + /* We expect the romstage to always initialize it. */ + if (!cbmem_reinit(high_tables_base)) { +#if CONFIG_HAVE_ACPI_RESUME && !defined(__PRE_RAM__) + /* Something went wrong, our high memory area got wiped */ + if (acpi_slp_type == 3 || acpi_slp_type == 2) + acpi_slp_type = 0; +#endif cbmem_init(high_tables_base, high_tables_size); + rv = 1; } -#else - cbmem_init(high_tables_base, high_tables_size); -#endif +#ifndef __PRE_RAM__ cbmem_arch_init(); +#endif + return rv; } +#endif -#ifndef __ROMCC__ +#ifndef __PRE_RAM__ void cbmem_list(void) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __ROMCC__ - cbmem_toc = (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE); -#else - cbmem_toc = bss_cbmem_toc; -#endif - + cbmem_toc = get_cbmem_toc(); + if (cbmem_toc == NULL) return; @@ -217,22 +245,24 @@ void cbmem_list(void) if (cbmem_toc[i].magic != CBMEM_MAGIC) continue; - printk_debug("%2d. ", i); + printk(BIOS_DEBUG, "%2d. ", i); switch (cbmem_toc[i].id) { - case CBMEM_ID_FREESPACE: printk_debug("FREE SPACE "); break; - case CBMEM_ID_GDT: printk_debug("GDT "); break; - case CBMEM_ID_ACPI: printk_debug("ACPI "); break; - case CBMEM_ID_CBTABLE: printk_debug("COREBOOT "); break; - case CBMEM_ID_PIRQ: printk_debug("IRQ TABLE "); break; - case CBMEM_ID_MPTABLE: printk_debug("SMP TABLE "); break; - case CBMEM_ID_RESUME: printk_debug("ACPI RESUME"); break; - default: printk_debug("%08x ", cbmem_toc[i].id); + case CBMEM_ID_FREESPACE: printk(BIOS_DEBUG, "FREE SPACE "); break; + case CBMEM_ID_GDT: printk(BIOS_DEBUG, "GDT "); break; + case CBMEM_ID_ACPI: printk(BIOS_DEBUG, "ACPI "); break; + case CBMEM_ID_CBTABLE: printk(BIOS_DEBUG, "COREBOOT "); break; + case CBMEM_ID_PIRQ: printk(BIOS_DEBUG, "IRQ TABLE "); break; + case CBMEM_ID_MPTABLE: printk(BIOS_DEBUG, "SMP TABLE "); break; + case CBMEM_ID_RESUME: printk(BIOS_DEBUG, "ACPI RESUME"); break; + case CBMEM_ID_SMBIOS: printk(BIOS_DEBUG, "SMBIOS "); break; + case CBMEM_ID_TIMESTAMP: printk(BIOS_DEBUG, "TIME STAMP "); break; + case CBMEM_ID_CONSOLE: printk(BIOS_DEBUG, "CONSOLE "); break; + default: printk(BIOS_DEBUG, "%08x ", cbmem_toc[i].id); } - printk_debug("%08llx ", cbmem_toc[i].base); - printk_debug("%08llx\n", cbmem_toc[i].size); + printk(BIOS_DEBUG, "%08llx ", cbmem_toc[i].base); + printk(BIOS_DEBUG, "%08llx\n", cbmem_toc[i].size); } } #endif -#endif