mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
Merge branch 'master' of git://git.denx.de/u-boot-x86
This commit is contained in:
commit
fd4d564b3c
44 changed files with 2347 additions and 128 deletions
15
README
15
README
|
@ -1414,6 +1414,13 @@ CBFS (Coreboot Filesystem) support
|
|||
boot. See the documentation file README.video for a
|
||||
description of this variable.
|
||||
|
||||
CONFIG_VIDEO_VGA
|
||||
|
||||
Enable the VGA video / BIOS for x86. The alternative if you
|
||||
are using coreboot is to use the coreboot frame buffer
|
||||
driver.
|
||||
|
||||
|
||||
- Keyboard Support:
|
||||
CONFIG_KEYBOARD
|
||||
|
||||
|
@ -2205,6 +2212,14 @@ CBFS (Coreboot Filesystem) support
|
|||
HERMES, IP860, RPXlite, LWMON,
|
||||
FLAGADM, TQM8260
|
||||
|
||||
- Access to physical memory region (> 4GB)
|
||||
Some basic support is provided for operations on memory not
|
||||
normally accessible to U-Boot - e.g. some architectures
|
||||
support access to more than 4GB of memory on 32-bit
|
||||
machines using physical address extension or similar.
|
||||
Define CONFIG_PHYSMEM to access this basic support, which
|
||||
currently only supports clearing the memory.
|
||||
|
||||
- Error Recovery:
|
||||
CONFIG_PANIC_HANG
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@ include $(TOPDIR)/config.mk
|
|||
|
||||
LIB := $(obj)lib$(SOC).o
|
||||
|
||||
SOBJS-$(CONFIG_SYS_COREBOOT) += car.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += coreboot.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += tables.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += ipchecksum.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += sdram.o
|
||||
COBJS-$(CONFIG_SYS_COREBOOT) += timestamp.o
|
||||
COBJS-$(CONFIG_PCI) += pci.o
|
||||
|
||||
SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
|
||||
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||
|
||||
|
|
23
arch/x86/cpu/coreboot/config.mk
Normal file
23
arch/x86/cpu/coreboot/config.mk
Normal file
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# Copyright (c) 2012 The Chromium OS Authors.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# 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; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
CONFIG_ARCH_DEVICE_TREE := coreboot
|
|
@ -26,13 +26,15 @@
|
|||
#include <asm/u-boot-x86.h>
|
||||
#include <flash.h>
|
||||
#include <netdev.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;
|
||||
|
||||
unsigned long monitor_flash_len = CONFIG_SYS_MONITOR_LEN;
|
||||
|
||||
/*
|
||||
* Miscellaneous platform dependent initializations
|
||||
*/
|
||||
|
@ -41,6 +43,9 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -62,8 +67,29 @@ int board_early_init_r(void)
|
|||
|
||||
void show_boot_progress(int val)
|
||||
{
|
||||
}
|
||||
#if MIN_PORT80_KCLOCKS_DELAY
|
||||
static uint32_t prev_stamp;
|
||||
static uint32_t base;
|
||||
|
||||
/*
|
||||
* 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 (!prev_stamp) {
|
||||
base = rdtsc() / 1000;
|
||||
prev_stamp = 0;
|
||||
} else {
|
||||
uint32_t now;
|
||||
|
||||
do {
|
||||
now = rdtsc() / 1000 - base;
|
||||
} while (now < (prev_stamp + MIN_PORT80_KCLOCKS_DELAY));
|
||||
prev_stamp = now;
|
||||
}
|
||||
#endif
|
||||
outb(val, 0x80);
|
||||
}
|
||||
|
||||
int last_stage_init(void)
|
||||
{
|
||||
|
@ -82,6 +108,33 @@ int board_eth_init(bd_t *bis)
|
|||
return pci_eth_init(bis);
|
||||
}
|
||||
|
||||
void setup_pcat_compatibility()
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include <asm/e820.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/arch-coreboot/sysinfo.h>
|
||||
#include <asm/arch-coreboot/tables.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/sysinfo.h>
|
||||
#include <asm/arch/tables.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -51,6 +52,58 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
|
|||
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.
|
||||
*/
|
||||
int calculate_relocation_address(void)
|
||||
{
|
||||
const uint64_t uboot_size = (uintptr_t)&__bss_end -
|
||||
(uintptr_t)&__text_start;
|
||||
const uint64_t total_size = uboot_size + CONFIG_SYS_MALLOC_LEN +
|
||||
CONFIG_SYS_STACK_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 - uboot_size > dest_addr)
|
||||
dest_addr = end;
|
||||
}
|
||||
|
||||
/* If no suitable area was found, return an error. */
|
||||
if (!dest_addr)
|
||||
return 1;
|
||||
|
||||
dest_addr -= uboot_size;
|
||||
dest_addr &= ~((1 << 12) - 1);
|
||||
gd->relocaddr = dest_addr;
|
||||
gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
|
||||
gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init_f(void)
|
||||
{
|
||||
int i;
|
||||
|
@ -71,5 +124,20 @@ int dram_init_f(void)
|
|||
|
||||
int dram_init(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;
|
||||
}
|
||||
|
|
61
arch/x86/cpu/coreboot/timestamp.c
Normal file
61
arch/x86/cpu/coreboot/timestamp.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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;
|
||||
timer_set_tsc_base(ts_table->base_time);
|
||||
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());
|
||||
}
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <asm/control_regs.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/processor-flags.h>
|
||||
#include <asm/interrupt.h>
|
||||
|
@ -147,16 +148,27 @@ int cpu_init_r(void) __attribute__((weak, alias("x86_cpu_init_r")));
|
|||
|
||||
void x86_enable_caches(void)
|
||||
{
|
||||
const u32 nw_cd_rst = ~(X86_CR0_NW | X86_CR0_CD);
|
||||
unsigned long cr0;
|
||||
|
||||
/* turn on the cache and disable write through */
|
||||
asm("movl %%cr0, %%eax\n"
|
||||
"andl %0, %%eax\n"
|
||||
"movl %%eax, %%cr0\n"
|
||||
"wbinvd\n" : : "i" (nw_cd_rst) : "eax");
|
||||
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();
|
||||
|
@ -200,3 +212,17 @@ void __reset_cpu(ulong addr)
|
|||
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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -28,10 +28,14 @@
|
|||
*/
|
||||
|
||||
#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>
|
||||
|
||||
#define DECLARE_INTERRUPT(x) \
|
||||
".globl irq_"#x"\n" \
|
||||
|
@ -41,72 +45,6 @@
|
|||
"pushl $"#x"\n" \
|
||||
"jmp irq_common_entry\n"
|
||||
|
||||
/*
|
||||
* Volatile isn't enough to prevent the compiler from reordering the
|
||||
* read/write functions for the control registers and messing everything up.
|
||||
* A memory clobber would solve the problem, but would prevent reordering of
|
||||
* all loads stores around it, which can hurt performance. Solution is to
|
||||
* use a variable and mimic reads and writes to it to enforce serialisation
|
||||
*/
|
||||
static unsigned long __force_order;
|
||||
|
||||
static inline unsigned long read_cr0(void)
|
||||
{
|
||||
unsigned long val;
|
||||
asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline unsigned long read_cr2(void)
|
||||
{
|
||||
unsigned long val;
|
||||
asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline unsigned long read_cr3(void)
|
||||
{
|
||||
unsigned long val;
|
||||
asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline unsigned long read_cr4(void)
|
||||
{
|
||||
unsigned long val;
|
||||
asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
|
||||
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;
|
||||
}
|
||||
|
||||
void dump_regs(struct irq_regs *regs)
|
||||
{
|
||||
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
|
||||
|
@ -679,3 +617,32 @@ asm(".globl irq_common_entry\n" \
|
|||
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)
|
||||
{
|
||||
static u64 tick_base;
|
||||
u64 now_tick = rdtsc();
|
||||
|
||||
if (!tick_base)
|
||||
tick_base = now_tick;
|
||||
|
||||
return now_tick - tick_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
|
||||
|
|
|
@ -55,8 +55,16 @@ _x86boot_start:
|
|||
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 */
|
||||
/*
|
||||
* 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
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
.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
|
||||
|
|
16
arch/x86/dts/coreboot.dtsi
Normal file
16
arch/x86/dts/coreboot.dtsi
Normal file
|
@ -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";
|
||||
};
|
||||
};
|
13
arch/x86/dts/skeleton.dtsi
Normal file
13
arch/x86/dts/skeleton.dtsi
Normal file
|
@ -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>; };
|
||||
};
|
52
arch/x86/include/asm/arch-coreboot/timestamp.h
Normal file
52
arch/x86/include/asm/arch-coreboot/timestamp.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
#endif
|
|
@ -32,4 +32,20 @@
|
|||
#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__ */
|
||||
|
|
105
arch/x86/include/asm/control_regs.h
Normal file
105
arch/x86/include/asm/control_regs.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#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
|
|
@ -78,6 +78,12 @@ static inline gd_t *get_fs_gd_ptr(void)
|
|||
|
||||
#include <asm-generic/global_data_flags.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
|
27
arch/x86/include/asm/gpio.h
Normal file
27
arch/x86/include/asm/gpio.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Google Inc. All rights reserved.
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _X86_GPIO_H_
|
||||
#define _X86_GPIO_H_
|
||||
|
||||
#include <asm-generic/gpio.h>
|
||||
|
||||
#endif /* _X86_GPIO_H_ */
|
|
@ -37,5 +37,6 @@ int init_bd_struct_r(void);
|
|||
int flash_init_r(void);
|
||||
int status_led_set_r(void);
|
||||
int set_load_addr_r(void);
|
||||
int init_func_spi(void);
|
||||
|
||||
#endif /* !_INIT_HELPERS_H_ */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#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
|
||||
|
@ -220,7 +222,7 @@ static inline void sync(void)
|
|||
static inline void *
|
||||
map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
|
||||
{
|
||||
return (void *)paddr;
|
||||
return (void *)(uintptr_t)paddr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -233,7 +235,7 @@ static inline void unmap_physmem(void *vaddr, unsigned long flags)
|
|||
|
||||
static inline phys_addr_t virt_to_phys(void * vaddr)
|
||||
{
|
||||
return (phys_addr_t)(vaddr);
|
||||
return (phys_addr_t)(uintptr_t)(vaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
469
arch/x86/include/asm/msr-index.h
Normal file
469
arch/x86/include/asm/msr-index.h
Normal file
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* Taken from the linux kernel file of the same name
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Graeme Russ, <graeme.russ@gmail.com>
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#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 */
|
238
arch/x86/include/asm/msr.h
Normal file
238
arch/x86/include/asm/msr.h
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* Taken from the linux kernel file of the same name
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Graeme Russ, <graeme.russ@gmail.com>
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#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 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 */
|
206
arch/x86/include/asm/mtrr.h
Normal file
206
arch/x86/include/asm/mtrr.h
Normal file
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* Generic MTRR (Memory Type Range Register) ioctls.
|
||||
* Taken from the Linux kernel
|
||||
*
|
||||
* (C) Copyright 2012
|
||||
* Graeme Russ, <graeme.russ@gmail.com>
|
||||
*
|
||||
* Copyright (C) 1997-1999 Richard Gooch <rgooch@atnf.csiro.au>
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_MTRR_H
|
||||
#define _ASM_X86_MTRR_H
|
||||
|
||||
#define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
|
||||
#define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define MTRR_IOCTL_BASE 'M'
|
||||
|
||||
struct mtrr_sentry {
|
||||
unsigned long base; /* Base address */
|
||||
unsigned int size; /* Size of region */
|
||||
unsigned int type; /* Type of region */
|
||||
};
|
||||
|
||||
/*
|
||||
* Warning: this structure has a different order from i386
|
||||
* on x86-64. The 32bit emulation code takes care of that.
|
||||
* But you need to use this for 64bit, otherwise your X server
|
||||
* will break.
|
||||
*/
|
||||
|
||||
#ifdef __i386__
|
||||
struct mtrr_gentry {
|
||||
unsigned int regnum; /* Register number */
|
||||
unsigned long base; /* Base address */
|
||||
unsigned int size; /* Size of region */
|
||||
unsigned int type; /* Type of region */
|
||||
};
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
struct mtrr_gentry {
|
||||
unsigned long base; /* Base address */
|
||||
unsigned int size; /* Size of region */
|
||||
unsigned int regnum; /* Register number */
|
||||
unsigned int type; /* Type of region */
|
||||
};
|
||||
#endif /* !__i386__ */
|
||||
|
||||
struct mtrr_var_range {
|
||||
__u32 base_lo;
|
||||
__u32 base_hi;
|
||||
__u32 mask_lo;
|
||||
__u32 mask_hi;
|
||||
};
|
||||
|
||||
/*
|
||||
* In the Intel processor's MTRR interface, the MTRR type is always held in
|
||||
* an 8 bit field:
|
||||
*/
|
||||
typedef __u8 mtrr_type;
|
||||
|
||||
#define MTRR_NUM_FIXED_RANGES 88
|
||||
#define MTRR_MAX_VAR_RANGES 256
|
||||
|
||||
struct mtrr_state_type {
|
||||
struct mtrr_var_range var_ranges[MTRR_MAX_VAR_RANGES];
|
||||
mtrr_type fixed_ranges[MTRR_NUM_FIXED_RANGES];
|
||||
unsigned char enabled;
|
||||
unsigned char have_fixed;
|
||||
mtrr_type def_type;
|
||||
};
|
||||
|
||||
/* These are the various ioctls */
|
||||
#define MTRRIOC_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry)
|
||||
#define MTRRIOC_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry)
|
||||
#define MTRRIOC_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry)
|
||||
#define MTRRIOC_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry)
|
||||
#define MTRRIOC_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry)
|
||||
#define MTRRIOC_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry)
|
||||
#define MTRRIOC_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry)
|
||||
#define MTRRIOC_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry)
|
||||
#define MTRRIOC_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry)
|
||||
#define MTRRIOC_KILL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry)
|
||||
|
||||
/* These are the region types */
|
||||
#define MTRR_TYPE_UNCACHABLE 0
|
||||
#define MTRR_TYPE_WRCOMB 1
|
||||
/*#define MTRR_TYPE_ 2*/
|
||||
/*#define MTRR_TYPE_ 3*/
|
||||
#define MTRR_TYPE_WRTHROUGH 4
|
||||
#define MTRR_TYPE_WRPROT 5
|
||||
#define MTRR_TYPE_WRBACK 6
|
||||
#define MTRR_NUM_TYPES 7
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* The following functions are for use by other drivers */
|
||||
# ifdef CONFIG_MTRR
|
||||
extern u8 mtrr_type_lookup(u64 addr, u64 end);
|
||||
extern void mtrr_save_fixed_ranges(void *);
|
||||
extern void mtrr_save_state(void);
|
||||
extern int mtrr_add(unsigned long base, unsigned long size,
|
||||
unsigned int type, bool increment);
|
||||
extern int mtrr_add_page(unsigned long base, unsigned long size,
|
||||
unsigned int type, bool increment);
|
||||
extern int mtrr_del(int reg, unsigned long base, unsigned long size);
|
||||
extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
|
||||
extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
|
||||
extern void mtrr_ap_init(void);
|
||||
extern void mtrr_bp_init(void);
|
||||
extern void set_mtrr_aps_delayed_init(void);
|
||||
extern void mtrr_aps_init(void);
|
||||
extern void mtrr_bp_restore(void);
|
||||
extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
|
||||
extern int amd_special_default_mtrr(void);
|
||||
# else
|
||||
static inline u8 mtrr_type_lookup(u64 addr, u64 end)
|
||||
{
|
||||
/*
|
||||
* Return no-MTRRs:
|
||||
*/
|
||||
return 0xff;
|
||||
}
|
||||
#define mtrr_save_fixed_ranges(arg) do {} while (0)
|
||||
#define mtrr_save_state() do {} while (0)
|
||||
static inline int mtrr_del(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
|
||||
{
|
||||
}
|
||||
|
||||
#define mtrr_ap_init() do {} while (0)
|
||||
#define mtrr_bp_init() do {} while (0)
|
||||
#define set_mtrr_aps_delayed_init() do {} while (0)
|
||||
#define mtrr_aps_init() do {} while (0)
|
||||
#define mtrr_bp_restore() do {} while (0)
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
|
||||
struct mtrr_sentry32 {
|
||||
compat_ulong_t base; /* Base address */
|
||||
compat_uint_t size; /* Size of region */
|
||||
compat_uint_t type; /* Type of region */
|
||||
};
|
||||
|
||||
struct mtrr_gentry32 {
|
||||
compat_ulong_t regnum; /* Register number */
|
||||
compat_uint_t base; /* Base address */
|
||||
compat_uint_t size; /* Size of region */
|
||||
compat_uint_t type; /* Type of region */
|
||||
};
|
||||
|
||||
#define MTRR_IOCTL_BASE 'M'
|
||||
|
||||
#define MTRRIOC32_ADD_ENTRY _IOW(MTRR_IOCTL_BASE, 0, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_SET_ENTRY _IOW(MTRR_IOCTL_BASE, 1, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_DEL_ENTRY _IOW(MTRR_IOCTL_BASE, 2, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_GET_ENTRY _IOWR(MTRR_IOCTL_BASE, 3, struct mtrr_gentry32)
|
||||
#define MTRRIOC32_KILL_ENTRY _IOW(MTRR_IOCTL_BASE, 4, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_ADD_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 5, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_SET_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 6, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_DEL_PAGE_ENTRY _IOW(MTRR_IOCTL_BASE, 7, struct mtrr_sentry32)
|
||||
#define MTRRIOC32_GET_PAGE_ENTRY _IOWR(MTRR_IOCTL_BASE, 8, struct mtrr_gentry32)
|
||||
#define MTRRIOC32_KILL_PAGE_ENTRY \
|
||||
_IOW(MTRR_IOCTL_BASE, 9, struct mtrr_sentry32)
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_MTRR_H */
|
|
@ -45,8 +45,8 @@ typedef unsigned long long u64;
|
|||
|
||||
typedef u32 dma_addr_t;
|
||||
|
||||
typedef unsigned long phys_addr_t;
|
||||
typedef unsigned long phys_size_t;
|
||||
typedef unsigned long long phys_addr_t;
|
||||
typedef unsigned long long phys_size_t;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
|
@ -63,9 +63,20 @@ u32 isa_map_rom(u32 bus_addr, int size);
|
|||
|
||||
/* arch/x86/lib/... */
|
||||
int video_bios_init(void);
|
||||
int video_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 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_ */
|
||||
|
|
|
@ -32,7 +32,7 @@ COBJS-y += realmode.o
|
|||
SOBJS-y += realmode_switch.o
|
||||
|
||||
COBJS-$(CONFIG_SYS_PC_BIOS) += bios_setup.o
|
||||
COBJS-$(CONFIG_VIDEO) += video_bios.o
|
||||
COBJS-$(CONFIG_VIDEO_VGA) += video_bios.o
|
||||
endif
|
||||
|
||||
COBJS-y += board.o
|
||||
|
@ -47,9 +47,10 @@ COBJS-$(CONFIG_SYS_GENERIC_TIMER) += pcat_timer.o
|
|||
COBJS-$(CONFIG_PCI) += pci.o
|
||||
COBJS-$(CONFIG_PCI) += pci_type1.o
|
||||
COBJS-y += relocate.o
|
||||
COBJS-y += physmem.o
|
||||
COBJS-y += string.o
|
||||
COBJS-$(CONFIG_SYS_X86_ISR_TIMER) += timer.o
|
||||
COBJS-$(CONFIG_VIDEO) += video.o
|
||||
COBJS-$(CONFIG_VIDEO_VGA) += video.o
|
||||
COBJS-$(CONFIG_CMD_ZBOOT) += zimage.o
|
||||
|
||||
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||
|
|
|
@ -99,10 +99,17 @@ typedef int (init_fnc_t) (void);
|
|||
init_fnc_t *init_sequence_f[] = {
|
||||
cpu_init_f,
|
||||
board_early_init_f,
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
find_fdt,
|
||||
fdtdec_check_fdt,
|
||||
#endif
|
||||
env_init,
|
||||
init_baudrate_f,
|
||||
serial_init,
|
||||
console_init_f,
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
prepare_fdt,
|
||||
#endif
|
||||
dram_init_f,
|
||||
calculate_relocation_address,
|
||||
|
||||
|
@ -153,6 +160,9 @@ init_fnc_t *init_sequence_r[] = {
|
|||
serial_initialize_r,
|
||||
#ifndef CONFIG_SYS_NO_FLASH
|
||||
flash_init_r,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI
|
||||
init_func_spi;
|
||||
#endif
|
||||
env_relocate_r,
|
||||
#ifdef CONFIG_PCI
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
#include <net.h>
|
||||
#include <ide.h>
|
||||
#include <serial.h>
|
||||
#include <spi.h>
|
||||
#include <status_led.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/u-boot-x86.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#include <asm/init_helpers.h>
|
||||
|
||||
|
@ -71,7 +73,7 @@ int init_baudrate_f(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int calculate_relocation_address(void)
|
||||
__weak int calculate_relocation_address(void)
|
||||
{
|
||||
ulong text_start = (ulong)&__text_start;
|
||||
ulong bss_end = (ulong)&__bss_end;
|
||||
|
@ -85,15 +87,16 @@ int calculate_relocation_address(void)
|
|||
|
||||
/* Stack is at top of available memory */
|
||||
dest_addr = gd->ram_size;
|
||||
gd->start_addr_sp = dest_addr;
|
||||
|
||||
/* U-Boot is below the stack */
|
||||
dest_addr -= CONFIG_SYS_STACK_SIZE;
|
||||
/* U-Boot is at the top */
|
||||
dest_addr -= (bss_end - text_start);
|
||||
dest_addr &= ~15;
|
||||
gd->relocaddr = dest_addr;
|
||||
gd->reloc_off = (dest_addr - text_start);
|
||||
|
||||
/* Stack is at the bottom, so it can grow down */
|
||||
gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,3 +163,40 @@ int set_load_addr_r(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_func_spi(void)
|
||||
{
|
||||
puts("SPI: ");
|
||||
spi_init();
|
||||
puts("ready\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
int find_fdt(void)
|
||||
{
|
||||
#ifdef CONFIG_OF_EMBED
|
||||
/* Get a pointer to the FDT */
|
||||
gd->fdt_blob = _binary_dt_dtb_start;
|
||||
#elif defined CONFIG_OF_SEPARATE
|
||||
/* FDT is at end of image */
|
||||
gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* MA 02111-1307 USA
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <environment.h>
|
||||
#include <serial.h>
|
||||
#include <kgdb.h>
|
||||
#include <scsi.h>
|
||||
|
@ -36,10 +37,35 @@ int serial_initialize_r(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell if it's OK to load the environment early in boot.
|
||||
*
|
||||
* If CONFIG_OF_CONFIG is defined, we'll check with the FDT to see
|
||||
* if this is OK (defaulting to saying it's not OK).
|
||||
*
|
||||
* NOTE: Loading the environment early can be a bad idea if security is
|
||||
* important, since no verification is done on the environment.
|
||||
*
|
||||
* @return 0 if environment should not be loaded, !=0 if it is ok to load
|
||||
*/
|
||||
static int should_load_env(void)
|
||||
{
|
||||
#ifdef CONFIG_OF_CONTROL
|
||||
return fdtdec_get_config_int(gd->fdt_blob, "load-environment", 0);
|
||||
#elif defined CONFIG_DELAY_ENVIRONMENT
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int env_relocate_r(void)
|
||||
{
|
||||
/* initialize environment */
|
||||
env_relocate();
|
||||
if (should_load_env())
|
||||
env_relocate();
|
||||
else
|
||||
set_default_env(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
228
arch/x86/lib/physmem.c
Normal file
228
arch/x86/lib/physmem.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -80,12 +80,12 @@ int do_elf_reloc_fixups(void)
|
|||
|
||||
/* Check that the target points into .text */
|
||||
if (*offset_ptr_ram >= CONFIG_SYS_TEXT_BASE &&
|
||||
*offset_ptr_ram <
|
||||
*offset_ptr_ram <=
|
||||
(CONFIG_SYS_TEXT_BASE + size)) {
|
||||
*offset_ptr_ram += gd->reloc_off;
|
||||
}
|
||||
}
|
||||
} while (re_src++ < re_end);
|
||||
} while (++re_src < re_end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ struct timer_isr_function {
|
|||
|
||||
static struct timer_isr_function *first_timer_isr;
|
||||
static unsigned long system_ticks;
|
||||
static uint64_t base_value;
|
||||
|
||||
/*
|
||||
* register_timer_isr() allows multiple architecture and board specific
|
||||
|
@ -98,3 +99,19 @@ ulong get_timer(ulong base)
|
|||
{
|
||||
return system_ticks - base;
|
||||
}
|
||||
|
||||
void timer_set_tsc_base(uint64_t new_base)
|
||||
{
|
||||
base_value = new_base;
|
||||
}
|
||||
|
||||
uint64_t timer_get_tsc(void)
|
||||
{
|
||||
uint64_t time_now;
|
||||
|
||||
time_now = rdtsc();
|
||||
if (!base_value)
|
||||
base_value = time_now;
|
||||
|
||||
return time_now - base_value;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
#include <asm/realmode.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:
|
||||
|
@ -279,10 +283,23 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int 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)
|
||||
{
|
||||
board_final_cleanup();
|
||||
|
||||
printf("\nStarting kernel ...\n\n");
|
||||
|
||||
#ifdef CONFIG_SYS_COREBOOT
|
||||
timestamp_add_now(TS_U_BOOT_START_KERNEL);
|
||||
#endif
|
||||
#if defined CONFIG_ZBOOT_32
|
||||
/*
|
||||
* Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params
|
||||
|
@ -292,9 +309,9 @@ void boot_zimage(void *setup_base, void *load_address)
|
|||
* itself in arch/i386/cpu/cpu.c.
|
||||
*/
|
||||
__asm__ __volatile__ (
|
||||
"movl $0, %%ebp \n"
|
||||
"cli \n"
|
||||
"jmp %[kernel_entry] \n"
|
||||
"movl $0, %%ebp\n"
|
||||
"cli\n"
|
||||
"jmp *%[kernel_entry]\n"
|
||||
:: [kernel_entry]"a"(load_address),
|
||||
[boot_params] "S"(setup_base),
|
||||
"b"(0), "D"(0)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/dts-v1/;
|
||||
|
||||
/include/ "coreboot.dtsi"
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
@ -10,19 +12,11 @@
|
|||
silent_console = <0>;
|
||||
};
|
||||
|
||||
aliases {
|
||||
console = "/serial@e0401000";
|
||||
};
|
||||
gpio: gpio {};
|
||||
|
||||
serial@e0401000 {
|
||||
compatible = "ns16550";
|
||||
reg = <0xe0401000 0x40>;
|
||||
id = <1>;
|
||||
reg-shift = <1>;
|
||||
baudrate = <115200>;
|
||||
clock-frequency = <4000000>;
|
||||
multiplier = <1>;
|
||||
status = "ok";
|
||||
serial {
|
||||
reg = <0x3f8 8>;
|
||||
clock-frequency = <115200>;
|
||||
};
|
||||
|
||||
chosen { };
|
24
board/chromebook-x86/dts/link.dts
Normal file
24
board/chromebook-x86/dts/link.dts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/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>; };
|
||||
};
|
|
@ -1100,7 +1100,7 @@ gr_cpci_ax2000 sparc leon3 - gaisler
|
|||
gr_ep2s60 sparc leon3 - gaisler
|
||||
grsim sparc leon3 - gaisler
|
||||
gr_xc3s_1500 sparc leon3 - gaisler
|
||||
coreboot-x86 x86 x86 coreboot chromebook-x86 coreboot coreboot:SYS_TEXT_BASE=0xFC0000
|
||||
coreboot-x86 x86 x86 coreboot chromebook-x86 coreboot coreboot:SYS_TEXT_BASE=0x01110000
|
||||
eNET x86 x86 eNET - sc520 eNET:SYS_TEXT_BASE=0x38040000
|
||||
eNET_SRAM x86 x86 eNET - sc520 eNET:SYS_TEXT_BASE=0x19000000
|
||||
# Target ARCH CPU Board name Vendor SoC Options
|
||||
|
|
|
@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
|
|||
LIB := $(obj)libgpio.o
|
||||
|
||||
COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
|
||||
COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
|
||||
COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
|
||||
COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o
|
||||
COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
|
||||
|
|
290
drivers/gpio/intel_ich6_gpio.c
Normal file
290
drivers/gpio/intel_ich6_gpio.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* Copyright (c) 2012 The Chromium OS Authors.
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a GPIO driver for Intel ICH6 and later. The x86 GPIOs are accessed
|
||||
* through the PCI bus. Each PCI device has 256 bytes of configuration space,
|
||||
* consisting of a standard header and a device-specific set of registers. PCI
|
||||
* bus 0, device 31, function 0 gives us access to the chipset GPIOs (among
|
||||
* other things). Within the PCI configuration space, the GPIOBASE register
|
||||
* tells us where in the device's I/O region we can find more registers to
|
||||
* actually access the GPIOs.
|
||||
*
|
||||
* PCI bus/device/function 0:1f:0 => PCI config registers
|
||||
* PCI config register "GPIOBASE"
|
||||
* PCI I/O space + [GPIOBASE] => start of GPIO registers
|
||||
* GPIO registers => gpio pin function, direction, value
|
||||
*
|
||||
*
|
||||
* Danger Will Robinson! Bank 0 (GPIOs 0-31) seems to be fairly stable. Most
|
||||
* ICH versions have more, but the decoding the matrix that describes them is
|
||||
* absurdly complex and constantly changing. We'll provide Bank 1 and Bank 2,
|
||||
* but they will ONLY work for certain unspecified chipsets because the offset
|
||||
* from GPIOBASE changes randomly. Even then, many GPIOs are unimplemented or
|
||||
* reserved or subject to arcane restrictions.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* Where in config space is the register that points to the GPIO registers? */
|
||||
#define PCI_CFG_GPIOBASE 0x48
|
||||
|
||||
#define NUM_BANKS 3
|
||||
|
||||
/* Within the I/O space, where are the registers to control the GPIOs? */
|
||||
static struct {
|
||||
u8 use_sel;
|
||||
u8 io_sel;
|
||||
u8 lvl;
|
||||
} gpio_bank[NUM_BANKS] = {
|
||||
{ 0x00, 0x04, 0x0c }, /* Bank 0 */
|
||||
{ 0x30, 0x34, 0x38 }, /* Bank 1 */
|
||||
{ 0x40, 0x44, 0x48 } /* Bank 2 */
|
||||
};
|
||||
|
||||
static pci_dev_t dev; /* handle for 0:1f:0 */
|
||||
static u32 gpiobase; /* offset into I/O space */
|
||||
static int found_it_once; /* valid GPIO device? */
|
||||
static u32 lock[NUM_BANKS]; /* "lock" for access to pins */
|
||||
|
||||
static int bad_arg(int num, int *bank, int *bitnum)
|
||||
{
|
||||
int i = num / 32;
|
||||
int j = num % 32;
|
||||
|
||||
if (num < 0 || i > NUM_BANKS) {
|
||||
debug("%s: bogus gpio num: %d\n", __func__, num);
|
||||
return -1;
|
||||
}
|
||||
*bank = i;
|
||||
*bitnum = j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mark_gpio(int bank, int bitnum)
|
||||
{
|
||||
if (lock[bank] & (1UL << bitnum)) {
|
||||
debug("%s: %d.%d already marked\n", __func__, bank, bitnum);
|
||||
return -1;
|
||||
}
|
||||
lock[bank] |= (1 << bitnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clear_gpio(int bank, int bitnum)
|
||||
{
|
||||
lock[bank] &= ~(1 << bitnum);
|
||||
}
|
||||
|
||||
static int notmine(int num, int *bank, int *bitnum)
|
||||
{
|
||||
if (bad_arg(num, bank, bitnum))
|
||||
return -1;
|
||||
return !(lock[*bank] & (1UL << *bitnum));
|
||||
}
|
||||
|
||||
static int gpio_init(void)
|
||||
{
|
||||
u8 tmpbyte;
|
||||
u16 tmpword;
|
||||
u32 tmplong;
|
||||
|
||||
/* Have we already done this? */
|
||||
if (found_it_once)
|
||||
return 0;
|
||||
|
||||
/* Where should it be? */
|
||||
dev = PCI_BDF(0, 0x1f, 0);
|
||||
|
||||
/* Is the device present? */
|
||||
pci_read_config_word(dev, PCI_VENDOR_ID, &tmpword);
|
||||
if (tmpword != PCI_VENDOR_ID_INTEL) {
|
||||
debug("%s: wrong VendorID\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pci_read_config_word(dev, PCI_DEVICE_ID, &tmpword);
|
||||
debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
|
||||
/*
|
||||
* We'd like to validate the Device ID too, but pretty much any
|
||||
* value is either a) correct with slight differences, or b)
|
||||
* correct but undocumented. We'll have to check a bunch of other
|
||||
* things instead...
|
||||
*/
|
||||
|
||||
/* I/O should already be enabled (it's a RO bit). */
|
||||
pci_read_config_word(dev, PCI_COMMAND, &tmpword);
|
||||
if (!(tmpword & PCI_COMMAND_IO)) {
|
||||
debug("%s: device IO not enabled\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Header Type must be normal (bits 6-0 only; see spec.) */
|
||||
pci_read_config_byte(dev, PCI_HEADER_TYPE, &tmpbyte);
|
||||
if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
|
||||
debug("%s: invalid Header type\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Base Class must be a bridge device */
|
||||
pci_read_config_byte(dev, PCI_CLASS_CODE, &tmpbyte);
|
||||
if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
|
||||
debug("%s: invalid class\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* Sub Class must be ISA */
|
||||
pci_read_config_byte(dev, PCI_CLASS_SUB_CODE, &tmpbyte);
|
||||
if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
|
||||
debug("%s: invalid subclass\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Programming Interface must be 0x00 (no others exist) */
|
||||
pci_read_config_byte(dev, PCI_CLASS_PROG, &tmpbyte);
|
||||
if (tmpbyte != 0x00) {
|
||||
debug("%s: invalid interface type\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPIOBASE moved to its current offset with ICH6, but prior to
|
||||
* that it was unused (or undocumented). Check that it looks
|
||||
* okay: not all ones or zeros, and mapped to I/O space (bit 0).
|
||||
*/
|
||||
pci_read_config_dword(dev, PCI_CFG_GPIOBASE, &tmplong);
|
||||
if (tmplong == 0x00000000 || tmplong == 0xffffffff ||
|
||||
!(tmplong & 0x00000001)) {
|
||||
debug("%s: unexpected GPIOBASE value\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Okay, I guess we're looking at the right device. The actual
|
||||
* GPIO registers are in the PCI device's I/O space, starting
|
||||
* at the offset that we just read. Bit 0 indicates that it's
|
||||
* an I/O address, not a memory address, so mask that off.
|
||||
*/
|
||||
gpiobase = tmplong & 0xfffffffe;
|
||||
|
||||
/* Finally. These are the droids we're looking for. */
|
||||
found_it_once = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_request(unsigned num, const char *label /* UNUSED */)
|
||||
{
|
||||
u32 tmplong;
|
||||
int i = 0, j = 0;
|
||||
|
||||
/* Is the hardware ready? */
|
||||
if (gpio_init())
|
||||
return -1;
|
||||
|
||||
if (bad_arg(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Make sure that the GPIO pin we want isn't already in use for some
|
||||
* built-in hardware function. We have to check this for every
|
||||
* requested pin.
|
||||
*/
|
||||
tmplong = inl(gpiobase + gpio_bank[i].use_sel);
|
||||
if (!(tmplong & (1UL << j))) {
|
||||
debug("%s: gpio %d is reserved for internal use\n", __func__,
|
||||
num);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mark_gpio(i, j);
|
||||
}
|
||||
|
||||
int gpio_free(unsigned num)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (notmine(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
clear_gpio(i, j);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_direction_input(unsigned num)
|
||||
{
|
||||
u32 tmplong;
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (notmine(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
tmplong = inl(gpiobase + gpio_bank[i].io_sel);
|
||||
tmplong |= (1UL << j);
|
||||
outl(gpiobase + gpio_bank[i].io_sel, tmplong);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_direction_output(unsigned num, int value)
|
||||
{
|
||||
u32 tmplong;
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (notmine(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
tmplong = inl(gpiobase + gpio_bank[i].io_sel);
|
||||
tmplong &= ~(1UL << j);
|
||||
outl(gpiobase + gpio_bank[i].io_sel, tmplong);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpio_get_value(unsigned num)
|
||||
{
|
||||
u32 tmplong;
|
||||
int i = 0, j = 0;
|
||||
int r;
|
||||
|
||||
if (notmine(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
tmplong = inl(gpiobase + gpio_bank[i].lvl);
|
||||
r = (tmplong & (1UL << j)) ? 1 : 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int gpio_set_value(unsigned num, int value)
|
||||
{
|
||||
u32 tmplong;
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (notmine(num, &i, &j))
|
||||
return -1;
|
||||
|
||||
tmplong = inl(gpiobase + gpio_bank[i].lvl);
|
||||
if (value)
|
||||
tmplong |= (1UL << j);
|
||||
else
|
||||
tmplong &= ~(1UL << j);
|
||||
outl(gpiobase + gpio_bank[i].lvl, tmplong);
|
||||
return 0;
|
||||
}
|
|
@ -2293,6 +2293,8 @@ int video_get_screen_columns(void)
|
|||
|
||||
void video_clear(void)
|
||||
{
|
||||
if (!video_fb_address)
|
||||
return;
|
||||
#ifdef VIDEO_HW_RECTFILL
|
||||
video_hw_rectfill(VIDEO_PIXEL_SIZE, /* bytes per pixel */
|
||||
0, /* dest pos x */
|
||||
|
|
|
@ -35,10 +35,13 @@
|
|||
* (easy to change)
|
||||
*/
|
||||
#define CONFIG_SYS_COREBOOT
|
||||
#undef CONFIG_SHOW_BOOT_PROGRESS
|
||||
#define CONFIG_SHOW_BOOT_PROGRESS
|
||||
#define CONFIG_LAST_STAGE_INIT
|
||||
#define CONFIG_X86_NO_RESET_VECTOR
|
||||
#define CONFIG_SYS_VSNPRINTF
|
||||
#define CONFIG_INTEL_CORE_ARCH /* Sandy bridge and ivy bridge chipsets. */
|
||||
#define CONFIG_ZBOOT_32
|
||||
#define CONFIG_PHYSMEM
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Watchdog Configuration
|
||||
|
@ -77,6 +80,7 @@
|
|||
*/
|
||||
#define CONFIG_RTC_MC146818
|
||||
#define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0
|
||||
#define CONFIG_SYS_ISA_IO CONFIG_SYS_ISA_IO_BASE_ADDRESS
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Serial Configuration
|
||||
|
@ -102,18 +106,9 @@
|
|||
#define CONFIG_SYS_STDIO_DEREGISTER
|
||||
#define CONFIG_CBMEM_CONSOLE
|
||||
|
||||
/* max. 1 IDE bus */
|
||||
#define CONFIG_SYS_IDE_MAXBUS 1
|
||||
/* max. 1 drive per IDE bus */
|
||||
#define CONFIG_SYS_IDE_MAXDEVICE (CONFIG_SYS_IDE_MAXBUS * 1)
|
||||
|
||||
#define CONFIG_SYS_ATA_BASE_ADDR CONFIG_SYS_ISA_IO_BASE_ADDRESS
|
||||
#define CONFIG_SYS_ATA_IDE0_OFFSET 0x01f0
|
||||
#define CONFIG_SYS_ATA_IDE1_OFFSET 0x0170
|
||||
#define CONFIG_SYS_ATA_DATA_OFFSET 0
|
||||
#define CONFIG_SYS_ATA_REG_OFFSET 0
|
||||
#define CONFIG_SYS_ATA_ALT_OFFSET 0x200
|
||||
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
#define CONFIG_COMMAND_HISTORY
|
||||
#define CONFIG_AUTOCOMPLETE
|
||||
|
||||
#define CONFIG_SUPPORT_VFAT
|
||||
/************************************************************
|
||||
|
@ -124,19 +119,30 @@
|
|||
/************************************************************
|
||||
* DISK Partition support
|
||||
************************************************************/
|
||||
#define CONFIG_EFI_PARTITION
|
||||
#define CONFIG_DOS_PARTITION
|
||||
#define CONFIG_MAC_PARTITION
|
||||
#define CONFIG_ISO_PARTITION /* Experimental */
|
||||
|
||||
#define CONFIG_CMD_PART
|
||||
#define CONFIG_CMD_CBFS
|
||||
#define CONFIG_CMD_EXT4
|
||||
#define CONFIG_CMD_EXT4_WRITE
|
||||
#define CONFIG_PARTITION_UUIDS
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Video Configuration
|
||||
*/
|
||||
#undef CONFIG_VIDEO
|
||||
#undef CONFIG_CFB_CONSOLE
|
||||
#define CONFIG_VIDEO
|
||||
#define CONFIG_VIDEO_COREBOOT
|
||||
#define CONFIG_VIDEO_SW_CURSOR
|
||||
#define VIDEO_FB_16BPP_WORD_SWAP
|
||||
#define CONFIG_I8042_KBD
|
||||
#define CONFIG_CFB_CONSOLE
|
||||
#define CONFIG_SYS_CONSOLE_INFO_QUIET
|
||||
|
||||
/* x86 GPIOs are accessed through a PCI device */
|
||||
#define CONFIG_INTEL_ICH6_GPIO
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Command line configuration.
|
||||
|
@ -150,6 +156,7 @@
|
|||
#define CONFIG_CMD_ECHO
|
||||
#undef CONFIG_CMD_FLASH
|
||||
#define CONFIG_CMD_FPGA
|
||||
#define CONFIG_CMD_GPIO
|
||||
#define CONFIG_CMD_IMI
|
||||
#undef CONFIG_CMD_IMLS
|
||||
#define CONFIG_CMD_IRQ
|
||||
|
@ -167,12 +174,19 @@
|
|||
#define CONFIG_CMD_SETGETDCR
|
||||
#define CONFIG_CMD_SOURCE
|
||||
#define CONFIG_CMD_XIMG
|
||||
#define CONFIG_CMD_IDE
|
||||
#define CONFIG_CMD_SCSI
|
||||
|
||||
#define CONFIG_CMD_FAT
|
||||
#define CONFIG_CMD_EXT2
|
||||
|
||||
#define CONFIG_CMD_ZBOOT
|
||||
|
||||
#define CONFIG_BOOTDELAY 2
|
||||
#define CONFIG_BOOTARGS "root=/dev/mtdblock0 console=ttyS0,9600"
|
||||
#define CONFIG_BOOTARGS \
|
||||
"root=/dev/sdb3 init=/sbin/init rootwait ro"
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000"
|
||||
|
||||
|
||||
#if defined(CONFIG_CMD_KGDB)
|
||||
#define CONFIG_KGDB_BAUDRATE 115200
|
||||
|
|
123
include/pci.h
123
include/pci.h
|
@ -67,7 +67,130 @@
|
|||
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
|
||||
#define PCI_CLASS_DEVICE 0x0a /* Device class */
|
||||
#define PCI_CLASS_CODE 0x0b /* Device class code */
|
||||
#define PCI_CLASS_CODE_TOO_OLD 0x00
|
||||
#define PCI_CLASS_CODE_STORAGE 0x01
|
||||
#define PCI_CLASS_CODE_NETWORK 0x02
|
||||
#define PCI_CLASS_CODE_DISPLAY 0x03
|
||||
#define PCI_CLASS_CODE_MULTIMEDIA 0x04
|
||||
#define PCI_CLASS_CODE_MEMORY 0x05
|
||||
#define PCI_CLASS_CODE_BRIDGE 0x06
|
||||
#define PCI_CLASS_CODE_COMM 0x07
|
||||
#define PCI_CLASS_CODE_PERIPHERAL 0x08
|
||||
#define PCI_CLASS_CODE_INPUT 0x09
|
||||
#define PCI_CLASS_CODE_DOCKING 0x0A
|
||||
#define PCI_CLASS_CODE_PROCESSOR 0x0B
|
||||
#define PCI_CLASS_CODE_SERIAL 0x0C
|
||||
#define PCI_CLASS_CODE_WIRELESS 0x0D
|
||||
#define PCI_CLASS_CODE_I2O 0x0E
|
||||
#define PCI_CLASS_CODE_SATELLITE 0x0F
|
||||
#define PCI_CLASS_CODE_CRYPTO 0x10
|
||||
#define PCI_CLASS_CODE_DATA 0x11
|
||||
/* Base Class 0x12 - 0xFE is reserved */
|
||||
#define PCI_CLASS_CODE_OTHER 0xFF
|
||||
|
||||
#define PCI_CLASS_SUB_CODE 0x0a /* Device sub-class code */
|
||||
#define PCI_CLASS_SUB_CODE_TOO_OLD_NOTVGA 0x00
|
||||
#define PCI_CLASS_SUB_CODE_TOO_OLD_VGA 0x01
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_SCSI 0x00
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_IDE 0x01
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_FLOPPY 0x02
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_IPIBUS 0x03
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_RAID 0x04
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_ATA 0x05
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_SATA 0x06
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_SAS 0x07
|
||||
#define PCI_CLASS_SUB_CODE_STORAGE_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_ETHERNET 0x00
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_TOKENRING 0x01
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_FDDI 0x02
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_ATM 0x03
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_ISDN 0x04
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_WORLDFIP 0x05
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_PICMG 0x06
|
||||
#define PCI_CLASS_SUB_CODE_NETWORK_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_DISPLAY_VGA 0x00
|
||||
#define PCI_CLASS_SUB_CODE_DISPLAY_XGA 0x01
|
||||
#define PCI_CLASS_SUB_CODE_DISPLAY_3D 0x02
|
||||
#define PCI_CLASS_SUB_CODE_DISPLAY_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_MULTIMEDIA_VIDEO 0x00
|
||||
#define PCI_CLASS_SUB_CODE_MULTIMEDIA_AUDIO 0x01
|
||||
#define PCI_CLASS_SUB_CODE_MULTIMEDIA_PHONE 0x02
|
||||
#define PCI_CLASS_SUB_CODE_MULTIMEDIA_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_MEMORY_RAM 0x00
|
||||
#define PCI_CLASS_SUB_CODE_MEMORY_FLASH 0x01
|
||||
#define PCI_CLASS_SUB_CODE_MEMORY_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_HOST 0x00
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_ISA 0x01
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_EISA 0x02
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_MCA 0x03
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_PCI 0x04
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_PCMCIA 0x05
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_NUBUS 0x06
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_CARDBUS 0x07
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_RACEWAY 0x08
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_SEMI_PCI 0x09
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_INFINIBAND 0x0A
|
||||
#define PCI_CLASS_SUB_CODE_BRIDGE_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_COMM_SERIAL 0x00
|
||||
#define PCI_CLASS_SUB_CODE_COMM_PARALLEL 0x01
|
||||
#define PCI_CLASS_SUB_CODE_COMM_MULTIPORT 0x02
|
||||
#define PCI_CLASS_SUB_CODE_COMM_MODEM 0x03
|
||||
#define PCI_CLASS_SUB_CODE_COMM_GPIB 0x04
|
||||
#define PCI_CLASS_SUB_CODE_COMM_SMARTCARD 0x05
|
||||
#define PCI_CLASS_SUB_CODE_COMM_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_PIC 0x00
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_DMA 0x01
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_TIMER 0x02
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_RTC 0x03
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_HOTPLUG 0x04
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_SD 0x05
|
||||
#define PCI_CLASS_SUB_CODE_PERIPHERAL_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_KEYBOARD 0x00
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_DIGITIZER 0x01
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_MOUSE 0x02
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_SCANNER 0x03
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_GAMEPORT 0x04
|
||||
#define PCI_CLASS_SUB_CODE_INPUT_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_DOCKING_GENERIC 0x00
|
||||
#define PCI_CLASS_SUB_CODE_DOCKING_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_386 0x00
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_486 0x01
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_PENTIUM 0x02
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_ALPHA 0x10
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_POWERPC 0x20
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_MIPS 0x30
|
||||
#define PCI_CLASS_SUB_CODE_PROCESSOR_COPROC 0x40
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_1394 0x00
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_ACCESSBUS 0x01
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_SSA 0x02
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_USB 0x03
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_FIBRECHAN 0x04
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_SMBUS 0x05
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_INFINIBAND 0x06
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_IPMI 0x07
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_SERCOS 0x08
|
||||
#define PCI_CLASS_SUB_CODE_SERIAL_CANBUS 0x09
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_IRDA 0x00
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_IR 0x01
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_RF 0x10
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_BLUETOOTH 0x11
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_BROADBAND 0x12
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_80211A 0x20
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_80211B 0x21
|
||||
#define PCI_CLASS_SUB_CODE_WIRELESS_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_I2O_V1_0 0x00
|
||||
#define PCI_CLASS_SUB_CODE_SATELLITE_TV 0x01
|
||||
#define PCI_CLASS_SUB_CODE_SATELLITE_AUDIO 0x02
|
||||
#define PCI_CLASS_SUB_CODE_SATELLITE_VOICE 0x03
|
||||
#define PCI_CLASS_SUB_CODE_SATELLITE_DATA 0x04
|
||||
#define PCI_CLASS_SUB_CODE_CRYPTO_NETWORK 0x00
|
||||
#define PCI_CLASS_SUB_CODE_CRYPTO_ENTERTAINMENT 0x10
|
||||
#define PCI_CLASS_SUB_CODE_CRYPTO_OTHER 0x80
|
||||
#define PCI_CLASS_SUB_CODE_DATA_DPIO 0x00
|
||||
#define PCI_CLASS_SUB_CODE_DATA_PERFCNTR 0x01
|
||||
#define PCI_CLASS_SUB_CODE_DATA_COMMSYNC 0x10
|
||||
#define PCI_CLASS_SUB_CODE_DATA_MGMT 0x20
|
||||
#define PCI_CLASS_SUB_CODE_DATA_OTHER 0x80
|
||||
|
||||
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
|
||||
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
|
||||
|
|
21
include/physmem.h
Normal file
21
include/physmem.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These functions work like memset but operate on physical memory which may
|
||||
* not be accessible directly.
|
||||
*
|
||||
* @param s The physical address to start setting memory at.
|
||||
* @param c The character to set each byte of the region to.
|
||||
* @param n The number of bytes to set.
|
||||
*
|
||||
* @return The physical address of the memory which was set.
|
||||
*/
|
||||
phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n);
|
|
@ -48,6 +48,7 @@ COBJS-$(CONFIG_LMB) += lmb.o
|
|||
COBJS-y += ldiv.o
|
||||
COBJS-$(CONFIG_MD5) += md5.o
|
||||
COBJS-y += net_utils.o
|
||||
COBJS-$(CONFIG_PHYSMEM) += physmem.o
|
||||
COBJS-y += qsort.o
|
||||
COBJS-$(CONFIG_SHA1) += sha1.o
|
||||
COBJS-$(CONFIG_SHA256) += sha256.o
|
||||
|
|
24
lib/physmem.c
Normal file
24
lib/physmem.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
static phys_addr_t __arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
|
||||
{
|
||||
void *s_ptr = (void *)(uintptr_t)s;
|
||||
|
||||
assert(((phys_addr_t)(uintptr_t)s) == s);
|
||||
assert(((phys_addr_t)(uintptr_t)(s + n)) == s + n);
|
||||
return (phys_addr_t)(uintptr_t)memset(s_ptr, c, n);
|
||||
}
|
||||
|
||||
phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n)
|
||||
__attribute__((weak, alias("__arch_phys_memset")));
|
Loading…
Add table
Reference in a new issue