X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fcbmem.c;h=f800b048668d8501cefdcdbc4bd1572b7ce0db40;hb=e246b31121df3c15022d108390c389f352c40d81;hp=92a848497d84f4d06c0f9de27a170b26ae3ba0f5;hpb=de3206a7bebce99f11e753164cc4d46357bba96a;p=coreboot.git diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c index 92a848497..f800b0486 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 @@ -43,7 +40,25 @@ struct cbmem_entry { } __attribute__((packed)); #ifndef __PRE_RAM__ -struct cbmem_entry *bss_cbmem_toc; +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,14 +79,19 @@ void cbmem_init(u64 baseaddr, u64 size) #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) { @@ -87,7 +107,9 @@ 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); + printk(BIOS_DEBUG, "Re-Initializing CBMEM area to 0x%lx\n", + (unsigned long)baseaddr); + #ifndef __PRE_RAM__ bss_cbmem_toc = cbmem_toc; #endif @@ -99,30 +121,42 @@ void *cbmem_add(u32 id, u64 size) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __PRE_RAM__ - 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 */ @@ -132,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, @@ -155,12 +189,8 @@ void *cbmem_find(u32 id) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __PRE_RAM__ - 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; @@ -172,41 +202,42 @@ void *cbmem_find(u32 id) return (void *)NULL; } -#ifndef __PRE_RAM__ -#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 */ + /* 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; - cbmem_init(high_tables_base, high_tables_size); - } - } else { +#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 __PRE_RAM__ void cbmem_list(void) { struct cbmem_entry *cbmem_toc; int i; -#ifdef __PRE_RAM__ - 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; @@ -214,22 +245,23 @@ 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; + 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