Home | History | Annotate | Download | only in lib
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2015, Bin Meng <bmeng.cn (at) gmail.com>
      4  */
      5 
      6 #include <common.h>
      7 #include <smbios.h>
      8 #include <asm/sfi.h>
      9 #include <asm/mpspec.h>
     10 #include <asm/tables.h>
     11 #include <asm/acpi_table.h>
     12 #include <asm/coreboot_tables.h>
     13 
     14 /**
     15  * Function prototype to write a specific configuration table
     16  *
     17  * @addr:	start address to write the table
     18  * @return:	end address of the table
     19  */
     20 typedef ulong (*table_write)(ulong addr);
     21 
     22 static table_write table_write_funcs[] = {
     23 #ifdef CONFIG_GENERATE_PIRQ_TABLE
     24 	write_pirq_routing_table,
     25 #endif
     26 #ifdef CONFIG_GENERATE_SFI_TABLE
     27 	write_sfi_table,
     28 #endif
     29 #ifdef CONFIG_GENERATE_MP_TABLE
     30 	write_mp_table,
     31 #endif
     32 #ifdef CONFIG_GENERATE_ACPI_TABLE
     33 	write_acpi_tables,
     34 #endif
     35 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
     36 	write_smbios_table,
     37 #endif
     38 };
     39 
     40 void table_fill_string(char *dest, const char *src, size_t n, char pad)
     41 {
     42 	int start, len;
     43 	int i;
     44 
     45 	strncpy(dest, src, n);
     46 
     47 	/* Fill the remaining bytes with pad */
     48 	len = strlen(src);
     49 	start = len < n ? len : n;
     50 	for (i = start; i < n; i++)
     51 		dest[i] = pad;
     52 }
     53 
     54 void write_tables(void)
     55 {
     56 	u32 rom_table_start = ROM_TABLE_ADDR;
     57 	u32 rom_table_end;
     58 #ifdef CONFIG_SEABIOS
     59 	u32 high_table, table_size;
     60 	struct memory_area cfg_tables[ARRAY_SIZE(table_write_funcs) + 1];
     61 #endif
     62 	int i;
     63 
     64 	for (i = 0; i < ARRAY_SIZE(table_write_funcs); i++) {
     65 		rom_table_end = table_write_funcs[i](rom_table_start);
     66 		rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN);
     67 
     68 #ifdef CONFIG_SEABIOS
     69 		table_size = rom_table_end - rom_table_start;
     70 		high_table = (u32)high_table_malloc(table_size);
     71 		if (high_table) {
     72 			table_write_funcs[i](high_table);
     73 
     74 			cfg_tables[i].start = high_table;
     75 			cfg_tables[i].size = table_size;
     76 		} else {
     77 			printf("%d: no memory for configuration tables\n", i);
     78 		}
     79 #endif
     80 
     81 		rom_table_start = rom_table_end;
     82 	}
     83 
     84 #ifdef CONFIG_SEABIOS
     85 	/* make sure the last item is zero */
     86 	cfg_tables[i].size = 0;
     87 	write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
     88 #endif
     89 }
     90