diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/arch/x86 | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/arch/x86')
77 files changed, 7112 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/arch/x86/config.mk b/qemu/roms/u-boot/arch/x86/config.mk new file mode 100644 index 000000000..38cb7c93a --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/config.mk @@ -0,0 +1,32 @@ +# +# (C) Copyright 2000-2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000 + +PLATFORM_CPPFLAGS += -fno-strict-aliasing +PLATFORM_CPPFLAGS += -mregparm=3 +PLATFORM_CPPFLAGS += -fomit-frame-pointer +PF_CPPFLAGS_X86 := $(call cc-option, -fno-toplevel-reorder, \ + $(call cc-option, -fno-unit-at-a-time)) \ + $(call cc-option, -mpreferred-stack-boundary=2) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86) +PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm +PLATFORM_CPPFLAGS += -DREALMODE_BASE=0x7c0 + +# Support generic board on x86 +__HAVE_ARCH_GENERIC_BOARD := y + +PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden + +PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions + +LDFLAGS_FINAL += --gc-sections -pie +LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3 +LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3 + +export NORMAL_LIBGCC = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +CONFIG_USE_PRIVATE_LIBGCC := arch/x86/lib diff --git a/qemu/roms/u-boot/arch/x86/cpu/Makefile b/qemu/roms/u-boot/arch/x86/cpu/Makefile new file mode 100644 index 000000000..415bc2498 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +extra-y = start.o +extra-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o +obj-y = interrupts.o cpu.o diff --git a/qemu/roms/u-boot/arch/x86/cpu/config.mk b/qemu/roms/u-boot/arch/x86/cpu/config.mk new file mode 100644 index 000000000..c1568cacd --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/config.mk @@ -0,0 +1,16 @@ +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +CROSS_COMPILE ?= i386-linux- + +PLATFORM_CPPFLAGS += -DCONFIG_X86 -D__I386__ -march=i386 -Werror + +# DO NOT MODIFY THE FOLLOWING UNLESS YOU REALLY KNOW WHAT YOU ARE DOING! +LDPPFLAGS += -DRESET_SEG_START=0xffff0000 +LDPPFLAGS += -DRESET_SEG_SIZE=0x10000 +LDPPFLAGS += -DRESET_VEC_LOC=0xfff0 +LDPPFLAGS += -DSTART_16=0xf800 diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/Makefile b/qemu/roms/u-boot/arch/x86/cpu/coreboot/Makefile new file mode 100644 index 000000000..cd0bf4ed3 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/Makefile @@ -0,0 +1,22 @@ +# +# Copyright (c) 2011 The Chromium OS Authors. +# +# (C) Copyright 2008 +# Graeme Russ, graeme.russ@gmail.com. +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_SYS_COREBOOT) += car.o +obj-$(CONFIG_SYS_COREBOOT) += coreboot.o +obj-$(CONFIG_SYS_COREBOOT) += tables.o +obj-$(CONFIG_SYS_COREBOOT) += ipchecksum.o +obj-$(CONFIG_SYS_COREBOOT) += sdram.o +obj-$(CONFIG_SYS_COREBOOT) += timestamp.o +obj-$(CONFIG_PCI) += pci.o diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/car.S b/qemu/roms/u-boot/arch/x86/cpu/coreboot/car.S new file mode 100644 index 000000000..6982106c1 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/car.S @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.section .text + +.globl car_init +car_init: + jmp car_init_ret diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/coreboot.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/coreboot.c new file mode 100644 index 000000000..e24f13afa --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/coreboot.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2008 + * Graeme Russ, graeme.russ@gmail.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/u-boot-x86.h> +#include <flash.h> +#include <netdev.h> +#include <ns16550.h> +#include <asm/msr.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <asm/arch-coreboot/tables.h> +#include <asm/arch-coreboot/sysinfo.h> +#include <asm/arch/timestamp.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Miscellaneous platform dependent initializations + */ +int cpu_init_f(void) +{ + int ret = get_coreboot_info(&lib_sysinfo); + if (ret != 0) + printf("Failed to parse coreboot tables.\n"); + + timestamp_init(); + + return ret; +} + +int board_early_init_f(void) +{ + return 0; +} + +int board_early_init_r(void) +{ + /* CPU Speed to 100MHz */ + gd->cpu_clk = 100000000; + + /* Crystal is 33.000MHz */ + gd->bus_clk = 33000000; + + return 0; +} + +void show_boot_progress(int val) +{ +#if MIN_PORT80_KCLOCKS_DELAY + /* + * Scale the time counter reading to avoid using 64 bit arithmetics. + * Can't use get_timer() here becuase it could be not yet + * initialized or even implemented. + */ + if (!gd->arch.tsc_prev) { + gd->arch.tsc_base_kclocks = rdtsc() / 1000; + gd->arch.tsc_prev = 0; + } else { + uint32_t now; + + do { + now = rdtsc() / 1000 - gd->arch.tsc_base_kclocks; + } while (now < (gd->arch.tsc_prev + MIN_PORT80_KCLOCKS_DELAY)); + gd->arch.tsc_prev = now; + } +#endif + outb(val, 0x80); +} + +int last_stage_init(void) +{ + if (gd->flags & GD_FLG_COLD_BOOT) + timestamp_add_to_bootstage(); + + return 0; +} + +#ifndef CONFIG_SYS_NO_FLASH +ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info) +{ + return 0; +} +#endif + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} + +#define MTRR_TYPE_WP 5 +#define MTRRcap_MSR 0xfe +#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) +#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) + +int board_final_cleanup(void) +{ + /* Un-cache the ROM so the kernel has one + * more MTRR available. + * + * Coreboot should have assigned this to the + * top available variable MTRR. + */ + u8 top_mtrr = (native_read_msr(MTRRcap_MSR) & 0xff) - 1; + u8 top_type = native_read_msr(MTRRphysBase_MSR(top_mtrr)) & 0xff; + + /* Make sure this MTRR is the correct Write-Protected type */ + if (top_type == MTRR_TYPE_WP) { + disable_caches(); + wrmsrl(MTRRphysBase_MSR(top_mtrr), 0); + wrmsrl(MTRRphysMask_MSR(top_mtrr), 0); + enable_caches(); + } + + /* Issue SMI to Coreboot to lock down ME and registers */ + printf("Finalizing Coreboot\n"); + outb(0xcb, 0xb2); + + return 0; +} + +void panic_puts(const char *str) +{ + NS16550_t port = (NS16550_t)0x3f8; + + NS16550_init(port, 1); + while (*str) + NS16550_putc(port, *str++); +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/ipchecksum.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/ipchecksum.c new file mode 100644 index 000000000..57733d8f0 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/ipchecksum.c @@ -0,0 +1,54 @@ +/* + * This file is part of the libpayload project. + * + * It has originally been taken from the FreeBSD project. + * + * Copyright (c) 2001 Charles Mott <cm@linktel.net> + * Copyright (c) 2008 coresystems GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <compiler.h> +#include <asm/arch-coreboot/ipchecksum.h> + +unsigned short ipchksum(const void *vptr, unsigned long nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *) ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return ~sum; +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/pci.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/pci.c new file mode 100644 index 000000000..33f16a307 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/pci.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2008,2009 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <pci.h> +#include <asm/pci.h> + +static struct pci_controller coreboot_hose; + +static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev, + struct pci_config_table *table) +{ + u8 secondary; + hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary); + hose->last_busno = max(hose->last_busno, secondary); + pci_hose_scan_bus(hose, secondary); +} + +static struct pci_config_table pci_coreboot_config_table[] = { + /* vendor, device, class, bus, dev, func */ + { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, + PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge }, + {} +}; + +void pci_init_board(void) +{ + coreboot_hose.config_table = pci_coreboot_config_table; + coreboot_hose.first_busno = 0; + coreboot_hose.last_busno = 0; + + pci_set_region(coreboot_hose.regions + 0, 0x0, 0x0, 0xffffffff, + PCI_REGION_MEM); + coreboot_hose.region_count = 1; + + pci_setup_type1(&coreboot_hose); + + pci_register_hose(&coreboot_hose); + + pci_hose_scan(&coreboot_hose); +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/sdram.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/sdram.c new file mode 100644 index 000000000..959feaaea --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/sdram.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010,2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <asm/e820.h> +#include <asm/u-boot-x86.h> +#include <asm/global_data.h> +#include <asm/processor.h> +#include <asm/sections.h> +#include <asm/arch/sysinfo.h> +#include <asm/arch/tables.h> + +DECLARE_GLOBAL_DATA_PTR; + +unsigned install_e820_map(unsigned max_entries, struct e820entry *entries) +{ + int i; + + unsigned num_entries = min(lib_sysinfo.n_memranges, max_entries); + if (num_entries < lib_sysinfo.n_memranges) { + printf("Warning: Limiting e820 map to %d entries.\n", + num_entries); + } + for (i = 0; i < num_entries; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + + entries[i].addr = memrange->base; + entries[i].size = memrange->size; + entries[i].type = memrange->type; + } + return num_entries; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. It + * overrides the default implementation found elsewhere which simply picks the + * end of ram, wherever that may be. The location of the stack, the relocation + * address, and how far U-Boot is moved by relocation are set in the global + * data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + uintptr_t dest_addr = 0; + int i; + + for (i = 0; i < lib_sysinfo.n_memranges; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + /* Force U-Boot to relocate to a page aligned address. */ + uint64_t start = roundup(memrange->base, 1 << 12); + uint64_t end = memrange->base + memrange->size; + + /* Ignore non-memory regions. */ + if (memrange->type != CB_MEM_RAM) + continue; + + /* Filter memory over 4GB. */ + if (end > 0xffffffffULL) + end = 0x100000000ULL; + /* Skip this region if it's too small. */ + if (end - start < total_size) + continue; + + /* Use this address if it's the largest so far. */ + if (end > dest_addr) + dest_addr = end; + } + + /* If no suitable area was found, return an error. */ + if (!dest_addr) + panic("No available memory found for relocation"); + + return (ulong)dest_addr; +} + +int dram_init_f(void) +{ + int i; + phys_size_t ram_size = 0; + + for (i = 0; i < lib_sysinfo.n_memranges; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + unsigned long long end = memrange->base + memrange->size; + + if (memrange->type == CB_MEM_RAM && end > ram_size) + ram_size = end; + } + gd->ram_size = ram_size; + if (ram_size == 0) + return -1; + return 0; +} + +int dram_init_banksize(void) +{ + int i, j; + + if (CONFIG_NR_DRAM_BANKS) { + for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) { + struct memrange *memrange = &lib_sysinfo.memrange[i]; + + if (memrange->type == CB_MEM_RAM) { + gd->bd->bi_dram[j].start = memrange->base; + gd->bd->bi_dram[j].size = memrange->size; + j++; + if (j >= CONFIG_NR_DRAM_BANKS) + break; + } + } + } + return 0; +} + +int dram_init(void) +{ + return dram_init_banksize(); +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/tables.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/tables.c new file mode 100644 index 000000000..0d91adc5e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/tables.c @@ -0,0 +1,235 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * Copyright (C) 2009 coresystems GmbH + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common.h> +#include <asm/arch-coreboot/ipchecksum.h> +#include <asm/arch-coreboot/sysinfo.h> +#include <asm/arch-coreboot/tables.h> + +/* + * This needs to be in the .data section so that it's copied over during + * relocation. By default it's put in the .bss section which is simply filled + * with zeroes when transitioning from "ROM", which is really RAM, to other + * RAM. + */ +struct sysinfo_t lib_sysinfo __attribute__((section(".data"))); + +/* + * Some of this is x86 specific, and the rest of it is generic. Right now, + * since we only support x86, we'll avoid trying to make lots of infrastructure + * we don't need. If in the future, we want to use coreboot on some other + * architecture, then take out the generic parsing code and move it elsewhere. + */ + +/* === Parsing code === */ +/* This is the generic parsing code. */ + +static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_memory *mem = (struct cb_memory *)ptr; + int count = MEM_RANGE_COUNT(mem); + int i; + + if (count > SYSINFO_MAX_MEM_RANGES) + count = SYSINFO_MAX_MEM_RANGES; + + info->n_memranges = 0; + + for (i = 0; i < count; i++) { + struct cb_memory_range *range = + (struct cb_memory_range *)MEM_RANGE_PTR(mem, i); + + info->memrange[info->n_memranges].base = + UNPACK_CB64(range->start); + + info->memrange[info->n_memranges].size = + UNPACK_CB64(range->size); + + info->memrange[info->n_memranges].type = range->type; + + info->n_memranges++; + } +} + +static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_serial *ser = (struct cb_serial *)ptr; + info->serial = ser; +} + +static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr; + + info->vbnv_start = vbnv->vbnv_start; + info->vbnv_size = vbnv->vbnv_size; +} + +static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info) +{ + int i; + struct cb_gpios *gpios = (struct cb_gpios *)ptr; + + info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ? + (gpios->count) : SYSINFO_MAX_GPIOS; + + for (i = 0; i < info->num_gpios; i++) + info->gpios[i] = gpios->gpios[i]; +} + +static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_vdat *vdat = (struct cb_vdat *) ptr; + + info->vdat_addr = vdat->vdat_addr; + info->vdat_size = vdat->vdat_size; +} + +static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info) +{ + info->tstamp_table = ((struct cb_cbmem_tab *)ptr)->cbmem_tab; +} + +static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info) +{ + info->cbmem_cons = ((struct cb_cbmem_tab *)ptr)->cbmem_tab; +} + +static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info) +{ + info->framebuffer = (struct cb_framebuffer *)ptr; +} + +static void cb_parse_string(unsigned char *ptr, char **info) +{ + *info = (char *)((struct cb_string *)ptr)->string; +} + +static int cb_parse_header(void *addr, int len, struct sysinfo_t *info) +{ + struct cb_header *header; + unsigned char *ptr = (unsigned char *)addr; + int i; + + for (i = 0; i < len; i += 16, ptr += 16) { + header = (struct cb_header *)ptr; + if (!strncmp((const char *)header->signature, "LBIO", 4)) + break; + } + + /* We walked the entire space and didn't find anything. */ + if (i >= len) + return -1; + + if (!header->table_bytes) + return 0; + + /* Make sure the checksums match. */ + if (ipchksum((u16 *) header, sizeof(*header)) != 0) + return -1; + + if (ipchksum((u16 *) (ptr + sizeof(*header)), + header->table_bytes) != header->table_checksum) + return -1; + + /* Now, walk the tables. */ + ptr += header->header_bytes; + + /* Inintialize some fields to sentinel values. */ + info->vbnv_start = info->vbnv_size = (uint32_t)(-1); + + for (i = 0; i < header->table_entries; i++) { + struct cb_record *rec = (struct cb_record *)ptr; + + /* We only care about a few tags here (maybe more later). */ + switch (rec->tag) { + case CB_TAG_FORWARD: + return cb_parse_header( + (void *)(unsigned long) + ((struct cb_forward *)rec)->forward, + len, info); + continue; + case CB_TAG_MEMORY: + cb_parse_memory(ptr, info); + break; + case CB_TAG_SERIAL: + cb_parse_serial(ptr, info); + break; + case CB_TAG_VERSION: + cb_parse_string(ptr, &info->version); + break; + case CB_TAG_EXTRA_VERSION: + cb_parse_string(ptr, &info->extra_version); + break; + case CB_TAG_BUILD: + cb_parse_string(ptr, &info->build); + break; + case CB_TAG_COMPILE_TIME: + cb_parse_string(ptr, &info->compile_time); + break; + case CB_TAG_COMPILE_BY: + cb_parse_string(ptr, &info->compile_by); + break; + case CB_TAG_COMPILE_HOST: + cb_parse_string(ptr, &info->compile_host); + break; + case CB_TAG_COMPILE_DOMAIN: + cb_parse_string(ptr, &info->compile_domain); + break; + case CB_TAG_COMPILER: + cb_parse_string(ptr, &info->compiler); + break; + case CB_TAG_LINKER: + cb_parse_string(ptr, &info->linker); + break; + case CB_TAG_ASSEMBLER: + cb_parse_string(ptr, &info->assembler); + break; + /* + * FIXME we should warn on serial if coreboot set up a + * framebuffer buf the payload does not know about it. + */ + case CB_TAG_FRAMEBUFFER: + cb_parse_framebuffer(ptr, info); + break; + case CB_TAG_GPIO: + cb_parse_gpios(ptr, info); + break; + case CB_TAG_VDAT: + cb_parse_vdat(ptr, info); + break; + case CB_TAG_TIMESTAMPS: + cb_parse_tstamp(ptr, info); + break; + case CB_TAG_CBMEM_CONSOLE: + cb_parse_cbmem_cons(ptr, info); + break; + case CB_TAG_VBNV: + cb_parse_vbnv(ptr, info); + break; + } + + ptr += rec->size; + } + + return 1; +} + +/* == Architecture specific == */ +/* This is the x86 specific stuff. */ + +int get_coreboot_info(struct sysinfo_t *info) +{ + int ret = cb_parse_header((void *)0x00000000, 0x1000, info); + + if (ret != 1) + ret = cb_parse_header((void *)0x000f0000, 0x1000, info); + + return (ret == 1) ? 0 : -1; +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/coreboot/timestamp.c b/qemu/roms/u-boot/arch/x86/cpu/coreboot/timestamp.c new file mode 100644 index 000000000..bd3558a02 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/coreboot/timestamp.c @@ -0,0 +1,101 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#include <common.h> +#include <asm/arch/timestamp.h> +#include <asm/arch/sysinfo.h> +#include <linux/compiler.h> + +struct timestamp_entry { + uint32_t entry_id; + uint64_t entry_stamp; +} __packed; + +struct timestamp_table { + uint64_t base_time; + uint32_t max_entries; + uint32_t num_entries; + struct timestamp_entry entries[0]; /* Variable number of entries */ +} __packed; + +static struct timestamp_table *ts_table __attribute__((section(".data"))); + +void timestamp_init(void) +{ + ts_table = lib_sysinfo.tstamp_table; +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(ts_table->base_time); +#endif + timestamp_add_now(TS_U_BOOT_INITTED); +} + +void timestamp_add(enum timestamp_id id, uint64_t ts_time) +{ + struct timestamp_entry *tse; + + if (!ts_table || (ts_table->num_entries == ts_table->max_entries)) + return; + + tse = &ts_table->entries[ts_table->num_entries++]; + tse->entry_id = id; + tse->entry_stamp = ts_time - ts_table->base_time; +} + +void timestamp_add_now(enum timestamp_id id) +{ + timestamp_add(id, rdtsc()); +} + +int timestamp_add_to_bootstage(void) +{ + uint i; + + if (!ts_table) + return -1; + + for (i = 0; i < ts_table->num_entries; i++) { + struct timestamp_entry *tse = &ts_table->entries[i]; + const char *name = NULL; + + switch (tse->entry_id) { + case TS_START_ROMSTAGE: + name = "start-romstage"; + break; + case TS_BEFORE_INITRAM: + name = "before-initram"; + break; + case TS_DEVICE_INITIALIZE: + name = "device-initialize"; + break; + case TS_DEVICE_DONE: + name = "device-done"; + break; + case TS_SELFBOOT_JUMP: + name = "selfboot-jump"; + break; + } + if (name) { + bootstage_add_record(0, name, BOOTSTAGEF_ALLOC, + tse->entry_stamp / + get_tbclk_mhz()); + } + } + + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/cpu.c b/qemu/roms/u-boot/arch/x86/cpu/cpu.c new file mode 100644 index 000000000..623e3af61 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/cpu.c @@ -0,0 +1,242 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <asm/control_regs.h> +#include <asm/processor.h> +#include <asm/processor-flags.h> +#include <asm/interrupt.h> +#include <linux/compiler.h> + +/* + * Constructor for a conventional segment GDT (or LDT) entry + * This is a macro so it can be used in initialisers + */ +#define GDT_ENTRY(flags, base, limit) \ + ((((base) & 0xff000000ULL) << (56-24)) | \ + (((flags) & 0x0000f0ffULL) << 40) | \ + (((limit) & 0x000f0000ULL) << (48-16)) | \ + (((base) & 0x00ffffffULL) << 16) | \ + (((limit) & 0x0000ffffULL))) + +struct gdt_ptr { + u16 len; + u32 ptr; +} __packed; + +static void load_ds(u32 segment) +{ + asm volatile("movl %0, %%ds" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_es(u32 segment) +{ + asm volatile("movl %0, %%es" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_fs(u32 segment) +{ + asm volatile("movl %0, %%fs" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_gs(u32 segment) +{ + asm volatile("movl %0, %%gs" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_ss(u32 segment) +{ + asm volatile("movl %0, %%ss" : : "r" (segment * X86_GDT_ENTRY_SIZE)); +} + +static void load_gdt(const u64 *boot_gdt, u16 num_entries) +{ + struct gdt_ptr gdt; + + gdt.len = (num_entries * 8) - 1; + gdt.ptr = (u32)boot_gdt; + + asm volatile("lgdtl %0\n" : : "m" (gdt)); +} + +void setup_gdt(gd_t *id, u64 *gdt_addr) +{ + /* CS: code, read/execute, 4 GB, base 0 */ + gdt_addr[X86_GDT_ENTRY_32BIT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff); + + /* DS: data, read/write, 4 GB, base 0 */ + gdt_addr[X86_GDT_ENTRY_32BIT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff); + + /* FS: data, read/write, 4 GB, base (Global Data Pointer) */ + id->arch.gd_addr = id; + gdt_addr[X86_GDT_ENTRY_32BIT_FS] = GDT_ENTRY(0xc093, + (ulong)&id->arch.gd_addr, 0xfffff); + + /* 16-bit CS: code, read/execute, 64 kB, base 0 */ + gdt_addr[X86_GDT_ENTRY_16BIT_CS] = GDT_ENTRY(0x109b, 0, 0x0ffff); + + /* 16-bit DS: data, read/write, 64 kB, base 0 */ + gdt_addr[X86_GDT_ENTRY_16BIT_DS] = GDT_ENTRY(0x1093, 0, 0x0ffff); + + load_gdt(gdt_addr, X86_GDT_NUM_ENTRIES); + load_ds(X86_GDT_ENTRY_32BIT_DS); + load_es(X86_GDT_ENTRY_32BIT_DS); + load_gs(X86_GDT_ENTRY_32BIT_DS); + load_ss(X86_GDT_ENTRY_32BIT_DS); + load_fs(X86_GDT_ENTRY_32BIT_FS); +} + +int __weak x86_cleanup_before_linux(void) +{ +#ifdef CONFIG_BOOTSTAGE_STASH + bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH, + CONFIG_BOOTSTAGE_STASH_SIZE); +#endif + + return 0; +} + +int x86_cpu_init_f(void) +{ + const u32 em_rst = ~X86_CR0_EM; + const u32 mp_ne_set = X86_CR0_MP | X86_CR0_NE; + + /* initialize FPU, reset EM, set MP and NE */ + asm ("fninit\n" \ + "movl %%cr0, %%eax\n" \ + "andl %0, %%eax\n" \ + "orl %1, %%eax\n" \ + "movl %%eax, %%cr0\n" \ + : : "i" (em_rst), "i" (mp_ne_set) : "eax"); + + return 0; +} +int cpu_init_f(void) __attribute__((weak, alias("x86_cpu_init_f"))); + +int x86_cpu_init_r(void) +{ + /* Initialize core interrupt and exception functionality of CPU */ + cpu_init_interrupts(); + return 0; +} +int cpu_init_r(void) __attribute__((weak, alias("x86_cpu_init_r"))); + +void x86_enable_caches(void) +{ + unsigned long cr0; + + cr0 = read_cr0(); + cr0 &= ~(X86_CR0_NW | X86_CR0_CD); + write_cr0(cr0); + wbinvd(); +} +void enable_caches(void) __attribute__((weak, alias("x86_enable_caches"))); + +void x86_disable_caches(void) +{ + unsigned long cr0; + + cr0 = read_cr0(); + cr0 |= X86_CR0_NW | X86_CR0_CD; + wbinvd(); + write_cr0(cr0); + wbinvd(); +} +void disable_caches(void) __attribute__((weak, alias("x86_disable_caches"))); + +int x86_init_cache(void) +{ + enable_caches(); + + return 0; +} +int init_cache(void) __attribute__((weak, alias("x86_init_cache"))); + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + printf("resetting ...\n"); + + /* wait 50 ms */ + udelay(50000); + disable_interrupts(); + reset_cpu(0); + + /*NOTREACHED*/ + return 0; +} + +void flush_cache(unsigned long dummy1, unsigned long dummy2) +{ + asm("wbinvd\n"); +} + +void __attribute__ ((regparm(0))) generate_gpf(void); + +/* segment 0x70 is an arbitrary segment which does not exist */ +asm(".globl generate_gpf\n" + ".hidden generate_gpf\n" + ".type generate_gpf, @function\n" + "generate_gpf:\n" + "ljmp $0x70, $0x47114711\n"); + +void __reset_cpu(ulong addr) +{ + printf("Resetting using x86 Triple Fault\n"); + set_vector(13, generate_gpf); /* general protection fault handler */ + set_vector(8, generate_gpf); /* double fault handler */ + generate_gpf(); /* start the show */ +} +void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu"))); + +int dcache_status(void) +{ + return !(read_cr0() & 0x40000000); +} + +/* Define these functions to allow ehch-hcd to function */ +void flush_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void invalidate_dcache_range(unsigned long start, unsigned long stop) +{ +} + +void dcache_enable(void) +{ + enable_caches(); +} + +void dcache_disable(void) +{ + disable_caches(); +} + +void icache_enable(void) +{ +} + +void icache_disable(void) +{ +} + +int icache_status(void) +{ + return 1; +} diff --git a/qemu/roms/u-boot/arch/x86/cpu/interrupts.c b/qemu/roms/u-boot/arch/x86/cpu/interrupts.c new file mode 100644 index 000000000..6f3d85fab --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/interrupts.c @@ -0,0 +1,633 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * Portions of this file are derived from the Linux kernel source + * Copyright (C) 1991, 1992 Linus Torvalds + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/cache.h> +#include <asm/control_regs.h> +#include <asm/interrupt.h> +#include <asm/io.h> +#include <asm/processor-flags.h> +#include <linux/compiler.h> +#include <asm/msr.h> +#include <asm/u-boot-x86.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define DECLARE_INTERRUPT(x) \ + ".globl irq_"#x"\n" \ + ".hidden irq_"#x"\n" \ + ".type irq_"#x", @function\n" \ + "irq_"#x":\n" \ + "pushl $"#x"\n" \ + "jmp irq_common_entry\n" + +void dump_regs(struct irq_regs *regs) +{ + unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; + unsigned long d0, d1, d2, d3, d6, d7; + unsigned long sp; + + printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n", + (u16)regs->xcs, regs->eip, regs->eflags); + + printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", + regs->eax, regs->ebx, regs->ecx, regs->edx); + printf("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", + regs->esi, regs->edi, regs->ebp, regs->esp); + printf(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", + (u16)regs->xds, (u16)regs->xes, (u16)regs->xfs, + (u16)regs->xgs, (u16)regs->xss); + + cr0 = read_cr0(); + cr2 = read_cr2(); + cr3 = read_cr3(); + cr4 = read_cr4(); + + printf("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", + cr0, cr2, cr3, cr4); + + d0 = get_debugreg(0); + d1 = get_debugreg(1); + d2 = get_debugreg(2); + d3 = get_debugreg(3); + + printf("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n", + d0, d1, d2, d3); + + d6 = get_debugreg(6); + d7 = get_debugreg(7); + printf("DR6: %08lx DR7: %08lx\n", + d6, d7); + + printf("Stack:\n"); + sp = regs->esp; + + sp += 64; + + while (sp > (regs->esp - 16)) { + if (sp == regs->esp) + printf("--->"); + else + printf(" "); + printf("0x%8.8lx : 0x%8.8lx\n", sp, (ulong)readl(sp)); + sp -= 4; + } +} + +struct idt_entry { + u16 base_low; + u16 selector; + u8 res; + u8 access; + u16 base_high; +} __packed; + +struct desc_ptr { + unsigned short size; + unsigned long address; + unsigned short segment; +} __packed; + +struct idt_entry idt[256] __aligned(16); + +struct desc_ptr idt_ptr; + +static inline void load_idt(const struct desc_ptr *dtr) +{ + asm volatile("cs lidt %0" : : "m" (*dtr)); +} + +void set_vector(u8 intnum, void *routine) +{ + idt[intnum].base_high = (u16)((u32)(routine) >> 16); + idt[intnum].base_low = (u16)((u32)(routine) & 0xffff); +} + +/* + * Ideally these would be defined static to avoid a checkpatch warning, but + * the compiler cannot see them in the inline asm and complains that they + * aren't defined + */ +void irq_0(void); +void irq_1(void); + +int cpu_init_interrupts(void) +{ + int i; + + int irq_entry_size = irq_1 - irq_0; + void *irq_entry = (void *)irq_0; + + /* Just in case... */ + disable_interrupts(); + + /* Setup the IDT */ + for (i = 0; i < 256; i++) { + idt[i].access = 0x8e; + idt[i].res = 0; + idt[i].selector = 0x10; + set_vector(i, irq_entry); + irq_entry += irq_entry_size; + } + + idt_ptr.size = 256 * 8; + idt_ptr.address = (unsigned long) idt; + idt_ptr.segment = 0x18; + + load_idt(&idt_ptr); + + /* It is now safe to enable interrupts */ + enable_interrupts(); + + return 0; +} + +void __do_irq(int irq) +{ + printf("Unhandled IRQ : %d\n", irq); +} +void do_irq(int irq) __attribute__((weak, alias("__do_irq"))); + +void enable_interrupts(void) +{ + asm("sti\n"); +} + +int disable_interrupts(void) +{ + long flags; + + asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); + + return flags & X86_EFLAGS_IF; +} + +/* IRQ Low-Level Service Routine */ +void irq_llsr(struct irq_regs *regs) +{ + /* + * For detailed description of each exception, refer to: + * Intel® 64 and IA-32 Architectures Software Developer's Manual + * Volume 1: Basic Architecture + * Order Number: 253665-029US, November 2008 + * Table 6-1. Exceptions and Interrupts + */ + switch (regs->irq_id) { + case 0x00: + printf("Divide Error (Division by zero)\n"); + dump_regs(regs); + hang(); + break; + case 0x01: + printf("Debug Interrupt (Single step)\n"); + dump_regs(regs); + break; + case 0x02: + printf("NMI Interrupt\n"); + dump_regs(regs); + break; + case 0x03: + printf("Breakpoint\n"); + dump_regs(regs); + break; + case 0x04: + printf("Overflow\n"); + dump_regs(regs); + hang(); + break; + case 0x05: + printf("BOUND Range Exceeded\n"); + dump_regs(regs); + hang(); + break; + case 0x06: + printf("Invalid Opcode (UnDefined Opcode)\n"); + dump_regs(regs); + hang(); + break; + case 0x07: + printf("Device Not Available (No Math Coprocessor)\n"); + dump_regs(regs); + hang(); + break; + case 0x08: + printf("Double fault\n"); + dump_regs(regs); + hang(); + break; + case 0x09: + printf("Co-processor segment overrun\n"); + dump_regs(regs); + hang(); + break; + case 0x0a: + printf("Invalid TSS\n"); + dump_regs(regs); + break; + case 0x0b: + printf("Segment Not Present\n"); + dump_regs(regs); + hang(); + break; + case 0x0c: + printf("Stack Segment Fault\n"); + dump_regs(regs); + hang(); + break; + case 0x0d: + printf("General Protection\n"); + dump_regs(regs); + break; + case 0x0e: + printf("Page fault\n"); + dump_regs(regs); + hang(); + break; + case 0x0f: + printf("Floating-Point Error (Math Fault)\n"); + dump_regs(regs); + break; + case 0x10: + printf("Alignment check\n"); + dump_regs(regs); + break; + case 0x11: + printf("Machine Check\n"); + dump_regs(regs); + break; + case 0x12: + printf("SIMD Floating-Point Exception\n"); + dump_regs(regs); + break; + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + printf("Reserved Exception\n"); + dump_regs(regs); + break; + + default: + /* Hardware or User IRQ */ + do_irq(regs->irq_id); + } +} + +/* + * OK - This looks really horrible, but it serves a purpose - It helps create + * fully relocatable code. + * - The call to irq_llsr will be a relative jump + * - The IRQ entries will be guaranteed to be in order + * Interrupt entries are now very small (a push and a jump) but they are + * now slower (all registers pushed on stack which provides complete + * crash dumps in the low level handlers + * + * Interrupt Entry Point: + * - Interrupt has caused eflags, CS and EIP to be pushed + * - Interrupt Vector Handler has pushed orig_eax + * - pt_regs.esp needs to be adjusted by 40 bytes: + * 12 bytes pushed by CPU (EFLAGSF, CS, EIP) + * 4 bytes pushed by vector handler (irq_id) + * 24 bytes pushed before SP (SS, GS, FS, ES, DS, EAX) + * NOTE: Only longs are pushed on/popped off the stack! + */ +asm(".globl irq_common_entry\n" \ + ".hidden irq_common_entry\n" \ + ".type irq_common_entry, @function\n" \ + "irq_common_entry:\n" \ + "cld\n" \ + "pushl %ss\n" \ + "pushl %gs\n" \ + "pushl %fs\n" \ + "pushl %es\n" \ + "pushl %ds\n" \ + "pushl %eax\n" \ + "movl %esp, %eax\n" \ + "addl $40, %eax\n" \ + "pushl %eax\n" \ + "pushl %ebp\n" \ + "pushl %edi\n" \ + "pushl %esi\n" \ + "pushl %edx\n" \ + "pushl %ecx\n" \ + "pushl %ebx\n" \ + "mov %esp, %eax\n" \ + "call irq_llsr\n" \ + "popl %ebx\n" \ + "popl %ecx\n" \ + "popl %edx\n" \ + "popl %esi\n" \ + "popl %edi\n" \ + "popl %ebp\n" \ + "popl %eax\n" \ + "popl %eax\n" \ + "popl %ds\n" \ + "popl %es\n" \ + "popl %fs\n" \ + "popl %gs\n" \ + "popl %ss\n" \ + "add $4, %esp\n" \ + "iret\n" \ + DECLARE_INTERRUPT(0) \ + DECLARE_INTERRUPT(1) \ + DECLARE_INTERRUPT(2) \ + DECLARE_INTERRUPT(3) \ + DECLARE_INTERRUPT(4) \ + DECLARE_INTERRUPT(5) \ + DECLARE_INTERRUPT(6) \ + DECLARE_INTERRUPT(7) \ + DECLARE_INTERRUPT(8) \ + DECLARE_INTERRUPT(9) \ + DECLARE_INTERRUPT(10) \ + DECLARE_INTERRUPT(11) \ + DECLARE_INTERRUPT(12) \ + DECLARE_INTERRUPT(13) \ + DECLARE_INTERRUPT(14) \ + DECLARE_INTERRUPT(15) \ + DECLARE_INTERRUPT(16) \ + DECLARE_INTERRUPT(17) \ + DECLARE_INTERRUPT(18) \ + DECLARE_INTERRUPT(19) \ + DECLARE_INTERRUPT(20) \ + DECLARE_INTERRUPT(21) \ + DECLARE_INTERRUPT(22) \ + DECLARE_INTERRUPT(23) \ + DECLARE_INTERRUPT(24) \ + DECLARE_INTERRUPT(25) \ + DECLARE_INTERRUPT(26) \ + DECLARE_INTERRUPT(27) \ + DECLARE_INTERRUPT(28) \ + DECLARE_INTERRUPT(29) \ + DECLARE_INTERRUPT(30) \ + DECLARE_INTERRUPT(31) \ + DECLARE_INTERRUPT(32) \ + DECLARE_INTERRUPT(33) \ + DECLARE_INTERRUPT(34) \ + DECLARE_INTERRUPT(35) \ + DECLARE_INTERRUPT(36) \ + DECLARE_INTERRUPT(37) \ + DECLARE_INTERRUPT(38) \ + DECLARE_INTERRUPT(39) \ + DECLARE_INTERRUPT(40) \ + DECLARE_INTERRUPT(41) \ + DECLARE_INTERRUPT(42) \ + DECLARE_INTERRUPT(43) \ + DECLARE_INTERRUPT(44) \ + DECLARE_INTERRUPT(45) \ + DECLARE_INTERRUPT(46) \ + DECLARE_INTERRUPT(47) \ + DECLARE_INTERRUPT(48) \ + DECLARE_INTERRUPT(49) \ + DECLARE_INTERRUPT(50) \ + DECLARE_INTERRUPT(51) \ + DECLARE_INTERRUPT(52) \ + DECLARE_INTERRUPT(53) \ + DECLARE_INTERRUPT(54) \ + DECLARE_INTERRUPT(55) \ + DECLARE_INTERRUPT(56) \ + DECLARE_INTERRUPT(57) \ + DECLARE_INTERRUPT(58) \ + DECLARE_INTERRUPT(59) \ + DECLARE_INTERRUPT(60) \ + DECLARE_INTERRUPT(61) \ + DECLARE_INTERRUPT(62) \ + DECLARE_INTERRUPT(63) \ + DECLARE_INTERRUPT(64) \ + DECLARE_INTERRUPT(65) \ + DECLARE_INTERRUPT(66) \ + DECLARE_INTERRUPT(67) \ + DECLARE_INTERRUPT(68) \ + DECLARE_INTERRUPT(69) \ + DECLARE_INTERRUPT(70) \ + DECLARE_INTERRUPT(71) \ + DECLARE_INTERRUPT(72) \ + DECLARE_INTERRUPT(73) \ + DECLARE_INTERRUPT(74) \ + DECLARE_INTERRUPT(75) \ + DECLARE_INTERRUPT(76) \ + DECLARE_INTERRUPT(77) \ + DECLARE_INTERRUPT(78) \ + DECLARE_INTERRUPT(79) \ + DECLARE_INTERRUPT(80) \ + DECLARE_INTERRUPT(81) \ + DECLARE_INTERRUPT(82) \ + DECLARE_INTERRUPT(83) \ + DECLARE_INTERRUPT(84) \ + DECLARE_INTERRUPT(85) \ + DECLARE_INTERRUPT(86) \ + DECLARE_INTERRUPT(87) \ + DECLARE_INTERRUPT(88) \ + DECLARE_INTERRUPT(89) \ + DECLARE_INTERRUPT(90) \ + DECLARE_INTERRUPT(91) \ + DECLARE_INTERRUPT(92) \ + DECLARE_INTERRUPT(93) \ + DECLARE_INTERRUPT(94) \ + DECLARE_INTERRUPT(95) \ + DECLARE_INTERRUPT(97) \ + DECLARE_INTERRUPT(96) \ + DECLARE_INTERRUPT(98) \ + DECLARE_INTERRUPT(99) \ + DECLARE_INTERRUPT(100) \ + DECLARE_INTERRUPT(101) \ + DECLARE_INTERRUPT(102) \ + DECLARE_INTERRUPT(103) \ + DECLARE_INTERRUPT(104) \ + DECLARE_INTERRUPT(105) \ + DECLARE_INTERRUPT(106) \ + DECLARE_INTERRUPT(107) \ + DECLARE_INTERRUPT(108) \ + DECLARE_INTERRUPT(109) \ + DECLARE_INTERRUPT(110) \ + DECLARE_INTERRUPT(111) \ + DECLARE_INTERRUPT(112) \ + DECLARE_INTERRUPT(113) \ + DECLARE_INTERRUPT(114) \ + DECLARE_INTERRUPT(115) \ + DECLARE_INTERRUPT(116) \ + DECLARE_INTERRUPT(117) \ + DECLARE_INTERRUPT(118) \ + DECLARE_INTERRUPT(119) \ + DECLARE_INTERRUPT(120) \ + DECLARE_INTERRUPT(121) \ + DECLARE_INTERRUPT(122) \ + DECLARE_INTERRUPT(123) \ + DECLARE_INTERRUPT(124) \ + DECLARE_INTERRUPT(125) \ + DECLARE_INTERRUPT(126) \ + DECLARE_INTERRUPT(127) \ + DECLARE_INTERRUPT(128) \ + DECLARE_INTERRUPT(129) \ + DECLARE_INTERRUPT(130) \ + DECLARE_INTERRUPT(131) \ + DECLARE_INTERRUPT(132) \ + DECLARE_INTERRUPT(133) \ + DECLARE_INTERRUPT(134) \ + DECLARE_INTERRUPT(135) \ + DECLARE_INTERRUPT(136) \ + DECLARE_INTERRUPT(137) \ + DECLARE_INTERRUPT(138) \ + DECLARE_INTERRUPT(139) \ + DECLARE_INTERRUPT(140) \ + DECLARE_INTERRUPT(141) \ + DECLARE_INTERRUPT(142) \ + DECLARE_INTERRUPT(143) \ + DECLARE_INTERRUPT(144) \ + DECLARE_INTERRUPT(145) \ + DECLARE_INTERRUPT(146) \ + DECLARE_INTERRUPT(147) \ + DECLARE_INTERRUPT(148) \ + DECLARE_INTERRUPT(149) \ + DECLARE_INTERRUPT(150) \ + DECLARE_INTERRUPT(151) \ + DECLARE_INTERRUPT(152) \ + DECLARE_INTERRUPT(153) \ + DECLARE_INTERRUPT(154) \ + DECLARE_INTERRUPT(155) \ + DECLARE_INTERRUPT(156) \ + DECLARE_INTERRUPT(157) \ + DECLARE_INTERRUPT(158) \ + DECLARE_INTERRUPT(159) \ + DECLARE_INTERRUPT(160) \ + DECLARE_INTERRUPT(161) \ + DECLARE_INTERRUPT(162) \ + DECLARE_INTERRUPT(163) \ + DECLARE_INTERRUPT(164) \ + DECLARE_INTERRUPT(165) \ + DECLARE_INTERRUPT(166) \ + DECLARE_INTERRUPT(167) \ + DECLARE_INTERRUPT(168) \ + DECLARE_INTERRUPT(169) \ + DECLARE_INTERRUPT(170) \ + DECLARE_INTERRUPT(171) \ + DECLARE_INTERRUPT(172) \ + DECLARE_INTERRUPT(173) \ + DECLARE_INTERRUPT(174) \ + DECLARE_INTERRUPT(175) \ + DECLARE_INTERRUPT(176) \ + DECLARE_INTERRUPT(177) \ + DECLARE_INTERRUPT(178) \ + DECLARE_INTERRUPT(179) \ + DECLARE_INTERRUPT(180) \ + DECLARE_INTERRUPT(181) \ + DECLARE_INTERRUPT(182) \ + DECLARE_INTERRUPT(183) \ + DECLARE_INTERRUPT(184) \ + DECLARE_INTERRUPT(185) \ + DECLARE_INTERRUPT(186) \ + DECLARE_INTERRUPT(187) \ + DECLARE_INTERRUPT(188) \ + DECLARE_INTERRUPT(189) \ + DECLARE_INTERRUPT(190) \ + DECLARE_INTERRUPT(191) \ + DECLARE_INTERRUPT(192) \ + DECLARE_INTERRUPT(193) \ + DECLARE_INTERRUPT(194) \ + DECLARE_INTERRUPT(195) \ + DECLARE_INTERRUPT(196) \ + DECLARE_INTERRUPT(197) \ + DECLARE_INTERRUPT(198) \ + DECLARE_INTERRUPT(199) \ + DECLARE_INTERRUPT(200) \ + DECLARE_INTERRUPT(201) \ + DECLARE_INTERRUPT(202) \ + DECLARE_INTERRUPT(203) \ + DECLARE_INTERRUPT(204) \ + DECLARE_INTERRUPT(205) \ + DECLARE_INTERRUPT(206) \ + DECLARE_INTERRUPT(207) \ + DECLARE_INTERRUPT(208) \ + DECLARE_INTERRUPT(209) \ + DECLARE_INTERRUPT(210) \ + DECLARE_INTERRUPT(211) \ + DECLARE_INTERRUPT(212) \ + DECLARE_INTERRUPT(213) \ + DECLARE_INTERRUPT(214) \ + DECLARE_INTERRUPT(215) \ + DECLARE_INTERRUPT(216) \ + DECLARE_INTERRUPT(217) \ + DECLARE_INTERRUPT(218) \ + DECLARE_INTERRUPT(219) \ + DECLARE_INTERRUPT(220) \ + DECLARE_INTERRUPT(221) \ + DECLARE_INTERRUPT(222) \ + DECLARE_INTERRUPT(223) \ + DECLARE_INTERRUPT(224) \ + DECLARE_INTERRUPT(225) \ + DECLARE_INTERRUPT(226) \ + DECLARE_INTERRUPT(227) \ + DECLARE_INTERRUPT(228) \ + DECLARE_INTERRUPT(229) \ + DECLARE_INTERRUPT(230) \ + DECLARE_INTERRUPT(231) \ + DECLARE_INTERRUPT(232) \ + DECLARE_INTERRUPT(233) \ + DECLARE_INTERRUPT(234) \ + DECLARE_INTERRUPT(235) \ + DECLARE_INTERRUPT(236) \ + DECLARE_INTERRUPT(237) \ + DECLARE_INTERRUPT(238) \ + DECLARE_INTERRUPT(239) \ + DECLARE_INTERRUPT(240) \ + DECLARE_INTERRUPT(241) \ + DECLARE_INTERRUPT(242) \ + DECLARE_INTERRUPT(243) \ + DECLARE_INTERRUPT(244) \ + DECLARE_INTERRUPT(245) \ + DECLARE_INTERRUPT(246) \ + DECLARE_INTERRUPT(247) \ + DECLARE_INTERRUPT(248) \ + DECLARE_INTERRUPT(249) \ + DECLARE_INTERRUPT(250) \ + DECLARE_INTERRUPT(251) \ + DECLARE_INTERRUPT(252) \ + DECLARE_INTERRUPT(253) \ + DECLARE_INTERRUPT(254) \ + DECLARE_INTERRUPT(255)); + +#if defined(CONFIG_INTEL_CORE_ARCH) +/* + * Get the number of CPU time counter ticks since it was read first time after + * restart. This yields a free running counter guaranteed to take almost 6 + * years to wrap around even at 100GHz clock rate. + */ +u64 get_ticks(void) +{ + u64 now_tick = rdtsc(); + + if (!gd->arch.tsc_base) + gd->arch.tsc_base = now_tick; + + return now_tick - gd->arch.tsc_base; +} + +#define PLATFORM_INFO_MSR 0xce + +unsigned long get_tbclk(void) +{ + u32 ratio; + u64 platform_info = native_read_msr(PLATFORM_INFO_MSR); + + ratio = (platform_info >> 8) & 0xff; + return 100 * 1000 * 1000 * ratio; /* 100MHz times Max Non Turbo ratio */ +} +#endif diff --git a/qemu/roms/u-boot/arch/x86/cpu/resetvec.S b/qemu/roms/u-boot/arch/x86/cpu/resetvec.S new file mode 100644 index 000000000..68a5b947d --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/resetvec.S @@ -0,0 +1,22 @@ +/* + * U-boot - x86 Startup Code + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* Reset vector, jumps to start16.S */ + +.extern start16 + +.section .resetvec, "ax" +.code16 +reset_vector: + cli + cld + jmp start16 + + .org 0xf + nop diff --git a/qemu/roms/u-boot/arch/x86/cpu/start.S b/qemu/roms/u-boot/arch/x86/cpu/start.S new file mode 100644 index 000000000..329bb3ab3 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/start.S @@ -0,0 +1,188 @@ +/* + * U-boot - x86 Startup Code + * + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <version.h> +#include <asm/global_data.h> +#include <asm/processor.h> +#include <asm/processor-flags.h> +#include <generated/generic-asm-offsets.h> + +.section .text +.code32 +.globl _start +.type _start, @function +.globl _x86boot_start +_x86boot_start: + /* + * This is the fail safe 32-bit bootstrap entry point. The + * following code is not executed from a cold-reset (actually, a + * lot of it is, but from real-mode after cold reset. It is + * repeated here to put the board into a state as close to cold + * reset as necessary) + */ + cli + cld + + /* Turn off cache (this might require a 486-class CPU) */ + movl %cr0, %eax + orl $(X86_CR0_NW | X86_CR0_CD), %eax + movl %eax, %cr0 + wbinvd + + /* Tell 32-bit code it is being entered from an in-RAM copy */ + movw $GD_FLG_WARM_BOOT, %bx + jmp 1f +_start: + /* + * This is the 32-bit cold-reset entry point. Initialize %bx to 0 + * in case we're preceeded by some sort of boot stub. + */ + movw $GD_FLG_COLD_BOOT, %bx +1: + + /* Load the segement registes to match the gdt loaded in start16.S */ + movl $(X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE), %eax + movw %ax, %fs + movw %ax, %ds + movw %ax, %gs + movw %ax, %es + movw %ax, %ss + + /* Clear the interrupt vectors */ + lidt blank_idt_ptr + + /* Early platform init (setup gpio, etc ) */ + jmp early_board_init +.globl early_board_init_ret +early_board_init_ret: + + /* Initialise Cache-As-RAM */ + jmp car_init +.globl car_init_ret +car_init_ret: + /* + * We now have CONFIG_SYS_CAR_SIZE bytes of Cache-As-RAM (or SRAM, + * or fully initialised SDRAM - we really don't care which) + * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack + */ + + /* Stack grows down from top of CAR */ + movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp + + /* Reserve space on stack for global data */ + subl $GENERATED_GBL_DATA_SIZE, %esp + + /* Align global data to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Setup first parameter to setup_gdt */ + movl %esp, %eax + + /* Reserve space for global descriptor table */ + subl $X86_GDT_SIZE, %esp + + /* Align temporary global descriptor table to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Set second parameter to setup_gdt */ + movl %esp, %edx + + /* Setup global descriptor table so gd->xyz works */ + call setup_gdt + + /* Set parameter to board_init_f() to boot flags */ + xorl %eax, %eax + movw %bx, %ax + + /* Enter, U-boot! */ + call board_init_f + + /* indicate (lack of) progress */ + movw $0x85, %ax + jmp die + +.globl board_init_f_r_trampoline +.type board_init_f_r_trampoline, @function +board_init_f_r_trampoline: + /* + * SDRAM has been initialised, U-Boot code has been copied into + * RAM, BSS has been cleared and relocation adjustments have been + * made. It is now time to jump into the in-RAM copy of U-Boot + * + * %eax = Address of top of new stack + */ + + /* Stack grows down from top of SDRAM */ + movl %eax, %esp + + /* Reserve space on stack for global data */ + subl $GENERATED_GBL_DATA_SIZE, %esp + + /* Align global data to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Setup first parameter to memcpy (and setup_gdt) */ + movl %esp, %eax + + /* Setup second parameter to memcpy */ + fs movl 0, %edx + + /* Set third parameter to memcpy */ + movl $GENERATED_GBL_DATA_SIZE, %ecx + + /* Copy global data from CAR to SDRAM stack */ + call memcpy + + /* Reserve space for global descriptor table */ + subl $X86_GDT_SIZE, %esp + + /* Align global descriptor table to 16-byte boundary */ + andl $0xfffffff0, %esp + + /* Set second parameter to setup_gdt */ + movl %esp, %edx + + /* Setup global descriptor table so gd->xyz works */ + call setup_gdt + + /* Re-enter U-Boot by calling board_init_f_r */ + call board_init_f_r + +die: + hlt + jmp die + hlt + +blank_idt_ptr: + .word 0 /* limit */ + .long 0 /* base */ + + .p2align 2 /* force 4-byte alignment */ + +multiboot_header: + /* magic */ + .long 0x1BADB002 + /* flags */ + .long (1 << 16) + /* checksum */ + .long -0x1BADB002 - (1 << 16) + /* header addr */ + .long multiboot_header - _x86boot_start + CONFIG_SYS_TEXT_BASE + /* load addr */ + .long CONFIG_SYS_TEXT_BASE + /* load end addr */ + .long 0 + /* bss end addr */ + .long 0 + /* entry addr */ + .long CONFIG_SYS_TEXT_BASE diff --git a/qemu/roms/u-boot/arch/x86/cpu/start16.S b/qemu/roms/u-boot/arch/x86/cpu/start16.S new file mode 100644 index 000000000..8b9b327cd --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/start16.S @@ -0,0 +1,130 @@ +/* + * U-boot - x86 Startup Code + * + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002,2003 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/global_data.h> +#include <asm/processor-flags.h> + +#define BOOT_SEG 0xffff0000 /* linear segment of boot code */ +#define a32 .byte 0x67; +#define o32 .byte 0x66; + +.section .start16, "ax" +.code16 +.globl start16 +start16: + /* Set the Cold Boot / Hard Reset flag */ + movl $GD_FLG_COLD_BOOT, %ebx + + /* + * First we let the BSP do some early initialization + * this code have to map the flash to its final position + */ + jmp board_init16 +.globl board_init16_ret +board_init16_ret: + + /* Turn of cache (this might require a 486-class CPU) */ + movl %cr0, %eax + orl $(X86_CR0_NW | X86_CR0_CD), %eax + movl %eax, %cr0 + wbinvd + + /* load the temporary Global Descriptor Table */ +o32 cs lidt idt_ptr +o32 cs lgdt gdt_ptr + + /* Now, we enter protected mode */ + movl %cr0, %eax + orl $X86_CR0_PE, %eax + movl %eax, %cr0 + + /* Flush the prefetch queue */ + jmp ff +ff: + /* Finally jump to the 32bit initialization code */ + movw $code32start, %ax + movw %ax, %bp +o32 cs ljmp *(%bp) + + /* 48-bit far pointer */ +code32start: + .long _start /* offset */ + .word 0x10 /* segment */ + +idt_ptr: + .word 0 /* limit */ + .long 0 /* base */ + +/* + * The following Global Descriptor Table is just enough to get us into + * 'Flat Protected Mode' - It will be discarded as soon as the final + * GDT is setup in a safe location in RAM + */ +gdt_ptr: + .word 0x20 /* limit (32 bytes = 4 GDT entries) */ + .long BOOT_SEG + gdt /* base */ + +/* Some CPUs are picky about GDT alignment... */ +.align 16 +gdt: + /* + * The GDT table ... + * + * Selector Type + * 0x00 NULL + * 0x08 Unused + * 0x10 32bit code + * 0x18 32bit data/stack + */ + /* The NULL Desciptor - Mandatory */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* Unused Desciptor - (matches Linux) */ + .word 0x0000 /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x00 /* access */ + .byte 0x00 /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Code Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Exec (Code), Readable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x9b /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ + + /* + * The Data Segment Descriptor: + * - Base = 0x00000000 + * - Size = 4GB + * - Access = Present, Ring 0, Non-Exec (Data), Writable + * - Flags = 4kB Granularity, 32-bit + */ + .word 0xffff /* limit_low */ + .word 0x0000 /* base_low */ + .byte 0x00 /* base_middle */ + .byte 0x93 /* access */ + .byte 0xcf /* flags + limit_high */ + .byte 0x00 /* base_high */ diff --git a/qemu/roms/u-boot/arch/x86/cpu/u-boot.lds b/qemu/roms/u-boot/arch/x86/cpu/u-boot.lds new file mode 100644 index 000000000..f48bff54e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/cpu/u-boot.lds @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */ + __text_start = .; + .text : { *(.text*); } + + . = ALIGN(4); + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { *(.data*) } + + . = ALIGN(4); + .hash : { *(.hash*) } + + . = ALIGN(4); + .got : { *(.got*) } + + . = ALIGN(4); + __data_end = .; + __init_end = .; + + . = ALIGN(4); + .dynsym : { *(.dynsym*) } + + . = ALIGN(4); + __rel_dyn_start = .; + .rel.dyn : { *(.rel.dyn) } + __rel_dyn_end = .; + . = ALIGN(4); + _end = .; + + .bss __rel_dyn_start (OVERLAY) : { + __bss_start = .; + *(.bss) + *(COM*) + . = ALIGN(4); + __bss_end = .; + } + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } + +#ifdef CONFIG_X86_RESET_VECTOR + + /* + * The following expressions place the 16-bit Real-Mode code and + * Reset Vector at the end of the Flash ROM + */ + . = START_16; + .start16 : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + START_16)) { KEEP(*(.start16)); } + + . = RESET_VEC_LOC; + .resetvec : AT (CONFIG_SYS_TEXT_BASE + (CONFIG_SYS_MONITOR_LEN - RESET_SEG_SIZE + RESET_VEC_LOC)) { KEEP(*(.resetvec)); } +#endif +} diff --git a/qemu/roms/u-boot/arch/x86/dts/.gitignore b/qemu/roms/u-boot/arch/x86/dts/.gitignore new file mode 100644 index 000000000..b60ed208c --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/.gitignore @@ -0,0 +1 @@ +*.dtb diff --git a/qemu/roms/u-boot/arch/x86/dts/Makefile b/qemu/roms/u-boot/arch/x86/dts/Makefile new file mode 100644 index 000000000..48265ef6d --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/Makefile @@ -0,0 +1,12 @@ +dtb-y += link.dtb \ + alex.dtb + +targets += $(dtb-y) + +DTC_FLAGS += -R 4 -p 0x1000 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := *.dtb diff --git a/qemu/roms/u-boot/arch/x86/dts/alex.dts b/qemu/roms/u-boot/arch/x86/dts/alex.dts new file mode 100644 index 000000000..2f1354461 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/alex.dts @@ -0,0 +1,24 @@ +/dts-v1/; + +/include/ "coreboot.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "Google Alex"; + compatible = "google,alex", "intel,atom-pineview"; + + config { + silent_console = <0>; + }; + + gpio: gpio {}; + + serial { + reg = <0x3f8 8>; + clock-frequency = <115200>; + }; + + chosen { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/qemu/roms/u-boot/arch/x86/dts/coreboot.dtsi b/qemu/roms/u-boot/arch/x86/dts/coreboot.dtsi new file mode 100644 index 000000000..4862a5970 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/coreboot.dtsi @@ -0,0 +1,16 @@ +/include/ "skeleton.dtsi" + +/ { + aliases { + console = "/serial"; + }; + + serial { + compatible = "ns16550"; + reg-shift = <1>; + io-mapped = <1>; + multiplier = <1>; + baudrate = <115200>; + status = "disabled"; + }; +}; diff --git a/qemu/roms/u-boot/arch/x86/dts/link.dts b/qemu/roms/u-boot/arch/x86/dts/link.dts new file mode 100644 index 000000000..4a37dac4e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/link.dts @@ -0,0 +1,35 @@ +/dts-v1/; + +/include/ "coreboot.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "Google Link"; + compatible = "google,link", "intel,celeron-ivybridge"; + + config { + silent_console = <0>; + }; + + gpio: gpio {}; + + serial { + reg = <0x3f8 8>; + clock-frequency = <115200>; + }; + + chosen { }; + memory { device_type = "memory"; reg = <0 0>; }; + + spi { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ich9"; + spi-flash@0 { + reg = <0>; + compatible = "winbond,w25q64", "spi-flash"; + memory-map = <0xff800000 0x00800000>; + }; + }; +}; diff --git a/qemu/roms/u-boot/arch/x86/dts/skeleton.dtsi b/qemu/roms/u-boot/arch/x86/dts/skeleton.dtsi new file mode 100644 index 000000000..b41d241de --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/dts/skeleton.dtsi @@ -0,0 +1,13 @@ +/* + * Skeleton device tree; the bare minimum needed to boot; just include and + * add a compatible value. The bootloader will typically populate the memory + * node. + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { }; + aliases { }; + memory { device_type = "memory"; reg = <0 0>; }; +}; diff --git a/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/ipchecksum.h b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/ipchecksum.h new file mode 100644 index 000000000..1d73b4d91 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/ipchecksum.h @@ -0,0 +1,37 @@ +/* + * This file is part of the libpayload project. + * + * It has originally been taken from the FreeBSD project. + * + * Copyright (c) 2001 Charles Mott <cm@linktel.net> + * Copyright (c) 2008 coresystems GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _COREBOOT_IPCHECKSUM_H +#define _COREBOOT_IPCHECKSUM_H + +unsigned short ipchksum(const void *vptr, unsigned long nbytes); + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/sysinfo.h b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/sysinfo.h new file mode 100644 index 000000000..8e4a61de7 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/sysinfo.h @@ -0,0 +1,62 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _COREBOOT_SYSINFO_H +#define _COREBOOT_SYSINFO_H + +#include <common.h> +#include <compiler.h> +#include <libfdt.h> +#include <asm/arch/tables.h> + +/* Allow a maximum of 16 memory range definitions. */ +#define SYSINFO_MAX_MEM_RANGES 16 +/* Allow a maximum of 8 GPIOs */ +#define SYSINFO_MAX_GPIOS 8 + +struct sysinfo_t { + int n_memranges; + struct memrange { + unsigned long long base; + unsigned long long size; + unsigned int type; + } memrange[SYSINFO_MAX_MEM_RANGES]; + + u32 cmos_range_start; + u32 cmos_range_end; + u32 cmos_checksum_location; + u32 vbnv_start; + u32 vbnv_size; + + char *version; + char *extra_version; + char *build; + char *compile_time; + char *compile_by; + char *compile_host; + char *compile_domain; + char *compiler; + char *linker; + char *assembler; + + struct cb_framebuffer *framebuffer; + + int num_gpios; + struct cb_gpio gpios[SYSINFO_MAX_GPIOS]; + + void *vdat_addr; + u32 vdat_size; + void *tstamp_table; + void *cbmem_cons; + + struct cb_serial *serial; +}; + +extern struct sysinfo_t lib_sysinfo; + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/tables.h b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/tables.h new file mode 100644 index 000000000..0d02fe059 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/tables.h @@ -0,0 +1,294 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _COREBOOT_TABLES_H +#define _COREBOOT_TABLES_H + +#include <compiler.h> + +struct cbuint64 { + u32 lo; + u32 hi; +}; + +struct cb_header { + u8 signature[4]; + u32 header_bytes; + u32 header_checksum; + u32 table_bytes; + u32 table_checksum; + u32 table_entries; +}; + +struct cb_record { + u32 tag; + u32 size; +}; + +#define CB_TAG_UNUSED 0x0000 +#define CB_TAG_MEMORY 0x0001 + +struct cb_memory_range { + struct cbuint64 start; + struct cbuint64 size; + u32 type; +}; + +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 + +struct cb_memory { + u32 tag; + u32 size; + struct cb_memory_range map[0]; +}; + +#define CB_TAG_HWRPB 0x0002 + +struct cb_hwrpb { + u32 tag; + u32 size; + u64 hwrpb; +}; + +#define CB_TAG_MAINBOARD 0x0003 + +struct cb_mainboard { + u32 tag; + u32 size; + u8 vendor_idx; + u8 part_number_idx; + u8 strings[0]; +}; + +#define CB_TAG_VERSION 0x0004 +#define CB_TAG_EXTRA_VERSION 0x0005 +#define CB_TAG_BUILD 0x0006 +#define CB_TAG_COMPILE_TIME 0x0007 +#define CB_TAG_COMPILE_BY 0x0008 +#define CB_TAG_COMPILE_HOST 0x0009 +#define CB_TAG_COMPILE_DOMAIN 0x000a +#define CB_TAG_COMPILER 0x000b +#define CB_TAG_LINKER 0x000c +#define CB_TAG_ASSEMBLER 0x000d + +struct cb_string { + u32 tag; + u32 size; + u8 string[0]; +}; + +#define CB_TAG_SERIAL 0x000f + +struct cb_serial { + u32 tag; + u32 size; +#define CB_SERIAL_TYPE_IO_MAPPED 1 +#define CB_SERIAL_TYPE_MEMORY_MAPPED 2 + u32 type; + u32 baseaddr; + u32 baud; +}; + +#define CB_TAG_CONSOLE 0x00010 + +struct cb_console { + u32 tag; + u32 size; + u16 type; +}; + +#define CB_TAG_CONSOLE_SERIAL8250 0 +#define CB_TAG_CONSOLE_VGA 1 /* OBSOLETE */ +#define CB_TAG_CONSOLE_BTEXT 2 /* OBSOLETE */ +#define CB_TAG_CONSOLE_LOGBUF 3 +#define CB_TAG_CONSOLE_SROM 4 /* OBSOLETE */ +#define CB_TAG_CONSOLE_EHCI 5 + +#define CB_TAG_FORWARD 0x00011 + +struct cb_forward { + u32 tag; + u32 size; + u64 forward; +}; + +#define CB_TAG_FRAMEBUFFER 0x0012 +struct cb_framebuffer { + u32 tag; + u32 size; + + u64 physical_address; + u32 x_resolution; + u32 y_resolution; + u32 bytes_per_line; + u8 bits_per_pixel; + u8 red_mask_pos; + u8 red_mask_size; + u8 green_mask_pos; + u8 green_mask_size; + u8 blue_mask_pos; + u8 blue_mask_size; + u8 reserved_mask_pos; + u8 reserved_mask_size; +}; + +#define CB_TAG_GPIO 0x0013 +#define GPIO_MAX_NAME_LENGTH 16 +struct cb_gpio { + u32 port; + u32 polarity; + u32 value; + u8 name[GPIO_MAX_NAME_LENGTH]; +}; + +struct cb_gpios { + u32 tag; + u32 size; + + u32 count; + struct cb_gpio gpios[0]; +}; + +#define CB_TAG_FDT 0x0014 +struct cb_fdt { + uint32_t tag; + uint32_t size; /* size of the entire entry */ + /* the actual FDT gets placed here */ +}; + +#define CB_TAG_VDAT 0x0015 +struct cb_vdat { + uint32_t tag; + uint32_t size; /* size of the entire entry */ + void *vdat_addr; + uint32_t vdat_size; +}; + +#define CB_TAG_TIMESTAMPS 0x0016 +#define CB_TAG_CBMEM_CONSOLE 0x0017 +#define CB_TAG_MRC_CACHE 0x0018 +struct cb_cbmem_tab { + uint32_t tag; + uint32_t size; + void *cbmem_tab; +}; + +#define CB_TAG_VBNV 0x0019 +struct cb_vbnv { + uint32_t tag; + uint32_t size; + uint32_t vbnv_start; + uint32_t vbnv_size; +}; + +#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 +struct cb_cmos_option_table { + u32 tag; + u32 size; + u32 header_length; +}; + +#define CB_TAG_OPTION 0x00c9 +#define CMOS_MAX_NAME_LENGTH 32 +struct cb_cmos_entries { + u32 tag; + u32 size; + u32 bit; + u32 length; + u32 config; + u32 config_id; + u8 name[CMOS_MAX_NAME_LENGTH]; +}; + + +#define CB_TAG_OPTION_ENUM 0x00ca +#define CMOS_MAX_TEXT_LENGTH 32 +struct cb_cmos_enums { + u32 tag; + u32 size; + u32 config_id; + u32 value; + u8 text[CMOS_MAX_TEXT_LENGTH]; +}; + +#define CB_TAG_OPTION_DEFAULTS 0x00cb +#define CMOS_IMAGE_BUFFER_SIZE 128 +struct cb_cmos_defaults { + u32 tag; + u32 size; + u32 name_length; + u8 name[CMOS_MAX_NAME_LENGTH]; + u8 default_set[CMOS_IMAGE_BUFFER_SIZE]; +}; + +#define CB_TAG_OPTION_CHECKSUM 0x00cc +#define CHECKSUM_NONE 0 +#define CHECKSUM_PCBIOS 1 +struct cb_cmos_checksum { + u32 tag; + u32 size; + u32 range_start; + u32 range_end; + u32 location; + u32 type; +}; + +/* Helpful macros */ + +#define MEM_RANGE_COUNT(_rec) \ + (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0])) + +#define MEM_RANGE_PTR(_rec, _idx) \ + (((u8 *) (_rec)) + sizeof(*(_rec)) \ + + (sizeof((_rec)->map[0]) * (_idx))) + +#define MB_VENDOR_STRING(_mb) \ + (((unsigned char *) ((_mb)->strings)) + (_mb)->vendor_idx) + +#define MB_PART_STRING(_mb) \ + (((unsigned char *) ((_mb)->strings)) + (_mb)->part_number_idx) + +#define UNPACK_CB64(_in) \ + ((((u64) _in.hi) << 32) | _in.lo) + +struct sysinfo_t; + +int get_coreboot_info(struct sysinfo_t *info); + +#define CBMEM_TOC_RESERVED 512 +#define MAX_CBMEM_ENTRIES 16 +#define CBMEM_MAGIC 0x434f5245 + +struct cbmem_entry { + u32 magic; + u32 id; + u64 base; + u64 size; +} __packed; + +#define CBMEM_ID_FREESPACE 0x46524545 +#define CBMEM_ID_GDT 0x4c474454 +#define CBMEM_ID_ACPI 0x41435049 +#define CBMEM_ID_CBTABLE 0x43425442 +#define CBMEM_ID_PIRQ 0x49525154 +#define CBMEM_ID_MPTABLE 0x534d5054 +#define CBMEM_ID_RESUME 0x5245534d +#define CBMEM_ID_RESUME_SCRATCH 0x52455343 +#define CBMEM_ID_SMBIOS 0x534d4254 +#define CBMEM_ID_TIMESTAMP 0x54494d45 +#define CBMEM_ID_MRCDATA 0x4d524344 +#define CBMEM_ID_CONSOLE 0x434f4e53 +#define CBMEM_ID_NONE 0x00000000 + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/timestamp.h b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/timestamp.h new file mode 100644 index 000000000..fcfc1d544 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/arch-coreboot/timestamp.h @@ -0,0 +1,59 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#ifndef __COREBOOT_TIMESTAMP_H__ +#define __COREBOOT_TIMESTAMP_H__ + +enum timestamp_id { + /* coreboot specific timestamp IDs */ + TS_START_ROMSTAGE = 1, + TS_BEFORE_INITRAM = 2, + TS_AFTER_INITRAM = 3, + TS_END_ROMSTAGE = 4, + TS_START_COPYRAM = 8, + TS_END_COPYRAM = 9, + TS_START_RAMSTAGE = 10, + TS_DEVICE_ENUMERATE = 30, + TS_DEVICE_CONFIGURE = 40, + TS_DEVICE_ENABLE = 50, + TS_DEVICE_INITIALIZE = 60, + TS_DEVICE_DONE = 70, + TS_CBMEM_POST = 75, + TS_WRITE_TABLES = 80, + TS_LOAD_PAYLOAD = 90, + TS_ACPI_WAKE_JUMP = 98, + TS_SELFBOOT_JUMP = 99, + + /* U-Boot entry IDs start at 1000 */ + TS_U_BOOT_INITTED = 1000, /* This is where u-boot starts */ + TS_U_BOOT_START_KERNEL = 1100, /* Right before jumping to kernel. */ +}; + +void timestamp_init(void); +void timestamp_add(enum timestamp_id id, uint64_t ts_time); +void timestamp_add_now(enum timestamp_id id); + +/** + * timestamp_add_to_bootstage - Add important coreboot timestamps to bootstage + * + * @return 0 if ok, -1 if no timestamps were found + */ +int timestamp_add_to_bootstage(void); + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/bitops.h b/qemu/roms/u-boot/arch/x86/include/asm/bitops.h new file mode 100644 index 000000000..5a7e4cba2 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/bitops.h @@ -0,0 +1,389 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +#define ADDR (*(volatile long *) addr) + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its new value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile void * addr); +#endif + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#ifdef __KERNEL__ + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r+1; +} +#define PLATFORM_FFS + +static inline int __ilog2(unsigned int x) +{ + return generic_fls(x) - 1; +} + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +#define ext2_set_bit __test_and_set_bit +#define ext2_clear_bit __test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) __set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _I386_BITOPS_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/bootparam.h b/qemu/roms/u-boot/arch/x86/include/asm/bootparam.h new file mode 100644 index 000000000..140095117 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/bootparam.h @@ -0,0 +1,120 @@ +#ifndef _ASM_X86_BOOTPARAM_H +#define _ASM_X86_BOOTPARAM_H + +#include <linux/types.h> +#include <linux/screen_info.h> +#include <linux/apm_bios.h> +#include <linux/edd.h> +#include <asm/e820.h> +#include <asm/ist.h> +#include <asm/video/edid.h> + +/* setup data types */ +#define SETUP_NONE 0 +#define SETUP_E820_EXT 1 + +/* extensible setup data list node */ +struct setup_data { + __u64 next; + __u32 type; + __u32 len; + __u8 data[0]; +}; + +struct setup_header { + __u8 setup_sects; + __u16 root_flags; + __u32 syssize; + __u16 ram_size; +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + __u16 vid_mode; + __u16 root_dev; + __u16 boot_flag; + __u16 jump; + __u32 header; + __u16 version; + __u32 realmode_swtch; + __u16 start_sys; + __u16 kernel_version; + __u8 type_of_loader; + __u8 loadflags; +#define LOADED_HIGH (1<<0) +#define QUIET_FLAG (1<<5) +#define KEEP_SEGMENTS (1<<6) +#define CAN_USE_HEAP (1<<7) + __u16 setup_move_size; + __u32 code32_start; + __u32 ramdisk_image; + __u32 ramdisk_size; + __u32 bootsect_kludge; + __u16 heap_end_ptr; + __u8 ext_loader_ver; + __u8 ext_loader_type; + __u32 cmd_line_ptr; + __u32 initrd_addr_max; + __u32 kernel_alignment; + __u8 relocatable_kernel; + __u8 _pad2[3]; + __u32 cmdline_size; + __u32 hardware_subarch; + __u64 hardware_subarch_data; + __u32 payload_offset; + __u32 payload_length; + __u64 setup_data; +} __attribute__((packed)); + +struct sys_desc_table { + __u16 length; + __u8 table[14]; +}; + +struct efi_info { + __u32 efi_loader_signature; + __u32 efi_systab; + __u32 efi_memdesc_size; + __u32 efi_memdesc_version; + __u32 efi_memmap; + __u32 efi_memmap_size; + __u32 efi_systab_hi; + __u32 efi_memmap_hi; +}; + +/* The so-called "zeropage" */ +struct boot_params { + struct screen_info screen_info; /* 0x000 */ + struct apm_bios_info apm_bios_info; /* 0x040 */ + __u8 _pad2[4]; /* 0x054 */ + __u64 tboot_addr; /* 0x058 */ + struct ist_info ist_info; /* 0x060 */ + __u8 _pad3[16]; /* 0x070 */ + __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 edid_info edid_info; /* 0x140 */ + struct efi_info efi_info; /* 0x1c0 */ + __u32 alt_mem_k; /* 0x1e0 */ + __u32 scratch; /* Scratch field! */ /* 0x1e4 */ + __u8 e820_entries; /* 0x1e8 */ + __u8 eddbuf_entries; /* 0x1e9 */ + __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ + __u8 _pad6[6]; /* 0x1eb */ + struct setup_header hdr; /* setup header */ /* 0x1f1 */ + __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; + __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ + struct e820entry e820_map[E820MAX]; /* 0x2d0 */ + __u8 _pad8[48]; /* 0xcd0 */ + struct edd_info eddbuf[EDDMAXNR]; /* 0xd00 */ + __u8 _pad9[276]; /* 0xeec */ +} __attribute__((packed)); + +enum { + X86_SUBARCH_PC = 0, + X86_SUBARCH_LGUEST, + X86_SUBARCH_XEN, + X86_SUBARCH_MRST, + X86_NR_SUBARCHS, +}; +#endif /* _ASM_X86_BOOTPARAM_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/byteorder.h b/qemu/roms/u-boot/arch/x86/include/asm/byteorder.h new file mode 100644 index 000000000..7dfeb8bbe --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/byteorder.h @@ -0,0 +1,43 @@ +#ifndef _I386_BYTEORDER_H +#define _I386_BYTEORDER_H + +#include <asm/types.h> + +#ifdef __GNUC__ + + +static __inline__ __u32 ___arch__swab32(__u32 x) +{ +#ifdef CONFIG_X86_BSWAP + __asm__("bswap %0" : "=r" (x) : "0" (x)); +#else + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); +#endif + return x; +} + +static __inline__ __u16 ___arch__swab16(__u16 x) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ \ + : "=q" (x) \ + : "0" (x)); \ + return x; +} + +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#endif /* __GNUC__ */ + +#include <linux/byteorder/little_endian.h> + +#endif /* _I386_BYTEORDER_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/cache.h b/qemu/roms/u-boot/arch/x86/include/asm/cache.h new file mode 100644 index 000000000..508b63f5a --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/cache.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __X86_CACHE_H__ +#define __X86_CACHE_H__ + +/* + * If CONFIG_SYS_CACHELINE_SIZE is defined use it for DMA alignment. Otherwise + * use 64-bytes, a safe default for x86. + */ +#ifdef CONFIG_SYS_CACHELINE_SIZE +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#else +#define ARCH_DMA_MINALIGN 64 +#endif + +static inline void wbinvd(void) +{ + asm volatile ("wbinvd" : : : "memory"); +} + +static inline void invd(void) +{ + asm volatile("invd" : : : "memory"); +} + +/* Enable caches and write buffer */ +void enable_caches(void); + +/* Disable caches and write buffer */ +void disable_caches(void); + +#endif /* __X86_CACHE_H__ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/config.h b/qemu/roms/u-boot/arch/x86/include/asm/config.h new file mode 100644 index 000000000..f06a15cdf --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/config.h @@ -0,0 +1,11 @@ +/* + * Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_CONFIG_H_ +#define _ASM_CONFIG_H_ + +#define CONFIG_SYS_GENERIC_BOARD +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/control_regs.h b/qemu/roms/u-boot/arch/x86/include/asm/control_regs.h new file mode 100644 index 000000000..9e67478a3 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/control_regs.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * Portions of this file are derived from the Linux kernel source + * Copyright (C) 1991, 1992 Linus Torvalds + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __X86_CONTROL_REGS_H +#define __X86_CONTROL_REGS_H + +/* + * The memory clobber prevents the GCC from reordering the read/write order + * of CR0 +*/ +static inline unsigned long read_cr0(void) +{ + unsigned long val; + + asm volatile ("movl %%cr0, %0" : "=r" (val) : : "memory"); + return val; +} + +static inline void write_cr0(unsigned long val) +{ + asm volatile ("movl %0, %%cr0" : : "r" (val) : "memory"); +} + +static inline unsigned long read_cr2(void) +{ + unsigned long val; + + asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long read_cr3(void) +{ + unsigned long val; + + asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long read_cr4(void) +{ + unsigned long val; + + asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : : "memory"); + return val; +} + +static inline unsigned long get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("mov %%db0, %0" : "=r" (val)); + break; + case 1: + asm("mov %%db1, %0" : "=r" (val)); + break; + case 2: + asm("mov %%db2, %0" : "=r" (val)); + break; + case 3: + asm("mov %%db3, %0" : "=r" (val)); + break; + case 6: + asm("mov %%db6, %0" : "=r" (val)); + break; + case 7: + asm("mov %%db7, %0" : "=r" (val)); + break; + default: + val = 0; + } + return val; +} + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/e820.h b/qemu/roms/u-boot/arch/x86/include/asm/e820.h new file mode 100644 index 000000000..d155ce9ce --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/e820.h @@ -0,0 +1,155 @@ +#ifndef _ASM_X86_E820_H +#define _ASM_X86_E820_H +#define E820MAP 0x2d0 /* our map */ +#define E820MAX 128 /* number of entries in E820MAP */ + +/* + * Legacy E820 BIOS limits us to 128 (E820MAX) nodes due to the + * constrained space in the zeropage. If we have more nodes than + * that, and if we've booted off EFI firmware, then the EFI tables + * passed us from the EFI firmware can list more nodes. Size our + * internal memory map tables to have room for these additional + * nodes, based on up to three entries per node for which the + * kernel was built: MAX_NUMNODES == (1 << CONFIG_NODES_SHIFT), + * plus E820MAX, allowing space for the possible duplicate E820 + * entries that might need room in the same arrays, prior to the + * call to sanitize_e820_map() to remove duplicates. The allowance + * of three memory map entries per node is "enough" entries for + * the initial hardware platform motivating this mechanism to make + * use of additional EFI map entries. Future platforms may want + * to allow more than three entries per node or otherwise refine + * this size. + */ + +/* + * Odd: 'make headers_check' complains about numa.h if I try + * to collapse the next two #ifdef lines to a single line: + * #if defined(__KERNEL__) && defined(CONFIG_EFI) + */ +#ifdef __KERNEL__ +#ifdef CONFIG_EFI +#include <linux/numa.h> +#define E820_X_MAX (E820MAX + 3 * MAX_NUMNODES) +#else /* ! CONFIG_EFI */ +#define E820_X_MAX E820MAX +#endif +#else /* ! __KERNEL__ */ +#define E820_X_MAX E820MAX +#endif + +#define E820NR 0x1e8 /* # entries in E820MAP */ + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + +/* reserved RAM used by kernel itself */ +#define E820_RESERVED_KERN 128 + +#ifndef __ASSEMBLY__ +#include <linux/types.h> +struct e820entry { + __u64 addr; /* start of memory segment */ + __u64 size; /* size of memory segment */ + __u32 type; /* type of memory segment */ +} __attribute__((packed)); + +struct e820map { + __u32 nr_map; + struct e820entry map[E820_X_MAX]; +}; + +#define ISA_START_ADDRESS 0xa0000 +#define ISA_END_ADDRESS 0x100000 + +#define BIOS_BEGIN 0x000a0000 +#define BIOS_END 0x00100000 + +#ifdef __KERNEL__ +/* see comment in arch/x86/kernel/e820.c */ +extern struct e820map e820; +extern struct e820map e820_saved; + +extern unsigned long pci_mem_start; +extern int e820_any_mapped(u64 start, u64 end, unsigned type); +extern int e820_all_mapped(u64 start, u64 end, unsigned type); +extern void e820_add_region(u64 start, u64 size, int type); +extern void e820_print_map(char *who); +extern int +sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map); +extern u64 e820_update_range(u64 start, u64 size, unsigned old_type, + unsigned new_type); +extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type, + int checktype); +extern void update_e820(void); +extern void e820_setup_gap(void); +extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize, + unsigned long start_addr, unsigned long long end_addr); +struct setup_data; +extern void parse_e820_ext(struct setup_data *data, unsigned long pa_data); + +#if defined(CONFIG_X86_64) || \ + (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) +extern void e820_mark_nosave_regions(unsigned long limit_pfn); +#else +static inline void e820_mark_nosave_regions(unsigned long limit_pfn) +{ +} +#endif + +#ifdef CONFIG_MEMTEST +extern void early_memtest(unsigned long start, unsigned long end); +#else +static inline void early_memtest(unsigned long start, unsigned long end) +{ +} +#endif + +extern unsigned long end_user_pfn; + +extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); +extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); +extern void reserve_early(u64 start, u64 end, char *name); +extern void reserve_early_overlap_ok(u64 start, u64 end, char *name); +extern void free_early(u64 start, u64 end); +extern void early_res_to_bootmem(u64 start, u64 end); +extern u64 early_reserve_e820(u64 startt, u64 sizet, u64 align); + +extern unsigned long e820_end_of_ram_pfn(void); +extern unsigned long e820_end_of_low_ram_pfn(void); +extern int e820_find_active_region(const struct e820entry *ei, + unsigned long start_pfn, + unsigned long last_pfn, + unsigned long *ei_startpfn, + unsigned long *ei_endpfn); +extern void e820_register_active_regions(int nid, unsigned long start_pfn, + unsigned long end_pfn); +extern u64 e820_hole_size(u64 start, u64 end); +extern void finish_e820_parsing(void); +extern void e820_reserve_resources(void); +extern void e820_reserve_resources_late(void); +extern void setup_memory_map(void); +extern char *default_machine_specific_memory_setup(void); + +/* + * Returns true iff the specified range [s,e) is completely contained inside + * the ISA region. + */ +/* +static inline bool is_ISA_range(u64 s, u64 e) +{ + return s >= ISA_START_ADDRESS && e <= ISA_END_ADDRESS; +} +*/ +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ + +#ifdef __KERNEL__ +/* #include <linux/ioport.h> */ + +#define HIGH_MEMORY (1024*1024) +#endif /* __KERNEL__ */ + +#endif /* _ASM_X86_E820_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/errno.h b/qemu/roms/u-boot/arch/x86/include/asm/errno.h new file mode 100644 index 000000000..4c82b503d --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/qemu/roms/u-boot/arch/x86/include/asm/global_data.h b/qemu/roms/u-boot/arch/x86/include/asm/global_data.h new file mode 100644 index 000000000..3e8e2cdb9 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/global_data.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2002-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H + +#ifndef __ASSEMBLY__ + +/* Architecture-specific global data */ +struct arch_global_data { + struct global_data *gd_addr; /* Location of Global Data */ + uint64_t tsc_base; /* Initial value returned by rdtsc() */ + uint32_t tsc_base_kclocks; /* Initial tsc as a kclocks value */ + uint32_t tsc_prev; /* For show_boot_progress() */ + void *new_fdt; /* Relocated FDT */ +}; + +#endif + +#include <asm-generic/global_data.h> + +#ifndef __ASSEMBLY__ +static inline __attribute__((no_instrument_function)) gd_t *get_fs_gd_ptr(void) +{ + gd_t *gd_ptr; + + asm volatile("fs movl 0, %0\n" : "=r" (gd_ptr)); + + return gd_ptr; +} + +#define gd get_fs_gd_ptr() + +#endif + +/* + * Our private Global Data Flags + */ +#define GD_FLG_COLD_BOOT 0x00100 /* Cold Boot */ +#define GD_FLG_WARM_BOOT 0x00200 /* Warm Boot */ + +#define DECLARE_GLOBAL_DATA_PTR + +#endif /* __ASM_GBL_DATA_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/gpio.h b/qemu/roms/u-boot/arch/x86/include/asm/gpio.h new file mode 100644 index 000000000..fe09f3151 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/gpio.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2012, Google Inc. All rights reserved. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_GPIO_H_ +#define _X86_GPIO_H_ + +#include <asm-generic/gpio.h> + +#endif /* _X86_GPIO_H_ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/i8254.h b/qemu/roms/u-boot/arch/x86/include/asm/i8254.h new file mode 100644 index 000000000..c3ccd4f90 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/i8254.h @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +/* i8254.h Intel 8254 PIT registers */ + + +#ifndef _ASMI386_I8254_H_ +#define _ASMI386_I8954_H_ 1 + + +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ + +/* PIT Command Register Bit Definitions */ + +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ + +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ + +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0A /* Select mode 5 */ + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/i8259.h b/qemu/roms/u-boot/arch/x86/include/asm/i8259.h new file mode 100644 index 000000000..73113f90a --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/i8259.h @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* i8259.h i8259 PIC Registers */ + +#ifndef _ASMI386_I8259_H_ +#define _ASMI386_I8959_H_ 1 + + +/* PIC I/O mapped registers */ + +#define IRR 0x0 /* Interrupt Request Register */ +#define ISR 0x0 /* In-Service Register */ +#define ICW1 0x0 /* Initialization Control Word 1 */ +#define OCW2 0x0 /* Operation Control Word 2 */ +#define OCW3 0x0 /* Operation Control Word 3 */ +#define ICW2 0x1 /* Initialization Control Word 2 */ +#define ICW3 0x1 /* Initialization Control Word 3 */ +#define ICW4 0x1 /* Initialization Control Word 4 */ +#define IMR 0x1 /* Interrupt Mask Register */ + +/* bits for IRR, IMR, ISR and ICW3 */ +#define IR7 0x80 /* IR7 */ +#define IR6 0x40 /* IR6 */ +#define IR5 0x20 /* IR5 */ +#define IR4 0x10 /* IR4 */ +#define IR3 0x08 /* IR3 */ +#define IR2 0x04 /* IR2 */ +#define IR1 0x02 /* IR1 */ +#define IR0 0x01 /* IR0 */ + +/* bits for SEOI */ +#define SEOI_IR7 0x07 /* IR7 */ +#define SEOI_IR6 0x06 /* IR6 */ +#define SEOI_IR5 0x05 /* IR5 */ +#define SEOI_IR4 0x04 /* IR4 */ +#define SEOI_IR3 0x03 /* IR3 */ +#define SEOI_IR2 0x02 /* IR2 */ +#define SEOI_IR1 0x01 /* IR1 */ +#define SEOI_IR0 0x00 /* IR0 */ + +/* OCW2 bits */ +#define OCW2_RCLR 0x00 /* Rotate/clear */ +#define OCW2_NEOI 0x20 /* Non specific EOI */ +#define OCW2_NOP 0x40 /* NOP */ +#define OCW2_SEOI 0x60 /* Specific EOI */ +#define OCW2_RSET 0x80 /* Rotate/set */ +#define OCW2_REOI 0xA0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xC0 /* Priority Set Command */ +#define OCW2_RSEOI 0xE0 /* Rotate on specific EOI */ + +/* ICW1 bits */ +#define ICW1_SEL 0x10 /* Select ICW1 */ +#define ICW1_LTIM 0x08 /* Level-Triggered Interrupt Mode */ +#define ICW1_ADI 0x04 /* Address Interval */ +#define ICW1_SNGL 0x02 /* Single PIC */ +#define ICW1_EICW4 0x01 /* Expect initilization ICW4 */ + +/* ICW2 is the starting vector number */ + +/* ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device */ + +/* ICW4 bits */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_PM 0x01 /* Microprocessor Mode */ + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/ibmpc.h b/qemu/roms/u-boot/arch/x86/include/asm/ibmpc.h new file mode 100644 index 000000000..0f9665f54 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/ibmpc.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_IBMPC_H_ +#define __ASM_IBMPC_H_ 1 + +/* misc ports in an ibm compatible pc */ + +#define MASTER_PIC 0x20 +#define PIT_BASE 0x40 +#define KBDDATA 0x60 +#define SYSCTLB 0x62 +#define KBDCMD 0x64 +#define SYSCTLA 0x92 +#define SLAVE_PIC 0xa0 + +#if 1 +#define UART0_BASE 0x3f8 +#define UART1_BASE 0x2f8 +#else +/* FixMe: uarts swapped */ +#define UART0_BASE 0x2f8 +#define UART1_BASE 0x3f8 +#endif + + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/init_helpers.h b/qemu/roms/u-boot/arch/x86/include/asm/init_helpers.h new file mode 100644 index 000000000..b07887ead --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/init_helpers.h @@ -0,0 +1,19 @@ +/* + * (C) Copyright 2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _INIT_HELPERS_H_ +#define _INIT_HELPERS_H_ + +int calculate_relocation_address(void); + +int init_cache_f_r(void); +int init_bd_struct_r(void); +int init_func_spi(void); +int find_fdt(void); +int prepare_fdt(void); + +#endif /* !_INIT_HELPERS_H_ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/interrupt.h b/qemu/roms/u-boot/arch/x86/include/asm/interrupt.h new file mode 100644 index 000000000..3f46e0920 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/interrupt.h @@ -0,0 +1,30 @@ +/* + * (C) Copyright 2009 + * Graeme Russ, graeme.russ@gmail.com + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_INTERRUPT_H_ +#define __ASM_INTERRUPT_H_ 1 + +#include <asm/types.h> + +/* arch/x86/cpu/interrupts.c */ +void set_vector(u8 intnum, void *routine); + +/* arch/x86/lib/interrupts.c */ +void disable_irq(int irq); +void enable_irq(int irq); + +/* Architecture specific functions */ +void mask_irq(int irq); +void unmask_irq(int irq); +void specific_eoi(int irq); + +extern char exception_stack[]; + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/io.h b/qemu/roms/u-boot/arch/x86/include/asm/io.h new file mode 100644 index 000000000..86bac90e8 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/io.h @@ -0,0 +1,249 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include <compiler.h> + +/* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + + /* + * Bit simplified and optimized by Jan Hubicka + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + * + * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, + * isa_read[wl] and isa_write[wl] fixed + * - Arnaldo Carvalho de Melo <acme@conectiva.com.br> + */ + +#define IO_SPACE_LIMIT 0xffff + +#include <asm/types.h> + + +#ifdef __KERNEL__ + + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile unsigned char *) (addr)) +#define readw(addr) (*(volatile unsigned short *) (addr)) +#define readl(addr) (*(volatile unsigned int *) (addr)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b)) +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +#define memset_io(a,b,c) memset((a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(b),(c)) +#define memcpy_toio(a,b,c) memcpy((a),(b),(c)) + +/* + * ISA space is 'always mapped' on a typical x86 system, no need to + * explicitly ioremap() it. The fact that the ISA IO space is mapped + * to PAGE_OFFSET is pure coincidence - it does not mean ISA values + * are physical addresses. The following constant pointer can be + * used as the IO-area pointer (it can be iounmapped as well, so the + * analogy with PCI is quite large): + */ +#define isa_readb(a) readb((a)) +#define isa_readw(a) readw((a)) +#define isa_readl(a) readl((a)) +#define isa_writeb(b,a) writeb(b,(a)) +#define isa_writew(w,a) writew(w,(a)) +#define isa_writel(l,a) writel(l,(a)) +#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) + + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +/** + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. + */ + + +static inline int isa_check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (isa_readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#define __SLOW_DOWN_IO "\noutb %%al,$0xed" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + + +/* + * Talk about misusing macros.. + */ +#define __OUT1(s,x) \ +static inline void out##s(unsigned x value, unsigned short port) { + +#define __OUT2(s,s1,s2) \ +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" + + +#define __OUT(s,s1,x) \ +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} + +#define __IN1(s) \ +static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; + +#define __IN2(s,s1,s2) \ +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } + +#define __INS(s) \ +static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; ins" #s \ +: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define __OUTS(s) \ +static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; outs" #s \ +: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define RETURN_TYPE unsigned char +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int +__IN(l,"") +#undef RETURN_TYPE + +__OUT(b,"b",char) +__OUT(w,"w",short) +__OUT(l,,int) + +__INS(b) +__INS(w) +__INS(l) + +__OUTS(b) +__OUTS(w) +__OUTS(l) + +static inline void sync(void) +{ +} + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)(uintptr_t)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ + +} + +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(uintptr_t)(vaddr); +} + +/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/ioctl.h b/qemu/roms/u-boot/arch/x86/include/asm/ioctl.h new file mode 100644 index 000000000..b279fe06d --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/ioctl.h @@ -0,0 +1 @@ +#include <asm-generic/ioctl.h> diff --git a/qemu/roms/u-boot/arch/x86/include/asm/ist.h b/qemu/roms/u-boot/arch/x86/include/asm/ist.h new file mode 100644 index 000000000..0cdbb45ba --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/ist.h @@ -0,0 +1,26 @@ +#ifndef _ASM_X86_IST_H +#define _ASM_X86_IST_H + +/* + * Include file for the interface to IST BIOS + * Copyright 2002 Andy Grover <andrew.grover@intel.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <linux/types.h> + +struct ist_info { + __u32 signature; + __u32 command; + __u32 event; + __u32 perf_level; +}; + +#ifdef __KERNEL__ + +extern struct ist_info ist_info; + +#endif /* __KERNEL__ */ +#endif /* _ASM_X86_IST_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/msr-index.h b/qemu/roms/u-boot/arch/x86/include/asm/msr-index.h new file mode 100644 index 000000000..0a36e178f --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/msr-index.h @@ -0,0 +1,456 @@ +/* + * Taken from the linux kernel file of the same name + * + * (C) Copyright 2012 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_X86_MSR_INDEX_H +#define _ASM_X86_MSR_INDEX_H + +/* CPU model specific register (MSR) numbers */ + +/* x86-64 specific MSRs */ +#define MSR_EFER 0xc0000080 /* extended feature register */ +#define MSR_STAR 0xc0000081 /* legacy mode SYSCALL target */ +#define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ +#define MSR_CSTAR 0xc0000083 /* compat mode SYSCALL target */ +#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ +#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ +#define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow */ +#define MSR_TSC_AUX 0xc0000103 /* Auxiliary TSC */ + +/* EFER bits: */ +#define _EFER_SCE 0 /* SYSCALL/SYSRET */ +#define _EFER_LME 8 /* Long mode enable */ +#define _EFER_LMA 10 /* Long mode active (read-only) */ +#define _EFER_NX 11 /* No execute enable */ +#define _EFER_SVME 12 /* Enable virtualization */ +#define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */ +#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */ + +#define EFER_SCE (1<<_EFER_SCE) +#define EFER_LME (1<<_EFER_LME) +#define EFER_LMA (1<<_EFER_LMA) +#define EFER_NX (1<<_EFER_NX) +#define EFER_SVME (1<<_EFER_SVME) +#define EFER_LMSLE (1<<_EFER_LMSLE) +#define EFER_FFXSR (1<<_EFER_FFXSR) + +/* Intel MSRs. Some also available on other CPUs */ +#define MSR_IA32_PERFCTR0 0x000000c1 +#define MSR_IA32_PERFCTR1 0x000000c2 +#define MSR_FSB_FREQ 0x000000cd + +#define MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2 +#define NHM_C3_AUTO_DEMOTE (1UL << 25) +#define NHM_C1_AUTO_DEMOTE (1UL << 26) +#define ATM_LNC_C6_AUTO_DEMOTE (1UL << 25) + +#define MSR_MTRRcap 0x000000fe +#define MSR_IA32_BBL_CR_CTL 0x00000119 +#define MSR_IA32_BBL_CR_CTL3 0x0000011e + +#define MSR_IA32_SYSENTER_CS 0x00000174 +#define MSR_IA32_SYSENTER_ESP 0x00000175 +#define MSR_IA32_SYSENTER_EIP 0x00000176 + +#define MSR_IA32_MCG_CAP 0x00000179 +#define MSR_IA32_MCG_STATUS 0x0000017a +#define MSR_IA32_MCG_CTL 0x0000017b + +#define MSR_OFFCORE_RSP_0 0x000001a6 +#define MSR_OFFCORE_RSP_1 0x000001a7 + +#define MSR_IA32_PEBS_ENABLE 0x000003f1 +#define MSR_IA32_DS_AREA 0x00000600 +#define MSR_IA32_PERF_CAPABILITIES 0x00000345 + +#define MSR_MTRRfix64K_00000 0x00000250 +#define MSR_MTRRfix16K_80000 0x00000258 +#define MSR_MTRRfix16K_A0000 0x00000259 +#define MSR_MTRRfix4K_C0000 0x00000268 +#define MSR_MTRRfix4K_C8000 0x00000269 +#define MSR_MTRRfix4K_D0000 0x0000026a +#define MSR_MTRRfix4K_D8000 0x0000026b +#define MSR_MTRRfix4K_E0000 0x0000026c +#define MSR_MTRRfix4K_E8000 0x0000026d +#define MSR_MTRRfix4K_F0000 0x0000026e +#define MSR_MTRRfix4K_F8000 0x0000026f +#define MSR_MTRRdefType 0x000002ff + +#define MSR_IA32_CR_PAT 0x00000277 + +#define MSR_IA32_DEBUGCTLMSR 0x000001d9 +#define MSR_IA32_LASTBRANCHFROMIP 0x000001db +#define MSR_IA32_LASTBRANCHTOIP 0x000001dc +#define MSR_IA32_LASTINTFROMIP 0x000001dd +#define MSR_IA32_LASTINTTOIP 0x000001de + +/* DEBUGCTLMSR bits (others vary by model): */ +#define DEBUGCTLMSR_LBR (1UL << 0) +#define DEBUGCTLMSR_BTF (1UL << 1) +#define DEBUGCTLMSR_TR (1UL << 6) +#define DEBUGCTLMSR_BTS (1UL << 7) +#define DEBUGCTLMSR_BTINT (1UL << 8) +#define DEBUGCTLMSR_BTS_OFF_OS (1UL << 9) +#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10) +#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11) + +#define MSR_IA32_MC0_CTL 0x00000400 +#define MSR_IA32_MC0_STATUS 0x00000401 +#define MSR_IA32_MC0_ADDR 0x00000402 +#define MSR_IA32_MC0_MISC 0x00000403 + +#define MSR_AMD64_MC0_MASK 0xc0010044 + +#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) +#define MSR_IA32_MCx_STATUS(x) (MSR_IA32_MC0_STATUS + 4*(x)) +#define MSR_IA32_MCx_ADDR(x) (MSR_IA32_MC0_ADDR + 4*(x)) +#define MSR_IA32_MCx_MISC(x) (MSR_IA32_MC0_MISC + 4*(x)) + +#define MSR_AMD64_MCx_MASK(x) (MSR_AMD64_MC0_MASK + (x)) + +/* These are consecutive and not in the normal 4er MCE bank block */ +#define MSR_IA32_MC0_CTL2 0x00000280 +#define MSR_IA32_MCx_CTL2(x) (MSR_IA32_MC0_CTL2 + (x)) + +#define MSR_P6_PERFCTR0 0x000000c1 +#define MSR_P6_PERFCTR1 0x000000c2 +#define MSR_P6_EVNTSEL0 0x00000186 +#define MSR_P6_EVNTSEL1 0x00000187 + +/* AMD64 MSRs. Not complete. See the architecture manual for a more + complete list. */ + +#define MSR_AMD64_PATCH_LEVEL 0x0000008b +#define MSR_AMD64_NB_CFG 0xc001001f +#define MSR_AMD64_PATCH_LOADER 0xc0010020 +#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140 +#define MSR_AMD64_OSVW_STATUS 0xc0010141 +#define MSR_AMD64_DC_CFG 0xc0011022 +#define MSR_AMD64_IBSFETCHCTL 0xc0011030 +#define MSR_AMD64_IBSFETCHLINAD 0xc0011031 +#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032 +#define MSR_AMD64_IBSOPCTL 0xc0011033 +#define MSR_AMD64_IBSOPRIP 0xc0011034 +#define MSR_AMD64_IBSOPDATA 0xc0011035 +#define MSR_AMD64_IBSOPDATA2 0xc0011036 +#define MSR_AMD64_IBSOPDATA3 0xc0011037 +#define MSR_AMD64_IBSDCLINAD 0xc0011038 +#define MSR_AMD64_IBSDCPHYSAD 0xc0011039 +#define MSR_AMD64_IBSCTL 0xc001103a +#define MSR_AMD64_IBSBRTARGET 0xc001103b + +/* Fam 15h MSRs */ +#define MSR_F15H_PERF_CTL 0xc0010200 +#define MSR_F15H_PERF_CTR 0xc0010201 + +/* Fam 10h MSRs */ +#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058 +#define FAM10H_MMIO_CONF_ENABLE (1<<0) +#define FAM10H_MMIO_CONF_BUSRANGE_MASK 0xf +#define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2 +#define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL +#define FAM10H_MMIO_CONF_BASE_SHIFT 20 +#define MSR_FAM10H_NODE_ID 0xc001100c + +/* K8 MSRs */ +#define MSR_K8_TOP_MEM1 0xc001001a +#define MSR_K8_TOP_MEM2 0xc001001d +#define MSR_K8_SYSCFG 0xc0010010 +#define MSR_K8_INT_PENDING_MSG 0xc0010055 +/* C1E active bits in int pending message */ +#define K8_INTP_C1E_ACTIVE_MASK 0x18000000 +#define MSR_K8_TSEG_ADDR 0xc0010112 +#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */ +#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */ +#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */ + +/* K7 MSRs */ +#define MSR_K7_EVNTSEL0 0xc0010000 +#define MSR_K7_PERFCTR0 0xc0010004 +#define MSR_K7_EVNTSEL1 0xc0010001 +#define MSR_K7_PERFCTR1 0xc0010005 +#define MSR_K7_EVNTSEL2 0xc0010002 +#define MSR_K7_PERFCTR2 0xc0010006 +#define MSR_K7_EVNTSEL3 0xc0010003 +#define MSR_K7_PERFCTR3 0xc0010007 +#define MSR_K7_CLK_CTL 0xc001001b +#define MSR_K7_HWCR 0xc0010015 +#define MSR_K7_FID_VID_CTL 0xc0010041 +#define MSR_K7_FID_VID_STATUS 0xc0010042 + +/* K6 MSRs */ +#define MSR_K6_WHCR 0xc0000082 +#define MSR_K6_UWCCR 0xc0000085 +#define MSR_K6_EPMR 0xc0000086 +#define MSR_K6_PSOR 0xc0000087 +#define MSR_K6_PFIR 0xc0000088 + +/* Centaur-Hauls/IDT defined MSRs. */ +#define MSR_IDT_FCR1 0x00000107 +#define MSR_IDT_FCR2 0x00000108 +#define MSR_IDT_FCR3 0x00000109 +#define MSR_IDT_FCR4 0x0000010a + +#define MSR_IDT_MCR0 0x00000110 +#define MSR_IDT_MCR1 0x00000111 +#define MSR_IDT_MCR2 0x00000112 +#define MSR_IDT_MCR3 0x00000113 +#define MSR_IDT_MCR4 0x00000114 +#define MSR_IDT_MCR5 0x00000115 +#define MSR_IDT_MCR6 0x00000116 +#define MSR_IDT_MCR7 0x00000117 +#define MSR_IDT_MCR_CTRL 0x00000120 + +/* VIA Cyrix defined MSRs*/ +#define MSR_VIA_FCR 0x00001107 +#define MSR_VIA_LONGHAUL 0x0000110a +#define MSR_VIA_RNG 0x0000110b +#define MSR_VIA_BCR2 0x00001147 + +/* Transmeta defined MSRs */ +#define MSR_TMTA_LONGRUN_CTRL 0x80868010 +#define MSR_TMTA_LONGRUN_FLAGS 0x80868011 +#define MSR_TMTA_LRTI_READOUT 0x80868018 +#define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a + +/* Intel defined MSRs. */ +#define MSR_IA32_P5_MC_ADDR 0x00000000 +#define MSR_IA32_P5_MC_TYPE 0x00000001 +#define MSR_IA32_TSC 0x00000010 +#define MSR_IA32_PLATFORM_ID 0x00000017 +#define MSR_IA32_EBL_CR_POWERON 0x0000002a +#define MSR_EBC_FREQUENCY_ID 0x0000002c +#define MSR_IA32_FEATURE_CONTROL 0x0000003a + +#define FEATURE_CONTROL_LOCKED (1<<0) +#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1) +#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2) + +#define MSR_IA32_APICBASE 0x0000001b +#define MSR_IA32_APICBASE_BSP (1<<8) +#define MSR_IA32_APICBASE_ENABLE (1<<11) +#define MSR_IA32_APICBASE_BASE (0xfffff<<12) + +#define MSR_IA32_UCODE_WRITE 0x00000079 +#define MSR_IA32_UCODE_REV 0x0000008b + +#define MSR_IA32_PERF_STATUS 0x00000198 +#define MSR_IA32_PERF_CTL 0x00000199 + +#define MSR_IA32_MPERF 0x000000e7 +#define MSR_IA32_APERF 0x000000e8 + +#define MSR_IA32_THERM_CONTROL 0x0000019a +#define MSR_IA32_THERM_INTERRUPT 0x0000019b + +#define THERM_INT_HIGH_ENABLE (1 << 0) +#define THERM_INT_LOW_ENABLE (1 << 1) +#define THERM_INT_PLN_ENABLE (1 << 24) + +#define MSR_IA32_THERM_STATUS 0x0000019c + +#define THERM_STATUS_PROCHOT (1 << 0) +#define THERM_STATUS_POWER_LIMIT (1 << 10) + +#define MSR_THERM2_CTL 0x0000019d + +#define MSR_THERM2_CTL_TM_SELECT (1ULL << 16) + +#define MSR_IA32_MISC_ENABLE 0x000001a0 + +#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 + +#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 + +#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1 + +#define PACKAGE_THERM_STATUS_PROCHOT (1 << 0) +#define PACKAGE_THERM_STATUS_POWER_LIMIT (1 << 10) + +#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x000001b2 + +#define PACKAGE_THERM_INT_HIGH_ENABLE (1 << 0) +#define PACKAGE_THERM_INT_LOW_ENABLE (1 << 1) +#define PACKAGE_THERM_INT_PLN_ENABLE (1 << 24) + +/* Thermal Thresholds Support */ +#define THERM_INT_THRESHOLD0_ENABLE (1 << 15) +#define THERM_SHIFT_THRESHOLD0 8 +#define THERM_MASK_THRESHOLD0 (0x7f << THERM_SHIFT_THRESHOLD0) +#define THERM_INT_THRESHOLD1_ENABLE (1 << 23) +#define THERM_SHIFT_THRESHOLD1 16 +#define THERM_MASK_THRESHOLD1 (0x7f << THERM_SHIFT_THRESHOLD1) +#define THERM_STATUS_THRESHOLD0 (1 << 6) +#define THERM_LOG_THRESHOLD0 (1 << 7) +#define THERM_STATUS_THRESHOLD1 (1 << 8) +#define THERM_LOG_THRESHOLD1 (1 << 9) + +/* MISC_ENABLE bits: architectural */ +#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) +#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) +#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) +#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) +#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) +#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) +#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) + +/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ +#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) +#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) +#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) +#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) +#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) +#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) +#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) +#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) +#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) +#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) +#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) +#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) +#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) +#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) + +/* P4/Xeon+ specific */ +#define MSR_IA32_MCG_EAX 0x00000180 +#define MSR_IA32_MCG_EBX 0x00000181 +#define MSR_IA32_MCG_ECX 0x00000182 +#define MSR_IA32_MCG_EDX 0x00000183 +#define MSR_IA32_MCG_ESI 0x00000184 +#define MSR_IA32_MCG_EDI 0x00000185 +#define MSR_IA32_MCG_EBP 0x00000186 +#define MSR_IA32_MCG_ESP 0x00000187 +#define MSR_IA32_MCG_EFLAGS 0x00000188 +#define MSR_IA32_MCG_EIP 0x00000189 +#define MSR_IA32_MCG_RESERVED 0x0000018a + +/* Pentium IV performance counter MSRs */ +#define MSR_P4_BPU_PERFCTR0 0x00000300 +#define MSR_P4_BPU_PERFCTR1 0x00000301 +#define MSR_P4_BPU_PERFCTR2 0x00000302 +#define MSR_P4_BPU_PERFCTR3 0x00000303 +#define MSR_P4_MS_PERFCTR0 0x00000304 +#define MSR_P4_MS_PERFCTR1 0x00000305 +#define MSR_P4_MS_PERFCTR2 0x00000306 +#define MSR_P4_MS_PERFCTR3 0x00000307 +#define MSR_P4_FLAME_PERFCTR0 0x00000308 +#define MSR_P4_FLAME_PERFCTR1 0x00000309 +#define MSR_P4_FLAME_PERFCTR2 0x0000030a +#define MSR_P4_FLAME_PERFCTR3 0x0000030b +#define MSR_P4_IQ_PERFCTR0 0x0000030c +#define MSR_P4_IQ_PERFCTR1 0x0000030d +#define MSR_P4_IQ_PERFCTR2 0x0000030e +#define MSR_P4_IQ_PERFCTR3 0x0000030f +#define MSR_P4_IQ_PERFCTR4 0x00000310 +#define MSR_P4_IQ_PERFCTR5 0x00000311 +#define MSR_P4_BPU_CCCR0 0x00000360 +#define MSR_P4_BPU_CCCR1 0x00000361 +#define MSR_P4_BPU_CCCR2 0x00000362 +#define MSR_P4_BPU_CCCR3 0x00000363 +#define MSR_P4_MS_CCCR0 0x00000364 +#define MSR_P4_MS_CCCR1 0x00000365 +#define MSR_P4_MS_CCCR2 0x00000366 +#define MSR_P4_MS_CCCR3 0x00000367 +#define MSR_P4_FLAME_CCCR0 0x00000368 +#define MSR_P4_FLAME_CCCR1 0x00000369 +#define MSR_P4_FLAME_CCCR2 0x0000036a +#define MSR_P4_FLAME_CCCR3 0x0000036b +#define MSR_P4_IQ_CCCR0 0x0000036c +#define MSR_P4_IQ_CCCR1 0x0000036d +#define MSR_P4_IQ_CCCR2 0x0000036e +#define MSR_P4_IQ_CCCR3 0x0000036f +#define MSR_P4_IQ_CCCR4 0x00000370 +#define MSR_P4_IQ_CCCR5 0x00000371 +#define MSR_P4_ALF_ESCR0 0x000003ca +#define MSR_P4_ALF_ESCR1 0x000003cb +#define MSR_P4_BPU_ESCR0 0x000003b2 +#define MSR_P4_BPU_ESCR1 0x000003b3 +#define MSR_P4_BSU_ESCR0 0x000003a0 +#define MSR_P4_BSU_ESCR1 0x000003a1 +#define MSR_P4_CRU_ESCR0 0x000003b8 +#define MSR_P4_CRU_ESCR1 0x000003b9 +#define MSR_P4_CRU_ESCR2 0x000003cc +#define MSR_P4_CRU_ESCR3 0x000003cd +#define MSR_P4_CRU_ESCR4 0x000003e0 +#define MSR_P4_CRU_ESCR5 0x000003e1 +#define MSR_P4_DAC_ESCR0 0x000003a8 +#define MSR_P4_DAC_ESCR1 0x000003a9 +#define MSR_P4_FIRM_ESCR0 0x000003a4 +#define MSR_P4_FIRM_ESCR1 0x000003a5 +#define MSR_P4_FLAME_ESCR0 0x000003a6 +#define MSR_P4_FLAME_ESCR1 0x000003a7 +#define MSR_P4_FSB_ESCR0 0x000003a2 +#define MSR_P4_FSB_ESCR1 0x000003a3 +#define MSR_P4_IQ_ESCR0 0x000003ba +#define MSR_P4_IQ_ESCR1 0x000003bb +#define MSR_P4_IS_ESCR0 0x000003b4 +#define MSR_P4_IS_ESCR1 0x000003b5 +#define MSR_P4_ITLB_ESCR0 0x000003b6 +#define MSR_P4_ITLB_ESCR1 0x000003b7 +#define MSR_P4_IX_ESCR0 0x000003c8 +#define MSR_P4_IX_ESCR1 0x000003c9 +#define MSR_P4_MOB_ESCR0 0x000003aa +#define MSR_P4_MOB_ESCR1 0x000003ab +#define MSR_P4_MS_ESCR0 0x000003c0 +#define MSR_P4_MS_ESCR1 0x000003c1 +#define MSR_P4_PMH_ESCR0 0x000003ac +#define MSR_P4_PMH_ESCR1 0x000003ad +#define MSR_P4_RAT_ESCR0 0x000003bc +#define MSR_P4_RAT_ESCR1 0x000003bd +#define MSR_P4_SAAT_ESCR0 0x000003ae +#define MSR_P4_SAAT_ESCR1 0x000003af +#define MSR_P4_SSU_ESCR0 0x000003be +#define MSR_P4_SSU_ESCR1 0x000003bf /* guess: not in manual */ + +#define MSR_P4_TBPU_ESCR0 0x000003c2 +#define MSR_P4_TBPU_ESCR1 0x000003c3 +#define MSR_P4_TC_ESCR0 0x000003c4 +#define MSR_P4_TC_ESCR1 0x000003c5 +#define MSR_P4_U2L_ESCR0 0x000003b0 +#define MSR_P4_U2L_ESCR1 0x000003b1 + +#define MSR_P4_PEBS_MATRIX_VERT 0x000003f2 + +/* Intel Core-based CPU performance counters */ +#define MSR_CORE_PERF_FIXED_CTR0 0x00000309 +#define MSR_CORE_PERF_FIXED_CTR1 0x0000030a +#define MSR_CORE_PERF_FIXED_CTR2 0x0000030b +#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x0000038d +#define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e +#define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f +#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 + +/* Geode defined MSRs */ +#define MSR_GEODE_BUSCONT_CONF0 0x00001900 + +/* Intel VT MSRs */ +#define MSR_IA32_VMX_BASIC 0x00000480 +#define MSR_IA32_VMX_PINBASED_CTLS 0x00000481 +#define MSR_IA32_VMX_PROCBASED_CTLS 0x00000482 +#define MSR_IA32_VMX_EXIT_CTLS 0x00000483 +#define MSR_IA32_VMX_ENTRY_CTLS 0x00000484 +#define MSR_IA32_VMX_MISC 0x00000485 +#define MSR_IA32_VMX_CR0_FIXED0 0x00000486 +#define MSR_IA32_VMX_CR0_FIXED1 0x00000487 +#define MSR_IA32_VMX_CR4_FIXED0 0x00000488 +#define MSR_IA32_VMX_CR4_FIXED1 0x00000489 +#define MSR_IA32_VMX_VMCS_ENUM 0x0000048a +#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b +#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c + +/* AMD-V MSRs */ + +#define MSR_VM_CR 0xc0010114 +#define MSR_VM_IGNNE 0xc0010115 +#define MSR_VM_HSAVE_PA 0xc0010117 + +#endif /* _ASM_X86_MSR_INDEX_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/msr.h b/qemu/roms/u-boot/arch/x86/include/asm/msr.h new file mode 100644 index 000000000..3b5915d5e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/msr.h @@ -0,0 +1,226 @@ +/* + * Taken from the linux kernel file of the same name + * + * (C) Copyright 2012 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_X86_MSR_H +#define _ASM_X86_MSR_H + +#include <asm/msr-index.h> + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define X86_IOC_RDMSR_REGS _IOWR('c', 0xA0, __u32[8]) +#define X86_IOC_WRMSR_REGS _IOWR('c', 0xA1, __u32[8]) + +#ifdef __KERNEL__ + +#include <asm/errno.h> + +struct msr { + union { + struct { + u32 l; + u32 h; + }; + u64 q; + }; +}; + +struct msr_info { + u32 msr_no; + struct msr reg; + struct msr *msrs; + int err; +}; + +struct msr_regs_info { + u32 *regs; + int err; +}; + +static inline unsigned long long native_read_tscp(unsigned int *aux) +{ + unsigned long low, high; + asm volatile(".byte 0x0f,0x01,0xf9" + : "=a" (low), "=d" (high), "=c" (*aux)); + return low | ((u64)high << 32); +} + +/* + * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A" + * constraint has different meanings. For i386, "A" means exactly + * 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) +#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 + +static inline __attribute__((no_instrument_function)) + unsigned long long native_read_msr(unsigned int msr) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr)); + return EAX_EDX_VAL(val, low, high); +} + +static inline void native_write_msr(unsigned int msr, + unsigned low, unsigned high) +{ + asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory"); +} + +extern unsigned long long native_read_tsc(void); + +extern int native_rdmsr_safe_regs(u32 regs[8]); +extern int native_wrmsr_safe_regs(u32 regs[8]); + +static inline unsigned long long native_read_pmc(int counter) +{ + DECLARE_ARGS(val, low, high); + + asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter)); + return EAX_EDX_VAL(val, low, high); +} + +#ifdef CONFIG_PARAVIRT +#include <asm/paravirt.h> +#else +#include <errno.h> +/* + * Access to machine-specific registers (available on 586 and better only) + * Note: the rd* operations modify the parameters directly (without using + * pointer indirection), this allows gcc to optimize better + */ + +#define rdmsr(msr, val1, val2) \ +do { \ + u64 __val = native_read_msr((msr)); \ + (void)((val1) = (u32)__val); \ + (void)((val2) = (u32)(__val >> 32)); \ +} while (0) + +static inline void wrmsr(unsigned msr, unsigned low, unsigned high) +{ + native_write_msr(msr, low, high); +} + +#define rdmsrl(msr, val) \ + ((val) = native_read_msr((msr))) + +#define wrmsrl(msr, val) \ + native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32)) + +/* rdmsr with exception handling */ +#define rdmsr_safe(msr, p1, p2) \ +({ \ + int __err; \ + u64 __val = native_read_msr_safe((msr), &__err); \ + (*p1) = (u32)__val; \ + (*p2) = (u32)(__val >> 32); \ + __err; \ +}) + +static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) +{ + u32 gprs[8] = { 0 }; + int err; + + gprs[1] = msr; + gprs[7] = 0x9c5a203a; + + err = native_rdmsr_safe_regs(gprs); + + *p = gprs[0] | ((u64)gprs[2] << 32); + + return err; +} + +static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) +{ + u32 gprs[8] = { 0 }; + + gprs[0] = (u32)val; + gprs[1] = msr; + gprs[2] = val >> 32; + gprs[7] = 0x9c5a203a; + + return native_wrmsr_safe_regs(gprs); +} + +static inline int rdmsr_safe_regs(u32 regs[8]) +{ + return native_rdmsr_safe_regs(regs); +} + +static inline int wrmsr_safe_regs(u32 regs[8]) +{ + return native_wrmsr_safe_regs(regs); +} + +#define rdtscl(low) \ + ((low) = (u32)__native_read_tsc()) + +#define rdtscll(val) \ + ((val) = __native_read_tsc()) + +#define rdpmc(counter, low, high) \ +do { \ + u64 _l = native_read_pmc((counter)); \ + (low) = (u32)_l; \ + (high) = (u32)(_l >> 32); \ +} while (0) + +#define rdtscp(low, high, aux) \ +do { \ + unsigned long long _val = native_read_tscp(&(aux)); \ + (low) = (u32)_val; \ + (high) = (u32)(_val >> 32); \ +} while (0) + +#define rdtscpll(val, aux) (val) = native_read_tscp(&(aux)) + +#endif /* !CONFIG_PARAVIRT */ + + +#define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val), \ + (u32)((val) >> 32)) + +#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2)) + +#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0) + +struct msr *msrs_alloc(void); +void msrs_free(struct msr *msrs); + +#ifdef CONFIG_SMP +int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); +int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); +void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); +void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs); +int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h); +int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h); +int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); +int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]); + +#endif /* CONFIG_SMP */ +#endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ +#endif /* _ASM_X86_MSR_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/pci.h b/qemu/roms/u-boot/arch/x86/include/asm/pci.h new file mode 100644 index 000000000..6b161881e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/pci.h @@ -0,0 +1,16 @@ + +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _PCI_I386_H_ +#define _PCI_I386_H_ + +#define DEFINE_PCI_DEVICE_TABLE(_table) \ + const struct pci_device_id _table[] + +void pci_setup_type1(struct pci_controller *hose); +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/posix_types.h b/qemu/roms/u-boot/arch/x86/include/asm/posix_types.h new file mode 100644 index 000000000..5529f3270 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/posix_types.h @@ -0,0 +1,80 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/processor-flags.h b/qemu/roms/u-boot/arch/x86/include/asm/processor-flags.h new file mode 100644 index 000000000..7a3e836eb --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/processor-flags.h @@ -0,0 +1,100 @@ +#ifndef _ASM_X86_PROCESSOR_FLAGS_H +#define _ASM_X86_PROCESSOR_FLAGS_H +/* Various flags defined: can be included from assembler. */ + +/* + * EFLAGS bits + */ +#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ +#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ +#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */ +#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ +#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */ +#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ +#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */ +#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */ +#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */ +#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */ +#define X86_EFLAGS_NT 0x00004000 /* Nested Task */ +#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */ +#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */ +#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */ +#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */ +#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ +#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ + +/* + * Basic CPU control in CR0 + */ +#define X86_CR0_PE 0x00000001 /* Protection Enable */ +#define X86_CR0_MP 0x00000002 /* Monitor Coprocessor */ +#define X86_CR0_EM 0x00000004 /* Emulation */ +#define X86_CR0_TS 0x00000008 /* Task Switched */ +#define X86_CR0_ET 0x00000010 /* Extension Type */ +#define X86_CR0_NE 0x00000020 /* Numeric Error */ +#define X86_CR0_WP 0x00010000 /* Write Protect */ +#define X86_CR0_AM 0x00040000 /* Alignment Mask */ +#define X86_CR0_NW 0x20000000 /* Not Write-through */ +#define X86_CR0_CD 0x40000000 /* Cache Disable */ +#define X86_CR0_PG 0x80000000 /* Paging */ + +/* + * Paging options in CR3 + */ +#define X86_CR3_PWT 0x00000008 /* Page Write Through */ +#define X86_CR3_PCD 0x00000010 /* Page Cache Disable */ + +/* + * Intel CPU features in CR4 + */ +#define X86_CR4_VME 0x00000001 /* enable vm86 extensions */ +#define X86_CR4_PVI 0x00000002 /* virtual interrupts flag enable */ +#define X86_CR4_TSD 0x00000004 /* disable time stamp at ipl 3 */ +#define X86_CR4_DE 0x00000008 /* enable debugging extensions */ +#define X86_CR4_PSE 0x00000010 /* enable page size extensions */ +#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */ +#define X86_CR4_MCE 0x00000040 /* Machine check enable */ +#define X86_CR4_PGE 0x00000080 /* enable global pages */ +#define X86_CR4_PCE 0x00000100 /* enable performance counters at ipl 3 */ +#define X86_CR4_OSFXSR 0x00000200 /* enable fast FPU save and restore */ +#define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */ +#define X86_CR4_VMXE 0x00002000 /* enable VMX virtualization */ +#define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */ + +/* + * x86-64 Task Priority Register, CR8 + */ +#define X86_CR8_TPR 0x0000000F /* task priority register */ + +/* + * AMD and Transmeta use MSRs for configuration; see <asm/msr-index.h> + */ + +/* + * NSC/Cyrix CPU configuration register indexes + */ +#define CX86_PCR0 0x20 +#define CX86_GCR 0xb8 +#define CX86_CCR0 0xc0 +#define CX86_CCR1 0xc1 +#define CX86_CCR2 0xc2 +#define CX86_CCR3 0xc3 +#define CX86_CCR4 0xe8 +#define CX86_CCR5 0xe9 +#define CX86_CCR6 0xea +#define CX86_CCR7 0xeb +#define CX86_PCR1 0xf0 +#define CX86_DIR0 0xfe +#define CX86_DIR1 0xff +#define CX86_ARR_BASE 0xc4 +#define CX86_RCR_BASE 0xdc + +#ifdef __KERNEL__ +#ifdef CONFIG_VM86 +#define X86_VM_MASK X86_EFLAGS_VM +#else +#define X86_VM_MASK 0 /* No VM86 support */ +#endif +#endif + +#endif /* _ASM_X86_PROCESSOR_FLAGS_H */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/processor.h b/qemu/roms/u-boot/arch/x86/include/asm/processor.h new file mode 100644 index 000000000..bb3172ff9 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/processor.h @@ -0,0 +1,33 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_PROCESSOR_H_ +#define __ASM_PROCESSOR_H_ 1 + +#define X86_GDT_ENTRY_SIZE 8 + +#ifndef __ASSEMBLY__ + +enum { + X86_GDT_ENTRY_NULL = 0, + X86_GDT_ENTRY_UNUSED, + X86_GDT_ENTRY_32BIT_CS, + X86_GDT_ENTRY_32BIT_DS, + X86_GDT_ENTRY_32BIT_FS, + X86_GDT_ENTRY_16BIT_CS, + X86_GDT_ENTRY_16BIT_DS, + X86_GDT_NUM_ENTRIES +}; +#else +/* NOTE: If the above enum is modified, this define must be checked */ +#define X86_GDT_ENTRY_32BIT_DS 3 +#define X86_GDT_NUM_ENTRIES 7 +#endif + +#define X86_GDT_SIZE (X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE) + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/ptrace.h b/qemu/roms/u-boot/arch/x86/include/asm/ptrace.h new file mode 100644 index 000000000..a727dbfb0 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/ptrace.h @@ -0,0 +1,90 @@ +#ifndef _I386_PTRACE_H +#define _I386_PTRACE_H + +#include <asm/types.h> + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 +#define FRAME_SIZE 17 + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + int xds; + int xes; + int xfs; + int xgs; + long orig_eax; + long eip; + int xcs; + long eflags; + long esp; + int xss; +} __attribute__ ((packed)); + +struct irq_regs { + /* Pushed by irq_common_entry */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long esp; + long eax; + long xds; + long xes; + long xfs; + long xgs; + long xss; + /* Pushed by vector handler (irq_<num>) */ + long irq_id; + /* Pushed by cpu in response to interrupt */ + long eip; + long xcs; + long eflags; +} __attribute__ ((packed)); + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_GETFPXREGS 18 +#define PTRACE_SETFPXREGS 19 + +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + +#ifdef __KERNEL__ +#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) +#define instruction_pointer(regs) ((regs)->eip) +extern void show_regs(struct pt_regs *); +#endif + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/relocate.h b/qemu/roms/u-boot/arch/x86/include/asm/relocate.h new file mode 100644 index 000000000..eb186b9fb --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/relocate.h @@ -0,0 +1,18 @@ +/* + * (C) Copyright 2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _RELOCATE_H_ +#define _RELOCATE_H_ + +#include <common.h> + +int copy_uboot_to_ram(void); +int copy_fdt_to_ram(void); +int clear_bss(void); +int do_elf_reloc_fixups(void); + +#endif /* !_RELOCATE_H_ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/sections.h b/qemu/roms/u-boot/arch/x86/include/asm/sections.h new file mode 100644 index 000000000..22d7f5af7 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/sections.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_X86_SECTIONS_H +#define __ASM_X86_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/string.h b/qemu/roms/u-boot/arch/x86/include/asm/string.h new file mode 100644 index 000000000..0ad612f62 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/string.h @@ -0,0 +1,32 @@ +#ifndef __ASM_I386_STRING_H +#define __ASM_I386_STRING_H + +/* + * We don't do inline string functions, since the + * optimised inline asm versions are not small. + */ +#undef __HAVE_ARCH_STRNCPY +extern char *strncpy(char *__dest, __const__ char *__src, __kernel_size_t __n); + +#undef __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#undef __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, __kernel_size_t n); + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/types.h b/qemu/roms/u-boot/arch/x86/include/asm/types.h new file mode 100644 index 000000000..e9fde88f7 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/types.h @@ -0,0 +1,53 @@ +#ifndef __ASM_I386_TYPES_H +#define __ASM_I386_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +typedef unsigned long long phys_addr_t; +typedef unsigned long long phys_size_t; + +#endif /* __KERNEL__ */ + +#endif diff --git a/qemu/roms/u-boot/arch/x86/include/asm/u-boot-x86.h b/qemu/roms/u-boot/arch/x86/include/asm/u-boot-x86.h new file mode 100644 index 000000000..9e525dd78 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/u-boot-x86.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _U_BOOT_I386_H_ +#define _U_BOOT_I386_H_ 1 + +/* cpu/.../cpu.c */ +int x86_cpu_init_r(void); +int cpu_init_r(void); +int x86_cpu_init_f(void); +int cpu_init_f(void); +void init_gd(gd_t *id, u64 *gdt_addr); +void setup_gdt(gd_t *id, u64 *gdt_addr); +int init_cache(void); +int cleanup_before_linux(void); +void panic_puts(const char *str); + +/* cpu/.../timer.c */ +void timer_isr(void *); +typedef void (timer_fnc_t) (void); +int register_timer_isr (timer_fnc_t *isr_func); +unsigned long get_tbclk_mhz(void); +void timer_set_base(uint64_t base); +int pcat_timer_init(void); + +/* Architecture specific - can be in arch/x86/cpu/, arch/x86/lib/, or $(BOARD)/ */ +int dram_init_f(void); + +/* cpu/.../interrupts.c */ +int cpu_init_interrupts(void); + +/* board/.../... */ +int dram_init(void); + +void setup_pcat_compatibility(void); + +void isa_unmap_rom(u32 addr); +u32 isa_map_rom(u32 bus_addr, int size); + +/* arch/x86/lib/... */ +int video_bios_init(void); + +void board_init_f_r_trampoline(ulong) __attribute__ ((noreturn)); +void board_init_f_r(void) __attribute__ ((noreturn)); + +/* Read the time stamp counter */ +static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void) +{ + uint32_t high, low; + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)); + return (((uint64_t)high) << 32) | low; +} + +/* board/... */ +void timer_set_tsc_base(uint64_t new_base); +uint64_t timer_get_tsc(void); + +#endif /* _U_BOOT_I386_H_ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/u-boot.h b/qemu/roms/u-boot/arch/x86/include/asm/u-boot.h new file mode 100644 index 000000000..623771a39 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/u-boot.h @@ -0,0 +1,29 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_I386 + +#endif /* _U_BOOT_H_ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/unaligned.h b/qemu/roms/u-boot/arch/x86/include/asm/unaligned.h new file mode 100644 index 000000000..6cecbbb21 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/unaligned.h @@ -0,0 +1 @@ +#include <asm-generic/unaligned.h> diff --git a/qemu/roms/u-boot/arch/x86/include/asm/video/edid.h b/qemu/roms/u-boot/arch/x86/include/asm/video/edid.h new file mode 100644 index 000000000..928c342b3 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/video/edid.h @@ -0,0 +1,16 @@ +#ifndef __linux_video_edid_h__ +#define __linux_video_edid_h__ + +#if !defined(__KERNEL__) || defined(CONFIG_X86) + +struct edid_info { + unsigned char dummy[128]; +}; + +#ifdef __KERNEL__ +extern struct edid_info edid_info; +#endif /* __KERNEL__ */ + +#endif + +#endif /* __linux_video_edid_h__ */ diff --git a/qemu/roms/u-boot/arch/x86/include/asm/zimage.h b/qemu/roms/u-boot/arch/x86/include/asm/zimage.h new file mode 100644 index 000000000..0f3666268 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/include/asm/zimage.h @@ -0,0 +1,44 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ZIMAGE_H_ +#define _ASM_ZIMAGE_H_ + +#include <asm/bootparam.h> +#include <asm/e820.h> + +/* linux i386 zImage/bzImage header. Offsets relative to + * the start of the image */ + +#define HEAP_FLAG 0x80 +#define BIG_KERNEL_FLAG 0x01 + +/* magic numbers */ +#define KERNEL_MAGIC 0xaa55 +#define KERNEL_V2_MAGIC 0x53726448 +#define COMMAND_LINE_MAGIC 0xA33F + +/* limits */ +#define BZIMAGE_MAX_SIZE 15*1024*1024 /* 15MB */ +#define ZIMAGE_MAX_SIZE 512*1024 /* 512k */ +#define SETUP_MAX_SIZE 32768 + +#define SETUP_START_OFFSET 0x200 +#define BZIMAGE_LOAD_ADDR 0x100000 +#define ZIMAGE_LOAD_ADDR 0x10000 + +/* Implementation defined function to install an e820 map. */ +unsigned install_e820_map(unsigned max_entries, struct e820entry *); + +struct boot_params *load_zimage(char *image, unsigned long kernel_size, + void **load_address); +int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, + unsigned long initrd_addr, unsigned long initrd_size); + +void boot_zimage(void *setup_base, void *load_address); + +#endif diff --git a/qemu/roms/u-boot/arch/x86/lib/Makefile b/qemu/roms/u-boot/arch/x86/lib/Makefile new file mode 100644 index 000000000..f7303abcc --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/Makefile @@ -0,0 +1,28 @@ +# +# (C) Copyright 2002-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-y += cmd_boot.o +obj-y += gcc.o +obj-y += init_helpers.o +obj-y += interrupts.o +obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o +obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o +obj-$(CONFIG_PCI) += pci_type1.o +obj-y += relocate.o +obj-y += physmem.o +obj-y += string.o +obj-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o +obj-$(CONFIG_VIDEO_VGA) += video.o +obj-$(CONFIG_CMD_ZBOOT) += zimage.o + +LIBGCC := $(notdir $(NORMAL_LIBGCC)) +extra-y := $(LIBGCC) + +OBJCOPYFLAGS := --prefix-symbols=__normal_ +$(obj)/$(LIBGCC): $(NORMAL_LIBGCC) FORCE + $(call if_changed,objcopy) diff --git a/qemu/roms/u-boot/arch/x86/lib/asm-offsets.c b/qemu/roms/u-boot/arch/x86/lib/asm-offsets.c new file mode 100644 index 000000000..d65c6ab1b --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/asm-offsets.c @@ -0,0 +1,22 @@ +/* + * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c + * + * This program is used to generate definitions needed by + * assembly language modules. + * + * We use the technique used in the OSF Mach kernel code: + * generate asm statements containing #defines, + * compile this file to assembler, and then extract the + * #defines from the assembly-language output. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/kbuild.h> + +int main(void) +{ + DEFINE(GENERATED_GD_RELOC_OFF, offsetof(gd_t, reloc_off)); + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/bootm.c b/qemu/roms/u-boot/arch/x86/lib/bootm.c new file mode 100644 index 000000000..ff158dd6a --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/bootm.c @@ -0,0 +1,89 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <image.h> +#include <u-boot/zlib.h> +#include <asm/bootparam.h> +#include <asm/byteorder.h> +#include <asm/zimage.h> + +#define COMMAND_LINE_OFFSET 0x9000 + +/*cmd_boot.c*/ +int do_bootm_linux(int flag, int argc, char * const argv[], + bootm_headers_t *images) +{ + struct boot_params *base_ptr = NULL; + ulong os_data, os_len; + image_header_t *hdr; + void *load_address; + +#if defined(CONFIG_FIT) + const void *data; + size_t len; +#endif + + if (flag & BOOTM_STATE_OS_PREP) + return 0; + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 1; + + if (images->legacy_hdr_valid) { + hdr = images->legacy_hdr_os; + if (image_check_type(hdr, IH_TYPE_MULTI)) { + /* if multi-part image, we need to get first subimage */ + image_multi_getimg(hdr, 0, &os_data, &os_len); + } else { + /* otherwise get image data */ + os_data = image_get_data(hdr); + os_len = image_get_data_size(hdr); + } +#if defined(CONFIG_FIT) + } else if (images->fit_uname_os) { + int ret; + + ret = fit_image_get_data(images->fit_hdr_os, + images->fit_noffset_os, &data, &len); + if (ret) { + puts("Can't get image data/size!\n"); + goto error; + } + os_data = (ulong)data; + os_len = (ulong)len; +#endif + } else { + puts("Could not find kernel image!\n"); + goto error; + } + +#ifdef CONFIG_CMD_ZBOOT + base_ptr = load_zimage((void *)os_data, os_len, &load_address); +#endif + + if (NULL == base_ptr) { + printf("## Kernel loading failed ...\n"); + goto error; + } + + if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, + 0, images->rd_start, + images->rd_end - images->rd_start)) { + printf("## Setting up boot parameters failed ...\n"); + goto error; + } + + boot_zimage(base_ptr, load_address); + /* does not return */ + +error: + return 1; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/cmd_boot.c b/qemu/roms/u-boot/arch/x86/lib/cmd_boot.c new file mode 100644 index 000000000..a24d3f013 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/cmd_boot.c @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <malloc.h> +#include <asm/u-boot-x86.h> + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long do_go_exec(ulong (*entry)(int, char * const []), + int argc, char * const argv[]) +{ + unsigned long ret = 0; + char **argv_tmp; + + /* + * x86 does not use a dedicated register to pass the pointer to + * the global_data, so it is instead passed as argv[-1]. By using + * argv[-1], the called 'Application' can use the contents of + * argv natively. However, to safely use argv[-1] a new copy of + * argv is needed with the extra element + */ + argv_tmp = malloc(sizeof(char *) * (argc + 1)); + + if (argv_tmp) { + argv_tmp[0] = (char *)gd; + + memcpy(&argv_tmp[1], argv, (size_t)(sizeof(char *) * argc)); + + ret = (entry) (argc, &argv_tmp[1]); + free(argv_tmp); + } + + return ret; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/gcc.c b/qemu/roms/u-boot/arch/x86/lib/gcc.c new file mode 100644 index 000000000..497ad75b7 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/gcc.c @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 coresystems GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 or later of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#ifdef __GNUC__ + +/* + * GCC's libgcc handling is quite broken. While the libgcc functions + * are always regparm(0) the code that calls them uses whatever the + * compiler call specifies. Therefore we need a wrapper around those + * functions. See gcc bug PR41055 for more information. + */ +#define WRAP_LIBGCC_CALL(type, name) \ + type __normal_##name(type a, type b) __attribute__((regparm(0))); \ + type __wrap_##name(type a, type b); \ + type __attribute__((no_instrument_function)) \ + __wrap_##name(type a, type b) \ + { return __normal_##name(a, b); } + +WRAP_LIBGCC_CALL(long long, __divdi3) +WRAP_LIBGCC_CALL(unsigned long long, __udivdi3) +WRAP_LIBGCC_CALL(long long, __moddi3) +WRAP_LIBGCC_CALL(unsigned long long, __umoddi3) + +#endif diff --git a/qemu/roms/u-boot/arch/x86/lib/init_helpers.c b/qemu/roms/u-boot/arch/x86/lib/init_helpers.c new file mode 100644 index 000000000..b5d937feb --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/init_helpers.c @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <fdtdec.h> +#include <spi.h> +#include <asm/sections.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Get the top of usable RAM */ +__weak ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_size; +} + +int calculate_relocation_address(void) +{ + const ulong uboot_size = (uintptr_t)&__bss_end - + (uintptr_t)&__text_start; + ulong total_size; + ulong dest_addr; + ulong fdt_size = 0; + +#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) + if (gd->fdt_blob) + fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); +#endif + total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + + CONFIG_SYS_STACK_SIZE + fdt_size; + + dest_addr = board_get_usable_ram_top(total_size); + /* + * NOTE: All destination address are rounded down to 16-byte + * boundary to satisfy various worst-case alignment + * requirements + */ + dest_addr &= ~15; + +#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) + /* + * If the device tree is sitting immediate above our image then we + * must relocate it. If it is embedded in the data section, then it + * will be relocated with other data. + */ + if (gd->fdt_blob) { + dest_addr -= fdt_size; + gd->new_fdt = (void *)dest_addr; + dest_addr &= ~15; + } +#endif + /* U-Boot is below the FDT */ + dest_addr -= uboot_size; + dest_addr &= ~((1 << 12) - 1); + gd->relocaddr = dest_addr; + gd->reloc_off = dest_addr - (uintptr_t)&__text_start; + + /* Stack is at the bottom, so it can grow down */ + gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN; + + return 0; +} + +int init_cache_f_r(void) +{ + /* Initialise the CPU cache(s) */ + return init_cache(); +} + +bd_t bd_data; + +int init_bd_struct_r(void) +{ + gd->bd = &bd_data; + memset(gd->bd, 0, sizeof(bd_t)); + + return 0; +} + +int init_func_spi(void) +{ + puts("SPI: "); + spi_init(); + puts("ready\n"); + return 0; +} + +int find_fdt(void) +{ +#ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = __dtb_dt_begin; +#elif defined CONFIG_OF_SEPARATE + /* FDT is at end of image */ + gd->fdt_blob = (ulong *)&_end; +#endif + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); + + return 0; +} + +int prepare_fdt(void) +{ + /* For now, put this check after the console is ready */ + if (fdtdec_prepare_fdt()) { + panic("** CONFIG_OF_CONTROL defined but no FDT - please see " + "doc/README.fdt-control"); + } + + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/interrupts.c b/qemu/roms/u-boot/arch/x86/lib/interrupts.c new file mode 100644 index 000000000..6bb22d25e --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/interrupts.c @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2009 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2007 + * Daniel Hellstrom, Gaisler Research, <daniel@gaisler.com> + * + * (C) Copyright 2006 + * Detlev Zundel, DENX Software Engineering, <dzu@denx.de> + * + * (C) Copyright -2003 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * (C) Copyright 2001 + * Josh Huber, Mission Critical Linux, Inc, <huber@mclx.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This file contains the high-level API for the interrupt sub-system + * of the x86 port of U-Boot. Most of the functionality has been + * shamelessly stolen from the leon2 / leon3 ports of U-Boot. + * Daniel Hellstrom, Detlev Zundel, Wolfgang Denk and Josh Huber are + * credited for the corresponding work on those ports. The original + * interrupt handling routines for the x86 port were written by + * Daniel Engström + */ + +#include <common.h> +#include <asm/interrupt.h> + +struct irq_action { + interrupt_handler_t *handler; + void *arg; + unsigned int count; +}; + +static struct irq_action irq_handlers[CONFIG_SYS_NUM_IRQS] = { {0} }; +static int spurious_irq_cnt; +static int spurious_irq; + +void irq_install_handler(int irq, interrupt_handler_t *handler, void *arg) +{ + int status; + + if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + printf("irq_install_handler: bad irq number %d\n", irq); + return; + } + + if (irq_handlers[irq].handler != NULL) + printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n", + (ulong) handler, + (ulong) irq_handlers[irq].handler); + + status = disable_interrupts(); + + irq_handlers[irq].handler = handler; + irq_handlers[irq].arg = arg; + irq_handlers[irq].count = 0; + + unmask_irq(irq); + + if (status) + enable_interrupts(); + + return; +} + +void irq_free_handler(int irq) +{ + int status; + + if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + printf("irq_free_handler: bad irq number %d\n", irq); + return; + } + + status = disable_interrupts(); + + mask_irq(irq); + + irq_handlers[irq].handler = NULL; + irq_handlers[irq].arg = NULL; + + if (status) + enable_interrupts(); + + return; +} + +void do_irq(int hw_irq) +{ + int irq = hw_irq - 0x20; + + if (irq < 0 || irq >= CONFIG_SYS_NUM_IRQS) { + printf("do_irq: bad irq number %d\n", irq); + return; + } + + if (irq_handlers[irq].handler) { + mask_irq(irq); + + irq_handlers[irq].handler(irq_handlers[irq].arg); + irq_handlers[irq].count++; + + unmask_irq(irq); + specific_eoi(irq); + + } else { + if ((irq & 7) != 7) { + spurious_irq_cnt++; + spurious_irq = irq; + } + } +} + +#if defined(CONFIG_CMD_IRQ) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + int irq; + + printf("Spurious IRQ: %u, last unknown IRQ: %d\n", + spurious_irq_cnt, spurious_irq); + + printf("Interrupt-Information:\n"); + printf("Nr Routine Arg Count\n"); + + for (irq = 0; irq <= CONFIG_SYS_NUM_IRQS; irq++) { + if (irq_handlers[irq].handler != NULL) { + printf("%02d %08lx %08lx %d\n", + irq, + (ulong)irq_handlers[irq].handler, + (ulong)irq_handlers[irq].arg, + irq_handlers[irq].count); + } + } + + return 0; +} +#endif diff --git a/qemu/roms/u-boot/arch/x86/lib/pcat_interrupts.c b/qemu/roms/u-boot/arch/x86/lib/pcat_interrupts.c new file mode 100644 index 000000000..4c86f7fc6 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/pcat_interrupts.c @@ -0,0 +1,116 @@ +/* + * (C) Copyright 2009 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * This file provides the interrupt handling functionality for systems + * based on the standard PC/AT architecture using two cascaded i8259 + * Programmable Interrupt Controllers. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/i8259.h> +#include <asm/ibmpc.h> +#include <asm/interrupt.h> + +#if CONFIG_SYS_NUM_IRQS != 16 +#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined" +#endif + +int interrupt_init(void) +{ + u8 i; + + disable_interrupts(); + + /* Mask all interrupts */ + outb(0xff, MASTER_PIC + IMR); + outb(0xff, SLAVE_PIC + IMR); + + /* Master PIC */ + /* Place master PIC interrupts at INT20 */ + /* ICW3, One slave PIC is present */ + outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1); + outb(0x20, MASTER_PIC + ICW2); + outb(IR2, MASTER_PIC + ICW3); + outb(ICW4_PM, MASTER_PIC + ICW4); + + for (i = 0; i < 8; i++) + outb(OCW2_SEOI | i, MASTER_PIC + OCW2); + + /* Slave PIC */ + /* Place slave PIC interrupts at INT28 */ + /* Slave ID */ + outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1); + outb(0x28, SLAVE_PIC + ICW2); + outb(0x02, SLAVE_PIC + ICW3); + outb(ICW4_PM, SLAVE_PIC + ICW4); + + for (i = 0; i < 8; i++) + outb(OCW2_SEOI | i, SLAVE_PIC + OCW2); + + /* + * Enable cascaded interrupts by unmasking the cascade IRQ pin of + * the master PIC + */ + unmask_irq(2); + + enable_interrupts(); + + return 0; +} + +void mask_irq(int irq) +{ + int imr_port; + + if (irq >= CONFIG_SYS_NUM_IRQS) + return; + + if (irq > 7) + imr_port = SLAVE_PIC + IMR; + else + imr_port = MASTER_PIC + IMR; + + outb(inb(imr_port) | (1 << (irq & 7)), imr_port); +} + +void unmask_irq(int irq) +{ + int imr_port; + + if (irq >= CONFIG_SYS_NUM_IRQS) + return; + + if (irq > 7) + imr_port = SLAVE_PIC + IMR; + else + imr_port = MASTER_PIC + IMR; + + outb(inb(imr_port) & ~(1 << (irq & 7)), imr_port); +} + +void specific_eoi(int irq) +{ + if (irq >= CONFIG_SYS_NUM_IRQS) + return; + + if (irq > 7) { + /* + * IRQ is on the slave - Issue a corresponding EOI to the + * slave PIC and an EOI for IRQ2 (the cascade interrupt) + * on the master PIC + */ + outb(OCW2_SEOI | (irq & 7), SLAVE_PIC + OCW2); + irq = SEOI_IR2; + } + + outb(OCW2_SEOI | irq, MASTER_PIC + OCW2); +} diff --git a/qemu/roms/u-boot/arch/x86/lib/pcat_timer.c b/qemu/roms/u-boot/arch/x86/lib/pcat_timer.c new file mode 100644 index 000000000..3545a5048 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/pcat_timer.c @@ -0,0 +1,27 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/i8254.h> + +#define TIMER2_VALUE 0x0a8e /* 440Hz */ + +int pcat_timer_init(void) +{ + /* + * initialize 2, used to drive the speaker + * (to start a beep: write 3 to port 0x61, + * to stop it again: write 0) + */ + outb(PIT_CMD_CTR2 | PIT_CMD_BOTH | PIT_CMD_MODE3, + PIT_BASE + PIT_COMMAND); + outb(TIMER2_VALUE & 0xff, PIT_BASE + PIT_T2); + outb(TIMER2_VALUE >> 8, PIT_BASE + PIT_T2); + + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/pci_type1.c b/qemu/roms/u-boot/arch/x86/lib/pci_type1.c new file mode 100644 index 000000000..13942a33f --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/pci_type1.c @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Support for type PCI configuration cycles. + * based on pci_indirect.c + */ +#include <common.h> +#include <asm/io.h> +#include <pci.h> + +#define cfg_read(val, addr, op) (*val = op((int)(addr))) +#define cfg_write(val, addr, op) op((val), (int)(addr)) + +#define TYPE1_PCI_OP(rw, size, type, op, mask) \ +static int \ +type1_##rw##_config_##size(struct pci_controller *hose, \ + pci_dev_t dev, int offset, type val) \ +{ \ + outl(dev | (offset & 0xfc) | 0x80000000, (int)hose->cfg_addr); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), op); \ + return 0; \ +} + +TYPE1_PCI_OP(read, byte, u8 *, inb, 3) +TYPE1_PCI_OP(read, word, u16 *, inw, 2) +TYPE1_PCI_OP(read, dword, u32 *, inl, 0) + +TYPE1_PCI_OP(write, byte, u8, outb, 3) +TYPE1_PCI_OP(write, word, u16, outw, 2) +TYPE1_PCI_OP(write, dword, u32, outl, 0) + +/* bus mapping constants (used for PCI core initialization) */ +#define PCI_REG_ADDR 0x00000cf8 +#define PCI_REG_DATA 0x00000cfc + +void pci_setup_type1(struct pci_controller *hose) +{ + pci_set_ops(hose, + type1_read_config_byte, + type1_read_config_word, + type1_read_config_dword, + type1_write_config_byte, + type1_write_config_word, + type1_write_config_dword); + + hose->cfg_addr = (unsigned int *)PCI_REG_ADDR; + hose->cfg_data = (unsigned char *)PCI_REG_DATA; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/physmem.c b/qemu/roms/u-boot/arch/x86/lib/physmem.c new file mode 100644 index 000000000..59b3fe977 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/physmem.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#include <common.h> +#include <physmem.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Large pages are 2MB. */ +#define LARGE_PAGE_SIZE ((1 << 20) * 2) + +/* + * Paging data structures. + */ + +struct pdpe { + uint64_t p:1; + uint64_t mbz_0:2; + uint64_t pwt:1; + uint64_t pcd:1; + uint64_t mbz_1:4; + uint64_t avl:3; + uint64_t base:40; + uint64_t mbz_2:12; +}; + +typedef struct pdpe pdpt_t[512]; + +struct pde { + uint64_t p:1; /* present */ + uint64_t rw:1; /* read/write */ + uint64_t us:1; /* user/supervisor */ + uint64_t pwt:1; /* page-level writethrough */ + uint64_t pcd:1; /* page-level cache disable */ + uint64_t a:1; /* accessed */ + uint64_t d:1; /* dirty */ + uint64_t ps:1; /* page size */ + uint64_t g:1; /* global page */ + uint64_t avl:3; /* available to software */ + uint64_t pat:1; /* page-attribute table */ + uint64_t mbz_0:8; /* must be zero */ + uint64_t base:31; /* base address */ +}; + +typedef struct pde pdt_t[512]; + +static pdpt_t pdpt __aligned(4096); +static pdt_t pdts[4] __aligned(4096); + +/* + * Map a virtual address to a physical address and optionally invalidate any + * old mapping. + * + * @param virt The virtual address to use. + * @param phys The physical address to use. + * @param invlpg Whether to use invlpg to clear any old mappings. + */ +static void x86_phys_map_page(uintptr_t virt, phys_addr_t phys, int invlpg) +{ + /* Extract the two bit PDPT index and the 9 bit PDT index. */ + uintptr_t pdpt_idx = (virt >> 30) & 0x3; + uintptr_t pdt_idx = (virt >> 21) & 0x1ff; + + /* Set up a handy pointer to the appropriate PDE. */ + struct pde *pde = &(pdts[pdpt_idx][pdt_idx]); + + memset(pde, 0, sizeof(struct pde)); + pde->p = 1; + pde->rw = 1; + pde->us = 1; + pde->ps = 1; + pde->base = phys >> 21; + + if (invlpg) { + /* Flush any stale mapping out of the TLBs. */ + __asm__ __volatile__( + "invlpg %0\n\t" + : + : "m" (*(uint8_t *)virt) + ); + } +} + +/* Identity map the lower 4GB and turn on paging with PAE. */ +static void x86_phys_enter_paging(void) +{ + phys_addr_t page_addr; + unsigned i; + + /* Zero out the page tables. */ + memset(pdpt, 0, sizeof(pdpt)); + memset(pdts, 0, sizeof(pdts)); + + /* Set up the PDPT. */ + for (i = 0; i < ARRAY_SIZE(pdts); i++) { + pdpt[i].p = 1; + pdpt[i].base = ((uintptr_t)&pdts[i]) >> 12; + } + + /* Identity map everything up to 4GB. */ + for (page_addr = 0; page_addr < (1ULL << 32); + page_addr += LARGE_PAGE_SIZE) { + /* There's no reason to invalidate the TLB with paging off. */ + x86_phys_map_page(page_addr, page_addr, 0); + } + + /* Turn on paging */ + __asm__ __volatile__( + /* Load the page table address */ + "movl %0, %%cr3\n\t" + /* Enable pae */ + "movl %%cr4, %%eax\n\t" + "orl $0x00000020, %%eax\n\t" + "movl %%eax, %%cr4\n\t" + /* Enable paging */ + "movl %%cr0, %%eax\n\t" + "orl $0x80000000, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + : + : "r" (pdpt) + : "eax" + ); +} + +/* Disable paging and PAE mode. */ +static void x86_phys_exit_paging(void) +{ + /* Turn off paging */ + __asm__ __volatile__ ( + /* Disable paging */ + "movl %%cr0, %%eax\n\t" + "andl $0x7fffffff, %%eax\n\t" + "movl %%eax, %%cr0\n\t" + /* Disable pae */ + "movl %%cr4, %%eax\n\t" + "andl $0xffffffdf, %%eax\n\t" + "movl %%eax, %%cr4\n\t" + : + : + : "eax" + ); +} + +/* + * Set physical memory to a particular value when the whole region fits on one + * page. + * + * @param map_addr The address that starts the physical page. + * @param offset How far into that page to start setting a value. + * @param c The value to set memory to. + * @param size The size in bytes of the area to set. + */ +static void x86_phys_memset_page(phys_addr_t map_addr, uintptr_t offset, int c, + unsigned size) +{ + /* + * U-Boot should be far away from the beginning of memory, so that's a + * good place to map our window on top of. + */ + const uintptr_t window = LARGE_PAGE_SIZE; + + /* Make sure the window is below U-Boot. */ + assert(window + LARGE_PAGE_SIZE < + gd->relocaddr - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_STACK_SIZE); + /* Map the page into the window and then memset the appropriate part. */ + x86_phys_map_page(window, map_addr, 1); + memset((void *)(window + offset), c, size); +} + +/* + * A physical memory anologue to memset with matching parameters and return + * value. + */ +phys_addr_t arch_phys_memset(phys_addr_t start, int c, phys_size_t size) +{ + const phys_addr_t max_addr = (phys_addr_t)~(uintptr_t)0; + const phys_addr_t orig_start = start; + + if (!size) + return orig_start; + + /* Handle memory below 4GB. */ + if (start <= max_addr) { + phys_size_t low_size = MIN(max_addr + 1 - start, size); + void *start_ptr = (void *)(uintptr_t)start; + + assert(((phys_addr_t)(uintptr_t)start) == start); + memset(start_ptr, c, low_size); + start += low_size; + size -= low_size; + } + + /* Use paging and PAE to handle memory above 4GB up to 64GB. */ + if (size) { + phys_addr_t map_addr = start & ~(LARGE_PAGE_SIZE - 1); + phys_addr_t offset = start - map_addr; + + x86_phys_enter_paging(); + + /* Handle the first partial page. */ + if (offset) { + phys_addr_t end = + MIN(map_addr + LARGE_PAGE_SIZE, start + size); + phys_size_t cur_size = end - start; + x86_phys_memset_page(map_addr, offset, c, cur_size); + size -= cur_size; + map_addr += LARGE_PAGE_SIZE; + } + /* Handle the complete pages. */ + while (size > LARGE_PAGE_SIZE) { + x86_phys_memset_page(map_addr, 0, c, LARGE_PAGE_SIZE); + size -= LARGE_PAGE_SIZE; + map_addr += LARGE_PAGE_SIZE; + } + /* Handle the last partial page. */ + if (size) + x86_phys_memset_page(map_addr, 0, c, size); + + x86_phys_exit_paging(); + } + return orig_start; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/relocate.c b/qemu/roms/u-boot/arch/x86/lib/relocate.c new file mode 100644 index 000000000..526daaf93 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/relocate.c @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2008-2011 + * Graeme Russ, <graeme.russ@gmail.com> + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <libfdt.h> +#include <malloc.h> +#include <asm/u-boot-x86.h> +#include <asm/relocate.h> +#include <asm/sections.h> +#include <elf.h> + +DECLARE_GLOBAL_DATA_PTR; + +int copy_uboot_to_ram(void) +{ + size_t len = (size_t)&__data_end - (size_t)&__text_start; + + memcpy((void *)gd->relocaddr, (void *)&__text_start, len); + + return 0; +} + +int copy_fdt_to_ram(void) +{ + if (gd->new_fdt) { + ulong fdt_size; + + fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); + + memcpy(gd->new_fdt, gd->fdt_blob, fdt_size); + debug("Relocated fdt from %p to %p, size %lx\n", + gd->fdt_blob, gd->new_fdt, fdt_size); + gd->fdt_blob = gd->new_fdt; + } + + return 0; +} + +int clear_bss(void) +{ + ulong dst_addr = (ulong)&__bss_start + gd->reloc_off; + size_t len = (size_t)&__bss_end - (size_t)&__bss_start; + + memset((void *)dst_addr, 0x00, len); + + return 0; +} + +/* + * This function has more error checking than you might expect. Please see + * the commit message for more informaiton. + */ +int do_elf_reloc_fixups(void) +{ + Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start); + Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end); + + Elf32_Addr *offset_ptr_rom, *last_offset = NULL; + Elf32_Addr *offset_ptr_ram; + + /* The size of the region of u-boot that runs out of RAM. */ + uintptr_t size = (uintptr_t)&__bss_end - (uintptr_t)&__text_start; + + do { + /* Get the location from the relocation entry */ + offset_ptr_rom = (Elf32_Addr *)re_src->r_offset; + + /* Check that the location of the relocation is in .text */ + if (offset_ptr_rom >= (Elf32_Addr *)CONFIG_SYS_TEXT_BASE && + offset_ptr_rom > last_offset) { + + /* Switch to the in-RAM version */ + offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + + gd->reloc_off); + + /* Check that the target points into .text */ + if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE && + *offset_ptr_ram <= + (CONFIG_SYS_TEXT_BASE + size)) { + *offset_ptr_ram += gd->reloc_off; + } else { + debug(" %p: rom reloc %x, ram %p, value %x," + " limit %lx\n", re_src, + re_src->r_offset, offset_ptr_ram, + *offset_ptr_ram, + CONFIG_SYS_TEXT_BASE + size); + } + } else { + debug(" %p: rom reloc %x, last %p\n", re_src, + re_src->r_offset, last_offset); + } + last_offset = offset_ptr_rom; + + } while (++re_src < re_end); + + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/string.c b/qemu/roms/u-boot/arch/x86/lib/string.c new file mode 100644 index 000000000..a1656ccfe --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/string.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1991,1992,1993,1997,1998,2003, 2005 Free Software Foundation, Inc. + * This file is part of the GNU C Library. + * Copyright (c) 2011 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* From glibc-2.14, sysdeps/i386/memset.c */ + +#include <compiler.h> +#include <asm/string.h> +#include <linux/types.h> + +typedef uint32_t op_t; + +void *memset(void *dstpp, int c, size_t len) +{ + int d0; + unsigned long int dstp = (unsigned long int) dstpp; + + /* This explicit register allocation improves code very much indeed. */ + register op_t x asm("ax"); + + x = (unsigned char) c; + + /* Clear the direction flag, so filling will move forward. */ + asm volatile("cld"); + + /* This threshold value is optimal. */ + if (len >= 12) { + /* Fill X with four copies of the char we want to fill with. */ + x |= (x << 8); + x |= (x << 16); + + /* Adjust LEN for the bytes handled in the first loop. */ + len -= (-dstp) % sizeof(op_t); + + /* + * There are at least some bytes to set. No need to test for + * LEN == 0 in this alignment loop. + */ + + /* Fill bytes until DSTP is aligned on a longword boundary. */ + asm volatile( + "rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp), "=c" (d0) : + "0" (dstp), "1" ((-dstp) % sizeof(op_t)), "a" (x) : + "memory"); + + /* Fill longwords. */ + asm volatile( + "rep\n" + "stosl" /* %0, %2, %3 */ : + "=D" (dstp), "=c" (d0) : + "0" (dstp), "1" (len / sizeof(op_t)), "a" (x) : + "memory"); + len %= sizeof(op_t); + } + + /* Write the last few bytes. */ + asm volatile( + "rep\n" + "stosb" /* %0, %2, %3 */ : + "=D" (dstp), "=c" (d0) : + "0" (dstp), "1" (len), "a" (x) : + "memory"); + + return dstpp; +} + +#define OP_T_THRES 8 +#define OPSIZ (sizeof(op_t)) + +#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \ +do { \ + int __d0; \ + asm volatile( \ + /* Clear the direction flag, so copying goes forward. */ \ + "cld\n" \ + /* Copy bytes. */ \ + "rep\n" \ + "movsb" : \ + "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) : \ + "0" (dst_bp), "1" (src_bp), "2" (nbytes) : \ + "memory"); \ +} while (0) + +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ +do { \ + int __d0; \ + asm volatile( \ + /* Clear the direction flag, so copying goes forward. */ \ + "cld\n" \ + /* Copy longwords. */ \ + "rep\n" \ + "movsl" : \ + "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) : \ + "0" (dst_bp), "1" (src_bp), "2" ((nbytes) / 4) : \ + "memory"); \ + (nbytes_left) = (nbytes) % 4; \ +} while (0) + +void *memcpy(void *dstpp, const void *srcpp, size_t len) +{ + unsigned long int dstp = (long int)dstpp; + unsigned long int srcp = (long int)srcpp; + + /* Copy from the beginning to the end. */ + + /* If there not too few bytes to copy, use word copy. */ + if (len >= OP_T_THRES) { + /* Copy just a few bytes to make DSTP aligned. */ + len -= (-dstp) % OPSIZ; + BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ); + + /* Copy from SRCP to DSTP taking advantage of the known + * alignment of DSTP. Number of bytes remaining is put + * in the third argument, i.e. in LEN. This number may + * vary from machine to machine. + */ + WORD_COPY_FWD(dstp, srcp, len, len); + + /* Fall out and copy the tail. */ + } + + /* There are just a few bytes to copy. Use byte memory operations. */ + BYTE_COPY_FWD(dstp, srcp, len); + + return dstpp; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/tsc_timer.c b/qemu/roms/u-boot/arch/x86/lib/tsc_timer.c new file mode 100644 index 000000000..8b38702ef --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/tsc_timer.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <asm/io.h> +#include <asm/i8254.h> +#include <asm/ibmpc.h> +#include <asm/msr.h> +#include <asm/u-boot-x86.h> + +DECLARE_GLOBAL_DATA_PTR; + +void timer_set_base(u64 base) +{ + gd->arch.tsc_base = base; +} + +/* + * Get the number of CPU time counter ticks since it was read first time after + * restart. This yields a free running counter guaranteed to take almost 6 + * years to wrap around even at 100GHz clock rate. + */ +u64 __attribute__((no_instrument_function)) get_ticks(void) +{ + u64 now_tick = rdtsc(); + + /* We assume that 0 means the base hasn't been set yet */ + if (!gd->arch.tsc_base) + panic("No tick base available"); + return now_tick - gd->arch.tsc_base; +} + +#define PLATFORM_INFO_MSR 0xce + +/* Get the speed of the TSC timer in MHz */ +unsigned __attribute__((no_instrument_function)) long get_tbclk_mhz(void) +{ + u32 ratio; + u64 platform_info = native_read_msr(PLATFORM_INFO_MSR); + + /* 100MHz times Max Non Turbo ratio */ + ratio = (platform_info >> 8) & 0xff; + return 100 * ratio; +} + +unsigned long get_tbclk(void) +{ + return get_tbclk_mhz() * 1000 * 1000; +} + +static ulong get_ms_timer(void) +{ + return (get_ticks() * 1000) / get_tbclk(); +} + +ulong get_timer(ulong base) +{ + return get_ms_timer() - base; +} + +ulong __attribute__((no_instrument_function)) timer_get_us(void) +{ + return get_ticks() / get_tbclk_mhz(); +} + +ulong timer_get_boot_us(void) +{ + return timer_get_us(); +} + +void __udelay(unsigned long usec) +{ + u64 now = get_ticks(); + u64 stop; + + stop = now + usec * get_tbclk_mhz(); + + while ((int64_t)(stop - get_ticks()) > 0) + ; +} + +int timer_init(void) +{ +#ifdef CONFIG_SYS_PCAT_TIMER + /* Set up the PCAT timer if required */ + pcat_timer_init(); +#endif + + return 0; +} diff --git a/qemu/roms/u-boot/arch/x86/lib/video.c b/qemu/roms/u-boot/arch/x86/lib/video.c new file mode 100644 index 000000000..dfd2a8496 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/video.c @@ -0,0 +1,209 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <pci.h> +#include <stdio_dev.h> +#include <i8042.h> +#include <asm/ptrace.h> +#include <asm/io.h> +#include <asm/pci.h> + +/* basic textmode I/O from linux kernel */ +static char *vidmem = (char *)0xb8000; +static int vidport; +static int lines, cols; +static int orig_x, orig_y; + +static void beep(int dur) +{ + int i; + + outb_p(3, 0x61); + for (i = 0; i < 10*dur; i++) + udelay(1000); + + outb_p(0, 0x61); +} + +static void scroll(void) +{ + int i; + + memcpy(vidmem, vidmem + cols * 2, (lines - 1) * cols * 2); + for (i = (lines - 1) * cols * 2; i < lines * cols * 2; i += 2) + vidmem[i] = ' '; +} + +static void __video_putc(const char c, int *x, int *y) +{ + if (c == '\n') { + (*x) = 0; + if (++(*y) >= lines) { + scroll(); + (*y)--; + } + } else if (c == '\b') { + if ((*x) != 0) { + --(*x); + vidmem[((*x) + cols * (*y)) * 2] = ' '; + } + } else if (c == '\r') { + (*x) = 0; + + } else if (c == '\a') { + beep(3); + + } else if (c == '\t') { + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + __video_putc(' ', x, y); + } else if (c == '\v') { + switch ((*x) % 8) { + case 0: + __video_putc(' ', x, y); + case 7: + __video_putc(' ', x, y); + case 6: + __video_putc(' ', x, y); + case 5: + __video_putc(' ', x, y); + case 4: + __video_putc(' ', x, y); + case 3: + __video_putc(' ', x, y); + case 2: + __video_putc(' ', x, y); + case 1: + __video_putc(' ', x, y); + } + } else if (c == '\f') { + int i; + for (i = 0; i < lines * cols * 2; i += 2) + vidmem[i] = 0; + (*x) = 0; + (*y) = 0; + } else { + vidmem[((*x) + cols * (*y)) * 2] = c; + if (++(*x) >= cols) { + (*x) = 0; + if (++(*y) >= lines) { + scroll(); + (*y)--; + } + } + } +} + +static void video_putc(const char c) +{ + int x, y, pos; + + x = orig_x; + y = orig_y; + + __video_putc(c, &x, &y); + + orig_x = x; + orig_y = y; + + pos = (x + cols * y) * 2; /* Update cursor position */ + outb_p(14, vidport); + outb_p(0xff & (pos >> 9), vidport+1); + outb_p(15, vidport); + outb_p(0xff & (pos >> 1), vidport+1); +} + +static void video_puts(const char *s) +{ + int x, y, pos; + char c; + + x = orig_x; + y = orig_y; + + while ((c = *s++) != '\0') + __video_putc(c, &x, &y); + + orig_x = x; + orig_y = y; + + pos = (x + cols * y) * 2; /* Update cursor position */ + outb_p(14, vidport); + outb_p(0xff & (pos >> 9), vidport+1); + outb_p(15, vidport); + outb_p(0xff & (pos >> 1), vidport+1); +} + +int video_init(void) +{ + u16 pos; + + static struct stdio_dev vga_dev; + static struct stdio_dev kbd_dev; + + vidmem = (char *) 0xb8000; + vidport = 0x3d4; + + lines = 25; + cols = 80; + + outb_p(14, vidport); + pos = inb_p(vidport+1); + pos <<= 8; + outb_p(15, vidport); + pos |= inb_p(vidport+1); + + orig_x = pos%cols; + orig_y = pos/cols; + +#if 0 + printf("pos %x %d %d\n", pos, orig_x, orig_y); +#endif + if (orig_y > lines) + orig_x = orig_y = 0; + + memset(&vga_dev, 0, sizeof(vga_dev)); + strcpy(vga_dev.name, "vga"); + vga_dev.ext = 0; + vga_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; + vga_dev.putc = video_putc; /* 'putc' function */ + vga_dev.puts = video_puts; /* 'puts' function */ + vga_dev.tstc = NULL; /* 'tstc' function */ + vga_dev.getc = NULL; /* 'getc' function */ + + if (stdio_register(&vga_dev) == 0) + return 1; + + if (i8042_kbd_init()) + return 1; + + memset(&kbd_dev, 0, sizeof(kbd_dev)); + strcpy(kbd_dev.name, "kbd"); + kbd_dev.ext = 0; + kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + kbd_dev.putc = NULL; /* 'putc' function */ + kbd_dev.puts = NULL; /* 'puts' function */ + kbd_dev.tstc = i8042_tstc; /* 'tstc' function */ + kbd_dev.getc = i8042_getc; /* 'getc' function */ + + if (stdio_register(&kbd_dev) == 0) + return 1; + + return 0; +} + + +int drv_video_init(void) +{ + return video_init(); +} diff --git a/qemu/roms/u-boot/arch/x86/lib/zimage.c b/qemu/roms/u-boot/arch/x86/lib/zimage.c new file mode 100644 index 000000000..1dab3cc78 --- /dev/null +++ b/qemu/roms/u-boot/arch/x86/lib/zimage.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Linux x86 zImage and bzImage loading + * + * based on the procdure described in + * linux/Documentation/i386/boot.txt + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/ptrace.h> +#include <asm/zimage.h> +#include <asm/byteorder.h> +#include <asm/bootparam.h> +#ifdef CONFIG_SYS_COREBOOT +#include <asm/arch/timestamp.h> +#endif +#include <linux/compiler.h> + +/* + * Memory lay-out: + * + * relative to setup_base (which is 0x90000 currently) + * + * 0x0000-0x7FFF Real mode kernel + * 0x8000-0x8FFF Stack and heap + * 0x9000-0x90FF Kernel command line + */ +#define DEFAULT_SETUP_BASE 0x90000 +#define COMMAND_LINE_OFFSET 0x9000 +#define HEAP_END_OFFSET 0x8e00 + +#define COMMAND_LINE_SIZE 2048 + +unsigned generic_install_e820_map(unsigned max_entries, + struct e820entry *entries) +{ + return 0; +} + +unsigned install_e820_map(unsigned max_entries, + struct e820entry *entries) + __attribute__((weak, alias("generic_install_e820_map"))); + +static void build_command_line(char *command_line, int auto_boot) +{ + char *env_command_line; + + command_line[0] = '\0'; + + env_command_line = getenv("bootargs"); + + /* set console= argument if we use a serial console */ + if (!strstr(env_command_line, "console=")) { + if (!strcmp(getenv("stdout"), "serial")) { + + /* We seem to use serial console */ + sprintf(command_line, "console=ttyS0,%s ", + getenv("baudrate")); + } + } + + if (auto_boot) + strcat(command_line, "auto "); + + if (env_command_line) + strcat(command_line, env_command_line); + + printf("Kernel command line: \"%s\"\n", command_line); +} + +static int kernel_magic_ok(struct setup_header *hdr) +{ + if (KERNEL_MAGIC != hdr->boot_flag) { + printf("Error: Invalid Boot Flag " + "(found 0x%04x, expected 0x%04x)\n", + hdr->boot_flag, KERNEL_MAGIC); + return 0; + } else { + printf("Valid Boot Flag\n"); + return 1; + } +} + +static int get_boot_protocol(struct setup_header *hdr) +{ + if (hdr->header == KERNEL_V2_MAGIC) { + printf("Magic signature found\n"); + return hdr->version; + } else { + /* Very old kernel */ + printf("Magic signature not found\n"); + return 0x0100; + } +} + +struct boot_params *load_zimage(char *image, unsigned long kernel_size, + void **load_address) +{ + struct boot_params *setup_base; + int setup_size; + int bootproto; + int big_image; + + struct boot_params *params = (struct boot_params *)image; + struct setup_header *hdr = ¶ms->hdr; + + /* base address for real-mode segment */ + setup_base = (struct boot_params *)DEFAULT_SETUP_BASE; + + if (!kernel_magic_ok(hdr)) + return 0; + + /* determine size of setup */ + if (0 == hdr->setup_sects) { + printf("Setup Sectors = 0 (defaulting to 4)\n"); + setup_size = 5 * 512; + } else { + setup_size = (hdr->setup_sects + 1) * 512; + } + + printf("Setup Size = 0x%8.8lx\n", (ulong)setup_size); + + if (setup_size > SETUP_MAX_SIZE) + printf("Error: Setup is too large (%d bytes)\n", setup_size); + + /* determine boot protocol version */ + bootproto = get_boot_protocol(hdr); + + printf("Using boot protocol version %x.%02x\n", + (bootproto & 0xff00) >> 8, bootproto & 0xff); + + if (bootproto >= 0x0200) { + if (hdr->setup_sects >= 15) { + printf("Linux kernel version %s\n", + (char *)params + + hdr->kernel_version + 0x200); + } else { + printf("Setup Sectors < 15 - " + "Cannot print kernel version.\n"); + } + } + + /* Determine image type */ + big_image = (bootproto >= 0x0200) && + (hdr->loadflags & BIG_KERNEL_FLAG); + + /* Determine load address */ + if (big_image) + *load_address = (void *)BZIMAGE_LOAD_ADDR; + else + *load_address = (void *)ZIMAGE_LOAD_ADDR; + + printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base); + memset(setup_base, 0, sizeof(*setup_base)); + setup_base->hdr = params->hdr; + + if (bootproto >= 0x0204) + kernel_size = hdr->syssize * 16; + else + kernel_size -= setup_size; + + if (bootproto == 0x0100) { + /* + * A very old kernel MUST have its real-mode code + * loaded at 0x90000 + */ + if ((u32)setup_base != 0x90000) { + /* Copy the real-mode kernel */ + memmove((void *)0x90000, setup_base, setup_size); + + /* Copy the command line */ + memmove((void *)0x99000, + (u8 *)setup_base + COMMAND_LINE_OFFSET, + COMMAND_LINE_SIZE); + + /* Relocated */ + setup_base = (struct boot_params *)0x90000; + } + + /* It is recommended to clear memory up to the 32K mark */ + memset((u8 *)0x90000 + setup_size, 0, + SETUP_MAX_SIZE - setup_size); + } + + if (big_image) { + if (kernel_size > BZIMAGE_MAX_SIZE) { + printf("Error: bzImage kernel too big! " + "(size: %ld, max: %d)\n", + kernel_size, BZIMAGE_MAX_SIZE); + return 0; + } + } else if ((kernel_size) > ZIMAGE_MAX_SIZE) { + printf("Error: zImage kernel too big! (size: %ld, max: %d)\n", + kernel_size, ZIMAGE_MAX_SIZE); + return 0; + } + + printf("Loading %s at address %p (%ld bytes)\n", + big_image ? "bzImage" : "zImage", *load_address, kernel_size); + + memmove(*load_address, image + setup_size, kernel_size); + + return setup_base; +} + +int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, + unsigned long initrd_addr, unsigned long initrd_size) +{ + struct setup_header *hdr = &setup_base->hdr; + int bootproto = get_boot_protocol(hdr); + + setup_base->e820_entries = install_e820_map( + ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map); + + if (bootproto == 0x0100) { + setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC; + setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET; + } + if (bootproto >= 0x0200) { + hdr->type_of_loader = 8; + + if (initrd_addr) { + printf("Initial RAM disk at linear address " + "0x%08lx, size %ld bytes\n", + initrd_addr, initrd_size); + + hdr->ramdisk_image = initrd_addr; + hdr->ramdisk_size = initrd_size; + } + } + + if (bootproto >= 0x0201) { + hdr->heap_end_ptr = HEAP_END_OFFSET; + hdr->loadflags |= HEAP_FLAG; + } + + if (bootproto >= 0x0202) { + hdr->cmd_line_ptr = (uintptr_t)cmd_line; + } else if (bootproto >= 0x0200) { + setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC; + setup_base->screen_info.cl_offset = + (uintptr_t)cmd_line - (uintptr_t)setup_base; + + hdr->setup_move_size = 0x9100; + } + + /* build command line at COMMAND_LINE_OFFSET */ + build_command_line(cmd_line, auto_boot); + return 0; +} + +/* + * Implement a weak default function for boards that optionally + * need to clean up the system before jumping to the kernel. + */ +__weak void board_final_cleanup(void) +{ +} + +void boot_zimage(void *setup_base, void *load_address) +{ + debug("## Transferring control to Linux (at address %08x) ...\n", + (u32)setup_base); + + bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel"); +#ifdef CONFIG_BOOTSTAGE_REPORT + bootstage_report(); +#endif + board_final_cleanup(); + + printf("\nStarting kernel ...\n\n"); + +#ifdef CONFIG_SYS_COREBOOT + timestamp_add_now(TS_U_BOOT_START_KERNEL); +#endif + /* + * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params + * structure, and then jump to the kernel. We assume that %cs is + * 0x10, 4GB flat, and read/execute, and the data segments are 0x18, + * 4GB flat, and read/write. U-boot is setting them up that way for + * itself in arch/i386/cpu/cpu.c. + */ + __asm__ __volatile__ ( + "movl $0, %%ebp\n" + "cli\n" + "jmp *%[kernel_entry]\n" + :: [kernel_entry]"a"(load_address), + [boot_params] "S"(setup_base), + "b"(0), "D"(0) + : "%ebp" + ); +} + +void setup_pcat_compatibility(void) + __attribute__((weak, alias("__setup_pcat_compatibility"))); + +void __setup_pcat_compatibility(void) +{ +} + +int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + struct boot_params *base_ptr; + void *bzImage_addr = NULL; + void *load_address; + char *s; + ulong bzImage_size = 0; + ulong initrd_addr = 0; + ulong initrd_size = 0; + + disable_interrupts(); + + /* Setup board for maximum PC/AT Compatibility */ + setup_pcat_compatibility(); + + if (argc >= 2) { + /* argv[1] holds the address of the bzImage */ + s = argv[1]; + } else { + s = getenv("fileaddr"); + } + + if (s) + bzImage_addr = (void *)simple_strtoul(s, NULL, 16); + + if (argc >= 3) { + /* argv[2] holds the size of the bzImage */ + bzImage_size = simple_strtoul(argv[2], NULL, 16); + } + + if (argc >= 4) + initrd_addr = simple_strtoul(argv[3], NULL, 16); + if (argc >= 5) + initrd_size = simple_strtoul(argv[4], NULL, 16); + + /* Lets look for */ + base_ptr = load_zimage(bzImage_addr, bzImage_size, &load_address); + + if (!base_ptr) { + printf("## Kernel loading failed ...\n"); + return -1; + } + if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET, + 0, initrd_addr, initrd_size)) { + printf("Setting up boot parameters failed ...\n"); + return -1; + } + + /* we assume that the kernel is in place */ + boot_zimage(base_ptr, load_address); + /* does not return */ + + return -1; +} + +U_BOOT_CMD( + zboot, 5, 0, do_zboot, + "Boot bzImage", + "[addr] [size] [initrd addr] [initrd size]\n" + " addr - The optional starting address of the bzimage.\n" + " If not set it defaults to the environment\n" + " variable \"fileaddr\".\n" + " size - The optional size of the bzimage. Defaults to\n" + " zero.\n" + " initrd addr - The address of the initrd image to use, if any.\n" + " initrd size - The size of the initrd image to use, if any.\n" +); |