diff options
Diffstat (limited to 'arch/x86')
32 files changed, 509 insertions, 250 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 006a59d6fa6..dc9483ad723 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -30,7 +30,7 @@ config X86_RUN_32BIT arch_phys_memset() can be used for basic access to other memory. config X86_RUN_64BIT - bool "64-bit" + bool "32-bit SPL followed by 64-bit U-Boot" select X86_64 select SPL if !EFI_APP select SPL_SEPARATE_BSS if !EFI_APP @@ -40,6 +40,14 @@ config X86_RUN_64BIT runs through the 16-bit and 32-bit init, then switches to 64-bit mode and jumps to U-Boot proper. +config X86_RUN_64BIT_NO_SPL + bool "64-bit" + select X86_64 + help + Build U-Boot as a 64-bit binary without SPL. As U-Boot enters + in 64-bit mode, the assumption is that the silicon is fully + initialized (MP, page tables, etc.). + endchoice config X86_64 diff --git a/arch/x86/cpu/apollolake/hostbridge.c b/arch/x86/cpu/apollolake/hostbridge.c index 039236df02d..284f16cfd91 100644 --- a/arch/x86/cpu/apollolake/hostbridge.c +++ b/arch/x86/cpu/apollolake/hostbridge.c @@ -298,7 +298,7 @@ static int apl_acpi_hb_write_tables(const struct udevice *dev, /* (Re)calculate length and checksum */ header->length = ctx->current - (void *)dmar; - header->checksum = table_compute_checksum((void *)dmar, header->length); + acpi_update_checksum(header); acpi_align(ctx); acpi_add_table(ctx, dmar); diff --git a/arch/x86/cpu/coreboot/Kconfig b/arch/x86/cpu/coreboot/Kconfig index 085302c0482..66f25533b97 100644 --- a/arch/x86/cpu/coreboot/Kconfig +++ b/arch/x86/cpu/coreboot/Kconfig @@ -26,7 +26,7 @@ config SYS_COREBOOT imply CBMEM_CONSOLE imply X86_TSC_READ_BASE imply USE_PREBOOT - select BINMAN if X86_64 + select BINMAN if X86_RUN_64BIT select SYSINFO imply SYSINFO_EXTRA diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c index fa7430b436f..d0719d1a405 100644 --- a/arch/x86/cpu/coreboot/coreboot.c +++ b/arch/x86/cpu/coreboot/coreboot.c @@ -22,7 +22,7 @@ int arch_cpu_init(void) { int ret; - ret = IS_ENABLED(CONFIG_X86_RUN_64BIT) ? x86_cpu_reinit_f() : + ret = IS_ENABLED(CONFIG_X86_64) ? x86_cpu_reinit_f() : x86_cpu_init_f(); if (ret) return ret; diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index a8b21406ac0..c373b14df30 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -364,3 +364,27 @@ long locate_coreboot_table(void) return addr; } + +static bool has_cpuid(void) +{ + return flag_is_changeable_p(X86_EFLAGS_ID); +} + +static uint cpu_cpuid_extended_level(void) +{ + return cpuid_eax(0x80000000); +} + +int cpu_phys_address_size(void) +{ + if (!has_cpuid()) + return 32; + + if (cpu_cpuid_extended_level() >= 0x80000008) + return cpuid_eax(0x80000008) & 0xff; + + if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36)) + return 36; + + return 32; +} diff --git a/arch/x86/cpu/i386/call64.S b/arch/x86/cpu/i386/call64.S index d81bcc6f8f4..a9d3f16a6ad 100644 --- a/arch/x86/cpu/i386/call64.S +++ b/arch/x86/cpu/i386/call64.S @@ -7,10 +7,11 @@ */ #include <asm/msr-index.h> +#include <asm/processor.h> #include <asm/processor-flags.h> .code32 -.section .text_call64 +.section .text_call64, "ax" .globl cpu_call64 cpu_call64: /* @@ -21,17 +22,19 @@ cpu_call64: * ecx - target */ cli + pushl $0 /* top 64-bits of target */ push %ecx /* arg2 = target */ push %edx /* arg1 = setup_base */ mov %eax, %ebx - /* Load new GDT with the 64bit segments using 32bit descriptor */ - leal gdt, %eax - movl %eax, gdt+2 - lgdt gdt + # disable paging + movl %cr0, %eax + andl $~X86_CR0_PG, %eax + movl %eax, %cr0 /* Enable PAE mode */ - movl $(X86_CR4_PAE), %eax + movl %cr4, %eax + orl $X86_CR4_PAE, %eax movl %eax, %cr4 /* Enable the boot page tables */ @@ -44,12 +47,6 @@ cpu_call64: btsl $_EFER_LME, %eax wrmsr - /* After gdt is loaded */ - xorl %eax, %eax - lldt %ax - movl $0x20, %eax - ltr %ax - /* * Setup for the jump to 64bit mode * @@ -62,22 +59,18 @@ cpu_call64: */ pop %esi /* setup_base */ - pushl $0x10 - leal lret_target, %eax - pushl %eax - /* Enter paged protected Mode, activating Long Mode */ - movl $(X86_CR0_PG | X86_CR0_PE), %eax + movl %cr0, %eax + orl $X86_CR0_PG, %eax movl %eax, %cr0 /* Jump from 32bit compatibility mode into 64bit mode. */ - lret + ljmp $(X86_GDT_ENTRY_64BIT_CS * X86_GDT_ENTRY_SIZE), $lret_target -code64: +.code64 lret_target: - pop %eax /* target */ - mov %eax, %eax /* Clear bits 63:32 */ - jmp *%eax /* Jump to the 64-bit target */ + pop %rax /* target */ + jmp *%rax /* Jump to the 64-bit target */ .globl call64_stub_size call64_stub_size: diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index a51a24498a7..ee6dbeb5c48 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -35,10 +35,6 @@ DECLARE_GLOBAL_DATA_PTR; -#define CPUID_FEATURE_PAE BIT(6) -#define CPUID_FEATURE_PSE36 BIT(17) -#define CPUID_FEAURE_HTT BIT(28) - /* * Constructor for a conventional segment GDT (or LDT) entry * This is a macro so it can be used in initialisers @@ -160,6 +156,9 @@ void arch_setup_gd(gd_t *new_gd) gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_CS] = GDT_ENTRY(0x809b, 0, 0xfffff); gdt_addr[X86_GDT_ENTRY_16BIT_FLAT_DS] = GDT_ENTRY(0x8093, 0, 0xfffff); + gdt_addr[X86_GDT_ENTRY_64BIT_CS] = GDT_ENTRY(0xaf9b, 0, 0xfffff); + gdt_addr[X86_GDT_ENTRY_64BIT_TS1] = GDT_ENTRY(0x8980, 0, 0xfffff); + gdt_addr[X86_GDT_ENTRY_64BIT_TS2] = 0; load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES); load_ds(X86_GDT_ENTRY_32BIT_DS); @@ -409,25 +408,6 @@ static void setup_identity(void) } } -static uint cpu_cpuid_extended_level(void) -{ - return cpuid_eax(0x80000000); -} - -int cpu_phys_address_size(void) -{ - if (!has_cpuid()) - return 32; - - if (cpu_cpuid_extended_level() >= 0x80000008) - return cpuid_eax(0x80000008) & 0xff; - - if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36)) - return 36; - - return 32; -} - static void setup_mtrr(void) { u64 mtrr_cap; @@ -589,6 +569,13 @@ int cpu_has_64bit(void) #define PAGETABLE_BASE 0x80000 #define PAGETABLE_SIZE (6 * 4096) +#define _PRES BIT(0) /* present */ +#define _RW BIT(1) /* write allowed */ +#define _US BIT(2) /* user-access allowed */ +#define _A BIT(5) /* has been accessed */ +#define _DT BIT(6) /* has been written to */ +#define _PS BIT(7) /* indicates 2MB page size here */ + /** * build_pagetable() - build a flat 4GiB page table structure for 64-bti mode * @@ -601,15 +588,17 @@ static void build_pagetable(uint32_t *pgtable) memset(pgtable, '\0', PAGETABLE_SIZE); /* Level 4 needs a single entry */ - pgtable[0] = (ulong)&pgtable[1024] + 7; + pgtable[0] = (ulong)&pgtable[1024] + _PRES + _RW + _US + _A; /* Level 3 has one 64-bit entry for each GiB of memory */ for (i = 0; i < 4; i++) - pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + 7; + pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + + _PRES + _RW + _US + _A; /* Level 2 has 2048 64-bit entries, each repesenting 2MiB */ for (i = 0; i < 2048; i++) - pgtable[2048 + i * 2] = 0x183 + (i << 21UL); + pgtable[2048 + i * 2] = _PRES + _RW + _US + _PS + _A + _DT + + (i << 21UL); } int cpu_jump_to_64bit(ulong setup_base, ulong target) diff --git a/arch/x86/cpu/mtrr.c b/arch/x86/cpu/mtrr.c index 07ea89162de..7a0f00b9b8f 100644 --- a/arch/x86/cpu/mtrr.c +++ b/arch/x86/cpu/mtrr.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2014 Google, Inc + * Portions added from coreboot * * Memory Type Range Regsters - these are used to tell the CPU whether * memory is cacheable and if so the cache write mode to use. @@ -16,6 +17,7 @@ * since the MTRR registers are sometimes in flux. */ +#include <cpu.h> #include <cpu_func.h> #include <log.h> #include <sort.h> @@ -39,6 +41,27 @@ static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = { "Back", }; +u64 mtrr_to_size(u64 mask) +{ + u64 size; + + size = ~mask & ((1ULL << cpu_phys_address_size()) - 1); + size |= (1 << 12) - 1; + size += 1; + + return size; +} + +u64 mtrr_to_mask(u64 size) +{ + u64 mask; + + mask = ~(size - 1); + mask &= (1ull << cpu_phys_address_size()) - 1; + + return mask; +} + /* Prepare to adjust MTRRs */ void mtrr_open(struct mtrr_state *state, bool do_caches) { @@ -68,11 +91,9 @@ void mtrr_close(struct mtrr_state *state, bool do_caches) static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size) { - u64 mask; + u64 mask = mtrr_to_mask(size); wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type); - mask = ~(size - 1); - mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1; wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID); } @@ -184,30 +205,80 @@ int mtrr_commit(bool do_caches) return 0; } -int mtrr_add_request(int type, uint64_t start, uint64_t size) +/* fms: find most significant bit set (from Linux) */ +static inline uint fms(uint val) +{ + uint ret; + + __asm__("bsrl %1,%0\n\t" + "jnz 1f\n\t" + "movl $0,%0\n" + "1:" : "=r" (ret) : "mr" (val)); + + return ret; +} + +/* + * fms64: find most significant bit set in a 64-bit word + * As samples, fms64(0x0) = 0; fms64(0x4400) = 14; + * fms64(0x40400000000) = 42. + */ +static uint fms64(uint64_t val) +{ + u32 hi = (u32)(val >> 32); + + if (!hi) + return fms((u32)val); + + return fms(hi) + 32; +} + +int mtrr_add_request(int type, u64 base, uint64_t size) { struct mtrr_request *req; - uint64_t mask; + u64 mask; debug("%s: count=%d\n", __func__, gd->arch.mtrr_req_count); if (!gd->arch.has_mtrr) return -ENOSYS; - if (!is_power_of_2(size)) - return -EINVAL; - - if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS) - return -ENOSPC; - req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++]; - req->type = type; - req->start = start; - req->size = size; - debug("%d: type=%d, %08llx %08llx\n", gd->arch.mtrr_req_count - 1, - req->type, req->start, req->size); - mask = ~(req->size - 1); - mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1; - mask |= MTRR_PHYS_MASK_VALID; - debug(" %016llx %016llx\n", req->start | req->type, mask); + while (size) { + uint addr_lsb; + uint size_msb; + u64 mtrr_size; + + addr_lsb = fls64(base); + size_msb = fms64(size); + + /* + * All MTRR entries need to have their base aligned to the + * mask size. The maximum size is calculated by a function of + * the min base bit set and maximum size bit set. + * Algorithm is from coreboot + */ + if (!addr_lsb || addr_lsb > size_msb) + mtrr_size = 1ull << size_msb; + else + mtrr_size = 1ull << addr_lsb; + log_debug("addr_lsb %x size_msb %x mtrr_size %llx\n", + addr_lsb, size_msb, mtrr_size); + + if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS) + return -ENOSPC; + req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++]; + req->type = type; + req->start = base; + req->size = mtrr_size; + log_debug("%d: type=%d, %08llx %08llx ", + gd->arch.mtrr_req_count - 1, req->type, req->start, + req->size); + mask = mtrr_to_mask(req->size); + mask |= MTRR_PHYS_MASK_VALID; + log_debug(" %016llx %016llx\n", req->start | req->type, mask); + + size -= mtrr_size; + base += mtrr_size; + } return 0; } @@ -360,9 +431,7 @@ int mtrr_list(int reg_count, int cpu_select) base = info.mtrr[i].base; mask = info.mtrr[i].mask; - size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1); - size |= (1 << 12) - 1; - size += 1; + size = mtrr_to_size(mask); valid = mask & MTRR_PHYS_MASK_VALID; type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK]; printf("%d %-5s %-12s %016llx %016llx %016llx\n", i, diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c index 62a301c0fd3..ba3638e6acc 100644 --- a/arch/x86/cpu/qemu/dram.c +++ b/arch/x86/cpu/qemu/dram.c @@ -4,7 +4,9 @@ */ #include <init.h> +#include <spl.h> #include <asm/global_data.h> +#include <asm/mtrr.h> #include <asm/post.h> #include <asm/arch/qemu.h> #include <linux/sizes.h> @@ -44,6 +46,22 @@ int dram_init(void) gd->ram_size += qemu_get_high_memory_size(); post_code(POST_DRAM); + if (xpl_phase() == PHASE_BOARD_F) { + u64 total = gd->ram_size; + int ret; + + if (total > SZ_2G + SZ_1G) + total += SZ_1G; + ret = mtrr_add_request(MTRR_TYPE_WRBACK, 0, total); + if (ret != -ENOSYS) { + if (ret) + return log_msg_ret("mta", ret); + ret = mtrr_commit(false); + if (ret) + return log_msg_ret("mtc", ret); + } + } + return 0; } diff --git a/arch/x86/cpu/qemu/e820.c b/arch/x86/cpu/qemu/e820.c index 17a04f86479..078d1d86b02 100644 --- a/arch/x86/cpu/qemu/e820.c +++ b/arch/x86/cpu/qemu/e820.c @@ -6,6 +6,7 @@ * (C) Copyright 2019 Bin Meng <bmeng.cn@gmail.com> */ +#include <bloblist.h> #include <env_internal.h> #include <malloc.h> #include <asm/e820.h> @@ -19,51 +20,34 @@ unsigned int install_e820_map(unsigned int max_entries, struct e820_entry *entries) { u64 high_mem_size; - int n = 0; + struct e820_ctx ctx; - entries[n].addr = 0; - entries[n].size = ISA_START_ADDRESS; - entries[n].type = E820_RAM; - n++; + e820_init(&ctx, entries, max_entries); - entries[n].addr = ISA_START_ADDRESS; - entries[n].size = ISA_END_ADDRESS - ISA_START_ADDRESS; - entries[n].type = E820_RESERVED; - n++; + e820_next(&ctx, E820_RAM, ISA_START_ADDRESS); + e820_next(&ctx, E820_RESERVED, ISA_END_ADDRESS); /* - * since we use memalign(malloc) to allocate high memory for - * storing ACPI tables, we need to reserve them in e820 tables, - * otherwise kernel will reclaim them and data will be corrupted + * if we use bloblist to allocate high memory for storing ACPI tables, + * we need to reserve that region in e820 tables, otherwise the kernel + * will reclaim them and data will be corrupted. The ACPI tables may not + * have been written yet, so use the whole bloblist size */ - entries[n].addr = ISA_END_ADDRESS; - entries[n].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS; - entries[n].type = E820_RAM; - n++; - - /* for simplicity, reserve entire malloc space */ - entries[n].addr = gd->relocaddr - TOTAL_MALLOC_LEN; - entries[n].size = TOTAL_MALLOC_LEN; - entries[n].type = E820_RESERVED; - n++; - - entries[n].addr = gd->relocaddr; - entries[n].size = qemu_get_low_memory_size() - gd->relocaddr; - entries[n].type = E820_RESERVED; - n++; - - entries[n].addr = CONFIG_PCIE_ECAM_BASE; - entries[n].size = CONFIG_PCIE_ECAM_SIZE; - entries[n].type = E820_RESERVED; - n++; + if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) { + e820_to_addr(&ctx, E820_RAM, (ulong)gd->bloblist); + e820_next(&ctx, E820_ACPI, bloblist_get_total_size()); + } else { + /* If using memalign() reserve that whole region instead */ + e820_to_addr(&ctx, E820_RAM, gd->relocaddr - TOTAL_MALLOC_LEN); + e820_next(&ctx, E820_ACPI, TOTAL_MALLOC_LEN); + } + e820_to_addr(&ctx, E820_RAM, qemu_get_low_memory_size()); + e820_add(&ctx, E820_RESERVED, CONFIG_PCIE_ECAM_BASE, + CONFIG_PCIE_ECAM_SIZE); high_mem_size = qemu_get_high_memory_size(); - if (high_mem_size) { - entries[n].addr = SZ_4G; - entries[n].size = high_mem_size; - entries[n].type = E820_RAM; - n++; - } + if (high_mem_size) + e820_add(&ctx, E820_RAM, SZ_4G, high_mem_size); - return n; + return e820_finish(&ctx); } diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 563f63e2bc8..e846ccd44aa 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -15,14 +15,21 @@ #include <asm/arch/qemu.h> #include <asm/u-boot-x86.h> -static bool i440fx; - #if CONFIG_IS_ENABLED(QFW_PIO) U_BOOT_DRVINFO(x86_qfw_pio) = { .name = "qfw_pio", }; #endif +static bool is_i440fx(void) +{ + u16 device; + + pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID, &device); + + return device == PCI_DEVICE_ID_INTEL_82441; +} + static void enable_pm_piix(void) { u8 en; @@ -50,16 +57,17 @@ static void enable_pm_ich9(void) void qemu_chipset_init(void) { - u16 device, xbcs; + bool i440fx; + u16 xbcs; int pam, i; + i440fx = is_i440fx(); + /* * i440FX and Q35 chipset have different PAM register offset, but with * the same bitfield layout. Here we determine the offset based on its * PCI device ID. */ - pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID, &device); - i440fx = (device == PCI_DEVICE_ID_INTEL_82441); pam = i440fx ? I440FX_PAM : Q35_PAM; /* @@ -123,7 +131,7 @@ int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq) { u8 irq; - if (i440fx) { + if (is_i440fx()) { /* * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not * connected to I/O APIC INTPIN#16-19. Instead they are routed diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S index 0ef27cc5a00..385a691265e 100644 --- a/arch/x86/cpu/start.S +++ b/arch/x86/cpu/start.S @@ -254,7 +254,7 @@ multiboot_header: * GDT is setup in a safe location in RAM */ gdt_ptr2: - .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ + .word gdt2_end - gdt_ptr2 - 1 .long gdt_rom2 /* base */ /* Some CPUs are picky about GDT alignment... */ @@ -313,4 +313,6 @@ gdt_rom2: .byte 0x93 /* access */ .byte 0xcf /* flags + limit_high */ .byte 0x00 /* base_high */ +gdt2_end: + #endif diff --git a/arch/x86/cpu/start16.S b/arch/x86/cpu/start16.S index 865a49731e5..8d9acb193e0 100644 --- a/arch/x86/cpu/start16.S +++ b/arch/x86/cpu/start16.S @@ -61,7 +61,7 @@ idt_ptr: * GDT is setup in a safe location in RAM */ gdt_ptr: - .word 0x1f /* limit (31 bytes = 4 GDT entries - 1) */ + .word gdt_end - gdt_rom - 1 .long BOOT_SEG + gdt_rom /* base */ /* Some CPUs are picky about GDT alignment... */ @@ -120,3 +120,4 @@ gdt_rom: .byte 0x93 /* access */ .byte 0xcf /* flags + limit_high */ .byte 0x00 /* base_high */ +gdt_end: diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c index 71bc07f872a..25ae92c702f 100644 --- a/arch/x86/cpu/x86_64/cpu.c +++ b/arch/x86/cpu/x86_64/cpu.c @@ -59,11 +59,6 @@ int x86_cpu_reinit_f(void) return 0; } -int cpu_phys_address_size(void) -{ - return CONFIG_CPU_ADDR_BITS; -} - int x86_cpu_init_f(void) { return 0; diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h index ac4865300f1..657d920b14f 100644 --- a/arch/x86/include/asm/bootparam.h +++ b/arch/x86/include/asm/bootparam.h @@ -122,6 +122,14 @@ struct efi_info { __u32 efi_memmap_hi; }; +/* Gleaned from OFW's set-parameters in cpu/x86/pc/linux.fth */ +struct olpc_ofw_header { + __u32 ofw_magic; /* OFW signature */ + __u32 ofw_version; + __u32 cif_handler; /* callback into OFW */ + __u32 irq_desc_table; +} __attribute__((packed)); + /* The so-called "zeropage" */ struct boot_params { struct screen_info screen_info; /* 0x000 */ @@ -134,7 +142,12 @@ struct boot_params { __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */ __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ struct sys_desc_table sys_desc_table; /* 0x0a0 */ - __u8 _pad4[144]; /* 0x0b0 */ + struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */ + __u32 ext_ramdisk_image; /* 0x0c0 */ + __u32 ext_ramdisk_size; /* 0x0c4 */ + __u32 ext_cmd_line_ptr; /* 0x0c8 */ + __u8 _pad4[112]; /* 0x0cc */ + __u32 cc_blob_address; /* 0x13c */ struct edid_info edid_info; /* 0x140 */ struct efi_info efi_info; /* 0x1c0 */ __u32 alt_mem_k; /* 0x1e0 */ diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index fd389d4024c..5d24c17f8a3 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -58,6 +58,10 @@ enum { X86_SYSCON_PUNIT, /* Power unit */ }; +#define CPUID_FEATURE_PAE BIT(6) +#define CPUID_FEATURE_PSE36 BIT(17) +#define CPUID_FEAURE_HTT BIT(28) + struct cpuid_result { uint32_t eax; uint32_t ebx; @@ -105,68 +109,47 @@ static inline struct cpuid_result cpuid_ext(int op, unsigned ecx) return result; } -/* - * CPUID functions returning a single datum - */ -static inline unsigned int cpuid_eax(unsigned int op) +static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) { - unsigned int eax; - - __asm__("mov %%ebx, %%edi;" - "cpuid;" - "mov %%edi, %%ebx;" - : "=a" (eax) - : "0" (op) - : "ecx", "edx", "edi"); - return eax; + /* ecx is often an input as well as an output. */ + asm volatile("cpuid" + : "=a" (*eax), + "=b" (*ebx), + "=c" (*ecx), + "=d" (*edx) + : "0" (*eax), "2" (*ecx) + : "memory"); } -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx; - - __asm__("mov %%ebx, %%edi;" - "cpuid;" - "mov %%ebx, %%esi;" - "mov %%edi, %%ebx;" - : "=a" (eax), "=S" (ebx) - : "0" (op) - : "ecx", "edx", "edi"); - return ebx; +#define native_cpuid_reg(reg) \ +static inline unsigned int cpuid_##reg(unsigned int op) \ +{ \ + unsigned int eax = op, ebx, ecx = 0, edx; \ + \ + native_cpuid(&eax, &ebx, &ecx, &edx); \ + \ + return reg; \ } -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ecx; - - __asm__("mov %%ebx, %%edi;" - "cpuid;" - "mov %%edi, %%ebx;" - : "=a" (eax), "=c" (ecx) - : "0" (op) - : "edx", "edi"); - return ecx; -} +/* + * Native CPUID functions returning a single datum. + */ +native_cpuid_reg(eax) +native_cpuid_reg(ebx) +native_cpuid_reg(ecx) +native_cpuid_reg(edx) -static inline unsigned int cpuid_edx(unsigned int op) +#if CONFIG_IS_ENABLED(X86_64) +static inline int flag_is_changeable_p(u32 flag) { - unsigned int eax, edx; - - __asm__("mov %%ebx, %%edi;" - "cpuid;" - "mov %%edi, %%ebx;" - : "=a" (eax), "=d" (edx) - : "0" (op) - : "ecx", "edi"); - return edx; + return 1; } - -#if !CONFIG_IS_ENABLED(X86_64) - +#else /* Standard macro to see if a specific flag is changeable */ -static inline int flag_is_changeable_p(uint32_t flag) +static inline int flag_is_changeable_p(u32 flag) { - uint32_t f1, f2; + u32 f1, f2; asm( "pushfl\n\t" @@ -181,9 +164,9 @@ static inline int flag_is_changeable_p(uint32_t flag) "popfl\n\t" : "=&r" (f1), "=&r" (f2) : "ir" (flag)); - return ((f1^f2) & flag) != 0; + return ((f1 ^ f2) & flag) != 0; } -#endif +#endif /* X86_64 */ /** * cpu_enable_paging_pae() - Enable PAE-paging diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 1ab709abfc8..a535818b2d5 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h @@ -3,6 +3,8 @@ #define E820MAX 128 /* number of entries in E820MAP */ +#ifdef __ASSEMBLY__ + #define E820_RAM 1 #define E820_RESERVED 2 #define E820_ACPI 3 @@ -10,9 +12,21 @@ #define E820_UNUSABLE 5 #define E820_COUNT 6 /* Number of types */ -#ifndef __ASSEMBLY__ +#else + #include <linux/types.h> +/* Available e820 memory-region types */ +enum e820_type { + E820_RAM = 1, + E820_RESERVED, + E820_ACPI, + E820_NVS, + E820_UNUSABLE, + + E820_COUNT, +}; + struct e820_entry { __u64 addr; /* start of memory segment */ __u64 size; /* size of memory segment */ @@ -22,11 +36,82 @@ struct e820_entry { #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +/** + * Context to use for e820_add() + * + * @entries: Table being filled in + * @addr: Current address we are up to + * @count: Number of entries added to @entries so far + * @max_entries: Maximum number of entries allowed + */ +struct e820_ctx { + struct e820_entry *entries; + u64 addr; + int count; + int max_entries; +}; + +/** + * e820_init() - Start setting up an e820 table + * + * @ctx: Context to set up + * @entries: Place to put entries + * @max_entries: Maximum size of @entries + */ +void e820_init(struct e820_ctx *ctx, struct e820_entry *entries, + int max_entries); + +/** + * e820_add() - Add an entry to the table + * + * @ctx: Context + * @type: Type of entry + * @addr: Start address of entry + * @size Size of entry + */ +void e820_add(struct e820_ctx *ctx, enum e820_type type, u64 addr, u64 size); + +/** + * e820_to_addr() - Add an entry that covers the space up to a given address + * + * @ctx: Context + * @type: Type of entry + * @end_addr: Address where the entry should finish + */ +void e820_to_addr(struct e820_ctx *ctx, enum e820_type type, u64 end_addr); + +/** + * e820_next() - Add an entry that carries on from the last one + * + * @ctx: Context + * @type: Type of entry + * @size Size of entry + */ +void e820_next(struct e820_ctx *ctx, enum e820_type type, u64 size); + +/** + * e820_finish() - Finish the table + * + * Checks the table is not too large, panics if so + * + * @ctx: Context + * Returns: Number of entries + */ +int e820_finish(struct e820_ctx *ctx); + /* Implementation-defined function to install an e820 map */ unsigned int install_e820_map(unsigned int max_entries, struct e820_entry *); /** + * e820_dump() - Dump the e820 table + * + * @entries: Pointer to start of table + * @count: Number of entries in the table + */ +void e820_dump(struct e820_entry *entries, uint count); + +/** * cb_install_e820_map() - Install e820 map provided by coreboot sysinfo * * This should be used when booting from coreboot, since in that case the @@ -39,6 +124,14 @@ unsigned int install_e820_map(unsigned int max_entries, unsigned int cb_install_e820_map(unsigned int max_entries, struct e820_entry *entries); +/** + * e820_dump() - Dump an e820 table + * + * @entries: Pointer to first entry + * @count: Number of entries in the table + */ +void e820_dump(struct e820_entry *entries, uint count); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_X86_E820_H */ diff --git a/arch/x86/include/asm/interrupt.h b/arch/x86/include/asm/interrupt.h index e23fb2c8e72..c689fc23d08 100644 --- a/arch/x86/include/asm/interrupt.h +++ b/arch/x86/include/asm/interrupt.h @@ -10,6 +10,7 @@ #ifndef __ASM_INTERRUPT_H_ #define __ASM_INTERRUPT_H_ 1 +#include <stdbool.h> #include <asm/types.h> #define SYS_NUM_IRQS 16 diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index af5f9a11980..39dc7b33aa0 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -59,15 +59,14 @@ static inline unsigned long long native_read_tscp(unsigned int *aux) * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead, * it means rax *or* rdx. */ -#ifdef CONFIG_X86_64 -#define DECLARE_ARGS(val, low, high) unsigned low, high -#define EAX_EDX_VAL(val, low, high) ((low) | ((u64)(high) << 32)) -#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high) +#if CONFIG_IS_ENABLED(X86_64) +/* Using 64-bit values saves one instruction clearing the high half of low */ +#define DECLARE_ARGS(val, low, high) unsigned long low, high +#define EAX_EDX_VAL(val, low, high) ((low) | (high) << 32) #define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high) #else #define DECLARE_ARGS(val, low, high) unsigned long long val #define EAX_EDX_VAL(val, low, high) (val) -#define EAX_EDX_ARGS(val, low, high) "A" (val) #define EAX_EDX_RET(val, low, high) "=A" (val) #endif diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h index 2e995f54061..67e897daa25 100644 --- a/arch/x86/include/asm/mtrr.h +++ b/arch/x86/include/asm/mtrr.h @@ -91,6 +91,22 @@ struct mtrr_info { }; /** + * mtrr_to_size() - Convert a mask to a size value + * + * @mask: Value of the mask register + * Return: associated size + */ +u64 mtrr_to_size(u64 mask); + +/** + * mtrr_to_mask() - Convert a size to a mask value + * + * @size: Value of the size register + * Return: associated mask, without MTRR_PHYS_MASK_VALID + */ +u64 mtrr_to_mask(u64 size); + +/** * mtrr_open() - Prepare to adjust MTRRs * * Use mtrr_open() passing in a structure - this function will init it. Then diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index d7b68367861..ad8240be387 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -18,7 +18,10 @@ #define X86_GDT_ENTRY_16BIT_DS 6 #define X86_GDT_ENTRY_16BIT_FLAT_CS 7 #define X86_GDT_ENTRY_16BIT_FLAT_DS 8 -#define X86_GDT_NUM_ENTRIES 9 +#define X86_GDT_ENTRY_64BIT_CS 9 +#define X86_GDT_ENTRY_64BIT_TS1 10 +#define X86_GDT_ENTRY_64BIT_TS2 11 +#define X86_GDT_NUM_ENTRIES 12 #define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE) diff --git a/arch/x86/include/asm/setjmp.h b/arch/x86/include/asm/setjmp.h index 15915d0dc6b..13772574e15 100644 --- a/arch/x86/include/asm/setjmp.h +++ b/arch/x86/include/asm/setjmp.h @@ -5,8 +5,8 @@ * From Linux arch/um/sys-i386/setjmp.S */ -#ifndef __setjmp_h -#define __setjmp_h +#ifndef _ASM_SETJMP_H_ +#define _ASM_SETJMP_H_ 1 #ifdef CONFIG_X86_64 @@ -34,9 +34,4 @@ struct jmp_buf_data { #endif -typedef struct jmp_buf_data jmp_buf[1]; - -int setjmp(jmp_buf env); -void longjmp(jmp_buf env, int val); - -#endif +#endif /* _ASM_SETJMP_H_ */ diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 43e6a1de77d..a908356e8a6 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -26,7 +26,9 @@ obj-y += e820.o obj-y += init_helpers.o obj-y += interrupts.o obj-y += lpc-uclass.o +ifndef CONFIG_XPL_BUILD obj-y += mpspec.o +endif obj-$(CONFIG_$(PHASE_)ACPIGEN) += acpi_nhlt.o obj-y += northbridge-uclass.o obj-$(CONFIG_I8259_PIC) += i8259.o diff --git a/arch/x86/lib/acpi_nhlt.c b/arch/x86/lib/acpi_nhlt.c index 880ef31df7d..8aae5fa5af7 100644 --- a/arch/x86/lib/acpi_nhlt.c +++ b/arch/x86/lib/acpi_nhlt.c @@ -414,7 +414,7 @@ int nhlt_serialise_oem_overrides(struct acpi_ctx *ctx, struct nhlt *nhlt, cur.start = (void *)header; nhlt_serialise_endpoints(nhlt, &cur); - header->checksum = table_compute_checksum(header, sz); + acpi_update_checksum(header); nhlt_free_resources(nhlt); assert(cur.buf - cur.start == sz); diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 3186e48d63b..b13292c4150 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -173,7 +173,7 @@ int acpi_write_tcpa(struct acpi_ctx *ctx, const struct acpi_writer *entry) /* (Re)calculate length and checksum */ current = (u32)tcpa + sizeof(struct acpi_tcpa); header->length = current - (u32)tcpa; - header->checksum = table_compute_checksum(tcpa, header->length); + acpi_update_checksum(header); acpi_inc(ctx, tcpa->header.length); acpi_add_table(ctx, tcpa); @@ -242,7 +242,7 @@ static int acpi_write_tpm2(struct acpi_ctx *ctx, tpm2->lasa = nomap_to_sysmem(lasa); /* Calculate checksum. */ - header->checksum = table_compute_checksum(tpm2, header->length); + acpi_update_checksum(header); acpi_inc(ctx, tpm2->header.length); acpi_add_table(ctx, tpm2); @@ -279,9 +279,7 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry) * patched the GNVS address. Set the checksum to zero since it * is part of the region being checksummed. */ - ctx->dsdt->checksum = 0; - ctx->dsdt->checksum = table_compute_checksum((void *)ctx->dsdt, - ctx->dsdt->length); + acpi_update_checksum(ctx->dsdt); } /* Fill in platform-specific global NVS variables */ @@ -330,8 +328,7 @@ static int acpi_create_hpet(struct acpi_hpet *hpet) hpet->number = 0; hpet->min_tick = 0; /* HPET_MIN_TICKS */ - header->checksum = table_compute_checksum(hpet, - sizeof(struct acpi_hpet)); + acpi_update_checksum(header); return 0; } diff --git a/arch/x86/lib/bios.c b/arch/x86/lib/bios.c index 03f7360032c..de4578666fb 100644 --- a/arch/x86/lib/bios.c +++ b/arch/x86/lib/bios.c @@ -5,6 +5,9 @@ * Copyright (C) 2007 Advanced Micro Devices, Inc. * Copyright (C) 2009-2010 coresystems GmbH */ + +#define LOG_CATEGRORY LOGC_ARCH + #include <compiler.h> #include <bios_emul.h> #include <irq_func.h> @@ -228,7 +231,11 @@ static void vbe_set_graphics(int vesa_mode, struct vesa_state *mode_info) { unsigned char *framebuffer; - mode_info->video_mode = (1 << 14) | vesa_mode; + /* + * bit 14 is linear-framebuffer mode + * bit 15 means don't clear the display + */ + mode_info->video_mode = (1 << 14) | (1 << 15) | vesa_mode; vbe_get_mode_info(mode_info); framebuffer = (unsigned char *)(ulong)mode_info->vesa.phys_base_ptr; @@ -298,16 +305,14 @@ asmlinkage int interrupt_handler(u32 intnumber, u32 gsfs, u32 dses, cs = cs_ip >> 16; flags = stackflags; -#ifdef CONFIG_REALMODE_DEBUG - debug("oprom: INT# 0x%x\n", intnumber); - debug("oprom: eax: %08x ebx: %08x ecx: %08x edx: %08x\n", - eax, ebx, ecx, edx); - debug("oprom: ebp: %08x esp: %08x edi: %08x esi: %08x\n", - ebp, esp, edi, esi); - debug("oprom: ip: %04x cs: %04x flags: %08x\n", - ip, cs, flags); - debug("oprom: stackflags = %04x\n", stackflags); -#endif + log_debug("oprom: INT# 0x%x\n", intnumber); + log_debug("oprom: eax: %08x ebx: %08x ecx: %08x edx: %08x\n", + eax, ebx, ecx, edx); + log_debug("oprom: ebp: %08x esp: %08x edi: %08x esi: %08x\n", + ebp, esp, edi, esi); + log_debug("oprom: ip: %04x cs: %04x flags: %08x\n", + ip, cs, flags); + log_debug("oprom: stackflags = %04x\n", stackflags); /* * Fetch arguments from the stack and put them to a place diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c index b2cf1527b1c..e0c2284a901 100644 --- a/arch/x86/lib/bios_interrupts.c +++ b/arch/x86/lib/bios_interrupts.c @@ -7,6 +7,8 @@ * Copyright (C) 2007-2009 coresystems GmbH */ +#define LOG_CATEGRORY LOGC_ARCH + #include <log.h> #include <asm/pci.h> #include "bios_emul.h" @@ -198,10 +200,8 @@ int int1a_handler(void) dm_pci_write_config32(dev, reg, dword); break; } -#ifdef CONFIG_REALMODE_DEBUG - debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func, - bus, devfn, reg, M.x86.R_ECX); -#endif + log_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func, + bus, devfn, reg, M.x86.R_ECX); M.x86.R_EAX &= 0xffff00ff; /* Clear AH */ M.x86.R_EAX |= PCIBIOS_SUCCESSFUL; retval = 1; diff --git a/arch/x86/lib/e820.c b/arch/x86/lib/e820.c index d478b7486e3..bcc5f6f3044 100644 --- a/arch/x86/lib/e820.c +++ b/arch/x86/lib/e820.c @@ -3,13 +3,39 @@ * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> */ +#define LOG_CATEGORY LOGC_ARCH + #include <efi_loader.h> #include <lmb.h> +#include <log.h> #include <asm/e820.h> #include <asm/global_data.h> DECLARE_GLOBAL_DATA_PTR; +static const char *const e820_type_name[E820_COUNT] = { + [E820_RAM] = "RAM", + [E820_RESERVED] = "Reserved", + [E820_ACPI] = "ACPI", + [E820_NVS] = "ACPI NVS", + [E820_UNUSABLE] = "Unusable", +}; + +void e820_dump(struct e820_entry *entries, uint count) +{ + int i; + + printf("%12s %10s %s\n", "Addr", "Size", "Type"); + for (i = 0; i < count; i++) { + struct e820_entry *entry = &entries[i]; + + printf("%12llx %10llx %s\n", entry->addr, entry->size, + entry->type < E820_COUNT ? + e820_type_name[entry->type] : + simple_itoa(entry->type)); + } +} + /* * Install a default e820 table with 4 entries as follows: * @@ -37,6 +63,50 @@ __weak unsigned int install_e820_map(unsigned int max_entries, return 4; } +void e820_init(struct e820_ctx *ctx, struct e820_entry *entries, + int max_entries) +{ + memset(ctx, '\0', sizeof(*ctx)); + ctx->entries = entries; + ctx->max_entries = max_entries; +} + +void e820_add(struct e820_ctx *ctx, enum e820_type type, u64 addr, u64 size) +{ + struct e820_entry *entry = &ctx->entries[ctx->count++]; + + if (ctx->count <= ctx->max_entries) { + entry->addr = addr; + entry->size = size; + entry->type = type; + } + ctx->addr = addr + size; +} + +void e820_next(struct e820_ctx *ctx, enum e820_type type, u64 size) +{ + e820_add(ctx, type, ctx->addr, size); +} + +void e820_to_addr(struct e820_ctx *ctx, enum e820_type type, u64 addr) +{ + e820_next(ctx, type, addr - ctx->addr); +} + +int e820_finish(struct e820_ctx *ctx) +{ + if (ctx->count > ctx->max_entries) { + printf("e820 has %d entries but room for only %d\n", ctx->count, + ctx->max_entries); + panic("e820 table too large"); + } + log_debug("e820 map installed, n=%d\n", ctx->count); + if (_DEBUG) + e820_dump(ctx->entries, ctx->count); + + return ctx->count; +} + #if CONFIG_IS_ENABLED(EFI_LOADER) void efi_add_known_memory(void) { diff --git a/arch/x86/lib/i8259.c b/arch/x86/lib/i8259.c index 465ff70146f..088f78f4661 100644 --- a/arch/x86/lib/i8259.c +++ b/arch/x86/lib/i8259.c @@ -13,6 +13,8 @@ * Programmable Interrupt Controllers. */ +#define LOG_CATEGORY UCLASS_IRQ + #include <log.h> #include <asm/io.h> #include <asm/i8259.h> diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 7a033505101..0a6a761987e 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -84,8 +84,6 @@ static int x86_spl_init(void) log_debug("x86 spl starting\n"); if (IS_ENABLED(TPL)) ret = x86_cpu_reinit_f(); - else - ret = x86_cpu_init_f(); ret = spl_init(); if (ret) { log_debug("spl_init() failed (err=%d)\n", ret); @@ -283,7 +281,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { int ret; - printf("Jumping to 64-bit U-Boot: Note many features are missing\n"); + log_debug("Jumping to 64-bit U-Boot\n"); ret = cpu_jump_to_64bit_uboot(spl_image->entry_point); debug("ret=%d\n", ret); hang(); diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c index 44fe80c5224..ec52992209f 100644 --- a/arch/x86/lib/tables.c +++ b/arch/x86/lib/tables.c @@ -45,6 +45,13 @@ struct table_info { int align; }; +/* QEMU's tables include quite a bit of empty space */ +#ifdef CONFIG_QEMU +#define ACPI_SIZE (192 << 10) +#else +#define ACPI_SIZE SZ_64K +#endif + static struct table_info table_list[] = { #ifdef CONFIG_GENERATE_PIRQ_TABLE { "pirq", write_pirq_routing_table }, @@ -60,7 +67,7 @@ static struct table_info table_list[] = { * that the calculation of gd->table_end works properly */ #ifdef CONFIG_GENERATE_ACPI_TABLE - { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, SZ_64K, SZ_4K}, + { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, ACPI_SIZE, SZ_4K}, #endif #ifdef CONFIG_GENERATE_SMBIOS_TABLE /* diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 2eece34a073..2ea9bcf59c2 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -225,7 +225,7 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, else *load_addressp = ZIMAGE_LOAD_ADDR; - printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base); + printf("Building boot_params at %lx\n", (ulong)setup_base); memset(setup_base, 0, sizeof(*setup_base)); setup_base->hdr = params->hdr; @@ -301,10 +301,13 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, hdr->type_of_loader = 0x80; /* U-Boot version 0 */ if (initrd_addr) { printf("Initial RAM disk at linear address " - "0x%08lx, size %ld bytes\n", - initrd_addr, initrd_size); + "%lx, size %lx (%ld bytes)\n", + initrd_addr, initrd_size, initrd_size); hdr->ramdisk_image = initrd_addr; + setup_base->ext_ramdisk_image = 0; + setup_base->ext_ramdisk_size = 0; + setup_base->ext_cmd_line_ptr = 0; hdr->ramdisk_size = initrd_size; } } @@ -375,8 +378,7 @@ int zboot_load(void) struct boot_params *from = (struct boot_params *)state.base_ptr; base_ptr = (struct boot_params *)DEFAULT_SETUP_BASE; - log_debug("Building boot_params at 0x%8.8lx\n", - (ulong)base_ptr); + log_debug("Building boot_params at %lx\n", (ulong)base_ptr); memset(base_ptr, '\0', sizeof(*base_ptr)); base_ptr->hdr = from->hdr; } else { @@ -424,7 +426,7 @@ int zboot_go(void) entry = state.load_address; image_64bit = false; - if (IS_ENABLED(CONFIG_X86_RUN_64BIT) && + if (IS_ENABLED(CONFIG_X86_64) && (hdr->xloadflags & XLF_KERNEL_64)) { image_64bit = true; } @@ -464,14 +466,6 @@ static void print_num64(const char *name, u64 value) printf("%-20s: %llx\n", name, value); } -static const char *const e820_type_name[E820_COUNT] = { - [E820_RAM] = "RAM", - [E820_RESERVED] = "Reserved", - [E820_ACPI] = "ACPI", - [E820_NVS] = "ACPI NVS", - [E820_UNUSABLE] = "Unusable", -}; - static const char *const bootloader_id[] = { "LILO", "Loadlin", @@ -559,23 +553,13 @@ void zimage_dump(struct boot_params *base_ptr, bool show_cmdline) { struct setup_header *hdr; const char *version; - int i; printf("Setup located at %p:\n\n", base_ptr); print_num64("ACPI RSDP addr", base_ptr->acpi_rsdp_addr); printf("E820: %d entries\n", base_ptr->e820_entries); - if (base_ptr->e820_entries) { - printf("%12s %10s %s\n", "Addr", "Size", "Type"); - for (i = 0; i < base_ptr->e820_entries; i++) { - struct e820_entry *entry = &base_ptr->e820_map[i]; - - printf("%12llx %10llx %s\n", entry->addr, entry->size, - entry->type < E820_COUNT ? - e820_type_name[entry->type] : - simple_itoa(entry->type)); - } - } + if (base_ptr->e820_entries) + e820_dump(base_ptr->e820_map, base_ptr->e820_entries); hdr = &base_ptr->hdr; print_num("Setup sectors", hdr->setup_sects); |