Merge branch 'master' of git://git.denx.de/u-boot-x86

This commit is contained in:
Tom Rini 2016-01-28 10:07:22 -05:00
commit 4b5a4a0535
27 changed files with 567 additions and 36 deletions

View File

@ -358,6 +358,15 @@ config GENERATE_ACPI_TABLE
by the operating system. It defines platform-independent interfaces
for configuration and power management monitoring.
config QEMU_ACPI_TABLE
bool "Load ACPI table from QEMU fw_cfg interface"
depends on GENERATE_ACPI_TABLE && QEMU
default y
help
By default, U-Boot generates its own ACPI tables. This option, if
enabled, disables U-Boot's version and loads ACPI tables generated
by QEMU.
config GENERATE_SMBIOS_TABLE
bool "Generate an SMBIOS (System Management BIOS) table"
default y

View File

@ -59,11 +59,15 @@ static void x86_pci_write_config32(int dev, unsigned int where, u32 value)
}
/* This can be called after memory-mapped PCI is working */
int setup_early_uart(void)
int setup_internal_uart(int enable)
{
/* Enable the legacy UART hardware. */
/* Enable or disable the legacy UART hardware */
x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT,
1);
enable);
/* All done for the disable part, so just return */
if (!enable)
return 0;
/*
* Set up the pads to the UART function. This allows the signals to

View File

@ -17,4 +17,11 @@ config SYS_CAR_SIZE
hex
default 0x10000
config ACPI_PM1_BASE
hex
default 0xe400
help
ACPI Power Managment 1 (PM1) i/o-mapped base address.
This device is defined in ACPI specification, with 16 bytes in size.
endif

View File

@ -8,4 +8,6 @@ ifndef CONFIG_EFI_STUB
obj-y += car.o dram.o
endif
obj-y += cpu.o fw_cfg.o qemu.o
ifndef CONFIG_QEMU_ACPI_TABLE
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi.o dsdt.o
endif

View File

@ -10,10 +10,16 @@
#include <malloc.h>
#include <asm/io.h>
#include <asm/fw_cfg.h>
#include <asm/tables.h>
#include <asm/e820.h>
#include <linux/list.h>
#include <memalign.h>
static bool fwcfg_present;
static bool fwcfg_dma_present;
static LIST_HEAD(fw_list);
/* Read configuration item using fw_cfg PIO interface */
static void qemu_fwcfg_read_entry_pio(uint16_t entry,
uint32_t size, void *address)
@ -162,29 +168,311 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
return 0;
}
static int qemu_fwcfg_list_firmware(void)
static int qemu_fwcfg_read_firmware_list(void)
{
int i;
uint32_t count;
struct fw_cfg_files *files;
struct fw_file *file;
struct list_head *entry;
/* don't read it twice */
if (!list_empty(&fw_list))
return 0;
qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count);
if (!count)
return 0;
count = be32_to_cpu(count);
files = malloc(count * sizeof(struct fw_cfg_file));
if (!files)
return -ENOMEM;
for (i = 0; i < count; i++) {
file = malloc(sizeof(*file));
if (!file) {
printf("error: allocating resource\n");
goto err;
}
qemu_fwcfg_read_entry(FW_CFG_INVALID,
sizeof(struct fw_cfg_file), &file->cfg);
file->addr = 0;
list_add_tail(&file->list, &fw_list);
}
files->count = count;
qemu_fwcfg_read_entry(FW_CFG_INVALID,
count * sizeof(struct fw_cfg_file),
files->files);
return 0;
err:
list_for_each(entry, &fw_list) {
file = list_entry(entry, struct fw_file, list);
free(file);
}
return -ENOMEM;
}
#ifdef CONFIG_QEMU_ACPI_TABLE
static struct fw_file *qemu_fwcfg_find_file(const char *name)
{
struct list_head *entry;
struct fw_file *file;
list_for_each(entry, &fw_list) {
file = list_entry(entry, struct fw_file, list);
if (!strcmp(file->cfg.name, name))
return file;
}
return NULL;
}
/*
* This function allocates memory for ACPI tables
*
* @entry : BIOS linker command entry which tells where to allocate memory
* (either high memory or low memory)
* @addr : The address that should be used for low memory allcation. If the
* memory allocation request is 'ZONE_HIGH' then this parameter will
* be ignored.
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_allocate(struct bios_linker_entry *entry,
unsigned long *addr)
{
uint32_t size, align;
struct fw_file *file;
unsigned long aligned_addr;
align = le32_to_cpu(entry->alloc.align);
/* align must be power of 2 */
if (align & (align - 1)) {
printf("error: wrong alignment %u\n", align);
return -EINVAL;
}
file = qemu_fwcfg_find_file(entry->alloc.file);
if (!file) {
printf("error: can't find file %s\n", entry->alloc.file);
return -ENOENT;
}
size = be32_to_cpu(file->cfg.size);
/*
* ZONE_HIGH means we need to allocate from high memory, since
* malloc space is already at the end of RAM, so we directly use it.
* If allocation zone is ZONE_FSEG, then we use the 'addr' passed
* in which is low memory
*/
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
aligned_addr = (unsigned long)memalign(align, size);
if (!aligned_addr) {
printf("error: allocating resource\n");
return -ENOMEM;
}
} else if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG) {
aligned_addr = ALIGN(*addr, align);
} else {
printf("error: invalid allocation zone\n");
return -EINVAL;
}
debug("bios_linker_allocate: allocate file %s, size %u, zone %d, align %u, addr 0x%lx\n",
file->cfg.name, size, entry->alloc.zone, align, aligned_addr);
qemu_fwcfg_read_entry(be16_to_cpu(file->cfg.select),
size, (void *)aligned_addr);
file->addr = aligned_addr;
/* adjust address for low memory allocation */
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG)
*addr = (aligned_addr + size);
return 0;
}
/*
* This function patches ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells how to patch
* ACPI tables
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_pointer(struct bios_linker_entry *entry)
{
struct fw_file *dest, *src;
uint32_t offset = le32_to_cpu(entry->pointer.offset);
uint64_t pointer = 0;
dest = qemu_fwcfg_find_file(entry->pointer.dest_file);
if (!dest || !dest->addr)
return -ENOENT;
src = qemu_fwcfg_find_file(entry->pointer.src_file);
if (!src || !src->addr)
return -ENOENT;
debug("bios_linker_add_pointer: dest->addr 0x%lx, src->addr 0x%lx, offset 0x%x size %u, 0x%llx\n",
dest->addr, src->addr, offset, entry->pointer.size, pointer);
memcpy(&pointer, (char *)dest->addr + offset, entry->pointer.size);
pointer = le64_to_cpu(pointer);
pointer += (unsigned long)src->addr;
pointer = cpu_to_le64(pointer);
memcpy((char *)dest->addr + offset, &pointer, entry->pointer.size);
return 0;
}
/*
* This function updates checksum fields of ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells where to update ACPI table
* checksums
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_checksum(struct bios_linker_entry *entry)
{
struct fw_file *file;
uint8_t *data, cksum = 0;
uint8_t *cksum_start;
file = qemu_fwcfg_find_file(entry->cksum.file);
if (!file || !file->addr)
return -ENOENT;
data = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.offset));
cksum_start = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.start));
cksum = table_compute_checksum(cksum_start,
le32_to_cpu(entry->cksum.length));
*data = cksum;
return 0;
}
unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
{
entries[0].addr = 0;
entries[0].size = ISA_START_ADDRESS;
entries[0].type = E820_RAM;
entries[1].addr = ISA_START_ADDRESS;
entries[1].size = ISA_END_ADDRESS - ISA_START_ADDRESS;
entries[1].type = E820_RESERVED;
/*
* since we use memalign(malloc) to allocate high memory for
* storing ACPI tables, we need to reserve them in e820 tables,
* otherwise kernel will reclaim them and data will be corrupted
*/
entries[2].addr = ISA_END_ADDRESS;
entries[2].size = gd->relocaddr - TOTAL_MALLOC_LEN - ISA_END_ADDRESS;
entries[2].type = E820_RAM;
/* for simplicity, reserve entire malloc space */
entries[3].addr = gd->relocaddr - TOTAL_MALLOC_LEN;
entries[3].size = TOTAL_MALLOC_LEN;
entries[3].type = E820_RESERVED;
entries[4].addr = gd->relocaddr;
entries[4].size = gd->ram_size - gd->relocaddr;
entries[4].type = E820_RESERVED;
entries[5].addr = CONFIG_PCIE_ECAM_BASE;
entries[5].size = CONFIG_PCIE_ECAM_SIZE;
entries[5].type = E820_RESERVED;
return 6;
}
/* This function loads and patches ACPI tables provided by QEMU */
unsigned long write_acpi_tables(unsigned long addr)
{
int i, ret = 0;
struct fw_file *file;
struct bios_linker_entry *table_loader;
struct bios_linker_entry *entry;
uint32_t size;
struct list_head *list;
/* make sure fw_list is loaded */
ret = qemu_fwcfg_read_firmware_list();
if (ret) {
printf("error: can't read firmware file list\n");
return addr;
}
file = qemu_fwcfg_find_file("etc/table-loader");
if (!file) {
printf("error: can't find etc/table-loader\n");
return addr;
}
size = be32_to_cpu(file->cfg.size);
if ((size % sizeof(*entry)) != 0) {
printf("error: table-loader maybe corrupted\n");
return addr;
}
table_loader = malloc(size);
if (!table_loader) {
printf("error: no memory for table-loader\n");
return addr;
}
qemu_fwcfg_read_entry(be16_to_cpu(file->cfg.select),
size, table_loader);
for (i = 0; i < (size / sizeof(*entry)); i++) {
entry = table_loader + i;
switch (le32_to_cpu(entry->command)) {
case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
ret = bios_linker_allocate(entry, &addr);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
ret = bios_linker_add_pointer(entry);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
ret = bios_linker_add_checksum(entry);
if (ret)
goto out;
break;
default:
break;
}
}
out:
if (ret) {
list_for_each(list, &fw_list) {
file = list_entry(list, struct fw_file, list);
if (file->addr)
free((void *)file->addr);
}
}
free(table_loader);
return addr;
}
#endif
static int qemu_fwcfg_list_firmware(void)
{
int ret;
struct list_head *entry;
struct fw_file *file;
/* make sure fw_list is loaded */
ret = qemu_fwcfg_read_firmware_list();
if (ret)
return ret;
list_for_each(entry, &fw_list) {
file = list_entry(entry, struct fw_file, list);
printf("%-56s\n", file->cfg.name);
}
for (i = 0; i < files->count; i++)
printf("%-56s\n", files->files[i].name);
free(files);
return 0;
}

