diff --git a/Documentation/arch/x86/index.md b/Documentation/arch/x86/index.md index a30c5e25f8..c7115b46d2 100644 --- a/Documentation/arch/x86/index.md +++ b/Documentation/arch/x86/index.md @@ -26,9 +26,7 @@ In order to add support for x86_64 the following assumptions were made: * A stage can install new page tables in RAM ## Page tables -Page tables are generated by a tool in `util/pgtblgen/pgtblgen`. It writes -the page tables to a file which is then included into the CBFS as file called -`pagetables`. +A `pagetables` cbfs file is generated based on an assembly file. To generate the static page tables it must know the physical address where to place the file. diff --git a/src/cpu/x86/64bit/Makefile.inc b/src/cpu/x86/64bit/Makefile.inc index 721e62044d..1895498111 100644 --- a/src/cpu/x86/64bit/Makefile.inc +++ b/src/cpu/x86/64bit/Makefile.inc @@ -5,3 +5,15 @@ endif romstage-y += mode_switch.S postcar-y += mode_switch.S ramstage-y += mode_switch.S + +# Add --defsym=_start=0 to suppress a linker warning. +$(objcbfs)/pt: $(dir)/pt.S + $(CC_bootblock) $(CFLAGS_bootblock) $(CPPFLAGS_bootblock) -o $@.tmp $< -Wl,--section-start=.rodata=$(CONFIG_ARCH_X86_64_PGTBL_LOC),--defsym=_start=0 + $(OBJCOPY_ramstage) -Obinary -j .rodata $@.tmp $@ + rm $@.tmp + +cbfs-files-y += pagetables +pagetables-file := $(objcbfs)/pt +pagetables-type := raw +pagetables-compression := none +pagetables-COREBOOT-position := $(CONFIG_ARCH_X86_64_PGTBL_LOC) diff --git a/src/cpu/x86/64bit/pt.S b/src/cpu/x86/64bit/pt.S new file mode 100644 index 0000000000..b105528e5e --- /dev/null +++ b/src/cpu/x86/64bit/pt.S @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * For reference see "AMD64 Architecture Programmer's Manual Volume 2", + * Document 24593-Rev. 3.31-July 2019 Chapter 5.3.4 + * + * Page table attributes: WB, User+Supervisor, Present, Writeable, Accessed, Dirty + */ + +.section .rodata +#define _PRES (1ULL << 0) +#define _RW (1ULL << 1) +#define _US (1ULL << 2) +#define _A (1ULL << 5) +#define _D (1ULL << 6) +#define _PS (1ULL << 7) +#define _GEN_DIR(a) (_PRES + _RW + _US + _A + (a)) +#define _GEN_PAGE(a) (_PRES + _RW + _US + _PS + _A + _D + (a)) + +.global PM4LE +.align 32 +PM4LE: +.quad _GEN_DIR(PDPE_table) + +.align 4096 +PDE_tables: /* identity map 2MiB pages */ +.rept 2048 +.quad _GEN_PAGE(0x200000 * ((. - PDE_tables) >> 3)) +.endr + +.align 4096 +PDPE_table: /* Point to PDE */ +.rept 4 +.quad _GEN_DIR(PDE_tables + 4096 * ((. - PDPE_table) >> 3)) +.endr diff --git a/util/pgtblgen/Makefile.inc b/util/pgtblgen/Makefile.inc deleted file mode 100644 index 08fb6209e5..0000000000 --- a/util/pgtblgen/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ -ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_64),y) - -PGTBLGEN:= $(obj)/pgtblgen - -cbfs-files-y += pagetables -pagetables-file := $(obj)/mainboard/$(MAINBOARDDIR)/pagetables -pagetables-type := raw -pagetables-compression := none -pagetables-COREBOOT-position := $(CONFIG_ARCH_X86_64_PGTBL_LOC) - -$(obj)/mainboard/$(MAINBOARDDIR)/pagetables: $(PGTBLGEN) $(obj)/config.h - printf " TOOL Creating page tables\n" - $(PGTBLGEN) -b $(CONFIG_ARCH_X86_64_PGTBL_LOC) -a x86_64 -o $@ - -$(PGTBLGEN): util/pgtblgen/pgtblgen.c - printf " MAKE Creating PGTBLGEN tool\n" - $(HOSTCC) -std=c99 $< -I$(obj) -o $@ - -endif diff --git a/util/pgtblgen/description.md b/util/pgtblgen/description.md deleted file mode 100644 index f2e4763d75..0000000000 --- a/util/pgtblgen/description.md +++ /dev/null @@ -1 +0,0 @@ -Generates page tables based on fixed physical address. `C` diff --git a/util/pgtblgen/pgtblgen.c b/util/pgtblgen/pgtblgen.c deleted file mode 100644 index 7ed98b2825..0000000000 --- a/util/pgtblgen/pgtblgen.c +++ /dev/null @@ -1,158 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void usage(char *argv[]) -{ - printf("usage: %s -b -a -o \n", argv[0]); - printf(" -a\t architecture. Supported: x86_64\n"); - printf(" -b\t base address\n"); - printf(" -o\t the file to write to\n"); - printf(" -h\t show this help text\n"); -} - -/* - * For reference see "AMD64 ArchitectureProgrammer's Manual Volume 2", - * Document 24593-Rev. 3.31-July 2019 Chapter 5.3.4 - * - * Page table attributes: WB, User+Supervisor, Present, Writeable, Accessed, Dirty - */ -#define _PRES (1ULL << 0) -#define _RW (1ULL << 1) -#define _US (1ULL << 2) -#define _A (1ULL << 5) -#define _D (1ULL << 6) -#define _PS (1ULL << 7) -#define _GEN_DIR(a) (_PRES | _RW | _US | _A | (a)) -#define _GEN_PAGE(a) (_PRES | _RW | _US | _PS | _A | _D | (a)) - -/* - * Generate x86_64 page tables. - * The page tables needs to be placed at @base_address, and identity map - * the first @size_gib GiB of physical memory. - */ -static int gen_pgtbl_x86_64(const uint64_t base_address, - const size_t size_gib, - void **out_buf, - size_t *out_size) -{ - uint64_t *entry; - - if (!out_size || !out_buf) - return 1; - - *out_size = (size_gib + 2) * 4096; - *out_buf = malloc(*out_size); - if (!*out_buf) - return 1; - - memset(*out_buf, 0, *out_size); - entry = (uint64_t *)*out_buf; - - /* Generate one PM4LE entry - point to PDPE */ - entry[0] = _GEN_DIR(base_address + 4096); - entry += 512; - - /* PDPE table - point to PDE */ - for (size_t i = 0; i < size_gib; i++) - entry[i] = _GEN_DIR(base_address + 4096 * (i + 2)); - entry += 512; - - /* PDE tables - identity map 2MiB pages */ - for (size_t g = 0; g < size_gib; g++) { - for (size_t i = 0; i < 512; i++) { - uint64_t addr = ((1ULL << (12 + 9)) * i) | ((1ULL << (12 + 9 + 9)) * g); - entry[i] = _GEN_PAGE(addr); - } - entry += 512; - } - - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret = 1; - uint64_t base_address = 0; - char *filename = NULL; - char *arch = NULL; - void *buf = NULL; - size_t buf_size = 0; - int c; - - while ((c = getopt(argc, argv, "ho:a:b:")) != -1) - switch (c) { - case '?': /* falltrough */ - case 'h': - usage(argv); - return 0; - case 'o': - filename = optarg; - break; - case 'a': - arch = optarg; - break; - case 'b': - base_address = strtoull(optarg, NULL, 0); - break; - default: - break; - } - - if (!filename) { - fprintf(stderr, "E: Missing filename.\n"); - goto done; - } - if (!arch) { - fprintf(stderr, "E: Missing architecture.\n"); - goto done; - } else if (strcmp(arch, "x86_64") != 0) { - fprintf(stderr, "E: Unsupported architecture.\n"); - goto done; - } - if (base_address & 4095) { - fprintf(stderr, "E: Base address not 4 KiB aligned\n"); - goto done; - } - - /* FIXME: Identity map 4GiB for now, increase if necessary */ - if (strcmp(arch, "x86_64") == 0) - ret = gen_pgtbl_x86_64(base_address, 4, &buf, &buf_size); - - if (ret) { - fprintf(stderr, "Failed to generate page tables\n"); - goto done; - } - - // write the table - FILE *fd = fopen(filename, "wb"); - if (!fd) { - fprintf(stderr, "%s open failed: %s\n", filename, strerror(errno)); - goto done; - } - - if (fwrite(buf, 1, buf_size, fd) != buf_size) { - fprintf(stderr, "%s write failed: %s\n", filename, strerror(errno)); - fclose(fd); - goto done; - } - - if (fclose(fd)) { - fprintf(stderr, "%s close failed: %s\n", filename, strerror(errno)); - goto done; - } - - ret = 0; -done: - free(buf); - return ret; -}