Merge git://git.denx.de/u-boot-x86

master
Tom Rini 9 years ago
commit 79c884d7e4
  1. 1
      Makefile
  2. 22
      arch/x86/Kconfig
  3. 8
      arch/x86/cpu/baytrail/valleyview.c
  4. 33
      arch/x86/cpu/coreboot/sdram.c
  5. 1
      arch/x86/cpu/qemu/Makefile
  6. 176
      arch/x86/cpu/qemu/acpi.c
  7. 80
      arch/x86/cpu/qemu/acpi/cpu-hotplug.asl
  8. 25
      arch/x86/cpu/qemu/acpi/dbug.asl
  9. 31
      arch/x86/cpu/qemu/acpi/hpet.asl
  10. 102
      arch/x86/cpu/qemu/acpi/isa.asl
  11. 61
      arch/x86/cpu/qemu/acpi/pci-crs.asl
  12. 412
      arch/x86/cpu/qemu/dsdt.asl
  13. 4
      arch/x86/cpu/queensbay/tnc.c
  14. 14
      arch/x86/cpu/start.S
  15. 6
      arch/x86/dts/bayleybay.dts
  16. 17
      arch/x86/dts/crownbay.dts
  17. 3284
      arch/x86/dts/microcode/m0130679901.dtsi
  18. 32
      arch/x86/dts/minnowmax.dts
  19. 393
      arch/x86/include/asm/acpi_table.h
  20. 9
      arch/x86/include/asm/arch-coreboot/sysinfo.h
  21. 3
      arch/x86/include/asm/ibmpc.h
  22. 2
      arch/x86/include/asm/init_helpers.h
  23. 1
      arch/x86/lib/Makefile
  24. 436
      arch/x86/lib/acpi_table.c
  25. 2
      arch/x86/lib/fsp/fsp_car.S
  26. 16
      arch/x86/lib/fsp/fsp_common.c
  27. 51
      arch/x86/lib/init_helpers.c
  28. 5
      arch/x86/lib/tables.c
  29. 7
      board/intel/crownbay/crownbay.c
  30. 6
      common/board_f.c
  31. 33
      doc/README.efi
  32. 10
      doc/README.x86
  33. 71
      doc/driver-model/pci-info.txt
  34. 19
      drivers/core/device.c
  35. 10
      drivers/gpio/intel_ich6_gpio.c
  36. 652
      drivers/input/i8042.c
  37. 13
      drivers/misc/smsc_lpc47m.c
  38. 9
      drivers/net/e1000.c
  39. 73
      drivers/pci/pci-uclass.c
  40. 4
      drivers/pci/pci_rom.c
  41. 11
      drivers/video/cfb_console.c
  42. 24
      drivers/video/coreboot_fb.c
  43. 21
      drivers/video/ct69000.c
  44. 1
      include/configs/bayleybay.h
  45. 4
      include/configs/crownbay.h
  46. 1
      include/configs/minnowmax.h
  47. 1
      include/configs/qemu-x86.h
  48. 3
      include/configs/x86-common.h
  49. 103
      include/i8042.h
  50. 1
      include/pci.h
  51. 29
      include/smsc_lpc47m.h
  52. 2
      include/vbe.h
  53. 3
      lib/fdtdec.c
  54. 11
      scripts/Makefile.lib
  55. 238
      tools/ifdtool.c
  56. 2
      tools/patman/gitutil.py

@ -1040,6 +1040,7 @@ IFDTOOL_FLAGS = -f 0:$(objtree)/u-boot.dtb
IFDTOOL_FLAGS += -m 0x$(shell $(NM) u-boot |grep _dt_ucode_base_size |cut -d' ' -f1)
IFDTOOL_FLAGS += -U $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot.bin
IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin
IFDTOOL_FLAGS += -C
ifneq ($(CONFIG_HAVE_INTEL_ME),)
IFDTOOL_ME_FLAGS = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin

@ -229,9 +229,16 @@ config FSP_TEMP_RAM_ADDR
depends on HAVE_FSP
default 0x2000000
help
Stack top address which is used in FspInit after DRAM is ready and
Stack top address which is used in fsp_init() after DRAM is ready and
CAR is disabled.
config FSP_SYS_MALLOC_F_LEN
hex
depends on HAVE_FSP
default 0x100000
help
Additional size of malloc() pool before relocation.
config SMP
bool "Enable Symmetric Multiprocessing"
default n
@ -307,10 +314,10 @@ config VGA_BIOS_ADDR
0x90000 from the beginning of a 1MB flash device.
menu "System tables"
depends on !EFI && !SYS_COREBOOT
config GENERATE_PIRQ_TABLE
bool "Generate a PIRQ table"
depends on !EFI
default n
help
Generate a PIRQ routing table for this board. The PIRQ routing table
@ -321,7 +328,6 @@ config GENERATE_PIRQ_TABLE
config GENERATE_SFI_TABLE
bool "Generate a SFI (Simple Firmware Interface) table"
depends on !EFI
help
The Simple Firmware Interface (SFI) provides a lightweight method
for platform firmware to pass information to the operating system
@ -336,7 +342,6 @@ config GENERATE_SFI_TABLE
config GENERATE_MP_TABLE
bool "Generate an MP (Multi-Processor) table"
depends on !EFI
default n
help
Generate an MP (Multi-Processor) table for this board. The MP table
@ -344,6 +349,15 @@ config GENERATE_MP_TABLE
multiprocessing as well as symmetric I/O interrupt handling with
the local APIC and I/O APIC.
config GENERATE_ACPI_TABLE
bool "Generate an ACPI (Advanced Configuration and Power Interface) table"
default n
help
The Advanced Configuration and Power Interface (ACPI) specification
provides an open standard for device configuration and management
by the operating system. It defines platform-independent interfaces
for configuration and power management monitoring.
endmenu
config MAX_PIRQ_LINKS

@ -9,7 +9,6 @@
#include <pci_ids.h>
#include <asm/irq.h>
#include <asm/post.h>
#include <asm/fsp/fsp_support.h>
static struct pci_device_id mmc_supported[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO },
@ -41,14 +40,9 @@ int arch_cpu_init(void)
int arch_misc_init(void)
{
int ret;
if (!ll_boot_init())
return 0;
ret = pirq_init();
if (ret)
return ret;
return fsp_init_phase_pci();
return pirq_init();
}
#endif

@ -7,14 +7,7 @@
*/
#include <common.h>
#include <malloc.h>
#include <asm/e820.h>
#include <asm/u-boot-x86.h>
#include <asm/global_data.h>
#include <asm/init_helpers.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/zimage.h>
#include <asm/arch/sysinfo.h>
#include <asm/arch/tables.h>
@ -22,9 +15,10 @@ DECLARE_GLOBAL_DATA_PTR;
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
{
unsigned num_entries;
int i;
unsigned num_entries = min((unsigned)lib_sysinfo.n_memranges, max_entries);
num_entries = min((unsigned)lib_sysinfo.n_memranges, max_entries);
if (num_entries < lib_sysinfo.n_memranges) {
printf("Warning: Limiting e820 map to %d entries.\n",
num_entries);
@ -34,8 +28,18 @@ unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
entries[i].addr = memrange->base;
entries[i].size = memrange->size;
entries[i].type = memrange->type;
/*
* coreboot has some extensions (type 6 & 16) to the E820 types.
* When we detect this, mark it as E820_RESERVED.
*/
if (memrange->type == CB_MEM_VENDOR_RSVD ||
memrange->type == CB_MEM_TABLE)
entries[i].type = E820_RESERVED;
else
entries[i].type = memrange->type;
}
return num_entries;
}
@ -90,15 +94,15 @@ int dram_init(void)
struct memrange *memrange = &lib_sysinfo.memrange[i];
unsigned long long end = memrange->base + memrange->size;
if (memrange->type == CB_MEM_RAM && end > ram_size &&
memrange->base < (1ULL << 32))
ram_size = end;
if (memrange->type == CB_MEM_RAM && end > ram_size)
ram_size += memrange->size;
}
gd->ram_size = ram_size;
if (ram_size == 0)
return -1;
return calculate_relocation_address();
return 0;
}
void dram_init_banksize(void)
@ -109,8 +113,7 @@ void dram_init_banksize(void)
for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) {
struct memrange *memrange = &lib_sysinfo.memrange[i];
if (memrange->type == CB_MEM_RAM &&
memrange->base < (1ULL << 32)) {
if (memrange->type == CB_MEM_RAM) {
gd->bd->bi_dram[j].start = memrange->base;
gd->bd->bi_dram[j].size = memrange->size;
j++;

@ -8,4 +8,5 @@ ifndef CONFIG_EFI_STUB
obj-y += car.o dram.o
endif
obj-y += qemu.o
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
obj-$(CONFIG_PCI) += pci.o

@ -0,0 +1,176 @@
/*
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/acpi_table.h>
#include <asm/ioapic.h>
#include <asm/tables.h>
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
void *dsdt)
{
acpi_header_t *header = &(fadt->header);
u16 pmbase;
pci_dev_t bdf = PCI_BDF(0, 0x1f, 0);
pci_read_config_word(bdf, 0x40, &pmbase);
/*
* TODO(saket.sinha89@gmail.com): wrong value
* of pmbase by above function. Hard-coding it to
* correct value. Since no PCI register is
* programmed Power Management Interface is
* not working
*/
pmbase = 0x0600;
memset((void *)fadt, 0, sizeof(struct acpi_fadt));
memcpy(header->signature, "FACP", 4);
header->length = sizeof(struct acpi_fadt);
header->revision = 3;
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->asl_compiler_revision = 0;
fadt->firmware_ctrl = (unsigned long) facs;
fadt->dsdt = (unsigned long) dsdt;
fadt->model = 0x00;
fadt->preferred_pm_profile = PM_MOBILE;
fadt->sci_int = 0x9;
fadt->smi_cmd = 0;
fadt->acpi_enable = 0;
fadt->acpi_disable = 0;
fadt->s4bios_req = 0x0;
fadt->pstate_cnt = 0;
fadt->pm1a_evt_blk = pmbase;
fadt->pm1b_evt_blk = 0x0;
fadt->pm1a_cnt_blk = pmbase + 0x4;
fadt->pm1b_cnt_blk = 0x0;
fadt->pm2_cnt_blk = pmbase + 0x50;
fadt->pm_tmr_blk = pmbase + 0x8;
fadt->gpe0_blk = pmbase + 0x20;
fadt->gpe1_blk = 0;
fadt->pm1_evt_len = 4;
/*
* Upper word is reserved and
* Linux complains about 32 bit
*/
fadt->pm1_cnt_len = 2;
fadt->pm2_cnt_len = 1;
fadt->pm_tmr_len = 4;
fadt->gpe0_blk_len = 16;
fadt->gpe1_blk_len = 0;
fadt->gpe1_base = 0;
fadt->cst_cnt = 0;
fadt->p_lvl2_lat = 1;
fadt->p_lvl3_lat = 0x39;
fadt->flush_size = 0;
fadt->flush_stride = 0;
fadt->duty_offset = 1;
fadt->duty_width = 3;
fadt->day_alrm = 0xd;
fadt->mon_alrm = 0x00;
fadt->century = 0x32;
fadt->iapc_boot_arch = 0x00;
fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER |
ACPI_FADT_PLATFORM_CLOCK;
fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->reset_reg.bit_width = 8;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.resv = 0;
fadt->reset_reg.addrl = 0xcf9;
fadt->reset_reg.addrh = 0;
fadt->reset_value = 0x06;
/*
* Set X_FIRMWARE_CTRL only if FACS is
* above 4GB. If X_FIRMWARE_CTRL is set,
* then FIRMWARE_CTRL must be zero
*/
fadt->x_firmware_ctl_l = 0;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (unsigned long)dsdt;
fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = 1;
fadt->x_pm1a_evt_blk.bit_width = 32;
fadt->x_pm1a_evt_blk.bit_offset = 0;
fadt->x_pm1a_evt_blk.resv = 0;
fadt->x_pm1a_evt_blk.addrl = pmbase;
fadt->x_pm1a_evt_blk.addrh = 0x0;
fadt->x_pm1b_evt_blk.space_id = 0;
fadt->x_pm1b_evt_blk.bit_width = 0;
fadt->x_pm1b_evt_blk.bit_offset = 0;
fadt->x_pm1b_evt_blk.resv = 0;
fadt->x_pm1b_evt_blk.addrl = 0x0;
fadt->x_pm1b_evt_blk.addrh = 0x0;
fadt->x_pm1a_cnt_blk.space_id = 1;
/*
* Upper word is reserved and
* Linux complains about 32 bit
*/
fadt->x_pm1a_cnt_blk.bit_width = 16;
fadt->x_pm1a_cnt_blk.bit_offset = 0;
fadt->x_pm1a_cnt_blk.resv = 0;
fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
fadt->x_pm1a_cnt_blk.addrh = 0x0;
fadt->x_pm1b_cnt_blk.space_id = 0;
fadt->x_pm1b_cnt_blk.bit_width = 0;
fadt->x_pm1b_cnt_blk.bit_offset = 0;
fadt->x_pm1b_cnt_blk.resv = 0;
fadt->x_pm1b_cnt_blk.addrl = 0x0;
fadt->x_pm1b_cnt_blk.addrh = 0x0;
fadt->x_pm2_cnt_blk.space_id = 1;
fadt->x_pm2_cnt_blk.bit_width = 8;
fadt->x_pm2_cnt_blk.bit_offset = 0;
fadt->x_pm2_cnt_blk.resv = 0;
fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
fadt->x_pm2_cnt_blk.addrh = 0x0;
fadt->x_pm_tmr_blk.space_id = 1;
fadt->x_pm_tmr_blk.bit_width = 32;
fadt->x_pm_tmr_blk.bit_offset = 0;
fadt->x_pm_tmr_blk.resv = 0;
fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
fadt->x_pm_tmr_blk.addrh = 0x0;
fadt->x_gpe0_blk.space_id = 1;
fadt->x_gpe0_blk.bit_width = 128;
fadt->x_gpe0_blk.bit_offset = 0;
fadt->x_gpe0_blk.resv = 0;
fadt->x_gpe0_blk.addrl = pmbase + 0x20;
fadt->x_gpe0_blk.addrh = 0x0;
fadt->x_gpe1_blk.space_id = 0;
fadt->x_gpe1_blk.bit_width = 0;
fadt->x_gpe1_blk.bit_offset = 0;
fadt->x_gpe1_blk.resv = 0;
fadt->x_gpe1_blk.addrl = 0x0;
fadt->x_gpe1_blk.addrh = 0x0;
header->checksum = table_compute_checksum((void *)fadt, header->length);
}
unsigned long acpi_fill_madt(unsigned long current)
{
/* create all subtables for processors */
current = acpi_create_madt_lapics(current);
/*
* TODO(saket.sinha89@gmail.com): get these
* IRQ values from device tree
*/
current += acpi_create_madt_ioapic((struct acpi_madt_ioapic *)current,
2, IO_APIC_ADDR, 0);
current += acpi_create_madt_irqoverride(
(struct acpi_madt_irqoverride *)current, 0, 0, 2, 0);
current += acpi_create_madt_irqoverride(
(struct acpi_madt_irqoverride *)current, 0, 9, 9, 0xd);
current += acpi_create_madt_irqoverride(
(struct acpi_madt_irqoverride *)current, 0, 0xd, 0xd, 0xd);
acpi_create_madt_lapic_nmi(
(struct acpi_madt_lapic_nmi *)current, 0, 0, 0);
return current;
}

@ -0,0 +1,80 @@
/* CPU hotplug */
Scope(\_SB) {
/* Objects filled in by run-time generated SSDT */
External(NTFY, MethodObj)
External(CPON, PkgObj)
/* Methods called by run-time generated SSDT Processor objects */
Method(CPMA, 1, NotSerialized) {
/*
* _MAT method - create an madt apic buffer
* Arg0 = Processor ID = Local APIC ID
* Local0 = CPON flag for this cpu
*/
Store(DerefOf(Index(CPON, Arg0)), Local0)
/* Local1 = Buffer (in madt apic form) to return */
Store(Buffer(8) {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}, Local1)
/* Update the processor id, lapic id, and enable/disable status */
Store(Arg0, Index(Local1, 2))
Store(Arg0, Index(Local1, 3))
Store(Local0, Index(Local1, 4))
Return (Local1)
}
Method(CPST, 1, NotSerialized) {
/*
* _STA method - return ON status of cpu
* Arg0 = Processor ID = Local APIC ID
* Local0 = CPON flag for this cpu
*/
Store(DerefOf(Index(CPON, Arg0)), Local0)
If (Local0) {
Return (0xf)
} Else {
Return (0x0)
}
}
Method(CPEJ, 2, NotSerialized) {
/* _EJ0 method - eject callback */
Sleep(200)
}
/* CPU hotplug notify method */
OperationRegion(PRST, SystemIO, 0xaf00, 32)
Field(PRST, ByteAcc, NoLock, Preserve) {
PRS, 256
}
Method(PRSC, 0) {
/* Local5 = active cpu bitmap */
Store(PRS, Local5)
/* Local2 = last read byte from bitmap */
Store(Zero, Local2)
/* Local0 = Processor ID / APIC ID iterator */
Store(Zero, Local0)
While (LLess(Local0, SizeOf(CPON))) {
/* Local1 = CPON flag for this cpu */
Store(DerefOf(Index(CPON, Local0)), Local1)
If (And(Local0, 0x07)) {
/* Shift down previously read bitmap byte */
ShiftRight(Local2, 1, Local2)
} Else {
/* Read next byte from cpu bitmap */
Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2)
}
/* Local3 = active state for this cpu */
Store(And(Local2, 1), Local3)
If (LNotEqual(Local1, Local3)) {
/* State change - update CPON with new state */
Store(Local3, Index(CPON, Local0))
/* Do CPU notify */
If (LEqual(Local3, 1)) {
NTFY(Local0, 1)
} Else {
NTFY(Local0, 3)
}
}
Increment(Local0)
}
}
}

@ -0,0 +1,25 @@
/* Debugging */
Scope(\) {
/* Debug Output */
OperationRegion(DBG, SystemIO, 0x0402, 0x01)
Field(DBG, ByteAcc, NoLock, Preserve) {
DBGB, 8,
}
/*
* Debug method - use this method to send output to the QEMU
* BIOS debug port. This method handles strings, integers,
* and buffers. For example: DBUG("abc") DBUG(0x123)
*/
Method(DBUG, 1) {
ToHexString(Arg0, Local0)
ToBuffer(Local0, Local0)
Subtract(SizeOf(Local0), 1, Local1)
Store(Zero, Local2)
While (LLess(Local2, Local1)) {
Store(DerefOf(Index(Local0, Local2)), DBGB)
Increment(Local2)
}
Store(0x0a, dbgb)
}
}

@ -0,0 +1,31 @@
/* HPET */
Scope(\_SB) {
Device(HPET) {
Name(_HID, EISAID("PNP0103"))
Name(_UID, 0)
OperationRegion(HPTM, SystemMemory, 0xfed00000, 0x400)
Field(HPTM, DWordAcc, Lock, Preserve) {
VEND, 32,
PRD, 32,
}
Method(_STA, 0, NotSerialized) {
Store(VEND, Local0)
Store(PRD, Local1)
ShiftRight(Local0, 16, Local0)
If (LOr(LEqual(Local0, 0), LEqual(Local0, 0xffff))) {
Return (0x0)
}
If (LOr(LEqual(Local1, 0), LGreater(Local1, 100000000))) {
Return (0x0)
}
Return (0x0f)
}
Name(_CRS, ResourceTemplate() {
Memory32Fixed(ReadOnly,
0xfed00000, /* Address Base */
0x00000400, /* Address Length */
)
})
}
}

@ -0,0 +1,102 @@
/* Common legacy ISA style devices. */
Scope(\_SB.PCI0.ISA) {
Device(RTC) {
Name(_HID, EisaId("PNP0B00"))
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0070, 0x0070, 0x10, 0x02)
IRQNoFlags() { 8 }
IO(Decode16, 0x0072, 0x0072, 0x02, 0x06)
})
}
Device(KBD) {
Name(_HID, EisaId("PNP0303"))
Method(_STA, 0, NotSerialized) {
Return (0x0f)
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0060, 0x0060, 0x01, 0x01)
IO(Decode16, 0x0064, 0x0064, 0x01, 0x01)
IRQNoFlags() { 1 }
})
}
Device(MOU) {
Name(_HID, EisaId("PNP0F13"))
Method(_STA, 0, NotSerialized) {
Return (0x0f)
}
Name(_CRS, ResourceTemplate() {
IRQNoFlags() { 12 }
})
}
Device(FDC0) {
Name(_HID, EisaId("PNP0700"))
Method(_STA, 0, NotSerialized) {
Store(FDEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0f)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x03f2, 0x03f2, 0x00, 0x04)
IO(Decode16, 0x03f7, 0x03f7, 0x00, 0x01)
IRQNoFlags() { 6 }
DMA(Compatibility, NotBusMaster, Transfer8) { 2 }
})
}
Device(LPT) {
Name(_HID, EisaId("PNP0400"))
Method(_STA, 0, NotSerialized) {
Store(LPEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0f)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x0378, 0x0378, 0x08, 0x08)
IRQNoFlags() { 7 }
})
}
Device(COM1) {
Name(_HID, EisaId("PNP0501"))
Name(_UID, 0x01)
Method(_STA, 0, NotSerialized) {
Store(CAEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0f)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x03f8, 0x03f8, 0x00, 0x08)
IRQNoFlags() { 4 }
})
}
Device(COM2) {
Name(_HID, EisaId("PNP0501"))
Name(_UID, 0x02)
Method(_STA, 0, NotSerialized) {
Store(CBEN, Local0)
If (LEqual(Local0, 0)) {
Return (0x00)
} Else {
Return (0x0f)
}
}
Name(_CRS, ResourceTemplate() {
IO(Decode16, 0x02f8, 0x02f8, 0x00, 0x08)
IRQNoFlags() { 3 }
})
}
}