View File

@ -15,6 +15,31 @@
static bool i440fx;
static void enable_pm_piix(void)
{
u8 en;
u16 cmd;
/* Set the PM I/O base */
x86_pci_write_config32(PIIX_PM, PMBA, CONFIG_ACPI_PM1_BASE | 1);
/* Enable access to the PM I/O space */
cmd = x86_pci_read_config16(PIIX_PM, PCI_COMMAND);
cmd |= PCI_COMMAND_IO;
x86_pci_write_config16(PIIX_PM, PCI_COMMAND, cmd);
/* PM I/O Space Enable (PMIOSE) */
en = x86_pci_read_config8(PIIX_PM, PMREGMISC);
en |= PMIOSE;
x86_pci_write_config8(PIIX_PM, PMREGMISC, en);
}
static void enable_pm_ich9(void)
{
/* Set the PM I/O base */
x86_pci_write_config32(ICH9_PM, PMBA, CONFIG_ACPI_PM1_BASE | 1);
}
static void qemu_chipset_init(void)
{
u16 device, xbcs;
@ -53,10 +78,14 @@ static void qemu_chipset_init(void)
xbcs = x86_pci_read_config16(PIIX_ISA, XBCS);
xbcs |= APIC_EN;
x86_pci_write_config16(PIIX_ISA, XBCS, xbcs);
enable_pm_piix();
} else {
/* Configure PCIe ECAM base address */
x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR,
CONFIG_PCIE_ECAM_BASE | BAR_EN);
enable_pm_ich9();
}
qemu_fwcfg_init();

