x86: Prepare configuration tables in dedicated high memory region
authorBin Meng <bmeng.cn@gmail.com>
Wed, 11 May 2016 14:44:59 +0000 (07:44 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Mon, 23 May 2016 07:18:00 +0000 (15:18 +0800)
Currently when CONFIG_SEABIOS is on, U-Boot allocates configuration
tables via normal malloc(). To simplify, use a dedicated memory
region which is reserved on the stack before relocation for this
purpose. Add functions for reserve and malloc.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
arch/x86/Kconfig
arch/x86/include/asm/coreboot_tables.h
arch/x86/include/asm/global_data.h
arch/x86/lib/coreboot_table.c

index 9d0f50216145c7f7030e7a0efcbfcd50778cfc62..2ba36b790cd1fd97fdf5a0f3a2fd1dfae0ab0b54 100644 (file)
@@ -531,6 +531,20 @@ config SEABIOS
 
          Check http://www.seabios.org/SeaBIOS for details.
 
+config HIGH_TABLE_SIZE
+       hex "Size of configuration tables which reside in high memory"
+       default 0x10000
+       depends on SEABIOS
+       help
+         SeaBIOS itself resides in E seg and F seg, where U-Boot puts all
+         configuration tables like PIRQ/MP/ACPI. To avoid conflicts, U-Boot
+         puts a copy of configuration tables in high memory region which
+         is reserved on the stack before relocation. The region size is
+         determined by this option.
+
+         Increse it if the default size does not fit the board's needs.
+         This is most likely due to a large ACPI DSDT table is used.
+
 source "arch/x86/lib/efi/Kconfig"
 
 endmenu
index 15ccf9be6c07e608390ea0b9c40a4077f7ef2b80..e036f744f679b1b9b5c06a7f0457f845b83e445f 100644 (file)
@@ -294,6 +294,25 @@ struct cbmem_entry {
 #define CBMEM_ID_CONSOLE               0x434f4e53
 #define CBMEM_ID_NONE                  0x00000000
 
+/**
+ * high_table_reserve() - reserve configuration table in high memory
+ *
+ * This reserves configuration table in high memory.
+ *
+ * @return:    always 0
+ */
+int high_table_reserve(void);
+
+/**
+ * high_table_malloc() - allocate configuration table in high memory
+ *
+ * This allocates configuration table in high memory.
+ *
+ * @bytes:     size of configuration table to be allocated
+ * @return:    pointer to configuration table in high memory
+ */
+void *high_table_malloc(size_t bytes);
+
 /**
  * write_coreboot_table() - write coreboot table
  *
index 3bc2ac24cf3e6a6f2a7af33a609efad70869d769..7434f779b663d7d6b22782320f9ffa5a136609c8 100644 (file)
@@ -93,6 +93,10 @@ struct arch_global_data {
        char *mrc_output;
        unsigned int mrc_output_len;
        ulong table;                    /* Table pointer from previous loader */
+#ifdef CONFIG_SEABIOS
+       u32 high_table_ptr;
+       u32 high_table_limit;
+#endif
 };
 
 #endif
index cb45a7985754e783be4901e345fd989974e6730f..ceab3cf5e4f1bab37022c4bf520f13eb27d9ac6d 100644 (file)
@@ -9,6 +9,37 @@
 #include <asm/coreboot_tables.h>
 #include <asm/e820.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+int high_table_reserve(void)
+{
+       /* adjust stack pointer to reserve space for configuration tables */
+       gd->arch.high_table_limit = gd->start_addr_sp;
+       gd->start_addr_sp -= CONFIG_HIGH_TABLE_SIZE;
+       gd->arch.high_table_ptr = gd->start_addr_sp;
+
+       /* clear the memory */
+       memset((void *)gd->arch.high_table_ptr, 0, CONFIG_HIGH_TABLE_SIZE);
+
+       gd->start_addr_sp &= ~0xf;
+
+       return 0;
+}
+
+void *high_table_malloc(size_t bytes)
+{
+       u32 new_ptr;
+       void *ptr;
+
+       new_ptr = gd->arch.high_table_ptr + bytes;
+       if (new_ptr >= gd->arch.high_table_limit)
+               return NULL;
+       ptr = (void *)gd->arch.high_table_ptr;
+       gd->arch.high_table_ptr = new_ptr;
+
+       return ptr;
+}
+
 /**
  * cb_table_init() - initialize a coreboot table header
  *