@ -0,0 +1,61 @@
/* PCI CRS (current resources) definition. */
Scope(\_SB.PCI0) {
Name(CRES, ResourceTemplate() {
WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, /* Address Space Granularity */
0x0000, /* Address Range Minimum */
0x00ff, /* Address Range Maximum */
0x0000, /* Address Translation Offset */
0x0100, /* Address Length */
,, )
IO(Decode16,
0x0cf8, /* Address Range Minimum */
0x0cf8, /* Address Range Maximum */
0x01, /* Address Alignment */
0x08, /* Address Length */
)
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* Address Space Granularity */
0x0000, /* Address Range Minimum */
0x0cf7, /* Address Range Maximum */
0x0000, /* Address Translation Offset */
0x0cf8, /* Address Length */
,, , TypeStatic)
WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* Address Space Granularity */
0x0d00, /* Address Range Minimum */
0xffff, /* Address Range Maximum */
0x0000, /* Address Translation Offset */
0xf300, /* Address Length */
,, , TypeStatic)
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Address Space Granularity */
0x000a0000, /* Address Range Minimum */
0x000bffff, /* Address Range Maximum */
0x00000000, /* Address Translation Offset */
0x00020000, /* Address Length */
,, , AddressRangeMemory, TypeStatic)
DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
0x00000000, /* Address Space Granularity */
0xe0000000, /* Address Range Minimum */
0xfebfffff, /* Address Range Maximum */
0x00000000, /* Address Translation Offset */
0x1ec00000, /* Address Length */
,, PW32, AddressRangeMemory, TypeStatic)
})
Name(CR64, ResourceTemplate() {
QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Address Space Granularity */
0x80000000, /* Address Range Minimum */
0xffffffff, /* Address Range Maximum */
0x00000000, /* Address Translation Offset */
0x80000000, /* Address Length */
,, PW64, AddressRangeMemory, TypeStatic)
})
Method(_CRS, 0) {
Return (CRES)
}
}

@ -0,0 +1,412 @@
/*
* QEMU ACPI DSDT ASL definition
*
* Copyright (c) 2006 Fabrice Bellard
*
* Copyright (c) 2010 Isaku Yamahata
* yamahata at valinux co jp
* Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
*/
DefinitionBlock (
"dsdt.aml", /* Output Filename */
"DSDT", /* Signature */
0x01, /* DSDT Compliance Revision */
"UBOO", /* OEMID */
"UBOOT ", /* TABLE ID */
0x2 /* OEM Revision */
)
{
#include "acpi/dbug.asl"
Scope(\_SB) {
OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
PCIB, 8,
}
}
/* PCI Bus definition */
Scope(\_SB) {
Device(PCI0) {
Name(_HID, EisaId("PNP0A08"))
Name(_CID, EisaId("PNP0A03"))
Name(_ADR, 0x00)
Name(_UID, 1)
/* _OSC: based on sample of ACPI3.0b spec */
Name(SUPP, 0) /* PCI _OSC Support Field value */
Name(CTRL, 0) /* PCI _OSC Control Field value */
Method(_OSC, 4) {
/* Create DWORD-addressable fields from Capabilities Buffer */
CreateDWordField(Arg3, 0, CDW1)
/* Check for proper UUID */
If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
{
/* Create DWORD-addressable fields from Capabilities Buffer */
CreateDWordField(Arg3, 4, CDW2)
CreateDWordField(Arg3, 8, CDW3)
/* Save Capabilities DWORD2 & 3 */
Store(CDW2, SUPP)
Store(CDW3, CTRL)
/*
* Always allow native PME, AER (no dependencies)
* Never allow SHPC (no SHPC controller in this system)
*/
And(CTRL, 0x1d, CTRL)
If (LNotEqual(Arg1, One)) {
/* Unknown revision */
Or(CDW1, 0x08, CDW1)
}
If (LNotEqual(CDW3, CTRL)) {
/* Capabilities bits were masked */
Or(CDW1, 0x10, CDW1)
}
/* Update DWORD3 in the buffer */
Store(CTRL, CDW3)
} Else {
Or(CDW1, 4, CDW1) /* Unrecognized UUID */
}
Return (Arg3)
}
}
}
#include "acpi/pci-crs.asl"
#include "acpi/hpet.asl"
/* VGA */
Scope(\_SB.PCI0) {
Device(VGA) {
Name(_ADR, 0x00010000)
Method(_S1D, 0, NotSerialized) {
Return (0x00)
}
Method(_S2D, 0, NotSerialized) {
Return (0x00)
}
Method(_S3D, 0, NotSerialized) {
Return (0x00)
}
}
}
/* LPC ISA bridge */
Scope(\_SB.PCI0) {
/* PCI D31:f0 LPC ISA bridge */
Device(ISA) {
/* PCI D31:f0 */
Name(_ADR, 0x001f0000)
/* ICH9 PCI to ISA irq remapping */
OperationRegion(PIRQ, PCI_Config, 0x60, 0x0c)
OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
Field(LPCD, AnyAcc, NoLock, Preserve) {
COMA, 3,
, 1,
COMB, 3,
Offset(0x01),
LPTD, 2,
, 2,
FDCD, 2
}
OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
Field(LPCE, AnyAcc, NoLock, Preserve) {
CAEN, 1,
CBEN, 1,
LPEN, 1,
FDEN, 1
}
}
}
#include "acpi/isa.asl"
/* PCI IRQs */
/* Zero => PIC mode, One => APIC Mode */
Name(\PICF, Zero)
Method(\_PIC, 1, NotSerialized) {
Store(Arg0, \PICF)
}
Scope(\_SB) {
Scope(PCI0) {
#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3) \
Package() { nr##ffff, 0, lnk0, 0 }, \
Package() { nr##ffff, 1, lnk1, 0 }, \
Package() { nr##ffff, 2, lnk2, 0 }, \
Package() { nr##ffff, 3, lnk3, 0 }
#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
Name(PRTP, Package() {
prt_slot_lnkE(0x0000),
prt_slot_lnkF(0x0001),
prt_slot_lnkG(0x0002),
prt_slot_lnkH(0x0003),
prt_slot_lnkE(0x0004),
prt_slot_lnkF(0x0005),
prt_slot_lnkG(0x0006),
prt_slot_lnkH(0x0007),
prt_slot_lnkE(0x0008),
prt_slot_lnkF(0x0009),
prt_slot_lnkG(0x000a),
prt_slot_lnkH(0x000b),
prt_slot_lnkE(0x000c),
prt_slot_lnkF(0x000d),
prt_slot_lnkG(0x000e),
prt_slot_lnkH(0x000f),
prt_slot_lnkE(0x0010),
prt_slot_lnkF(0x0011),
prt_slot_lnkG(0x0012),
prt_slot_lnkH(0x0013),
prt_slot_lnkE(0x0014),
prt_slot_lnkF(0x0015),
prt_slot_lnkG(0x0016),
prt_slot_lnkH(0x0017),
prt_slot_lnkE(0x0018),
/* INTA -> PIRQA for slot 25 - 31
see the default value of D<N>IR */
prt_slot_lnkA(0x0019),
prt_slot_lnkA(0x001a),
prt_slot_lnkA(0x001b),
prt_slot_lnkA(0x001c),
prt_slot_lnkA(0x001d),
/* PCIe->PCI bridge. use PIRQ[E-H] */
prt_slot_lnkE(0x001e),
prt_slot_lnkA(0x001f)
})
#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3) \
Package() { nr##ffff, 0, gsi0, 0 }, \
Package() { nr##ffff, 1, gsi1, 0 }, \
Package() { nr##ffff, 2, gsi2, 0 }, \
Package() { nr##ffff, 3, gsi3, 0 }
#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
Name(PRTA, Package() {
prt_slot_gsiE(0x0000),
prt_slot_gsiF(0x0001),
prt_slot_gsiG(0x0002),
prt_slot_gsiH(0x0003),
prt_slot_gsiE(0x0004),
prt_slot_gsiF(0x0005),
prt_slot_gsiG(0x0006),
prt_slot_gsiH(0x0007),
prt_slot_gsiE(0x0008),
prt_slot_gsiF(0x0009),
prt_slot_gsiG(0x000a),
prt_slot_gsiH(0x000b),
prt_slot_gsiE(0x000c),
prt_slot_gsiF(0x000d),
prt_slot_gsiG(0x000e),
prt_slot_gsiH(0x000f),
prt_slot_gsiE(0x0010),
prt_slot_gsiF(0x0011),
prt_slot_gsiG(0x0012),
prt_slot_gsiH(0x0013),
prt_slot_gsiE(0x0014),
prt_slot_gsiF(0x0015),
prt_slot_gsiG(0x0016),
prt_slot_gsiH(0x0017),
prt_slot_gsiE(0x0018),
/*
* INTA -> PIRQA for slot 25 - 31, but 30
* see the default value of D<N>IR
*/
prt_slot_gsiA(0x0019),
prt_slot_gsiA(0x001a),
prt_slot_gsiA(0x001b),
prt_slot_gsiA(0x001c),
prt_slot_gsiA(0x001d),
/* PCIe->PCI bridge. use PIRQ[E-H] */
prt_slot_gsiE(0x001e),
prt_slot_gsiA(0x001f)
})
Method(_PRT, 0, NotSerialized) {
/*
* PCI IRQ routing table,
* example from ACPI 2.0a
* specification, section 6.2.8.1
* Note: we provide the same info
* as the PCI routing table
* of the Bochs BIOS
*/
If (LEqual(\PICF, Zero)) {
Return (PRTP)
} Else {
Return (PRTA)
}
}
}
Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
PRQA, 8,
PRQB, 8,
PRQC, 8,
PRQD, 8,
Offset(0x08),
PRQE, 8,
PRQF, 8,
PRQG, 8,
PRQH, 8
}
Method(IQST, 1, NotSerialized) {
/* _STA method - get status */
If (And(0x80, Arg0)) {
Return (0x09)
}
Return (0x0b)
}
Method(IQCR, 1, NotSerialized) {
/* _CRS method - get current settings */
Name(PRR0, ResourceTemplate() {
Interrupt(, Level, ActiveHigh, Shared) { 0 }
})
CreateDWordField(PRR0, 0x05, PRRI)
Store(And(Arg0, 0x0f), PRRI)
Return (PRR0)
}
#define define_link(link, uid, reg) \
Device(link) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, uid) \
Name(_PRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
5, 10, 11 \
} \
}) \
Method(_STA, 0, NotSerialized) { \
Return (IQST(reg)) \
} \
Method(_DIS, 0, NotSerialized) { \
Or(reg, 0x80, reg) \
} \
Method(_CRS, 0, NotSerialized) { \
Return (IQCR(reg)) \
} \
Method(_SRS, 1, NotSerialized) { \
CreateDWordField(Arg0, 0x05, PRRI) \
Store(PRRI, reg) \
} \
}
define_link(LNKA, 0, PRQA)
define_link(LNKB, 1, PRQB)
define_link(LNKC, 2, PRQC)
define_link(LNKD, 3, PRQD)
define_link(LNKE, 4, PRQE)
define_link(LNKF, 5, PRQF)
define_link(LNKG, 6, PRQG)
define_link(LNKH, 7, PRQH)
#define define_gsi_link(link, uid, gsi) \
Device(link) { \
Name(_HID, EISAID("PNP0C0F")) \
Name(_UID, uid) \
Name(_PRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
gsi \
} \
}) \
Name(_CRS, ResourceTemplate() { \
Interrupt(, Level, ActiveHigh, Shared) { \
gsi \
} \
}) \
Method(_SRS, 1, NotSerialized) { \
} \
}
define_gsi_link(GSIA, 0, 0x10)
define_gsi_link(GSIB, 0, 0x11)
define_gsi_link(GSIC, 0, 0x12)
define_gsi_link(GSID, 0, 0x13)
define_gsi_link(GSIE, 0, 0x14)
define_gsi_link(GSIF, 0, 0x15)
define_gsi_link(GSIG, 0, 0x16)
define_gsi_link(GSIH, 0, 0x17)
}
/* General purpose events */
Scope(\_GPE) {
Name(_HID, "ACPI0006")
Method(_L00) {
}
Method(_L01) {
}
Method(_L02) {
}
Method(_L03) {
}
Method(_L04) {
}
Method(_L05) {
}
Method(_L06) {
}
Method(_L07) {
}
Method(_L08) {
}
Method(_L09) {
}
Method(_L0A) {
}
Method(_L0B) {
}
Method(_L0C) {
}
Method(_L0D) {
}
Method(_L0E) {
}
Method(_L0F) {
}
}
}

