Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
066165f9b3 | ||
|
|
b57abc103a | ||
|
|
56d237b07a | ||
|
|
34051458cd | ||
|
|
ca35d5f966 | ||
|
|
e9418f47b7 | ||
|
|
2b5821219d | ||
|
|
3b3607e577 | ||
|
|
417467d331 | ||
|
|
849b044815 | ||
|
|
f7a87603b6 | ||
|
|
c45106f504 | ||
|
|
328d088c2b | ||
|
|
05e9c555b4 | ||
|
|
1003f27657 | ||
|
|
166b5295fc | ||
|
|
f7872bb0a8 | ||
|
|
f3c75fc39e | ||
|
|
aa879a9345 | ||
|
|
c2e9fe0ea7 | ||
|
|
98ea430d51 | ||
|
|
26774686ac | ||
|
|
a6d6b8b7be | ||
|
|
eac76060ec | ||
|
|
9494270349 | ||
|
|
ef405956c3 | ||
|
|
b96c349afa | ||
|
|
8289ee01ea | ||
|
|
406ffc2dfc |
@@ -745,3 +745,8 @@ zybo:
|
||||
variables:
|
||||
ROLE: zybo
|
||||
<<: *lab_dfn
|
||||
|
||||
qemu-x86_64:
|
||||
variables:
|
||||
ROLE: qemu-x86_64
|
||||
<<: *lab_dfn
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/processor-flags.h>
|
||||
|
||||
.code32
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* since the MTRR registers are sometimes in flux.
|
||||
*/
|
||||
|
||||
#include <cpu.h>
|
||||
#include <cpu_func.h>
|
||||
#include <log.h>
|
||||
#include <sort.h>
|
||||
@@ -70,9 +71,10 @@ static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
|
||||
{
|
||||
u64 mask;
|
||||
|
||||
wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type);
|
||||
mask = ~(size - 1);
|
||||
mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
|
||||
mask &= (1ull << cpu_phys_address_size()) - 1;
|
||||
|
||||
wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type);
|
||||
wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
|
||||
}
|
||||
|
||||
@@ -193,7 +195,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t size)
|
||||
if (!gd->arch.has_mtrr)
|
||||
return -ENOSYS;
|
||||
|
||||
if (!is_power_of_2(size))
|
||||
if (!is_power_of_2_u64(size))
|
||||
return -EINVAL;
|
||||
|
||||
if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
|
||||
@@ -205,7 +207,7 @@ int mtrr_add_request(int type, uint64_t start, uint64_t 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 &= (1ULL << cpu_phys_address_size()) - 1;
|
||||
mask |= MTRR_PHYS_MASK_VALID;
|
||||
debug(" %016llx %016llx\n", req->start | req->type, mask);
|
||||
|
||||
@@ -360,7 +362,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 = ~mask & ((1ULL << cpu_phys_address_size()) - 1);
|
||||
size |= (1 << 12) - 1;
|
||||
size += 1;
|
||||
valid = mask & MTRR_PHYS_MASK_VALID;
|
||||
|
||||
@@ -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>
|
||||
@@ -40,10 +42,23 @@ u64 qemu_get_high_memory_size(void)
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
gd->ram_size = qemu_get_low_memory_size();
|
||||
gd->ram_size += qemu_get_high_memory_size();
|
||||
post_code(POST_DRAM);
|
||||
|
||||
if (xpl_phase() == PHASE_BOARD_F) {
|
||||
ret = mtrr_add_request(MTRR_TYPE_WRBACK, 0, gd->ram_size);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
@@ -161,12 +165,33 @@ static inline unsigned int cpuid_edx(unsigned int op)
|
||||
return edx;
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(X86_64)
|
||||
|
||||
#if CONFIG_IS_ENABLED(X86_64)
|
||||
/* 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(u64 flag)
|
||||
{
|
||||
uint32_t f1, f2;
|
||||
u64 f1, f2;
|
||||
|
||||
asm (
|
||||
"pushfq\n\t"
|
||||
"pushfq\n\t"
|
||||
"popq %0\n\t"
|
||||
"movq %0,%1\n\t"
|
||||
"xorq %2,%0\n\t"
|
||||
"pushq %0\n\t"
|
||||
"popfq\n\t"
|
||||
"pushfq\n\t"
|
||||
"popq %0\n\t"
|
||||
"popfq\n\t"
|
||||
: "=&r" (f1), "=&r" (f2)
|
||||
: "ir" (flag));
|
||||
|
||||
return ((f1 ^ f2) & flag) != 0;
|
||||
}
|
||||
#else
|
||||
/* Standard macro to see if a specific flag is changeable */
|
||||
static inline int flag_is_changeable_p(u32 flag)
|
||||
{
|
||||
u32 f1, f2;
|
||||
|
||||
asm(
|
||||
"pushfl\n\t"
|
||||
@@ -181,9 +206,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
* Programmable Interrupt Controllers.
|
||||
*/
|
||||
|
||||
#define LOG_CATEGORY UCLASS_IRQ
|
||||
|
||||
#include <log.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/i8259.h>
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
CONFIG_X86=y
|
||||
CONFIG_TEXT_BASE=0x1110000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x1000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x1800
|
||||
CONFIG_BLOBLIST_SIZE_RELOC=0x20000
|
||||
CONFIG_NR_DRAM_BANKS=8
|
||||
CONFIG_ENV_SIZE=0x40000
|
||||
CONFIG_MAX_CPUS=2
|
||||
CONFIG_SPL_DM_SPI=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
|
||||
CONFIG_SPL_SYS_MALLOC_F_LEN=0x3000
|
||||
CONFIG_SPL_SYS_MALLOC_F_LEN=0x4800
|
||||
CONFIG_SPL_TEXT_BASE=0xfffd0000
|
||||
CONFIG_DEBUG_UART_BASE=0x3f8
|
||||
CONFIG_DEBUG_UART_CLOCK=1843200
|
||||
@@ -83,11 +83,11 @@ CONFIG_SYS_NS16550_PORT_MAPPED=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_CONSOLE_TRUETYPE=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_USER=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE=0x144
|
||||
CONFIG_VIDEO_BOCHS=y
|
||||
# CONFIG_VIDEO_VESA is not set
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
CONFIG_SPL_VIDEO=y
|
||||
# CONFIG_SPL_USE_TINY_PRINTF is not set
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
# CONFIG_GZIP is not set
|
||||
|
||||
@@ -62,9 +62,9 @@ CONFIG_SYS_NS16550_PORT_MAPPED=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_CONSOLE_TRUETYPE=y
|
||||
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE_USER=y
|
||||
CONFIG_FRAMEBUFFER_VESA_MODE=0x144
|
||||
CONFIG_VIDEO_BOCHS=y
|
||||
# CONFIG_VIDEO_VESA is not set
|
||||
CONFIG_CONSOLE_SCROLL_LINES=5
|
||||
CONFIG_GENERATE_ACPI_TABLE=y
|
||||
CONFIG_CMD_DHRYSTONE=y
|
||||
# CONFIG_GZIP is not set
|
||||
|
||||
@@ -52,6 +52,12 @@ bool is_power_of_2(unsigned long n)
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
static inline __attribute__((const))
|
||||
bool is_power_of_2_u64(u64 n)
|
||||
{
|
||||
return (n != 0 && ((n & (n - 1)) == 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* __roundup_pow_of_two() - round up to nearest power of two
|
||||
* @n: value to round up
|
||||
|
||||
@@ -799,6 +799,18 @@ static void add_u_boot_and_runtime(void)
|
||||
{
|
||||
unsigned long runtime_start, runtime_end, runtime_pages;
|
||||
unsigned long runtime_mask = EFI_PAGE_MASK;
|
||||
unsigned long uboot_start, uboot_pages;
|
||||
unsigned long uboot_stack_size = CONFIG_STACK_SIZE;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SANDBOX)) {
|
||||
/* Add U-Boot */
|
||||
uboot_start = ((uintptr_t)map_sysmem(gd->start_addr_sp, 0) -
|
||||
uboot_stack_size) & ~EFI_PAGE_MASK;
|
||||
uboot_pages = ((uintptr_t)map_sysmem(gd->ram_top - 1, 0) -
|
||||
uboot_start + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
|
||||
efi_add_memory_map_pg(uboot_start, uboot_pages,
|
||||
EFI_BOOT_SERVICES_CODE, false);
|
||||
}
|
||||
|
||||
#if defined(__aarch64__)
|
||||
/*
|
||||
|
||||
@@ -93,7 +93,7 @@ while getopts "a:Beko:rR:sS:w" opt; do
|
||||
extra+=" -netdev user,id=net0"
|
||||
;;
|
||||
k)
|
||||
kvm="-enable-kvm"
|
||||
kvm="-enable-kvm -cpu host"
|
||||
;;
|
||||
o)
|
||||
os=$OPTARG
|
||||
@@ -150,7 +150,7 @@ run_qemu() {
|
||||
else
|
||||
extra+=" -serial mon:stdio"
|
||||
fi
|
||||
echo "Running ${qemu} ${extra}"
|
||||
echo "Running ${qemu} -bios "$DIR/${BIOS}" ${kvm} ${extra}"
|
||||
"${qemu}" -bios "$DIR/${BIOS}" \
|
||||
-m 512 \
|
||||
-nic none \
|
||||
|
||||
@@ -334,6 +334,7 @@ def pytest_configure(config):
|
||||
ubconfig.dtb = build_dir + '/arch/sandbox/dts/test.dtb'
|
||||
ubconfig.connection_ok = True
|
||||
ubconfig.timing = config.getoption('timing')
|
||||
ubconfig.role = config.getoption('role')
|
||||
|
||||
env_vars = (
|
||||
'board_type',
|
||||
@@ -760,6 +761,26 @@ def setup_singlethread(item):
|
||||
if worker_id and worker_id != 'master':
|
||||
pytest.skip('must run single-threaded')
|
||||
|
||||
def setup_role(item):
|
||||
"""Process any 'role' marker for a test.
|
||||
|
||||
Skip this test if the role does not match.
|
||||
|
||||
Args:
|
||||
item (pytest.Item): The pytest test item
|
||||
"""
|
||||
required_roles = []
|
||||
for roles in item.iter_markers('role'):
|
||||
role = roles.args[0]
|
||||
if role.startswith('!'):
|
||||
if ubconfig.role == role[1:]:
|
||||
pytest.skip(f'role "{ubconfig.role}" not supported')
|
||||
return
|
||||
else:
|
||||
required_roles.append(role)
|
||||
if required_roles and ubconfig.role not in required_roles:
|
||||
pytest.skip(f'board "{ubconfig.role}" not supported')
|
||||
|
||||
def start_test_section(item):
|
||||
anchors[item.name] = log.start_section(item.name)
|
||||
|
||||
@@ -781,6 +802,7 @@ def pytest_runtest_setup(item):
|
||||
setup_buildconfigspec(item)
|
||||
setup_requiredtool(item)
|
||||
setup_singlethread(item)
|
||||
setup_role(item)
|
||||
|
||||
def pytest_runtest_protocol(item, nextitem):
|
||||
"""pytest hook: Called to execute a test.
|
||||
|
||||
@@ -369,21 +369,30 @@ class ConsoleBase(object):
|
||||
output.append(self.run_command(cmd))
|
||||
return output
|
||||
|
||||
def ctrlc(self):
|
||||
"""Send a CTRL-C character to U-Boot.
|
||||
def send(self, msg):
|
||||
"""Send characters without waiting for echo, etc."""
|
||||
self.run_command(msg, wait_for_prompt=False, wait_for_echo=False,
|
||||
send_nl=False)
|
||||
|
||||
def ctrl(self, char):
|
||||
"""Send a CTRL- character to U-Boot.
|
||||
|
||||
This is useful in order to stop execution of long-running synchronous
|
||||
commands such as "ums".
|
||||
|
||||
Args:
|
||||
None.
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
char (str): Character to send, e.g. 'C' to send Ctrl-C
|
||||
"""
|
||||
self.log.action(f'Sending Ctrl-{char}')
|
||||
self.send(chr(ord(char) - ord('@')))
|
||||
|
||||
self.log.action('Sending Ctrl-C')
|
||||
self.run_command(chr(3), wait_for_echo=False, send_nl=False)
|
||||
def ctrlc(self):
|
||||
"""Send a CTRL-C character to U-Boot.
|
||||
|
||||
This is useful in order to stop execution of long-running synchronous
|
||||
commands such as "ums".
|
||||
"""
|
||||
self.ctrl('C')
|
||||
|
||||
def wait_for(self, text):
|
||||
"""Wait for a pattern to be emitted by U-Boot.
|
||||
@@ -455,7 +464,7 @@ class ConsoleBase(object):
|
||||
finally:
|
||||
self.p.timeout = orig_timeout
|
||||
|
||||
def ensure_spawned(self, expect_reset=False):
|
||||
def ensure_spawned(self, expect_reset=False, timeout=None):
|
||||
"""Ensure a connection to a correctly running U-Boot instance.
|
||||
|
||||
This may require spawning a new Sandbox process or resetting target
|
||||
@@ -476,7 +485,7 @@ class ConsoleBase(object):
|
||||
# Reset the console timeout value as some tests may change
|
||||
# its default value during the execution
|
||||
if not self.config.gdbserver:
|
||||
self.p.timeout = TIMEOUT_MS
|
||||
self.p.timeout = timeout or TIMEOUT_MS
|
||||
return
|
||||
try:
|
||||
self.log.start_section('Starting U-Boot')
|
||||
@@ -487,7 +496,7 @@ class ConsoleBase(object):
|
||||
# future, possibly per-test to be optimal. This works for 'help'
|
||||
# on board 'seaboard'.
|
||||
if not self.config.gdbserver:
|
||||
self.p.timeout = TIMEOUT_MS
|
||||
self.p.timeout = timeout or TIMEOUT_MS
|
||||
self.p.logfile_read = self.logstream
|
||||
if self.config.use_running_system:
|
||||
# Send an empty command to set up the 'expect' logic. This has
|
||||
@@ -535,7 +544,7 @@ class ConsoleBase(object):
|
||||
def restart_uboot(self, expect_reset=False):
|
||||
"""Shut down and restart U-Boot."""
|
||||
self.cleanup_spawn()
|
||||
self.ensure_spawned(expect_reset)
|
||||
self.ensure_spawned(expect_reset, 60 * 1000)
|
||||
|
||||
def get_spawn_output(self):
|
||||
"""Return the start-up output from U-Boot
|
||||
|
||||
@@ -12,3 +12,4 @@ markers =
|
||||
requiredtool: U-Boot: Required host tools for a test.
|
||||
slow: U-Boot: Specific test will run slowly.
|
||||
singlethread: Cannot run in parallel
|
||||
role: U-Boot: Indicates the lab 'role' which can execute this test
|
||||
|
||||
53
test/py/tests/test_distro.py
Normal file
53
test/py/tests/test_distro.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright 2025 Canonical Ltd.
|
||||
# Written by Simon Glass <simon.glass@canonical.com>
|
||||
|
||||
import pytest
|
||||
|
||||
DOWN = '\x1b\x5b\x42\x0d'
|
||||
|
||||
# Enable early console so that the test can see if something goes wrong
|
||||
CONSOLE = 'earlycon=uart8250,io,0x3f8 console=uart8250,io,0x3f8'
|
||||
|
||||
@pytest.mark.boardspec('qemu-x86_64')
|
||||
@pytest.mark.role('qemu-x86_64')
|
||||
def test_distro(ubman):
|
||||
"""Test that of-platdata can be generated and used in sandbox"""
|
||||
with ubman.log.section('boot'):
|
||||
ubman.run_command('boot', wait_for_prompt=False)
|
||||
|
||||
with ubman.log.section('Grub'):
|
||||
# Wait for grub to come up and offset a menu
|
||||
ubman.p.expect(['Try or Install Ubuntu'])
|
||||
|
||||
# Press 'e' to edit the command line
|
||||
ubman.run_command('e', wait_for_prompt=False, send_nl=False)
|
||||
|
||||
# Wait until we see the editor appear
|
||||
ubman.p.expect(['/casper/initrd'])
|
||||
|
||||
# Go down to the 'linux' line
|
||||
ubman.send(DOWN * 3)
|
||||
|
||||
# Go to end of line
|
||||
ubman.ctrl('E')
|
||||
|
||||
# Backspace to remove 'quiet splash'
|
||||
ubman.send('\b' * len('quiet splash'))
|
||||
|
||||
# Send our noisy console
|
||||
ubman.send(CONSOLE)
|
||||
|
||||
# Tell grub to boot
|
||||
ubman.ctrl('X')
|
||||
ubman.p.expect(['Booting a command list'])
|
||||
|
||||
with ubman.log.section('Linux'):
|
||||
# Linux should start immediately
|
||||
ubman.p.expect(['Linux version'])
|
||||
|
||||
with ubman.log.section('Ubuntu'):
|
||||
# Shortly later, we should see this banner
|
||||
ubman.p.expect(['Welcome to .*Ubuntu 24.04.1 LTS.*!'])
|
||||
|
||||
ubman.restart_uboot()
|
||||
@@ -19,6 +19,7 @@ env__sleep_margin = 0.25
|
||||
|
||||
"""
|
||||
|
||||
@pytest.mark.role('!qemu-x86_64')
|
||||
def test_sleep(ubman):
|
||||
"""Test the sleep command, and validate that it sleeps for approximately
|
||||
the correct amount of time."""
|
||||
|
||||
Reference in New Issue
Block a user