View File

@ -21,7 +21,7 @@
aliases {
serial0 = &serial;
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -184,7 +184,7 @@
>;
};
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -10,7 +10,7 @@
compatible = "advantech,som-6896", "intel,broadwell";
aliases {
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -34,7 +34,7 @@
reg = <0x0000f800 0 0 0 0>;
compatible = "intel,pch9";
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -11,7 +11,7 @@
compatible = "google,link", "intel,celeron-ivybridge";
aliases {
spi0 = "/pci/pch/spi";
spi0 = &spi;
usb0 = &usb_0;
usb1 = &usb_1;
};
@ -252,7 +252,7 @@
/* Enable EC SMI source */
intel,alt-gp-smi-enable = <0x0100>;
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -10,7 +10,7 @@
compatible = "google,panther", "intel,haswell";
aliases {
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -56,7 +56,7 @@
reg = <0x0000f800 0 0 0 0>;
compatible = "intel,pch9";
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -19,7 +19,7 @@
compatible = "intel,crownbay", "intel,queensbay";
aliases {
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -227,7 +227,7 @@
>;
};
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -18,7 +18,7 @@
compatible = "intel,galileo", "intel,quark";
aliases {
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -115,7 +115,7 @@
>;
};
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -20,7 +20,7 @@
aliases {
serial0 = &serial;
spi0 = "/spi";
spi0 = &spi;
};
config {
@ -218,7 +218,7 @@
>;
};
spi {
spi: spi {
#address-cells = <1>;
#size-cells = <0>;
compatible = "intel,ich-spi";

View File

@ -13,6 +13,8 @@
#define PIIX_ISA PCI_BDF(0, 1, 0)
#define PIIX_IDE PCI_BDF(0, 1, 1)
#define PIIX_USB PCI_BDF(0, 1, 2)
#define PIIX_PM PCI_BDF(0, 1, 3)
#define ICH9_PM PCI_BDF(0, 0x1f, 0)
#define I440FX_VGA PCI_BDF(0, 2, 0)
#define QEMU_Q35 PCI_BDF(0, 0, 0)

View File

@ -33,4 +33,9 @@
#define LOW_RAM_ADDR 0x34
#define HIGH_RAM_ADDR 0x35
/* PM registers */
#define PMBA 0x40
#define PMREGMISC 0x80
#define PMIOSE (1 << 0)
#endif /* _ARCH_QEMU_H_ */

View File

@ -12,6 +12,8 @@
#define FW_DMA_PORT_LOW 0x514
#define FW_DMA_PORT_HIGH 0x518
#include <linux/list.h>
enum qemu_fwcfg_items {
FW_CFG_SIGNATURE = 0x00,
FW_CFG_ID = 0x01,
@ -45,11 +47,23 @@ enum qemu_fwcfg_items {
FW_CFG_INVALID = 0xffff,
};
enum {
BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1,
BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2,
BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
};
enum {
BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1,
BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2,
};
#define FW_CFG_FILE_SLOTS 0x10
#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST + FW_CFG_FILE_SLOTS)
#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
#define FW_CFG_MAX_FILE_PATH 56
#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH
#define QEMU_FW_CFG_SIGNATURE (('Q' << 24) | ('E' << 16) | ('M' << 8) | 'U')
@ -67,9 +81,10 @@ struct fw_cfg_file {
char name[FW_CFG_MAX_FILE_PATH];
};
struct fw_cfg_files {
__be32 count;
struct fw_cfg_file files[];
struct fw_file {
struct fw_cfg_file cfg; /* firmware file information */
unsigned long addr; /* firmware file in-memory address */
struct list_head list; /* list node to link to fw_list */
};
struct fw_cfg_dma_access {
@ -78,6 +93,55 @@ struct fw_cfg_dma_access {
__be64 address;
};
struct bios_linker_entry {
__le32 command;
union {
/*
* COMMAND_ALLOCATE - allocate a table from @alloc.file
* subject to @alloc.align alignment (must be power of 2)
* and @alloc.zone (can be HIGH or FSEG) requirements.
*
* Must appear exactly once for each file, and before
* this file is referenced by any other command.
*/
struct {
char file[BIOS_LINKER_LOADER_FILESZ];
__le32 align;
uint8_t zone;
} alloc;
/*
* COMMAND_ADD_POINTER - patch the table (originating from
* @dest_file) at @pointer.offset, by adding a pointer to the
* table originating from @src_file. 1,2,4 or 8 byte unsigned
* addition is used depending on @pointer.size.
*/
struct {
char dest_file[BIOS_LINKER_LOADER_FILESZ];
char src_file[BIOS_LINKER_LOADER_FILESZ];
__le32 offset;
uint8_t size;
} pointer;
/*
* COMMAND_ADD_CHECKSUM - calculate checksum of the range
* specified by @cksum_start and @cksum_length fields,
* and then add the value at @cksum.offset.
* Checksum simply sums -X for each byte X in the range
* using 8-bit math.
*/
struct {
char file[BIOS_LINKER_LOADER_FILESZ];
__le32 offset;
__le32 start;
__le32 length;
} cksum;
/* padding */
char pad[124];
};
} __packed;
/**
* Initialize QEMU fw_cfg interface
*/

View File

@ -45,7 +45,7 @@ void dram_init_banksize(void);
int default_print_cpuinfo(void);
/* Set up a UART which can be used with printch(), printhex8(), etc. */
int setup_early_uart(void);
int setup_internal_uart(int enable);
void setup_pcat_compatibility(void);

View File

@ -32,7 +32,9 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
obj-y += sfi.o
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
obj-y += string.o
ifndef CONFIG_QEMU_ACPI_TABLE
obj-$(CONFIG_GENERATE_ACPI_TABLE) += acpi_table.o
endif
obj-y += tables.o
obj-$(CONFIG_CMD_ZBOOT) += zimage.o
obj-$(CONFIG_HAVE_FSP) += fsp/

View File

@ -331,6 +331,10 @@ static void acpi_create_ssdt_generator(acpi_header_t *ssdt,
ssdt->checksum = table_compute_checksum((void *)ssdt, ssdt->length);
}
/*
* QEMU's version of write_acpi_tables is defined in
* arch/x86/cpu/qemu/fw_cfg.c
*/
unsigned long write_acpi_tables(unsigned long start)
{
unsigned long current;

View File

@ -111,7 +111,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
#endif
#ifdef CONFIG_DEBUG_UART
setup_early_uart();
setup_internal_uart(1);
#endif
fsp_hdr = find_fsp_header();

View File

@ -706,7 +706,7 @@ the board, then you can use post_code() calls from C or assembler to monitor
boot progress. This can be good for debugging.
If not, you can try to get serial working as early as possible. The early
debug serial port may be useful here. See setup_early_uart() for an example.
debug serial port may be useful here. See setup_internal_uart() for an example.
During the U-Boot porting, one of the important steps is to write correct PIRQ
routing information in the board device tree. Without it, device drivers in the

View File

@ -74,12 +74,41 @@ discovered by the FSP and used to setup main memory.
# Integer properties:
- fsp,dram-speed
- fsp,dram-speed:
0x0: "800 MHz"
0x1: "1066 MHz"
0x2: "1333 MHz"
0x3: "1600 MHz"
- fsp,dram-type
0x0: "DDR3"
0x1: "DDR3L"
0x2: "DDR3U"
0x4: "LPDDR2"
0x5: "LPDDR3"
0x6: "DDR4"
- fsp,dimm-width
0x0: "x8"
0x1: "x16"
0x2: "x32"
- fsp,dimm-density
0x0: "1 Gbit"
0x1: "2 Gbit"
0x2: "4 Gbit"
0x3: "8 Gbit"
- fsp,dimm-bus-width
0x0: "8 bits"
0x1: "16 bits"
0x2: "32 bits"
0x3: "64 bits"
- fsp,dimm-sides
0x0: "1 rank"
0x1: "2 ranks"
- fsp,dimm-tcl
- fsp,dimm-trpt-rcd
- fsp,dimm-twr

View File

@ -130,4 +130,12 @@ config RESET
effect a reset. The uclass will try all available drivers when
reset_walk() is called.
config WINBOND_W83627
bool "Enable Winbond Super I/O driver"
help
If you say Y here, you will get support for the Winbond
W83627 Super I/O driver. This can be used to enable the
legacy UART or other devices in the Winbond Super IO chips
on X86 platforms.
endmenu

View File

@ -41,3 +41,4 @@ obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
obj-$(CONFIG_RESET) += reset-uclass.o
obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/pnp_def.h>
#define WINBOND_ENTRY_KEY 0x87
#define WINBOND_EXIT_KEY 0xaa
/* Enable configuration: pass entry key '0x87' into index port dev twice */
static void pnp_enter_conf_state(u16 dev)
{
u16 port = dev >> 8;
outb(WINBOND_ENTRY_KEY, port);
outb(WINBOND_ENTRY_KEY, port);
}
/* Disable configuration: pass exit key '0xAA' into index port dev */
static void pnp_exit_conf_state(u16 dev)
{
u16 port = dev >> 8;
outb(WINBOND_EXIT_KEY, port);
}
/* Bring up early serial debugging output before the RAM is initialized */
void winbond_enable_serial(uint dev, uint iobase, uint irq)
{
pnp_enter_conf_state(dev);
pnp_set_logical_device(dev);
pnp_set_enable(dev, 0);
pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
pnp_set_irq(dev, PNP_IDX_IRQ0, irq);
pnp_set_enable(dev, 1);
pnp_exit_conf_state(dev);
}

View File

@ -100,6 +100,7 @@
* Command line configuration.
*/
#define CONFIG_CMD_DATE
#define CONFIG_CMD_FS_GENERIC
#define CONFIG_CMD_FPGA_LOADMK
#define CONFIG_CMD_IO
#define CONFIG_CMD_IRQ

35
include/winbond_w83627.h Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _WINBOND_W83627_H_
#define _WINBOND_W83627_H_
/* I/O address of Winbond Super IO chip */
#define WINBOND_IO_PORT 0x2e
/* Logical device number */
#define W83627DHG_FDC 0 /* Floppy */
#define W83627DHG_PP 1 /* Parallel port */
#define W83627DHG_SP1 2 /* Com1 */
#define W83627DHG_SP2 3 /* Com2 */
#define W83627DHG_KBC 5 /* PS/2 keyboard & mouse */
#define W83627DHG_SPI 6 /* Serial peripheral interface */
#define W83627DHG_WDTO_PLED 8 /* WDTO#, PLED */
#define W83627DHG_ACPI 10 /* ACPI */
#define W83627DHG_HWM 11 /* Hardware monitor */
#define W83627DHG_PECI_SST 12 /* PECI, SST */
/**
* 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
*/
void winbond_enable_serial(uint dev, uint iobase, uint irq);
#endif /* _WINBOND_W83627_H_ */