@ -36,8 +36,6 @@ int arch_cpu_init(void)
if (ret)
return ret;
unprotect_spi_flash();
return 0;
}
@ -80,5 +78,7 @@ void cpu_irq_init(void)
int arch_misc_init(void)
{
unprotect_spi_flash();
return pirq_init();
}

@ -115,8 +115,10 @@ car_init_ret:
#endif
#else
/*
* When we get here after car_init(), esp points to a temporary stack
* and esi holds the HOB list address returned by the FSP.
* U-Boot enters here twice. For the first time it comes from
* car_init_done() with esp points to a temporary stack and esi
* set to zero. For the second time it comes from fsp_init_done()
* with esi holding the HOB list address returned by the FSP.
*/
#endif
/* Set up global data */
@ -141,6 +143,14 @@ car_init_ret:
jz skip_hob
movl %esi, GD_HOB_LIST(%edx)
/*
* After fsp_init() returns, the stack has already been switched to a
* place within system memory as defined by CONFIG_FSP_TEMP_RAM_ADDR.
* Enlarge the size of malloc() pool before relocation since we have
* plenty of memory now.
*/
subl $CONFIG_FSP_SYS_MALLOC_F_LEN, %esp
movl %esp, GD_MALLOC_BASE(%edx)
skip_hob:
#else
/* Store table pointer */

@ -230,6 +230,12 @@
update@0 {
#include "microcode/m0230671117.dtsi"
};
update@1 {
#include "microcode/m0130673322.dtsi"
};
update@2 {
#include "microcode/m0130679901.dtsi"
};
};
};

@ -91,7 +91,6 @@
#address-cells = <3>;
#size-cells = <2>;
compatible = "pci-x86";
device_type = "pci";
u-boot,dm-pre-reloc;
ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
@ -100,14 +99,16 @@
pcie@17,0 {
#address-cells = <3>;
#size-cells = <2>;
compatible = "intel,pci";
device_type = "pci";
compatible = "pci-bridge";
u-boot,dm-pre-reloc;
reg = <0x0000b800 0x0 0x0 0x0 0x0>;
topcliff@0,0 {
#address-cells = <3>;
#size-cells = <2>;
compatible = "intel,pci";
device_type = "pci";
compatible = "pci-bridge";
u-boot,dm-pre-reloc;
reg = <0x00010000 0x0 0x0 0x0 0x0>;
pciuart0: uart@a,1 {
compatible = "pci8086,8811.00",
@ -115,6 +116,7 @@
"pciclass,070002",
"pciclass,0700",
"x86-uart";
u-boot,dm-pre-reloc;
reg = <0x00025100 0x0 0x0 0x0 0x0
0x01025110 0x0 0x0 0x0 0x0>;
reg-shift = <0>;
@ -128,6 +130,7 @@
"pciclass,070002",
"pciclass,0700",
"x86-uart";
u-boot,dm-pre-reloc;
reg = <0x00025200 0x0 0x0 0x0 0x0
0x01025210 0x0 0x0 0x0 0x0>;
reg-shift = <0>;
@ -141,6 +144,7 @@
"pciclass,070002",
"pciclass,0700",
"x86-uart";
u-boot,dm-pre-reloc;
reg = <0x00025300 0x0 0x0 0x0 0x0
0x01025310 0x0 0x0 0x0 0x0>;
reg-shift = <0>;
@ -154,6 +158,7 @@
"pciclass,070002",
"pciclass,0700",
"x86-uart";
u-boot,dm-pre-reloc;
reg = <0x00025400 0x0 0x0 0x0 0x0
0x01025410 0x0 0x0 0x0 0x0>;
reg-shift = <0>;
@ -168,7 +173,7 @@
compatible = "intel,irq-router";
intel,pirq-config = "pci";
intel,pirq-link = <0x60 8>;
intel,pirq-mask = <0xdee0>;
intel,pirq-mask = <0xcee0>;
intel,pirq-routing = <
/* TunnelCreek PCI devices */
PCI_BDF(0, 2, 0) INTA PIRQE

File diff suppressed because it is too large Load Diff

@ -30,6 +30,33 @@
compatible = "intel,x86-pinctrl";
io-base = <0x4c>;
/* GPIO E0 */
soc_gpio_s5_0@0 {
gpio-offset = <0x80 0>;
pad-offset = <0x1d0>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};
/* GPIO E1 */
soc_gpio_s5_1@0 {
gpio-offset = <0x80 1>;
pad-offset = <0x210>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};
/* GPIO E2 */
soc_gpio_s5_2@0 {
gpio-offset = <0x80 2>;
pad-offset = <0x1e0>;
mode-gpio;
output-value = <0>;
direction = <PIN_OUTPUT>;
};
pin_usb_host_en0@0 {
gpio-offset = <0x80 8>;
pad-offset = <0x260>;
@ -40,7 +67,7 @@
pin_usb_host_en1@0 {
gpio-offset = <0x80 9>;
pad-offset = <0x258>;
pad-offset = <0x250>;
mode-gpio;
output-value = <1>;
direction = <PIN_OUTPUT>;
@ -256,6 +283,9 @@
update@0 {
#include "microcode/m0130673322.dtsi"
};
update@1 {
#include "microcode/m0130679901.dtsi"
};
};
};

@ -0,0 +1,393 @@
/*
* Based on acpi.c from coreboot
*
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <malloc.h>
#include <asm/post.h>
#include <linux/string.h>
#define RSDP_SIG "RSD PTR " /* RSDT pointer signature */
#define ACPI_TABLE_CREATOR "UBOOT " /* Must be 8 bytes long! */
#define OEM_ID "UBOOT " /* Must be 6 bytes long! */
#define ASLC "INTL" /* Must be 4 bytes long! */
#define OEM_REVISION 42
#define ASL_COMPILER_REVISION 42
/* IO ports to generate SMIs */
#define APM_CNT 0xb2
#define APM_CNT_CST_CONTROL 0x85
#define APM_CNT_PST_CONTROL 0x80
#define APM_CNT_ACPI_DISABLE 0x1e
#define APM_CNT_ACPI_ENABLE 0xe1
#define APM_CNT_MBI_UPDATE 0xeb
#define APM_CNT_GNVS_UPDATE 0xea
#define APM_CNT_FINALIZE 0xcb
#define APM_CNT_LEGACY 0xcc
#define APM_ST 0xb3
/* Multiple Processor Interrupts */
#define MP_IRQ_POLARITY_DEFAULT 0x0
#define MP_IRQ_POLARITY_HIGH 0x1
#define MP_IRQ_POLARITY_LOW 0x3
#define MP_IRQ_POLARITY_MASK 0x3
#define MP_IRQ_TRIGGER_DEFAULT 0x0
#define MP_IRQ_TRIGGER_EDGE 0x4
#define MP_IRQ_TRIGGER_LEVEL 0xc
#define MP_IRQ_TRIGGER_MASK 0xc
/*
* Interrupt assigned for SCI in order to
* create the ACPI MADT IRQ override entry
*/
#define ACTL 0x00
#define SCIS_MASK 0x07
#define SCIS_IRQ9 0x00
#define SCIS_IRQ10 0x01
#define SCIS_IRQ11 0x02
#define SCIS_IRQ20 0x04
#define SCIS_IRQ21 0x05
#define SCIS_IRQ22 0x06
#define SCIS_IRQ23 0x07
#define ACPI_REV_ACPI_1_0 1
#define ACPI_REV_ACPI_2_0 1
#define ACPI_REV_ACPI_3_0 2
#define ACPI_REV_ACPI_4_0 3
#define ACPI_REV_ACPI_5_0 5
#define ACPI_RSDP_REV_ACPI_1_0 0
#define ACPI_RSDP_REV_ACPI_2_0 2
typedef struct acpi_gen_regaddr {
u8 space_id; /* Address space ID */
u8 bit_width; /* Register size in bits */
u8 bit_offset; /* Register bit offset */
union {
/* Reserved in ACPI 2.0 - 2.0b */
u8 resv;
/* Access size in ACPI 2.0c/3.0/4.0/5.0 */
u8 access_size;
};
u32 addrl; /* Register address, low 32 bits */
u32 addrh; /* Register address, high 32 bits */
} acpi_addr_t;
/*
* RSDP (Root System Description Pointer)
* Note: ACPI 1.0 didn't have length, xsdt_address, and ext_checksum
*/
struct acpi_rsdp {
char signature[8]; /* RSDP signature */
u8 checksum; /* Checksum of the first 20 bytes */
char oem_id[6]; /* OEM ID */
u8 revision; /* 0 for ACPI 1.0, 2 for ACPI 2.0/3.0/4.0 */
u32 rsdt_address; /* Physical address of RSDT (32 bits) */
u32 length; /* Total RSDP length (incl. extended part) */
u64 xsdt_address; /* Physical address of XSDT (64 bits) */
u8 ext_checksum; /* Checksum of the whole table */
u8 reserved[3];
};
enum acpi_address_space_type {
ACPI_ADDRESS_SPACE_MEMORY = 0, /* System memory */
ACPI_ADDRESS_SPACE_IO, /* System I/O */
ACPI_ADDRESS_SPACE_PCI, /* PCI config space */
ACPI_ADDRESS_SPACE_EC, /* Embedded controller */
ACPI_ADDRESS_SPACE_SMBUS, /* SMBus */
ACPI_ADDRESS_SPACE_PCC = 0x0a, /* Platform Comm. Channel */
ACPI_ADDRESS_SPACE_FIXED = 0x7f /* Functional fixed hardware */
};
/* functional fixed hardware */
#define ACPI_FFIXEDHW_VENDOR_INTEL 1 /* Intel */
#define ACPI_FFIXEDHW_CLASS_HLT 0 /* C1 Halt */
#define ACPI_FFIXEDHW_CLASS_IO_HLT 1 /* C1 I/O then Halt */
#define ACPI_FFIXEDHW_CLASS_MWAIT 2 /* MWAIT Native C-state */
#define ACPI_FFIXEDHW_FLAG_HW_COORD 1 /* Hardware Coordination bit */
#define ACPI_FFIXEDHW_FLAG_BM_STS 2 /* BM_STS avoidance bit */
/* Access size definitions for Generic address structure */
enum acpi_address_space_size {
ACPI_ACCESS_SIZE_UNDEFINED = 0, /* Undefined (legacy reasons) */
ACPI_ACCESS_SIZE_BYTE_ACCESS = 1,
ACPI_ACCESS_SIZE_WORD_ACCESS = 2,
ACPI_ACCESS_SIZE_DWORD_ACCESS = 3,
ACPI_ACCESS_SIZE_QWORD_ACCESS = 4
};
/* Generic ACPI header, provided by (almost) all tables */
typedef struct acpi_table_header {
char signature[4]; /* ACPI signature (4 ASCII characters) */
u32 length; /* Table length in bytes (incl. header) */
u8 revision; /* Table version (not ACPI version!) */
volatile u8 checksum; /* To make sum of entire table == 0 */
char oem_id[6]; /* OEM identification */
char oem_table_id[8]; /* OEM table identification */
u32 oem_revision; /* OEM revision number */
char asl_compiler_id[4]; /* ASL compiler vendor ID */
u32 asl_compiler_revision; /* ASL compiler revision number */
} acpi_header_t;
/* A maximum number of 32 ACPI tables ought to be enough for now */
#define MAX_ACPI_TABLES 32
/* RSDT (Root System Description Table) */
struct acpi_rsdt {
struct acpi_table_header header;
u32 entry[MAX_ACPI_TABLES];
};
/* XSDT (Extended System Description Table) */
struct acpi_xsdt {
struct acpi_table_header header;
u64 entry[MAX_ACPI_TABLES];
};
/* MCFG (PCI Express MMIO config space BAR description table) */
struct acpi_mcfg {
struct acpi_table_header header;
u8 reserved[8];
};
struct acpi_mcfg_mmconfig {
u32 base_address;
u32 base_reserved;
u16 pci_segment_group_number;
u8 start_bus_number;
u8 end_bus_number;
u8 reserved[4];
};
/* MADT (Multiple APIC Description Table) */
struct acpi_madt {
struct acpi_table_header header;
u32 lapic_addr; /* Local APIC address */
u32 flags; /* Multiple APIC flags */
} acpi_madt_t;
enum dev_scope_type {
SCOPE_PCI_ENDPOINT = 1,
SCOPE_PCI_SUB = 2,
SCOPE_IOAPIC = 3,
SCOPE_MSI_HPET = 4
};
typedef struct dev_scope {
u8 type;
u8 length;
u8 reserved[2];
u8 enumeration;
u8 start_bus;
struct {
u8 dev;
u8 fn;
} path[0];
} __packed dev_scope_t;
/* MADT: APIC Structure Type*/
enum acpi_apic_types {
LOCALAPIC = 0, /* Processor local APIC */
IOAPIC, /* I/O APIC */
IRQSOURCEOVERRIDE, /* Interrupt source override */
NMITYPE, /* NMI source */
LOCALNMITYPE, /* Local APIC NMI */
LAPICADDRESSOVERRIDE, /* Local APIC address override */
IOSAPIC, /* I/O SAPIC */
LOCALSAPIC, /* Local SAPIC */
PLATFORMIRQSOURCES, /* Platform interrupt sources */
LOCALX2SAPIC, /* Processor local x2APIC */
LOCALX2APICNMI, /* Local x2APIC NMI */
};
/* MADT: Processor Local APIC Structure */
struct acpi_madt_lapic {
u8 type; /* Type (0) */
u8 length; /* Length in bytes (8) */
u8 processor_id; /* ACPI processor ID */
u8 apic_id; /* Local APIC ID */
u32 flags; /* Local APIC flags */
};
#define LOCAL_APIC_FLAG_ENABLED (1 << 0)
/* bits 1-31: reserved */
#define PCAT_COMPAT (1 << 0)
/* bits 1-31: reserved */
/* MADT: Local APIC NMI Structure */
struct acpi_madt_lapic_nmi {
u8 type; /* Type (4) */
u8 length; /* Length in bytes (6) */
u8 processor_id; /* ACPI processor ID */
u16 flags; /* MPS INTI flags */
u8 lint; /* Local APIC LINT# */
};
/* MADT: I/O APIC Structure */
struct acpi_madt_ioapic {
u8 type; /* Type (1) */
u8 length; /* Length in bytes (12) */
u8 ioapic_id; /* I/O APIC ID */
u8 reserved;
u32 ioapic_addr; /* I/O APIC address */
u32 gsi_base; /* Global system interrupt base */
};
/* MADT: Interrupt Source Override Structure */
struct acpi_madt_irqoverride {
u8 type; /* Type (2) */
u8 length; /* Length in bytes (10) */
u8 bus; /* ISA (0) */
u8 source; /* Bus-relative int. source (IRQ) */
u32 gsirq; /* Global system interrupt */
u16 flags; /* MPS INTI flags */
};
/* FADT (Fixed ACPI Description Table) */
struct __packed acpi_fadt {
struct acpi_table_header header;
u32 firmware_ctrl;
u32 dsdt;
u8 model;
u8 preferred_pm_profile;
u16 sci_int;
u32 smi_cmd;
u8 acpi_enable;
u8 acpi_disable;
u8 s4bios_req;
u8 pstate_cnt;
u32 pm1a_evt_blk;
u32 pm1b_evt_blk;
u32 pm1a_cnt_blk;
u32 pm1b_cnt_blk;
u32 pm2_cnt_blk;
u32 pm_tmr_blk;
u32 gpe0_blk;
u32 gpe1_blk;
u8 pm1_evt_len;
u8 pm1_cnt_len;
u8 pm2_cnt_len;
u8 pm_tmr_len;
u8 gpe0_blk_len;
u8 gpe1_blk_len;
u8 gpe1_base;
u8 cst_cnt;
u16 p_lvl2_lat;
u16 p_lvl3_lat;
u16 flush_size;
u16 flush_stride;
u8 duty_offset;
u8 duty_width;
u8 day_alrm;
u8 mon_alrm;
u8 century;
u16 iapc_boot_arch;
u8 res2;
u32 flags;
struct acpi_gen_regaddr reset_reg;
u8 reset_value;
u8 res3;
u8 res4;
u8 res5;
u32 x_firmware_ctl_l;
u32 x_firmware_ctl_h;
u32 x_dsdt_l;
u32 x_dsdt_h;
struct acpi_gen_regaddr x_pm1a_evt_blk;
struct acpi_gen_regaddr x_pm1b_evt_blk;
struct acpi_gen_regaddr x_pm1a_cnt_blk;
struct acpi_gen_regaddr x_pm1b_cnt_blk;
struct acpi_gen_regaddr x_pm2_cnt_blk;
struct acpi_gen_regaddr x_pm_tmr_blk;
struct acpi_gen_regaddr x_gpe0_blk;
struct acpi_gen_regaddr x_gpe1_blk;
};
/* Flags for p_lvl2_lat and p_lvl3_lat */
#define ACPI_FADT_C2_NOT_SUPPORTED 101
#define ACPI_FADT_C3_NOT_SUPPORTED 1001
/* FADT Feature Flags */
#define ACPI_FADT_WBINVD (1 << 0)
#define ACPI_FADT_WBINVD_FLUSH (1 << 1)
#define ACPI_FADT_C1_SUPPORTED (1 << 2)
#define ACPI_FADT_C2_MP_SUPPORTED (1 << 3)
#define ACPI_FADT_POWER_BUTTON (1 << 4)
#define ACPI_FADT_SLEEP_BUTTON (1 << 5)
#define ACPI_FADT_FIXED_RTC (1 << 6)
#define ACPI_FADT_S4_RTC_WAKE (1 << 7)
#define ACPI_FADT_32BIT_TIMER (1 << 8)
#define ACPI_FADT_DOCKING_SUPPORTED (1 << 9)
#define ACPI_FADT_RESET_REGISTER (1 << 10)
#define ACPI_FADT_SEALED_CASE (1 << 11)
#define ACPI_FADT_HEADLESS (1 << 12)
#define ACPI_FADT_SLEEP_TYPE (1 << 13)
#define ACPI_FADT_PCI_EXPRESS_WAKE (1 << 14)
#define ACPI_FADT_PLATFORM_CLOCK (1 << 15)
#define ACPI_FADT_S4_RTC_VALID (1 << 16)
#define ACPI_FADT_REMOTE_POWER_ON (1 << 17)
#define ACPI_FADT_APIC_CLUSTER (1 << 18)
#define ACPI_FADT_APIC_PHYSICAL (1 << 19)
/* Bits 20-31: reserved ACPI 3.0 & 4.0 */
#define ACPI_FADT_HW_REDUCED_ACPI (1 << 20)
#define ACPI_FADT_LOW_PWR_IDLE_S0 (1 << 21)
/* bits 22-31: reserved ACPI 5.0 */
/* FADT Boot Architecture Flags */
#define ACPI_FADT_LEGACY_DEVICES (1 << 0)
#define ACPI_FADT_8042 (1 << 1)
#define ACPI_FADT_VGA_NOT_PRESENT (1 << 2)
#define ACPI_FADT_MSI_NOT_SUPPORTED (1 << 3)
#define ACPI_FADT_NO_PCIE_ASPM_CONTROL (1 << 4)
/* No legacy devices (including 8042) */
#define ACPI_FADT_LEGACY_FREE 0x00
/* FADT Preferred Power Management Profile */
#define PM_UNSPECIFIED 0
#define PM_DESKTOP 1
#define PM_MOBILE 2
#define PM_WORKSTATION 3
#define PM_ENTERPRISE_SERVER 4
#define PM_SOHO_SERVER 5
#define PM_APPLIANCE_PC 6
#define PM_PERFORMANCE_SERVER 7
#define PM_TABLET 8 /* ACPI 5.0 */
/* FACS (Firmware ACPI Control Structure) */
struct acpi_facs {
char signature[4]; /* "FACS" */
u32 length; /* Length in bytes (>= 64) */
u32 hardware_signature; /* Hardware signature */
u32 firmware_waking_vector; /* Firmware waking vector */
u32 global_lock; /* Global lock */
u32 flags; /* FACS flags */
u32 x_firmware_waking_vector_l; /* X FW waking vector, low */
u32 x_firmware_waking_vector_h; /* X FW waking vector, high */
u8 version; /* ACPI 4.0: 2 */
u8 resv[31]; /* FIXME: 4.0: ospm_flags */
};
/* FACS flags */
#define ACPI_FACS_S4BIOS_F (1 << 0)
#define ACPI_FACS_64BIT_WAKE_F (1 << 1)
/* Bits 31..2: reserved */
/* These can be used by the target port */
unsigned long acpi_create_madt_lapics(unsigned long current);
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr,
u32 gsi_base);
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
u8 bus, u8 source, u32 gsirq, u16 flags);
unsigned long acpi_fill_madt(unsigned long current);
void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
void *dsdt);
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, u8 cpu,
u16 flags, u8 lint);
unsigned long write_acpi_tables(unsigned long start);

@ -9,15 +9,12 @@
#ifndef _COREBOOT_SYSINFO_H
#define _COREBOOT_SYSINFO_H
#include <common.h>
#include <linux/compiler.h>
#include <libfdt.h>
#include <asm/arch/tables.h>
/* Allow a maximum of 16 memory range definitions. */
#define SYSINFO_MAX_MEM_RANGES 16
/* Maximum number of memory range definitions */
#define SYSINFO_MAX_MEM_RANGES 32
/* Allow a maximum of 8 GPIOs */
#define SYSINFO_MAX_GPIOS 8
#define SYSINFO_MAX_GPIOS 8
struct sysinfo_t {
int n_memranges;

@ -24,4 +24,7 @@
#define UART0_IRQ 4
#define UART1_IRQ 3
#define KBD_IRQ 1
#define MSE_IRQ 12
#endif

@ -8,8 +8,6 @@
#ifndef _INIT_HELPERS_H_
#define _INIT_HELPERS_H_
int calculate_relocation_address(void);
int init_cache_f_r(void);
int init_bd_struct_r(void);
int init_func_spi(void);

@ -30,6 +30,7 @@ obj-y += physmem.o
obj-$(CONFIG_X86_RAMTEST) += ramtest.o
obj-y += sfi.o
obj-y += string.o
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
obj-y += tables.o
obj-$(CONFIG_SYS_X86_TSC_TIMER) += tsc_timer.o
obj-$(CONFIG_CMD_ZBOOT) += zimage.o

@ -0,0 +1,436 @@
/*
* Based on acpi.c from coreboot
*
* Copyright (C) 2015, Saket Sinha <saket.sinha89@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <cpu.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <dm/lists.h>
#include <asm/acpi_table.h>
#include <asm/cpu.h>
#include <asm/ioapic.h>
#include <asm/lapic.h>
#include <asm/tables.h>
#include <asm/pci.h>
/*
* IASL compiles the dsdt entries and
* writes the hex values to AmlCode array.
* CamelCase cannot be handled here.
*/
extern const unsigned char AmlCode[];
/**
* Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
* and checksum.
*/
static void acpi_add_table(struct acpi_rsdp *rsdp, void *table)
{
int i, entries_num;
struct acpi_rsdt *rsdt;
struct acpi_xsdt *xsdt = NULL;
/* The RSDT is mandatory while the XSDT is not */
rsdt = (struct acpi_rsdt *)rsdp->rsdt_address;
if (rsdp->xsdt_address)
xsdt = (struct acpi_xsdt *)((u32)rsdp->xsdt_address);
/* This should always be MAX_ACPI_TABLES */
entries_num = ARRAY_SIZE(rsdt->entry);
for (i = 0; i < entries_num; i++) {
if (rsdt->entry[i] == 0)
break;
}
if (i >= entries_num) {
debug("ACPI: Error: too many tables.\n");
return;
}
/* Add table to the RSDT */
rsdt->entry[i] = (u32)table;
/* Fix RSDT length or the kernel will assume invalid entries */
rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i + 1));
/* Re-calculate checksum */
rsdt->header.checksum = 0;
rsdt->header.checksum = table_compute_checksum((u8 *)rsdt,
rsdt->header.length);
/*
* And now the same thing for the XSDT. We use the same index as for
* now we want the XSDT and RSDT to always be in sync in U-Boot
*/
if (xsdt) {
/* Add table to the XSDT */
xsdt->entry[i] = (u64)(u32)table;
/* Fix XSDT length */
xsdt->header.length = sizeof(acpi_header_t) +
(sizeof(u64) * (i + 1));
/* Re-calculate checksum */
xsdt->header.checksum = 0;
xsdt->header.checksum = table_compute_checksum((u8 *)xsdt,
xsdt->header.length);
}
}
static int acpi_create_madt_lapic(struct acpi_madt_lapic *lapic,
u8 cpu, u8 apic)
{
lapic->type = LOCALAPIC; /* Local APIC structure */
lapic->length = sizeof(struct acpi_madt_lapic);
lapic->flags = LOCAL_APIC_FLAG_ENABLED; /* Processor/LAPIC enabled */
lapic->processor_id = cpu;
lapic->apic_id = apic;
return lapic->length;
}
unsigned long acpi_create_madt_lapics(unsigned long current)
{
struct udevice *dev;
for (uclass_find_first_device(UCLASS_CPU, &dev);
dev;
uclass_find_next_device(&dev)) {
struct cpu_platdata *plat = dev_get_parent_platdata(dev);
current += acpi_create_madt_lapic(
(struct acpi_madt_lapic *)current,
plat->cpu_id, plat->cpu_id);
}
return current;
}
int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id, u32 addr,
u32 gsi_base)
{
ioapic->type = IOAPIC;
ioapic->length = sizeof(struct acpi_madt_ioapic);
ioapic->reserved = 0x00;
ioapic->gsi_base = gsi_base;
ioapic->ioapic_id = id;
ioapic->ioapic_addr = addr;
return ioapic->length;
}
int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
u8 bus, u8 source, u32 gsirq, u16 flags)
{
irqoverride->type = IRQSOURCEOVERRIDE;
irqoverride->length = sizeof(struct acpi_madt_irqoverride);
irqoverride->bus = bus;
irqoverride->source = source;
irqoverride->gsirq = gsirq;
irqoverride->flags = flags;
return irqoverride->length;
}
int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
u8 cpu, u16 flags, u8 lint)
{
lapic_nmi->type = LOCALNMITYPE;
lapic_nmi->length = sizeof(struct acpi_madt_lapic_nmi);
lapic_nmi->flags = flags;
lapic_nmi->processor_id = cpu;
lapic_nmi->lint = lint;
return lapic_nmi->length;
}
static void fill_header(acpi_header_t *header, char *signature, int length)
{
memcpy(header->signature, signature, length);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
}
static void acpi_create_madt(struct acpi_madt *madt)
{
acpi_header_t *header = &(madt->header);
unsigned long current = (unsigned long)madt + sizeof(struct acpi_madt);
memset((void *)madt, 0, sizeof(struct acpi_madt));
/* Fill out header fields */
fill_header(header, "APIC", 4);
header->length = sizeof(struct acpi_madt);
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
header->revision = ACPI_REV_ACPI_2_0;
madt->lapic_addr = LAPIC_DEFAULT_BASE;
madt->flags = PCAT_COMPAT;
current = acpi_fill_madt(current);
/* (Re)calculate length and checksum */
header->length = current - (unsigned long)madt;
header->checksum = table_compute_checksum((void *)madt, header->length);
}
static int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig,
u32 base, u16 seg_nr, u8 start, u8 end)
{
memset(mmconfig, 0, sizeof(*mmconfig));
mmconfig->base_address = base;
mmconfig->base_reserved = 0;
mmconfig->pci_segment_group_number = seg_nr;
mmconfig->start_bus_number = start;
mmconfig->end_bus_number = end;
return sizeof(struct acpi_mcfg_mmconfig);
}
static unsigned long acpi_fill_mcfg(unsigned long current)
{
current += acpi_create_mcfg_mmconfig
((struct acpi_mcfg_mmconfig *)current,
CONFIG_PCIE_ECAM_BASE, 0x0, 0x0, 255);
return current;
}
/* MCFG is defined in the PCI Firmware Specification 3.0 */
static void acpi_create_mcfg(struct acpi_mcfg *mcfg)
{
acpi_header_t *header = &(mcfg->header);
unsigned long current = (unsigned long)mcfg + sizeof(struct acpi_mcfg);
memset((void *)mcfg, 0, sizeof(struct acpi_mcfg));
/* Fill out header fields */
fill_header(header, "MCFG", 4);
header->length = sizeof(struct acpi_mcfg);
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
header->revision = ACPI_REV_ACPI_2_0;
current = acpi_fill_mcfg(current);
/* (Re)calculate length and checksum */
header->length = current - (unsigned long)mcfg;
header->checksum = table_compute_checksum((void *)mcfg, header->length);
}
static void acpi_create_facs(struct acpi_facs *facs)
{
memset((void *)facs, 0, sizeof(struct acpi_facs));
memcpy(facs->signature, "FACS", 4);
facs->length = sizeof(struct acpi_facs);
facs->hardware_signature = 0;
facs->firmware_waking_vector = 0;
facs->global_lock = 0;
facs->flags = 0;
facs->x_firmware_waking_vector_l = 0;
facs->x_firmware_waking_vector_h = 0;
facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */
}
static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
{
acpi_header_t *header = &(rsdt->header);
/* Fill out header fields */
fill_header(header, "RSDT", 4);
header->length = sizeof(struct acpi_rsdt);
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
header->revision = ACPI_REV_ACPI_2_0;
/* Entries are filled in later, we come with an empty set */
/* Fix checksum */
header->checksum = table_compute_checksum((void *)rsdt,
sizeof(struct acpi_rsdt));
}
static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
{
acpi_header_t *header = &(xsdt->header);
/* Fill out header fields */
fill_header(header, "XSDT", 4);
header->length = sizeof(struct acpi_xsdt);
/* ACPI 1.0/2.0: 1, ACPI 3.0: 2, ACPI 4.0: 3 */
header->revision = ACPI_REV_ACPI_2_0;
/* Entries are filled in later, we come with an empty set */
/* Fix checksum */
header->checksum = table_compute_checksum((void *)xsdt,
sizeof(struct acpi_xsdt));
}
static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
struct acpi_xsdt *xsdt)
{
memset(rsdp, 0, sizeof(struct acpi_rsdp));
memcpy(rsdp->signature, RSDP_SIG, 8);
memcpy(rsdp->oem_id, OEM_ID, 6);
rsdp->length = sizeof(struct acpi_rsdp);
rsdp->rsdt_address = (u32)rsdt;
/*
* Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2
*
* Some OSes expect an XSDT to be present for RSD PTR revisions >= 2.
* If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR
* revision 0)
*/
if (xsdt == NULL) {
rsdp->revision = ACPI_RSDP_REV_ACPI_1_0;
} else {
rsdp->xsdt_address = (u64)(u32)xsdt;
rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
}
/* Calculate checksums */
rsdp->checksum = table_compute_checksum((void *)rsdp, 20);
rsdp->ext_checksum = table_compute_checksum((void *)rsdp,
sizeof(struct acpi_rsdp));
}
static void acpi_create_ssdt_generator(acpi_header_t *ssdt,
const char *oem_table_id)
{
unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t);
memset((void *)ssdt, 0, sizeof(acpi_header_t));
memcpy(&ssdt->signature, "SSDT", 4);
/* Access size in ACPI 2.0c/3.0/4.0/5.0 */
ssdt->revision = ACPI_REV_ACPI_3_0;
memcpy(&ssdt->oem_id, OEM_ID, 6);
memcpy(&ssdt->oem_table_id, oem_table_id, 8);
ssdt->oem_revision = OEM_REVISION;
memcpy(&ssdt->asl_compiler_id, ASLC, 4);
ssdt->asl_compiler_revision = ASL_COMPILER_REVISION;
ssdt->length = sizeof(acpi_header_t);
/* (Re)calculate length and checksum */
ssdt->length = current - (unsigned long)ssdt;
ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
}
unsigned long write_acpi_tables(unsigned long start)
{
unsigned long current;
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
struct acpi_xsdt *xsdt;
struct acpi_facs *facs;
acpi_header_t *dsdt;
struct acpi_fadt *fadt;
struct acpi_mcfg *mcfg;
struct acpi_madt *madt;
acpi_header_t *ssdt;
current = start;
/* Align ACPI tables to 16byte */
current = ALIGN(current, 16);
debug("ACPI: Writing ACPI tables at %lx.\n", start);
/* We need at least an RSDP and an RSDT Table */
rsdp = (struct acpi_rsdp *)current;
current += sizeof(struct acpi_rsdp);
current = ALIGN(current, 16);
rsdt = (struct acpi_rsdt *)current;
current += sizeof(struct acpi_rsdt);
current = ALIGN(current, 16);
xsdt = (struct acpi_xsdt *)current;
current += sizeof(struct acpi_xsdt);
current = ALIGN(current, 16);
/* clear all table memory */
memset((void *)start, 0, current - start);
acpi_write_rsdp(rsdp, rsdt, xsdt);
acpi_write_rsdt(rsdt);
acpi_write_xsdt(xsdt);
debug("ACPI: * FACS\n");
facs = (struct acpi_facs *)current;
current += sizeof(struct acpi_facs);
current = ALIGN(current, 16);
acpi_create_facs(facs);
debug("ACPI: * DSDT\n");
dsdt = (acpi_header_t *)current;
memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
if (dsdt->length >= sizeof(acpi_header_t)) {
current += sizeof(acpi_header_t);
memcpy((char *)current,
(char *)&AmlCode + sizeof(acpi_header_t),
dsdt->length - sizeof(acpi_header_t));
current += dsdt->length - sizeof(acpi_header_t);
/* (Re)calculate length and checksum */
dsdt->length = current - (unsigned long)dsdt;
dsdt->checksum = 0;
dsdt->checksum = table_compute_checksum((void *)dsdt,
dsdt->length);
}
current = ALIGN(current, 16);
debug("ACPI: * FADT\n");
fadt = (struct acpi_fadt *)current;
current += sizeof(struct acpi_fadt);
current = ALIGN(current, 16);
acpi_create_fadt(fadt, facs, dsdt);
acpi_add_table(rsdp, fadt);
debug("ACPI: * MCFG\n");
mcfg = (struct acpi_mcfg *)current;
acpi_create_mcfg(mcfg);
if (mcfg->header.length > sizeof(struct acpi_mcfg)) {
current += mcfg->header.length;
current = ALIGN(current, 16);
acpi_add_table(rsdp, mcfg);
}
debug("ACPI: * MADT\n");
madt = (struct acpi_madt *)current;
acpi_create_madt(madt);
if (madt->header.length > sizeof(struct acpi_madt)) {
current += madt->header.length;
acpi_add_table(rsdp, madt);
}
current = ALIGN(current, 16);
debug("ACPI: * SSDT\n");
ssdt = (acpi_header_t *)current;
acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
if (ssdt->length > sizeof(acpi_header_t)) {
current += ssdt->length;
acpi_add_table(rsdp, ssdt);
current = ALIGN(current, 16);
}
debug("current = %lx\n", current);
debug("ACPI: done.\n");
return current;
}

@ -64,7 +64,7 @@ temp_ram_init_ret:
.global fsp_init_done
fsp_init_done:
/*
* We come here from FspInit with eax pointing to the HOB list.
* We come here from fsp_continue() with eax pointing to the HOB list.
* Save eax to esi temporarily.
*/
movl %eax, %esi

@ -56,8 +56,22 @@ void board_final_cleanup(void)
int x86_fsp_init(void)
{
if (!gd->arch.hob_list)
if (!gd->arch.hob_list) {
/*
* The first time we enter here, call fsp_init().
* Note the execution does not return to this function,
* instead it jumps to fsp_continue().
*/
fsp_init(CONFIG_FSP_TEMP_RAM_ADDR, BOOT_FULL_CONFIG, NULL);
} else {
/*
* The second time we enter here, adjust the size of malloc()
* pool before relocation. Given gd->malloc_base was adjusted
* after the call to board_init_f_mem() in arch/x86/cpu/start.S,
* we should fix up gd->malloc_limit here.
*/
gd->malloc_limit += CONFIG_FSP_SYS_MALLOC_F_LEN;
}
return 0;
}

@ -4,12 +4,10 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <fdtdec.h>
#include <spi.h>
#include <asm/errno.h>
#include <asm/mtrr.h>
#include <asm/sections.h>
DECLARE_GLOBAL_DATA_PTR;
@ -19,53 +17,6 @@ __weak ulong board_get_usable_ram_top(ulong total_size)
return gd->ram_size;
}
int calculate_relocation_address(void)
{
const ulong uboot_size = (uintptr_t)&__bss_end -
(uintptr_t)&__text_start;
ulong total_size;
ulong dest_addr;
ulong fdt_size = 0;
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
if (gd->fdt_blob)
fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
#endif
total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN +
CONFIG_SYS_STACK_SIZE + fdt_size;
dest_addr = board_get_usable_ram_top(total_size);
/*
* NOTE: All destination address are rounded down to 16-byte
* boundary to satisfy various worst-case alignment
* requirements
*/
dest_addr &= ~15;
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL)
/*
* If the device tree is sitting immediate above our image then we
* must relocate it. If it is embedded in the data section, then it
* will be relocated with other data.
*/
if (gd->fdt_blob) {
dest_addr -= fdt_size;
gd->new_fdt = (void *)dest_addr;
dest_addr &= ~15;
}
#endif
/* U-Boot is below the FDT */
dest_addr -= uboot_size;
dest_addr &= ~((1 << 12) - 1);
gd->relocaddr = dest_addr;
gd->reloc_off = dest_addr - (uintptr_t)&__text_start;
/* Stack is at the bottom, so it can grow down */
gd->start_addr_sp = dest_addr - CONFIG_SYS_MALLOC_LEN;
return 0;
}
int init_cache_f_r(void)
{
#if defined(CONFIG_X86_RESET_VECTOR) & !defined(CONFIG_HAVE_FSP)

@ -8,6 +8,7 @@
#include <asm/sfi.h>
#include <asm/mpspec.h>
#include <asm/tables.h>
#include <asm/acpi_table.h>
u8 table_compute_checksum(void *v, int len)
{
@ -51,4 +52,8 @@ void write_tables(void)
rom_table_end = write_mp_table(rom_table_end);
rom_table_end = ALIGN(rom_table_end, 1024);
#endif
#ifdef CONFIG_GENERATE_ACPI_TABLE
rom_table_end = write_acpi_tables(rom_table_end);
rom_table_end = ALIGN(rom_table_end, 1024);
#endif
}

@ -10,11 +10,12 @@
#include <netdev.h>
#include <smsc_lpc47m.h>
#define SERIAL_DEV PNP_DEV(0x2e, 4)
int board_early_init_f(void)
{
lpc47m_enable_serial(SERIAL_DEV, UART0_BASE, UART0_IRQ);
lpc47m_enable_serial(PNP_DEV(LPC47M_IO_PORT, LPC47M_SP1),
UART0_BASE, UART0_IRQ);
lpc47m_enable_kbc(PNP_DEV(LPC47M_IO_PORT, LPC47M_KBC),
KBD_IRQ, MSE_IRQ);
return 0;
}

@ -764,9 +764,6 @@ static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_OF_CONTROL
fdtdec_setup,
#endif
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
x86_fsp_init,
#endif
#ifdef CONFIG_TRACE
trace_early_init,
#endif
@ -775,6 +772,9 @@ static init_fnc_t init_sequence_f[] = {
/* TODO: can this go into arch_cpu_init()? */
probecpu,
#endif
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
x86_fsp_init,
#endif
arch_cpu_init, /* basic arch cpu dependent setup */
mark_bootstage,
initf_dm,

@ -47,23 +47,25 @@ machine. You can use devices, boot a kernel, etc.
Build Instructions
------------------
First choose a board that has EFI support and obtain an EFI implementation
for that board. It will be either 32-bit or 64-bit.
for that board. It will be either 32-bit or 64-bit. Alternatively, you can
opt for using QEMU [1] and the OVMF [2], as detailed below.
To build U-Boot as an EFI application (32-bit EFI required), enable
CONFIG_EFI and CONFIG_EFI_APP. The efi-x86 config is set up for this.
To build U-Boot as an EFI application (32-bit EFI required), enable CONFIG_EFI
and CONFIG_EFI_APP. The efi-x86 config (efi-x86_defconfig) is set up for this.
Just build U-Boot as normal, e.g.
To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust
an existing config to enable CONFIG_EFI, CONFIG_EFI_STUB and either
CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT.
make efi-x86_defconfig
make
Then build U-Boot as normal, e.g.
To build U-Boot as an EFI payload (32-bit or 64-bit EFI can be used), adjust an
existing config (like qemu-x86_defconfig) to enable CONFIG_EFI, CONFIG_EFI_STUB
and either CONFIG_EFI_STUB_32BIT or CONFIG_EFI_STUB_64BIT. All of these are
boolean Kconfig options. Then build U-Boot as normal, e.g.
make qemu-x86_defconfig
make menuconfig (or make xconfig if you prefer)
# change the settings as above
make
You will end up with one of these files:
You will end up with one of these files depending on what you build for:
u-boot-app.efi - U-Boot EFI application
u-boot-payload.efi - U-Boot EFI payload application
@ -71,8 +73,9 @@ You will end up with one of these files:
Trying it out
-------------
Qemu is an emulator and it can emulate an x86 machine. You can run the
payload with something like this:
QEMU is an emulator and it can emulate an x86 machine. Please make sure your
QEMU version is 2.3.0 or above to test this. You can run the payload with
something like this:
mkdir /tmp/efi
cp /path/to/u-boot*.efi /tmp/efi
@ -80,7 +83,8 @@ payload with something like this:
Add -nographic if you want to use the terminal for output. Once it starts
type 'fs0:u-boot-payload.efi' to run the payload or 'fs0:u-boot-app.efi' to
run the application. 'bios.bin' is the EFI 'BIOS'.
run the application. 'bios.bin' is the EFI 'BIOS'. Check [2] to obtain a
prebuilt EFI BIOS for QEMU or you can build one from source as well.
To try it on real hardware, put u-boot-app.efi on a suitable boot medium,
such as a USB stick. Then you can type something like this to start it:
@ -235,3 +239,6 @@ common/cmd_efi.c
Ben Stoltz, Simon Glass
Google, Inc
July 2015
[1] http://www.qemu.org
[2] http://www.tianocore.org/ovmf/

@ -245,10 +245,10 @@ this capability yet. The command is as follows:
# in the coreboot root directory
$ ./build/util/cbfstool/cbfstool build/coreboot.rom add-flat-binary \
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110015
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110000
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the
symbol address of _start (in arch/x86/cpu/start.S).
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE, which is the symbol address
of _x86boot_start (in arch/x86/cpu/start.S).
If you want to use ELF as the coreboot payload, change U-Boot configuration to
use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
@ -654,13 +654,13 @@ Use the device tree for configuration where possible.
For the microcode you can create a suitable device tree file using the
microcode tool:
./tools/microcode-tool -d microcode.dat create <model>
./tools/microcode-tool -d microcode.dat -m <model> create
or if you only have header files and not the full Intel microcode.dat database:
./tools/microcode-tool -H BAY_TRAIL_FSP_KIT/Microcode/M0130673322.h \
-H BAY_TRAIL_FSP_KIT/Microcode/M0130679901.h \
create all
-m all create
These are written to arch/x86/dts/microcode/ by default.

@ -34,9 +34,74 @@ under that bus.
Note that this is all done on a lazy basis, as needed, so until something is
touched on PCI (eg: a call to pci_find_devices()) it will not be probed.
PCI devices can appear in the device tree. If they do this serves to specify
the driver to use for the device. In this case they will be bound at
start-up.
PCI devices can appear in the flattened device tree. If they do this serves to
specify the driver to use for the device. In this case they will be bound at
first. Each PCI device node must have a compatible string list as well as a
<reg> property, as defined by the IEEE Std 1275-1994 PCI bus binding document
v2.1. Note we must describe PCI devices with the same bus hierarchy as the
hardware, otherwise driver model cannot detect the correct parent/children
relationship during PCI bus enumeration thus PCI devices won't be bound to
their drivers accordingly. A working example like below:
pci {
#address-cells = <3>;
#size-cells = <2>;
compatible = "pci-x86";
u-boot,dm-pre-reloc;
ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
0x01000000 0x0 0x2000 0x2000 0 0xe000>;
pcie@17,0 {
#address-cells = <3>;
#size-cells = <2>;
compatible = "pci-bridge";
u-boot,dm-pre-reloc;
reg = <0x0000b800 0x0 0x0 0x0 0x0>;
topcliff@0,0 {
#address-cells = <3>;
#size-cells = <2>;
compatible = "pci-bridge";
u-boot,dm-pre-reloc;
reg = <0x00010000 0x0 0x0 0x0 0x0>;
pciuart0: uart@a,1 {
compatible = "pci8086,8811.00",
"pci8086,8811",
"pciclass,070002",
"pciclass,0700",
"x86-uart";
u-boot,dm-pre-reloc;
reg = <0x00025100 0x0 0x0 0x0 0x0
0x01025110 0x0 0x0 0x0 0x0>;
......
};
......
};
};
......
};
In this example, the root PCI bus node is the "/pci" which matches "pci-x86"
driver. It has a subnode "pcie@17,0" with driver "pci-bridge". "pcie@17,0"
also has subnode "topcliff@0,0" which is a "pci-bridge" too. Under that bridge,
a PCI UART device "uart@a,1" is described. This exactly reflects the hardware
bus hierarchy: on the root PCI bus, there is a PCIe root port which connects
to a downstream device Topcliff chipset. Inside Topcliff chipset, it has a
PCIe-to-PCI bridge and all the chipset integrated devices like the PCI UART
device are on the PCI bus. Like other devices in the device tree, if we want
to bind PCI devices before relocation, "u-boot,dm-pre-reloc" must be declared
in each of these nodes.
If PCI devices are not listed in the device tree, U_BOOT_PCI_DEVICE can be used
to specify the driver to use for the device. The device tree takes precedence
over U_BOOT_PCI_DEVICE. Plese note with U_BOOT_PCI_DEVICE, only drivers with
DM_FLAG_PRE_RELOC will be bound before relocation. If neither device tree nor
U_BOOT_PCI_DEVICE is provided, the built-in driver (either pci_bridge_drv or
pci_generic_drv) will be used.
Sandbox

@ -226,17 +226,17 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
drv = dev->driver;
assert(drv);
/* Allocate private data if requested */
if (drv->priv_auto_alloc_size) {
/* Allocate private data if requested and not reentered */
if (drv->priv_auto_alloc_size && !dev->priv) {
dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
if (!dev->priv) {
ret = -ENOMEM;
goto fail;
}
}
/* Allocate private data if requested */
/* Allocate private data if requested and not reentered */
size = dev->uclass->uc_drv->per_device_auto_alloc_size;
if (size) {
if (size && !dev->uclass_priv) {
dev->uclass_priv = calloc(1, size);
if (!dev->uclass_priv) {
ret = -ENOMEM;
@ -251,7 +251,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
size = dev->parent->uclass->uc_drv->
per_child_auto_alloc_size;
}
if (size) {
if (size && !dev->parent_priv) {
dev->parent_priv = alloc_priv(size, drv->flags);
if (!dev->parent_priv) {
ret = -ENOMEM;
@ -264,6 +264,15 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
ret = device_probe(dev->parent);
if (ret)
goto fail;
/*
* The device might have already been probed during
* the call to device_probe() on its parent device
* (e.g. PCI bridge devices). Test the flags again
* so that we don't mess up the device.
*/
if (dev->flags & DM_FLAG_ACTIVATED)
return 0;
}
seq = uclass_resolve_seq(dev);

@ -75,7 +75,7 @@ static int gpio_ich6_get_base(unsigned long base)
/* Is the device present? */
tmpword = x86_pci_read_config16(pci_dev, PCI_VENDOR_ID);
if (tmpword != PCI_VENDOR_ID_INTEL) {
debug("%s: wrong VendorID\n", __func__);
debug("%s: wrong VendorID %x\n", __func__, tmpword);
return -ENODEV;
}
@ -144,7 +144,7 @@ static int gpio_ich6_get_base(unsigned long base)
* 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.
*/
return tmplong & 0xfffc;
return tmplong & 1 ? tmplong & ~3 : tmplong & ~15;
}
static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
@ -324,7 +324,7 @@ int gpio_ich6_pinctrl_init(void)
debug("%s: io-base offset not present\n", __func__);
} else {
iobase = gpio_ich6_get_base(iobase_offset);
if (iobase < 0) {
if (IS_ERR_VALUE(iobase)) {
debug("%s: invalid IOBASE address (%08x)\n", __func__,
iobase);
return -EINVAL;
@ -410,7 +410,7 @@ static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
{
struct ich6_bank_priv *bank = dev_get_priv(dev);
return _ich6_gpio_set_direction(inl(bank->io_sel), offset, 0);
return _ich6_gpio_set_direction(bank->io_sel, offset, 0);
}
static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
@ -419,7 +419,7 @@ static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
int ret;
struct ich6_bank_priv *bank = dev_get_priv(dev);
ret = _ich6_gpio_set_direction(inl(bank->io_sel), offset, 1);
ret = _ich6_gpio_set_direction(bank->io_sel, offset, 1);
if (ret)
return ret;

@ -10,49 +10,30 @@
/* includes */
#include <common.h>
#include <linux/compiler.h>
#ifdef CONFIG_USE_CPCIDVI
extern u8 gt_cpcidvi_in8(u32 offset);
extern void gt_cpcidvi_out8(u32 offset, u8 data);
#define in8(a) gt_cpcidvi_in8(a)
#define out8(a, b) gt_cpcidvi_out8(a, b)
#endif
#include <asm/io.h>
#include <i8042.h>
/* defines */
#define in8(p) inb(p)
#define out8(p, v) outb(v, p)
#ifdef CONFIG_CONSOLE_CURSOR
extern void console_cursor(int state);
static int blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
static int blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
static int cursor_state;
#endif
/* locals */
static int kbd_input = -1; /* no input yet */
static int kbd_mapping = KBD_US; /* default US keyboard */
static int kbd_flags = NORMAL; /* after reset */
static int kbd_state; /* unshift code */
static void kbd_conv_char(unsigned char scan_code);
static void kbd_led_set(void);
static void kbd_normal(unsigned char scan_code);
static void kbd_shift(unsigned char scan_code);
static void kbd_ctrl(unsigned char scan_code);
static void kbd_num(unsigned char scan_code);
static void kbd_caps(unsigned char scan_code);
static void kbd_scroll(unsigned char scan_code);
static void kbd_alt(unsigned char scan_code);
static int kbd_input_empty(void);
static int kbd_reset(void);
static int kbd_input = -1; /* no input yet */
static int kbd_mapping = KBD_US; /* default US keyboard */
static int kbd_flags = NORMAL; /* after reset */
static int kbd_state; /* unshift code */
static unsigned char kbd_fct_map[144] = {
/* kbd_fct_map table for scan code */
0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */
0, AS, AS, AS, AS, AS, AS, AS, /* scan 00-07 */
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 08-0F */
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */
AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */
AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */
@ -74,8 +55,8 @@ static unsigned char kbd_fct_map[144] = {
static unsigned char kbd_key_map[2][5][144] = {
{ /* US keyboard */
{ /* unshift code */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 08-0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
@ -94,8 +75,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* shift code */
0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */
'&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */
0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 00-07 */
'&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 08-0F */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */
'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */
@ -114,8 +95,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* control code */
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
@ -134,8 +115,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
},
{ /* non numeric code */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
'7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 08-0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */
'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */
@ -154,30 +135,30 @@ static unsigned char kbd_key_map[2][5][144] = {
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* right alt mode - not used in US keyboard */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 08-0F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
}
},
{ /* german keyboard */
{ /* German keyboard */
{ /* unshift code */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
@ -196,8 +177,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* shift code */
0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */
'/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */
0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 00-07 */
'/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 08-0F */
'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */
'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */
'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */
@ -216,8 +197,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* control code */
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */
0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 08-0F */
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */
0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */
0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */
@ -236,8 +217,8 @@ static unsigned char kbd_key_map[2][5][144] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
},
{ /* non numeric code */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */
0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 00-07 */
'7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */
'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */
@ -255,23 +236,23 @@ static unsigned char kbd_key_map[2][5][144] = {
'\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */
0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */
},
{ /* Right alt mode - is used in German keyboard */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */
'{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */
'@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */
0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */
0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */
{ /* right alt mode - is used in German keyboard */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
'{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 08-0F */
'@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50-57 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */
}
@ -298,167 +279,113 @@ static unsigned char ext_key_map[] = {
0x00 /* map end */
};
/******************************************************************************/
static int kbd_controller_present(void)
static int kbd_input_empty(void)
{
return in8(I8042_STATUS_REG) != 0xff;
}
int kbd_timeout = KBD_TIMEOUT * 1000;
/*
* Implement a weak default function for boards that optionally
* need to skip the i8042 initialization.
*/
int __weak board_i8042_skip(void)
{
/* As default, don't skip */
return 0;
while ((in8(I8042_STS_REG) & STATUS_IBF) && kbd_timeout--)
udelay(1);
return kbd_timeout != -1;
}
void i8042_flush(void)
static int kbd_output_full(void)
{
int timeout;
int kbd_timeout = KBD_TIMEOUT * 1000;
/*
* The delay is to give the keyboard controller some time to fill the
* next byte.
*/
while (1) {
timeout = 100; /* wait for no longer than 100us */
while (timeout > 0 && !(in8(I8042_STATUS_REG) & 0x01)) {
udelay(1);
timeout--;
}
while (((in8(I8042_STS_REG) & STATUS_OBF) == 0) && kbd_timeout--)
udelay(1);
/* Try to pull next byte if not timeout. */
if (in8(I8042_STATUS_REG) & 0x01)
in8(I8042_DATA_REG);
else
break;
}
return kbd_timeout != -1;
}
int i8042_disable(void)
static void kbd_led_set(void)
{
if (kbd_input_empty() == 0)
return -1;
/* Disable keyboard */
out8(I8042_COMMAND_REG, 0xad);
if (kbd_input_empty() == 0)
return -1;
return 0;
kbd_input_empty();
out8(I8042_DATA_REG, CMD_SET_KBD_LED);
kbd_input_empty();
out8(I8042_DATA_REG, (kbd_flags & 0x7));
}
/*******************************************************************************
*
* i8042_kbd_init - reset keyboard and init state flags
*/
int i8042_kbd_init(void)
static void kbd_normal(unsigned char scan_code)
{
int keymap, try;
char *penv;
if (!kbd_controller_present() || board_i8042_skip())
return -1;
unsigned char chr;
#ifdef CONFIG_USE_CPCIDVI
penv = getenv("console");
if (penv != NULL) {
if (strncmp(penv, "serial", 7) == 0)
return -1;
}
#endif
/* Init keyboard device (default US layout) */
keymap = KBD_US;
penv = getenv("keymap");
if (penv != NULL) {
if (strncmp(penv, "de", 3) == 0)
keymap = KBD_GER;
}
if ((kbd_flags & BRK) == NORMAL) {
chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
if ((chr == 0xff) || (chr == 0x00))
return;
for (try = 0; try < KBD_RESET_TRIES; try++) {
if (kbd_reset() == 0) {
kbd_mapping = keymap;
kbd_flags = NORMAL;
kbd_state = 0;
kbd_led_set();
return 0;
/* if caps lock convert upper to lower */
if (((kbd_flags & CAPS) == CAPS) &&
(chr >= 'a' && chr <= 'z')) {
chr -= 'a' - 'A';
}
kbd_input = chr;
}
return -1;
}
/*******************************************************************************
*
* i8042_tstc - test if keyboard input is available
* option: cursor blinking if called in a loop
*/
int i8042_tstc(struct stdio_dev *dev)
static void kbd_shift(unsigned char scan_code)
{
unsigned char scan_code = 0;
#ifdef CONFIG_CONSOLE_CURSOR
if (--blinkCount == 0) {
cursor_state ^= 1;
console_cursor(cursor_state);
blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
udelay(10);
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~SHIFT);
} else {
kbd_state = SH;
kbd_flags |= SHIFT;
}
#endif
}
if ((in8(I8042_STATUS_REG) & 0x01) == 0) {
return 0;
static void kbd_ctrl(unsigned char scan_code)
{
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~CTRL);
} else {
scan_code = in8(I8042_DATA_REG);
if (scan_code == 0xfa)
return 0;
kbd_conv_char(scan_code);
if (kbd_input != -1)
return 1;
kbd_state = CN;
kbd_flags |= CTRL;
}
return 0;
}
/*******************************************************************************
*
* i8042_getc - wait till keyboard input is available
* option: turn on/off cursor while waiting
*/
int i8042_getc(struct stdio_dev *dev)
static void kbd_num(unsigned char scan_code)
{
int ret_chr;
unsigned char scan_code;
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= NUM;
kbd_state = (kbd_flags & NUM) ? AS : NM;
kbd_led_set();
}
}
while (kbd_input == -1) {
while ((in8(I8042_STATUS_REG) & 0x01) == 0) {
#ifdef CONFIG_CONSOLE_CURSOR
if (--blinkCount == 0) {
cursor_state ^= 1;
console_cursor(cursor_state);
blinkCount = CONFIG_SYS_CONSOLE_BLINK_COUNT;
}
udelay(10);
#endif
}
scan_code = in8(I8042_DATA_REG);
if (scan_code != 0xfa)
kbd_conv_char (scan_code);
static void kbd_alt(unsigned char scan_code)
{
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~ALT);
} else {
kbd_state = AK;
kbd_flags &= ALT;
}
ret_chr = kbd_input;
kbd_input = -1;
return ret_chr;
}
static void kbd_caps(unsigned char scan_code)
{
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= CAPS;
kbd_led_set();
}
}
/******************************************************************************/
static void kbd_scroll(unsigned char scan_code)
{
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= STP;
kbd_led_set();
if (kbd_flags & STP)
kbd_input = 0x13;
else
kbd_input = 0x11;
}
}
static void kbd_conv_char(unsigned char scan_code)
{
@ -475,8 +402,8 @@ static void kbd_conv_char(unsigned char scan_code)
if ((scan_code == 0xe1) || (kbd_flags & E1)) {
if (scan_code == 0xe1) {
kbd_flags ^= BRK; /* reset the break flag */
kbd_flags ^= E1; /* bitwise EXOR with E1 flag */
kbd_flags ^= BRK; /* reset the break flag */
kbd_flags ^= E1; /* bitwise EXOR with E1 flag */
}
return;
}
@ -511,203 +438,218 @@ static void kbd_conv_char(unsigned char scan_code)
case NM:
kbd_num(scan_code);
break;
case AK:
kbd_alt(scan_code);
break;
case CP:
kbd_caps(scan_code);
break;
case ST:
kbd_scroll(scan_code);
break;
case AK:
kbd_alt(scan_code);
break;
}
return;
}
/******************************************************************************/
static void kbd_normal(unsigned char scan_code)
static int kbd_reset(void)
{
unsigned char chr;
u8 config;
if ((kbd_flags & BRK) == NORMAL) {
chr = kbd_key_map[kbd_mapping][kbd_state][scan_code];
if ((chr == 0xff) || (chr == 0x00))
return;
/* controller self test */
if (kbd_input_empty() == 0)
return -1;
out8(I8042_CMD_REG, CMD_SELF_TEST);
if (kbd_output_full() == 0)
return -1;
if (in8(I8042_DATA_REG) != KBC_TEST_OK)
return -1;
/* if caps lock convert upper to lower */
if (((kbd_flags & CAPS) == CAPS) &&
(chr >= 'a' && chr <= 'z')) {
chr -= 'a' - 'A';
}
kbd_input = chr;
}
}
/* keyboard reset */
if (kbd_input_empty() == 0)
return -1;
out8(I8042_DATA_REG, CMD_RESET_KBD);
if (kbd_output_full() == 0)
return -1;
if (in8(I8042_DATA_REG) != KBD_ACK)
return -1;
if (kbd_output_full() == 0)
return -1;
if (in8(I8042_DATA_REG) != KBD_POR)
return -1;
/* set AT translation and disable irq */
if (kbd_input_empty() == 0)
return -1;
out8(I8042_CMD_REG, CMD_RD_CONFIG);
if (kbd_output_full() == 0)
return -1;
config = in8(I8042_DATA_REG);
config |= CONFIG_AT_TRANS;
config &= ~(CONFIG_KIRQ_EN | CONFIG_MIRQ_EN);
if (kbd_input_empty() == 0)
return -1;
out8(I8042_CMD_REG, CMD_WR_CONFIG);
if (kbd_input_empty() == 0)
return -1;
out8(I8042_DATA_REG, config);
/******************************************************************************/
/* enable keyboard */
if (kbd_input_empty() == 0)
return -1;
out8(I8042_CMD_REG, CMD_KBD_EN);
if (kbd_input_empty() == 0)
return -1;
static void kbd_shift(unsigned char scan_code)
{
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~SHIFT);
} else {
kbd_state = SH;
kbd_flags |= SHIFT;
}
return 0;
}
/******************************************************************************/
static void kbd_ctrl(unsigned char scan_code)
static int kbd_controller_present(void)
{
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~CTRL);
} else {
kbd_state = CN;
kbd_flags |= CTRL;
}
return in8(I8042_STS_REG) != 0xff;
}
/******************************************************************************/
static void kbd_caps(unsigned char scan_code)
/*
* Implement a weak default function for boards that optionally
* need to skip the i8042 initialization.
*/
int __weak board_i8042_skip(void)
{
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= CAPS;
kbd_led_set(); /* update keyboard LED */
}
/* As default, don't skip */
return 0;
}
/******************************************************************************/
static void kbd_num(unsigned char scan_code)
void i8042_flush(void)
{
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= NUM;
kbd_state = (kbd_flags & NUM) ? AS : NM;
kbd_led_set(); /* update keyboard LED */
}
}
int timeout;
/******************************************************************************/
/*
* The delay is to give the keyboard controller some time
* to fill the next byte.
*/
while (1) {
timeout = 100; /* wait for no longer than 100us */
while (timeout > 0 && !(in8(I8042_STS_REG) & STATUS_OBF)) {
udelay(1);
timeout--;
}
static void kbd_scroll(unsigned char scan_code)
{
if ((kbd_flags & BRK) == NORMAL) {
kbd_flags ^= STP;
kbd_led_set(); /* update keyboard LED */
if (kbd_flags & STP)
kbd_input = 0x13;
/* Try to pull next byte if not timeout */
if (in8(I8042_STS_REG) & STATUS_OBF)
in8(I8042_DATA_REG);
else
kbd_input = 0x11;
break;
}
}
/******************************************************************************/
static void kbd_alt(unsigned char scan_code)
int i8042_disable(void)
{
if ((kbd_flags & BRK) == BRK) {
kbd_state = AS;
kbd_flags &= (~ALT);
} else {
kbd_state = AK;
kbd_flags &= ALT;
}
}
if (kbd_input_empty() == 0)
return -1;
/* Disable keyboard */
out8(I8042_CMD_REG, CMD_KBD_DIS);
/******************************************************************************/
if (kbd_input_empty() == 0)
return -1;
static void kbd_led_set(void)
{
kbd_input_empty();
out8(I8042_DATA_REG, 0xed); /* SET LED command */
kbd_input_empty();
out8(I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */
return 0;
}
/******************************************************************************/
static int kbd_input_empty(void)
/* i8042_kbd_init - reset keyboard and init state flags */
int i8042_kbd_init(void)
{
int kbdTimeout = KBD_TIMEOUT * 1000;
while ((in8(I8042_STATUS_REG) & I8042_STATUS_IN_DATA) && kbdTimeout--)
udelay(1);
int keymap, try;
char *penv;
return kbdTimeout != -1;
}
if (!kbd_controller_present() || board_i8042_skip()) {
debug("i8042 keyboard controller is not present\n");
return -1;
}
/******************************************************************************/
/* Init keyboard device (default US layout) */
keymap = KBD_US;
penv = getenv("keymap");
if (penv != NULL) {
if (strncmp(penv, "de", 3) == 0)
keymap = KBD_GER;
}
static int wait_until_kbd_output_full(void)
{
int kbdTimeout = KBD_TIMEOUT * 1000;
for (try = 0; try < KBD_RESET_TRIES; try++) {
if (kbd_reset() == 0) {
kbd_mapping = keymap;
kbd_flags = NORMAL;
kbd_state = 0;
kbd_led_set();
while (((in8(I8042_STATUS_REG) & 0x01) == 0) && kbdTimeout--)
udelay(1);
return 0;
}
}
return kbdTimeout != -1;
return -1;
}
/******************************************************************************/
static int kbd_reset(void)
/*
* i8042_tstc - test if keyboard input is available
*
* option: cursor blinking if called in a loop
*/
int i8042_tstc(struct stdio_dev *dev)
{
/* KB Reset */
if (kbd_input_empty() == 0)
return -1;
out8(I8042_DATA_REG, 0xff);
if (wait_until_kbd_output_full() == 0)
return -1;
if (in8(I8042_DATA_REG) != 0xfa) /* ACK */
return -1;
if (wait_until_kbd_output_full() == 0)
return -1;
if (in8(I8042_DATA_REG) != 0xaa) /* Test Pass*/
return -1;
if (kbd_input_empty() == 0)
return -1;
unsigned char scan_code = 0;
/* Set KBC mode */
out8(I8042_COMMAND_REG, 0x60);
#ifdef CONFIG_CONSOLE_CURSOR
if (--blink_count == 0) {
cursor_state ^= 1;
console_cursor(cursor_state);
blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
udelay(10);
}
#endif
if (kbd_input_empty() == 0)
return -1;
if ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
return 0;
} else {
scan_code = in8(I8042_DATA_REG);
if (scan_code == 0xfa)
return 0;
out8(I8042_DATA_REG, 0x45);
kbd_conv_char(scan_code);
if (kbd_input_empty() == 0)
return -1;
if (kbd_input != -1)
return 1;
}
/* Enable Keyboard */
out8(I8042_COMMAND_REG, 0xae);
if (kbd_input_empty() == 0)
return -1;
return 0;
}
out8(I8042_COMMAND_REG, 0x60);
if (kbd_input_empty() == 0)
return -1;
/*
* i8042_getc - wait till keyboard input is available
*
* option: turn on/off cursor while waiting
*/
int i8042_getc(struct stdio_dev *dev)
{
int ret_chr;
unsigned char scan_code;
out8(I8042_DATA_REG, 0xf4);
if (kbd_input_empty() == 0)
return -1;
while (kbd_input == -1) {
while ((in8(I8042_STS_REG) & STATUS_OBF) == 0) {
#ifdef CONFIG_CONSOLE_CURSOR
if (--blink_count == 0) {
cursor_state ^= 1;
console_cursor(cursor_state);
blink_count = CONFIG_SYS_CONSOLE_BLINK_COUNT;
}
udelay(10);
#endif
}
scan_code = in8(I8042_DATA_REG);
if (scan_code != 0xfa)
kbd_conv_char(scan_code);
}
ret_chr = kbd_input;
kbd_input = -1;
return 0;
return ret_chr;
}

@ -22,7 +22,7 @@ static void pnp_exit_conf_state(u16 dev)
outb(0xaa, port);
}
void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq)
void lpc47m_enable_serial(uint dev, uint iobase, uint irq)
{
pnp_enter_conf_state(dev);
pnp_set_logical_device(dev);
@ -32,3 +32,14 @@ void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq)
pnp_set_enable(dev, 1);
pnp_exit_conf_state(dev);
}
void lpc47m_enable_kbc(uint dev, uint irq0, uint irq1)
{
pnp_enter_conf_state(dev);
pnp_set_logical_device(dev);
pnp_set_enable(dev, 0);
pnp_set_irq(dev, PNP_IDX_IRQ0, irq0);
pnp_set_irq(dev, PNP_IDX_IRQ1, irq1);
pnp_set_enable(dev, 1);
pnp_exit_conf_state(dev);
}

@ -4978,8 +4978,8 @@ e1000_configure_tx(struct e1000_hw *hw)
unsigned long tipg, tarc;
uint32_t ipgr1, ipgr2;
E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base & 0xffffffff);
E1000_WRITE_REG(hw, TDBAH, (unsigned long)tx_base >> 32);
E1000_WRITE_REG(hw, TDBAL, lower_32_bits((unsigned long)tx_base));
E1000_WRITE_REG(hw, TDBAH, upper_32_bits((unsigned long)tx_base));
E1000_WRITE_REG(hw, TDLEN, 128);
@ -5103,6 +5103,7 @@ e1000_configure_rx(struct e1000_hw *hw)
{
unsigned long rctl, ctrl_ext;
rx_tail = 0;
/* make sure receives are disabled while setting up the descriptors */
rctl = E1000_READ_REG(hw, RCTL);
E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
@ -5122,8 +5123,8 @@ e1000_configure_rx(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw);
}
/* Setup the Base and Length of the Rx Descriptor Ring */
E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base & 0xffffffff);
E1000_WRITE_REG(hw, RDBAH, (unsigned long)rx_base >> 32);
E1000_WRITE_REG(hw, RDBAL, lower_32_bits((unsigned long)rx_base));
E1000_WRITE_REG(hw, RDBAH, upper_32_bits((unsigned long)rx_base));
E1000_WRITE_REG(hw, RDLEN, 128);

@ -14,6 +14,9 @@
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/device-internal.h>
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
#include <asm/fsp/fsp_support.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -461,6 +464,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
int n_ents;
int ret;
char name[30], *str;
bool bridge;
*devp = NULL;
@ -480,6 +484,17 @@ static int pci_find_and_bind_driver(struct udevice *parent,
continue;
drv = entry->driver;
/*
* In the pre-relocation phase, we only bind devices
* whose driver has the DM_FLAG_PRE_RELOC set, to save
* precious memory space as on some platforms as that
* space is pretty limited (ie: using Cache As RAM).
*/
if (!(gd->flags & GD_FLG_RELOC) &&
!(drv->flags & DM_FLAG_PRE_RELOC))
return 0;
/*
* We could pass the descriptor to the driver as
* platdata (instead of NULL) and allow its bind()
@ -499,14 +514,23 @@ static int pci_find_and_bind_driver(struct udevice *parent,
}
}
bridge = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI;
/*
* In the pre-relocation phase, we only bind bridge devices to save
* precious memory space as on some platforms as that space is pretty
* limited (ie: using Cache As RAM).
*/
if (!(gd->flags & GD_FLG_RELOC) && !bridge)
return 0;
/* Bind a generic driver so that the device can be used */
sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
PCI_FUNC(bdf));
str = strdup(name);
if (!str)
return -ENOMEM;
drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
"pci_generic_drv";
drv = bridge ? "pci_bridge_drv" : "pci_generic_drv";
ret = device_bind_driver(parent, drv, str, devp);
if (ret) {
debug("%s: Failed to bind generic driver: %d", __func__, ret);
@ -589,11 +613,13 @@ int pci_bind_bus_devices(struct udevice *bus)
return ret;
/* Update the platform data */
pplat = dev_get_parent_platdata(dev);
pplat->devfn = PCI_MASK_BUS(bdf);
pplat->vendor = vendor;
pplat->device = device;
pplat->class = class;
if (dev) {
pplat = dev_get_parent_platdata(dev);
pplat->devfn = PCI_MASK_BUS(bdf);
pplat->vendor = vendor;
pplat->device = device;
pplat->class = class;
}
}
return 0;
@ -606,6 +632,13 @@ error:
static int pci_uclass_post_bind(struct udevice *bus)
{
/*
* If there is no pci device listed in the device tree,
* don't bother scanning the device tree.
*/
if (bus->of_offset == -1)
return 0;
/*
* Scan the device tree for devices. This does not probe the PCI bus,
* as this is not permitted while binding. It just finds devices
* mentioned in the device tree.
@ -717,10 +750,6 @@ static int pci_uclass_post_probe(struct udevice *bus)
{
int ret;
/* Don't scan buses before relocation */
if (!(gd->flags & GD_FLG_RELOC))
return 0;
debug("%s: probing bus %d\n", __func__, bus->seq);
ret = pci_bind_bus_devices(bus);
if (ret)
@ -730,6 +759,24 @@ static int pci_uclass_post_probe(struct udevice *bus)
ret = pci_auto_config_devices(bus);
#endif
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP)
/*
* Per Intel FSP specification, we should call FSP notify API to
* inform FSP that PCI enumeration has been done so that FSP will
* do any necessary initialization as required by the chipset's
* BIOS Writer's Guide (BWG).
*
* Unfortunately we have to put this call here as with driver model,
* the enumeration is all done on a lazy basis as needed, so until
* something is touched on PCI it won't happen.
*
* Note we only call this 1) after U-Boot is relocated, and 2)
* root bus has finished probing.
*/
if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0))
ret = fsp_init_phase_pci();
#endif
return ret < 0 ? ret : 0;
}
@ -754,8 +801,8 @@ static int pci_uclass_child_post_bind(struct udevice *dev)
if (ret != -ENOENT)
return -EINVAL;
} else {
/* extract the bdf from fdt_pci_addr */
pplat->devfn = addr.phys_hi & 0xffff00;
/* extract the devfn from fdt_pci_addr */
pplat->devfn = addr.phys_hi & 0xff00;
}
return 0;

@ -187,7 +187,7 @@ int pci_rom_load(struct pci_rom_header *rom_header,
return 0;
}
static struct vbe_mode_info mode_info;
struct vbe_mode_info mode_info;
int vbe_get_video_info(struct graphic_device *gdev)
{
@ -232,7 +232,6 @@ int vbe_get_video_info(struct graphic_device *gdev)
void setup_video(struct screen_info *screen_info)
{
#ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
struct vesa_mode_info *vesa = &mode_info.vesa;
/* Sanity test on VESA parameters */
@ -258,7 +257,6 @@ void setup_video(struct screen_info *screen_info)
screen_info->blue_pos = vesa->blue_mask_pos;
screen_info->rsvd_size = vesa->reserved_mask_size;
screen_info->rsvd_pos = vesa->reserved_mask_pos;
#endif
}
int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)

@ -2247,16 +2247,17 @@ __weak int board_video_skip(void)
int drv_video_init(void)
{
int skip_dev_init;
struct stdio_dev console_dev;
bool have_keyboard;
bool __maybe_unused keyboard_ok = false;
/* Check if video initialization should be skipped */
if (board_video_skip())
return 0;
/* Init video chip - returns with framebuffer cleared */
skip_dev_init = (video_init() == -1);
if (video_init() == -1)
return 0;
if (board_cfb_skip())
return 0;
@ -2272,11 +2273,9 @@ int drv_video_init(void)
if (have_keyboard) {
debug("KBD: Keyboard init ...\n");
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
keyboard_ok = !(VIDEO_KBD_INIT_FCT == -1);
#endif
}
if (skip_dev_init)
return 0;
/* Init vga device */
memset(&console_dev, 0, sizeof(console_dev));
@ -2287,7 +2286,7 @@ int drv_video_init(void)
console_dev.puts = video_puts; /* 'puts' function */
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
if (have_keyboard) {
if (have_keyboard && keyboard_ok) {
/* Also init console device */
console_dev.flags |= DEV_FLAGS_INPUT;
console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */

@ -9,6 +9,7 @@
#include <common.h>
#include <asm/arch/tables.h>
#include <asm/arch/sysinfo.h>
#include <vbe.h>
#include <video_fb.h>
#include "videomodes.h"
@ -17,6 +18,26 @@
*/
GraphicDevice ctfb;
static void save_vesa_mode(void)
{
struct vesa_mode_info *vesa = &mode_info.vesa;
struct cb_framebuffer *fb = lib_sysinfo.framebuffer;
vesa->x_resolution = fb->x_resolution;
vesa->y_resolution = fb->y_resolution;
vesa->bits_per_pixel = fb->bits_per_pixel;
vesa->bytes_per_scanline = fb->bytes_per_line;
vesa->phys_base_ptr = fb->physical_address;
vesa->red_mask_size = fb->red_mask_size;
vesa->red_mask_pos = fb->red_mask_pos;
vesa->green_mask_size = fb->green_mask_size;
vesa->green_mask_pos = fb->green_mask_pos;
vesa->blue_mask_size = fb->blue_mask_size;
vesa->blue_mask_pos = fb->blue_mask_pos;
vesa->reserved_mask_size = fb->reserved_mask_size;
vesa->reserved_mask_pos = fb->reserved_mask_pos;
}
static int parse_coreboot_table_fb(GraphicDevice *gdev)
{
struct cb_framebuffer *fb = lib_sysinfo.framebuffer;
@ -81,5 +102,8 @@ void *video_hw_init(void)
memset((void *)gdev->pciBase, 0,
gdev->winSizeX * gdev->winSizeY * gdev->gdfBytesPP);
/* Initialize vesa_mode_info structure */
save_vesa_mode();
return (void *)gdev;
}

@ -256,9 +256,6 @@ struct ctfb_chips_properties {
static const struct ctfb_chips_properties chips[] = {
{PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
#ifdef CONFIG_USE_CPCIDVI
{PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220},
#endif
{PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220}, /* NOT TESTED */
{0, 0, 0, 0, 0, 0, 0, 0, 0} /* Terminator */
};
@ -944,9 +941,6 @@ SetDrawingEngine (int bits_per_pixel)
*/
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
#ifdef CONFIG_USE_CPCIDVI
{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030},
#endif
{}
};
@ -1111,22 +1105,7 @@ video_hw_init (void)
pGD->cprBase = pci_mem_base; /* Dummy */
/* set up Hardware */
#ifdef CONFIG_USE_CPCIDVI
if (device_id == PCI_DEVICE_ID_CT_69030) {
ctWrite (CT_MSR_W_O, 0x0b);
ctWrite (0x3cd, 0x13);
ctWrite_i (CT_FP_O, 0x02, 0x00);
ctWrite_i (CT_FP_O, 0x05, 0x00);
ctWrite_i (CT_FP_O, 0x06, 0x00);
ctWrite (0x3c2, 0x0b);
ctWrite_i (CT_FP_O, 0x02, 0x10);
ctWrite_i (CT_FP_O, 0x01, 0x09);
} else {
ctWrite (CT_MSR_W_O, 0x01);
}
#else
ctWrite (CT_MSR_W_O, 0x01);
#endif
/* set the extended Registers */
ctLoadRegs (CT_XR_O, xreg);

@ -16,7 +16,6 @@
#define CONFIG_SYS_MONITOR_LEN (1 << 20)
#define CONFIG_ARCH_MISC_INIT
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_PCI_PNP

@ -31,7 +31,6 @@
#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
#define CONFIG_PCI_IO_SIZE 0xe000
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_PCI_PNP
@ -54,9 +53,6 @@
#define CONFIG_PCH_GBE
#define CONFIG_PHYLIB
/* TunnelCreek IGD support */
#define CONFIG_VGA_AS_SINGLE_DEVICE
/* Environment configuration */
#define CONFIG_ENV_SECT_SIZE 0x1000
#define CONFIG_ENV_OFFSET 0

@ -19,7 +19,6 @@
#define CONFIG_SMSC_LPC47M
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
#define CONFIG_SYS_EARLY_PCI_INIT
#define CONFIG_PCI_PNP
#define CONFIG_RTL8169

@ -28,7 +28,6 @@
#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
#define CONFIG_PCI_IO_SIZE 0xe000
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
#define CONFIG_PCI_PNP
#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga\0" \

@ -87,7 +87,9 @@
#define CONFIG_ISO_PARTITION /* Experimental */
#define CONFIG_CMD_PART
#ifdef CONFIG_SYS_COREBOOT
#define CONFIG_CMD_CBFS
#endif
#define CONFIG_CMD_EXT4
#define CONFIG_CMD_EXT4_WRITE
#define CONFIG_PARTITION_UUIDS
@ -190,6 +192,7 @@
* PCI configuration
*/
#define CONFIG_PCI
#define CONFIG_PCI_CONFIG_HOST_BRIDGE
/*-----------------------------------------------------------------------
* USB configuration

@ -10,52 +10,67 @@
#ifndef _I8042_H_
#define _I8042_H_
#ifdef __I386__
#include <common.h>
#include <asm/io.h>
#define in8(p) inb(p)
#define out8(p,v) outb(v,p)
#endif
/* defines */
#define I8042_DATA_REG (CONFIG_SYS_ISA_IO + 0x0060) /* keyboard i/o buffer */
#define I8042_STATUS_REG (CONFIG_SYS_ISA_IO + 0x0064) /* keyboard status read */
#define I8042_COMMAND_REG (CONFIG_SYS_ISA_IO + 0x0064) /* keyboard ctrl write */
enum {
/* Output register (I8042_DATA_REG) has data for system */
I8042_STATUS_OUT_DATA = 1 << 0,
I8042_STATUS_IN_DATA = 1 << 1,
};
#define KBD_US 0 /* default US layout */
#define KBD_GER 1 /* german layout */
#define KBD_TIMEOUT 1000 /* 1 sec */
#define KBD_RESET_TRIES 3
#define AS 0 /* normal character index */
#define SH 1 /* shift index */
#define CN 2 /* control index */
#define NM 3 /* numeric lock index */
#define AK 4 /* right alt key */
#define CP 5 /* capslock index */
#define ST 6 /* stop output index */
#define EX 7 /* extended code index */
#define ES 8 /* escape and extended code index */
#define NORMAL 0x0000 /* normal key */
#define STP 0x0001 /* scroll lock stop output*/
#define NUM 0x0002 /* numeric lock */
#define CAPS 0x0004 /* capslock */
#define SHIFT 0x0008 /* shift */
#define CTRL 0x0010 /* control*/
#define EXT 0x0020 /* extended scan code 0xe0 */
#define ESC 0x0040 /* escape key press */
#define E1 0x0080 /* extended scan code 0xe1 */
#define BRK 0x0100 /* make break flag for keyboard */
#define ALT 0x0200 /* right alt */
#define I8042_DATA_REG 0x60 /* keyboard i/o buffer */
#define I8042_STS_REG 0x64 /* keyboard status read */
#define I8042_CMD_REG 0x64 /* keyboard ctrl write */
/* Status register bit defines */
#define STATUS_OBF (1 << 0)
#define STATUS_IBF (1 << 1)
/* Configuration byte bit defines */
#define CONFIG_KIRQ_EN (1 << 0)
#define CONFIG_MIRQ_EN (1 << 1)
#define CONFIG_SET_BIST (1 << 2)
#define CONFIG_KCLK_DIS (1 << 4)
#define CONFIG_MCLK_DIS (1 << 5)
#define CONFIG_AT_TRANS (1 << 6)
/* i8042 commands */
#define CMD_RD_CONFIG 0x20 /* read configuration byte */
#define CMD_WR_CONFIG 0x60 /* write configuration byte */
#define CMD_SELF_TEST 0xaa /* controller self-test */
#define CMD_KBD_DIS 0xad /* keyboard disable */
#define CMD_KBD_EN 0xae /* keyboard enable */
#define CMD_SET_KBD_LED 0xed /* set keyboard led */
#define CMD_RESET_KBD 0xff /* reset keyboard */
/* i8042 command result */
#define KBC_TEST_OK 0x55
#define KBD_ACK 0xfa
#define KBD_POR 0xaa
/* keyboard scan codes */
#define KBD_US 0 /* default US layout */
#define KBD_GER 1 /* german layout */
#define KBD_TIMEOUT 1000 /* 1 sec */
#define KBD_RESET_TRIES 3
#define AS 0 /* normal character index */
#define SH 1 /* shift index */
#define CN 2 /* control index */
#define NM 3 /* numeric lock index */
#define AK 4 /* right alt key */
#define CP 5 /* capslock index */
#define ST 6 /* stop output index */
#define EX 7 /* extended code index */
#define ES 8 /* escape and extended code index */
#define NORMAL 0x0000 /* normal key */
#define STP 0x0001 /* scroll lock stop output*/
#define NUM 0x0002 /* numeric lock */
#define CAPS 0x0004 /* capslock */
#define SHIFT 0x0008 /* shift */
#define CTRL 0x0010 /* control*/
#define EXT 0x0020 /* extended scan code 0xe0 */
#define ESC 0x0040 /* escape key press */
#define E1 0x0080 /* extended scan code 0xe1 */
#define BRK 0x0100 /* make break flag for keyboard */
#define ALT 0x0200 /* right alt */
/* exports */

@ -653,6 +653,7 @@ extern pci_addr_t pci_hose_phys_to_bus(struct pci_controller* hose,
#define pci_io_to_virt(dev, addr, len, map_flags) \
pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags))
/* For driver model these are defined in macros in pci_compat.c */
extern int pci_hose_read_config_byte(struct pci_controller *hose,
pci_dev_t dev, int where, u8 *val);
extern int pci_hose_read_config_word(struct pci_controller *hose,

@ -7,14 +7,35 @@
#ifndef _SMSC_LPC47M_H_
#define _SMSC_LPC47M_H_
/* I/O address of LPC47M */
#define LPC47M_IO_PORT 0x2e
/* Logical device number */
#define LPC47M_FDC 0 /* Floppy */
#define LPC47M_SP2 2 /* Serial Port 2 */
#define LPC47M_PP 3 /* Parallel Port */
#define LPC47M_SP1 4 /* Serial Port 1 */
#define LPC47M_KBC 7 /* Keyboard & Mouse */
#define LPC47M_PME 10 /* Power Control */
/**
* Configure the base I/O port of the specified serial device and enable the
* serial device.
*
* @dev: High 8 bits = Super I/O port, low 8 bits = logical device number.
* @iobase: Processor I/O port address to assign to this serial device.
* @irq: Processor IRQ number to assign to this serial device.
* @dev: high 8 bits = super I/O port, low 8 bits = logical device number
* @iobase: processor I/O port address to assign to this serial device
* @irq: processor IRQ number to assign to this serial device
*/
void lpc47m_enable_serial(uint dev, uint iobase, uint irq);
/**
* Configure the specified keyboard controller device and enable the keyboard
* controller device.
*
* @dev: high 8 bits = Super I/O port, low 8 bits = logical device number
* @irq0: processor IRQ number to assign to keyboard
* @irq1: processor IRQ number to assign to mouse
*/
void lpc47m_enable_serial(u16 dev, u16 iobase, u8 irq);
void lpc47m_enable_kbc(uint dev, uint irq0, uint irq1);
#endif /* _SMSC_LPC47M_H_ */

@ -102,6 +102,8 @@ struct vbe_ddc_info {
#define VESA_SET_MODE 0x4f02
#define VESA_GET_CUR_MODE 0x4f03
extern struct vbe_mode_info mode_info;
struct graphic_device;
int vbe_get_video_info(struct graphic_device *gdev);

@ -207,9 +207,8 @@ int fdtdec_get_pci_vendev(const void *blob, int node, u16 *vendor, u16 *device)
return 0;
}
} else {
list += (len + 1);
}
list += (len + 1);
}
return -ENOENT;

@ -297,6 +297,17 @@ $(obj)/%.dtb: $(src)/%.dts FORCE
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
# ACPI
# ---------------------------------------------------------------------------
quiet_cmd_acpi_c_asl= ASL $@
cmd_acpi_c_asl= \
$(CPP) -x assembler-with-cpp -P -o $<.tmp $<; \
iasl -p $< -tc -va $<.tmp; \
mv $(patsubst %.asl,%.hex,$<) $@
$(obj)/%.c: $(src)/%.asl
$(call cmd,acpi_c_asl)
# Bzip2
# ---------------------------------------------------------------------------

@ -706,10 +706,11 @@ int inject_region(char *image, int size, int region_type, char *region_fname)
* 0xffffffff so use an address relative to that. For an
* 8MB ROM the start address is 0xfff80000.
* @write_fname: Filename to add to the image
* @offset_uboot_top: Offset of the top of U-Boot
* @return number of bytes written if OK, -ve on error
*/
static int write_data(char *image, int size, unsigned int addr,
const char *write_fname)
const char *write_fname, int offset_uboot_top)
{
int write_fd, write_size;
int offset;
@ -719,6 +720,14 @@ static int write_data(char *image, int size, unsigned int addr,
return write_fd;
offset = (uint32_t)(addr + size);
if (offset_uboot_top && offset_uboot_top >= offset) {
fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
write_fname);
fprintf(stderr,
"U-Boot finishes at offset %x, file starts at %x\n",
offset_uboot_top, offset);
return -EXDEV;
}
debug("Writing %s to offset %#x\n", write_fname, offset);
if (offset < 0 || offset + write_size > size) {
@ -737,6 +746,171 @@ static int write_data(char *image, int size, unsigned int addr,
return write_size;
}
static int scan_ucode(const void *blob, char *ucode_base, int *countp,
const char **datap, int *data_sizep)
{
const char *data = NULL;
int node, count;
int data_size;
char *ucode;
for (node = 0, count = 0, ucode = ucode_base; node >= 0; count++) {
node = fdt_node_offset_by_compatible(blob, node,
"intel,microcode");
if (node < 0)
break;
data = fdt_getprop(blob, node, "data", &data_size);
if (!data) {
debug("Missing microcode data in FDT '%s': %s\n",
fdt_get_name(blob, node, NULL),
fdt_strerror(data_size));
return -ENOENT;
}
if (ucode_base)
memcpy(ucode, data, data_size);
ucode += data_size;
}
if (countp)
*countp = count;
if (datap)
*datap = data;
if (data_sizep)
*data_sizep = data_size;
return ucode - ucode_base;
}
static int remove_ucode(char *blob)
{
int node, count;
int ret;
/* Keep going until we find no more microcode to remove */
do {
for (node = 0, count = 0; node >= 0;) {
int ret;
node = fdt_node_offset_by_compatible(blob, node,
"intel,microcode");
if (node < 0)
break;
ret = fdt_delprop(blob, node, "data");
/*
* -FDT_ERR_NOTFOUND means we already removed the
* data for this one, so we just continue.
* 0 means we did remove it, so offsets may have
* changed and we need to restart our scan.
* Anything else indicates an error we should report.
*/
if (ret == -FDT_ERR_NOTFOUND)
continue;
else if (!ret)
node = 0;
else
return ret;
}
} while (count);
/* Pack down to remove excees space */
ret = fdt_pack(blob);
if (ret)
return ret;
return fdt_totalsize(blob);
}
static int write_ucode(char *image, int size, struct input_file *fdt,
int fdt_size, unsigned int ucode_ptr,
int collate_ucode)
{
const char *data = NULL;
char *ucode_buf;
const void *blob;
char *ucode_base;
uint32_t *ptr;
int ucode_size;
int data_size;
int offset;
int count;
int ret;
blob = (void *)image + (uint32_t)(fdt->addr + size);
debug("DTB at %lx\n", (char *)blob - image);
/* Find out about the micrcode we have */
ucode_size = scan_ucode(blob, NULL, &count, &data, &data_size);
if (ucode_size < 0)
return ucode_size;
if (!count) {
debug("No microcode found in FDT\n");
return -ENOENT;
}
if (count > 1 && !collate_ucode) {
fprintf(stderr,
"Cannot handle multiple microcode blocks - please use -C flag to collate them\n");
return -EMLINK;
}
/*
* Collect the microcode into a buffer, remove it from the device
* tree and place it immediately above the (now smaller) device tree.
*/
if (collate_ucode && count > 1) {
ucode_buf = malloc(ucode_size);
if (!ucode_buf) {
fprintf(stderr,
"Out of memory for microcode (%d bytes)\n",
ucode_size);
return -ENOMEM;
}
ret = scan_ucode(blob, ucode_buf, NULL, NULL, NULL);
if (ret < 0)
return ret;
/* Remove the microcode from the device tree */
ret = remove_ucode((char *)blob);
if (ret < 0) {
debug("Could not remove FDT microcode: %s\n",
fdt_strerror(ret));
return -EINVAL;
}
debug("Collated %d microcode block(s)\n", count);
debug("Device tree reduced from %x to %x bytes\n",
fdt_size, ret);
fdt_size = ret;
/*
* Place microcode area immediately above the FDT, aligned
* to a 16-byte boundary.
*/
ucode_base = (char *)(((unsigned long)blob + fdt_size + 15) &
~15);
data = ucode_base;
data_size = ucode_size;
memcpy(ucode_base, ucode_buf, ucode_size);
free(ucode_buf);
}
offset = (uint32_t)(ucode_ptr + size);
ptr = (void *)image + offset;
ptr[0] = (data - image) - size;
ptr[1] = data_size;
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n", ucode_ptr,
ptr[0], ptr[1]);
return (collate_ucode ? data + data_size : (char *)blob + fdt_size) -
image;
}
/**
* write_uboot() - Write U-Boot, device tree and microcode pointer
*
@ -752,51 +926,28 @@ static int write_data(char *image, int size, unsigned int addr,
* @return 0 if OK, -ve on error
*/
static int write_uboot(char *image, int size, struct input_file *uboot,
struct input_file *fdt, unsigned int ucode_ptr)
struct input_file *fdt, unsigned int ucode_ptr,
int collate_ucode)
{
const void *blob;
const char *data;
int uboot_size;
uint32_t *ptr;
int data_size;
int offset;
int node;
int ret;
int uboot_size, fdt_size;
uboot_size = write_data(image, size, uboot->addr, uboot->fname);
uboot_size = write_data(image, size, uboot->addr, uboot->fname, 0);
if (uboot_size < 0)
return uboot_size;
fdt->addr = uboot->addr + uboot_size;
debug("U-Boot size %#x, FDT at %#x\n", uboot_size, fdt->addr);
ret = write_data(image, size, fdt->addr, fdt->fname);
if (ret < 0)
return ret;
fdt_size = write_data(image, size, fdt->addr, fdt->fname, 0);
if (fdt_size < 0)
return fdt_size;
blob = (void *)image + (uint32_t)(fdt->addr + size);
if (ucode_ptr) {
blob = (void *)image + (uint32_t)(fdt->addr + size);
debug("DTB at %lx\n", (char *)blob - image);
node = fdt_node_offset_by_compatible(blob, 0,
"intel,microcode");
if (node < 0) {
debug("No microcode found in FDT: %s\n",
fdt_strerror(node));
return -ENOENT;
}
data = fdt_getprop(blob, node, "data", &data_size);
if (!data) {
debug("No microcode data found in FDT: %s\n",
fdt_strerror(data_size));
return -ENOENT;
}
offset = (uint32_t)(ucode_ptr + size);
ptr = (void *)image + offset;
ptr[0] = (data - image) - size;
ptr[1] = data_size;
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n",
ucode_ptr, ptr[0], ptr[1]);
return write_ucode(image, size, fdt, fdt_size, ucode_ptr,
collate_ucode);
}
return 0;
return ((char *)blob + fdt_size) - image;
}
static void print_version(void)
@ -860,7 +1011,7 @@ int main(int argc, char *argv[])
int mode_dump = 0, mode_extract = 0, mode_inject = 0;
int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0;
int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0;
int create = 0;
int create = 0, collate_ucode = 0;
char *region_type_string = NULL, *inject_fname = NULL;
char *desc_fname = NULL, *addr_str = NULL;
int region_type = -1, inputfreq = 0;
@ -880,6 +1031,7 @@ int main(int argc, char *argv[])
int ret;
static struct option long_options[] = {
{"create", 0, NULL, 'c'},
{"collate-microcode", 0, NULL, 'C'},
{"dump", 0, NULL, 'd'},
{"descriptor", 1, NULL, 'D'},
{"em100", 0, NULL, 'e'},
@ -898,12 +1050,15 @@ int main(int argc, char *argv[])
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lm:r:s:uU:vw:x?",
while ((opt = getopt_long(argc, argv, "cCdD:ef:hi:lm:r:s:uU:vw:x?",
long_options, &option_index)) != EOF) {
switch (opt) {
case 'c':
create = 1;
break;
case 'C':
collate_ucode = 1;
break;
case 'd':
mode_dump = 1;
break;
@ -1113,22 +1268,25 @@ int main(int argc, char *argv[])
}
if (mode_write_descriptor)
ret = write_data(image, size, -size, desc_fname);
ret = write_data(image, size, -size, desc_fname, 0);
if (mode_inject)
ret = inject_region(image, size, region_type, inject_fname);
if (mode_write) {
int offset_uboot_top = 0;
for (wr_idx = 0; wr_idx < wr_num; wr_idx++) {
ifile = &input_file[wr_idx];
if (ifile->type == IF_fdt) {
continue;
} else if (ifile->type == IF_uboot) {
ret = write_uboot(image, size, ifile, fdt,
ucode_ptr);
ucode_ptr, collate_ucode);
offset_uboot_top = ret;
} else {
ret = write_data(image, size, ifile->addr,
ifile->fname);
ifile->fname, offset_uboot_top);
}
if (ret < 0)
break;

@ -264,7 +264,7 @@ def CreatePatches(start, count, series):
"""
if series.get('version'):
version = '%s ' % series['version']
cmd = ['git', 'format-patch', '-M', '--signoff']
cmd = ['git', 'format-patch', '-D', '-M', '--signoff']
if series.get('cover'):
cmd.append('--cover-letter')
prefix = series.GetPatchPrefix()

Loading…
Cancel
Save