684 changes: 684 additions & 0 deletions configs/pcengines_apu4.config

Large diffs are not rendered by default.

28 changes: 23 additions & 5 deletions configs/pcengines_apu5.config
Expand Up @@ -17,7 +17,7 @@ CONFIG_COMPILER_GCC=y
# CONFIG_UTIL_GENPARSER is not set
CONFIG_COMPRESS_RAMSTAGE=y
CONFIG_INCLUDE_CONFIG_FILE=y
# CONFIG_COLLECT_TIMESTAMPS is not set
CONFIG_COLLECT_TIMESTAMPS=y
CONFIG_USE_BLOBS=y
# CONFIG_COVERAGE is not set
# CONFIG_UPDATE_IMAGE is not set
Expand Down Expand Up @@ -138,6 +138,7 @@ CONFIG_ID_SECTION_OFFSET=0x80
CONFIG_POST_DEVICE=y
CONFIG_VARIANT_DIR="apu5"
# CONFIG_VBOOT is not set
CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0
CONFIG_DIMM_MAX=4
CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00
CONFIG_TTYS0_LCS=3
Expand All @@ -155,14 +156,13 @@ CONFIG_MAINBOARD_VERSION="1.0"
# CONFIG_BOARD_PCENGINES_APU1 is not set
# CONFIG_BOARD_PCENGINES_APU2 is not set
# CONFIG_BOARD_PCENGINES_APU3 is not set
# CONFIG_BOARD_PCENGINES_APU4 is not set
CONFIG_BOARD_PCENGINES_APU5=y
# CONFIG_DRIVERS_PS2_KEYBOARD is not set
CONFIG_AGESA_BINARY_PI_FILE="3rdparty/blobs/mainboard/pcengines/apu2/AGESA.bin"
# CONFIG_APU2_PINMUX_OFF_C is not set
# CONFIG_APU2_PINMUX_GPIO0 is not set
CONFIG_APU2_PINMUX_UART_C=y
# CONFIG_APU2_PINMUX_OFF_D is not set
# CONFIG_APU2_PINMUX_GPIO1 is not set
CONFIG_APU2_PINMUX_UART_D=y
# CONFIG_FORCE_MPCIE2_CLK is not set
# CONFIG_NO_POST is not set
Expand Down Expand Up @@ -198,6 +198,7 @@ CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y
CONFIG_ROMSTAGE_ADDR=0x2000000
CONFIG_VERSTAGE_ADDR=0x2000000
CONFIG_HEAP_SIZE=0xc0000
CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y
CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/amd/pi/hudson/bootblock.c"
CONFIG_TTYS0_BASE=0x3f8
CONFIG_EHCI_BAR=0xfef00000
Expand Down Expand Up @@ -445,7 +446,22 @@ CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
# CONFIG_IPMI_KCS is not set
# CONFIG_DRIVERS_LENOVO_WACOM is not set
# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set
# CONFIG_SPI_FLASH is not set
CONFIG_SPI_FLASH=y
CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y
# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set
# CONFIG_SPI_FLASH_NO_FAST_READ is not set
CONFIG_SPI_FLASH_ADESTO=y
CONFIG_SPI_FLASH_AMIC=y
CONFIG_SPI_FLASH_ATMEL=y
CONFIG_SPI_FLASH_EON=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_SST=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set
# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set
# CONFIG_HAVE_SPI_CONSOLE_SUPPORT is not set
# CONFIG_DRIVERS_STORAGE is not set
CONFIG_DRIVERS_UART=y
Expand Down Expand Up @@ -594,6 +610,7 @@ CONFIG_SEABIOS_BOOTORDER_DEF_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/bootorde
CONFIG_SEABIOS_BOOTMENU_KEY_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/boot-menu-key"
CONFIG_SEABIOS_BOOTMENU_WAIT_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/boot-menu-wait"
CONFIG_SEABIOS_BOOTMENU_MESSAGE_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/boot-menu-message"
CONFIG_SEABIOS_SERCON_PORT_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/sercon-port"
CONFIG_SEABIOS_DEBUG_LEVEL=-1

#
Expand All @@ -609,6 +626,7 @@ CONFIG_PXE=y
CONFIG_BUILD_IPXE=y
CONFIG_IPXE_STABLE=y
# CONFIG_IPXE_MASTER is not set
# CONFIG_PXE_SERIAL_CONSOLE is not set
CONFIG_PXE_ROM_ID="8086,157b"
CONFIG_PXE_CUSTOM_GENERAL_H="../../../../apu2-documentation/ipxe/general.h"
CONFIG_PXE_CUSTOM_BOOTMENU_FILE="../../../../apu2-documentation/ipxe/menu.ipxe"
Expand All @@ -622,7 +640,6 @@ CONFIG_COMPRESSED_PAYLOAD_LZMA=y
CONFIG_MEMTEST_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_STABLE=y
# CONFIG_MEMTEST_MASTER is not set
CONFIG_MEMTEST_DISABLE_SPD=y
# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set
# CONFIG_TINT_SECONDARY_PAYLOAD is not set
CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
Expand All @@ -639,6 +656,7 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
# CONFIG_HAVE_DEBUG_SMBUS is not set
# CONFIG_DEBUG_MALLOC is not set
# CONFIG_DEBUG_ACPI is not set
# CONFIG_DEBUG_SPI_FLASH is not set
# CONFIG_TRACE is not set
# CONFIG_DEBUG_BOOT_STATE is not set
# CONFIG_DEBUG_ADA_CODE is not set
Expand Down
9 changes: 0 additions & 9 deletions payloads/Kconfig
Expand Up @@ -106,15 +106,6 @@ config MEMTEST_MASTER
non-reproducible, as it can fetch different code each time.
endchoice

config MEMTEST_DISABLE_SPD
bool "Disable retrieving SPD info"
depends on MEMTEST_SECONDARY_PAYLOAD
help
Disables retrieving RAM SPD info in Memtest86+.

Some chipsets and mainboards do not support this feature and it
should be disabled in Memtest86+ to avoid unwanted behaviour.

config NVRAMCUI_SECONDARY_PAYLOAD
bool "Load nvramcui as a secondary payload"
default n
Expand Down
31 changes: 15 additions & 16 deletions payloads/external/Makefile.inc
Expand Up @@ -138,6 +138,14 @@ etc/boot-menu-message-file := $(strip $(CONFIG_SEABIOS_BOOTMENU_MESSAGE_FILE))
etc/boot-menu-message-type := raw
endif


# add a SeaBIOS sercon-port file
ifneq ($(strip $(CONFIG_SEABIOS_SERCON_PORT_FILE)),)
cbfs-files-y += etc/sercon-port
etc/sercon-port-file := $(strip $(CONFIG_SEABIOS_SERCON_PORT_FILE))
etc/sercon-port-type := raw
endif

# Depthcharge

payloads/external/depthcharge/depthcharge/build/depthcharge.elf depthcharge: $(DOTCONFIG) $(CBFSTOOL)
Expand Down Expand Up @@ -206,10 +214,6 @@ ifeq ($(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO),yy)
SERIAL_BAUD_RATE=$(CONFIG_TTYS0_BAUD)
endif

ifeq ($(CONFIG_MEMTEST_DISABLE_SPD),y)
MEMTEST_SPD_OPTIONS=CB_NOSPD=1
endif

payloads/external/Memtest86Plus/memtest86plus/memtest: $(DOTCONFIG)
$(MAKE) -C payloads/external/Memtest86Plus all \
CC="$(CC_x86_32)" \
Expand All @@ -218,8 +222,6 @@ payloads/external/Memtest86Plus/memtest86plus/memtest: $(DOTCONFIG)
AS="$(AS_x86_32)" \
CONFIG_MEMTEST_MASTER=$(CONFIG_MEMTEST_MASTER) \
CONFIG_MEMTEST_STABLE=$(CONFIG_MEMTEST_STABLE) \
CONFIG_MEMTEST_SPD=$(CONFIG_MEMTEST_SPD) \
$(MEMTEST_SPD_OPTIONS) \
$(MEMTEST_SERIAL_OPTIONS) \
MFLAGS= MAKEFLAGS=

Expand All @@ -233,15 +235,6 @@ img/setup-file := payloads/external/sortbootorder/sortbootorder/sortbootorder.el
img/setup-type := payload
img/setup-compression := $(CBFS_PAYLOAD_COMPRESS_FLAG)

# sgabios

payloads/external/sgabios/sgabios.bin sgabios:
$(MAKE) -C payloads/external/sgabios

cbfs-files-y += vgaroms/sgabios.bin
vgaroms/sgabios.bin-file := payloads/external/sgabios/sgabios.bin
vgaroms/sgabios.bin-type := raw

# iPXE

PXE_ROM_PCI_ID:=$(subst $(comma),,$(CONFIG_PXE_ROM_ID))
Expand All @@ -265,13 +258,19 @@ cbfs-files-$(CONFIG_PXE_ROM)$(CONFIG_BUILD_IPXE) += genroms/pxe.rom
genroms/pxe.rom-file = $(PXE_ROM_FILE)
genroms/pxe.rom-type := raw

ifeq ($(CONFIG_PXE_SERIAL_CONSOLE),y)
IPXE_SERIAL_CONSOLE = $(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO)
else
IPXE_SERIAL_CONSOLE = n
endif

payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG)
$(MAKE) -C payloads/external/iPXE all \
CROSS_COMPILE="$(CROSS_COMPILE_$(ARCH-ramstage-y))" \
PXE_ROM_PCI_ID=$(PXE_ROM_PCI_ID) \
CONFIG_IPXE_MASTER=$(CONFIG_IPXE_MASTER) \
CONFIG_IPXE_STABLE=$(CONFIG_IPXE_STABLE) \
CONSOLE_SERIAL=$(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO) \
CONSOLE_SERIAL=$(IPXE_SERIAL_CONSOLE) \
IPXE_UART=$(IPXE_UART) \
CONFIG_TTYS0_BAUD=$(CONFIG_TTYS0_BAUD) \
CONFIG_PXE_CUSTOM_GENERAL_H=$(CONFIG_PXE_CUSTOM_GENERAL_H) \
Expand Down
4 changes: 2 additions & 2 deletions payloads/external/Memtest86Plus/Makefile
Expand Up @@ -15,12 +15,12 @@

TAG-$(CONFIG_MEMTEST_MASTER)=origin/master
NAME-$(CONFIG_MEMTEST_MASTER)=Master
TAG-$(CONFIG_MEMTEST_STABLE)=7afa395fe8b11d681b27c38e204814ba643c2108
TAG-$(CONFIG_MEMTEST_STABLE)=08dd5879f6518f79969be0cc96fc180e4293b90c
NAME-$(CONFIG_MEMTEST_STABLE)=Stable

project_name=Memtest86+
project_dir=$(CURDIR)/memtest86plus
project_git_repo=https://github.com/pcengines/memtest86plus.git
project_git_repo=https://review.coreboot.org/memtest86plus.git

all: build

Expand Down
8 changes: 7 additions & 1 deletion payloads/external/SeaBIOS/Kconfig
Expand Up @@ -5,7 +5,7 @@ choice
default SEABIOS_STABLE

config SEABIOS_STABLE
bool "1.10.2.1"
bool "1.11.0.1"
help
Stable SeaBIOS version
config SEABIOS_MASTER
Expand Down Expand Up @@ -116,6 +116,12 @@ config SEABIOS_BOOTMENU_MESSAGE_FILE
help
TBD

config SEABIOS_SERCON_PORT_FILE
string "SeaBIOS sercon-port file"
default "$(top)/src/mainboard/$(MAINBOARDDIR)/sercon-port"
help
TBD

config PAYLOAD_FILE
default "payloads/external/SeaBIOS/seabios/out/bios.bin.elf"

Expand Down
3 changes: 1 addition & 2 deletions payloads/external/SeaBIOS/Makefile
@@ -1,5 +1,5 @@
TAG-$(CONFIG_SEABIOS_MASTER)=origin/master
TAG-$(CONFIG_SEABIOS_STABLE)=rel-1.10.2.1
TAG-$(CONFIG_SEABIOS_STABLE)=rel-1.11.0.1
TAG-$(CONFIG_SEABIOS_REVISION)=$(CONFIG_SEABIOS_REVISION_ID)

project_git_repo=https://github.com/pcengines/seabios.git
Expand Down Expand Up @@ -40,7 +40,6 @@ config: checkout
echo " CONFIG SeaBIOS $(TAG-y)"
echo "CONFIG_COREBOOT=y" > seabios/.config
ifeq ($(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO),yy)
echo "CONFIG_SEABIOS_SERIAL_CONSOLE=y" >> seabios/.config
echo "CONFIG_DEBUG_SERIAL=y" >> seabios/.config
echo "CONFIG_DEBUG_SERIAL_PORT=$(CONFIG_TTYS0_BASE)" >> seabios/.config
echo "CONFIG_DEBUG_LEVEL=$(CONFIG_SEABIOS_DEBUG_LEVEL)" >> seabios/.config
Expand Down
7 changes: 7 additions & 0 deletions payloads/external/iPXE/Kconfig
Expand Up @@ -63,6 +63,13 @@ config PXE_ROM_FILE
help
The path and filename of the file to use as PXE ROM.

config PXE_SERIAL_CONSOLE
bool "Enable serial console"
def_bool n
help
Enable/disable iPXE serial console. Since SeaBIOS supports serial
console this option might be helpful to avoid duplicated output.

config PXE_ROM_ID
string "network card PCI IDs"
default "8086,157b"
Expand Down
4 changes: 2 additions & 2 deletions payloads/external/sortbootorder/Makefile
@@ -1,4 +1,4 @@
version=4.6.3
version=4.6.4
branch_name=v$(version)
project_url=https://github.com/pcengines/sortbootorder/archive/$(branch_name).tar.gz
archive_name=$(branch_name).tar.gz
Expand All @@ -14,7 +14,7 @@ all: sortbootorder

sortbootorder: download
echo " MAKE sortbootorder "
$(MAKE) -C sortbootorder
$(MAKE) -C sortbootorder VERSION=$(branch_name)

download:
test -d sortbootorder || { wget $(project_url); \
Expand Down
3 changes: 2 additions & 1 deletion src/cpu/amd/pi/spi.c
Expand Up @@ -17,7 +17,8 @@
#include <spi-generic.h>
#include <spi_flash.h>

#include "s3_resume.h"
// #include "s3_resume.h"
void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len);

void spi_SaveS3info(u32 pos, u32 size, u8 *buf, u32 len)
{
Expand Down
10 changes: 8 additions & 2 deletions src/drivers/spi/spi_flash.c
Expand Up @@ -72,8 +72,8 @@ int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t le
return ret;
}

static int spi_flash_cmd_read(const struct spi_slave *spi, const u8 *cmd,
size_t cmd_len, void *data, size_t data_len)
int spi_flash_cmd_read(const struct spi_slave *spi, const u8 *cmd,
size_t cmd_len, void *data, size_t data_len)
{
int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len);
if (ret) {
Expand Down Expand Up @@ -410,6 +410,12 @@ int spi_flash_status(const struct spi_flash *flash, u8 *reg)
return flash->internal_status(flash, reg);
}

int spi_flash_read_sec(const struct spi_flash *flash, u32 offset, size_t len,
void *buf)
{
return flash->internal_read_sec(flash, offset, len, buf);
}

static uint32_t volatile_group_count CAR_GLOBAL;

int spi_flash_volatile_group_begin(const struct spi_flash *flash)
Expand Down
2 changes: 2 additions & 0 deletions src/drivers/spi/spi_flash_internal.h
Expand Up @@ -33,6 +33,8 @@

/* Send a single-byte command to the device and read the response */
int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len);
int spi_flash_cmd_read(const struct spi_slave *spi, const u8 *cmd,
size_t cmd_len, void *data, size_t data_len);

int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
size_t len, void *data);
Expand Down
39 changes: 39 additions & 0 deletions src/drivers/spi/winbond.c
Expand Up @@ -25,6 +25,12 @@
#define CMD_W25_CE 0xc7 /* Chip Erase */
#define CMD_W25_DP 0xb9 /* Deep Power-down */
#define CMD_W25_RES 0xab /* Release from DP, and Read Signature */
#define CMD_W25_RD_SEC 0x48 /* Read security registers */

#define ADDR_W25_SEC1 0x10 /* Address offset for sec register 1 */
#define ADDR_W25_SEC2 0x20 /* Address offset for sec register 2 */
#define ADDR_W25_SEC3 0x30 /* Address offset for sec register 3 */
#define ADDR_W25_SEC_SHIFT 8 /* Address shift for sec registers */

struct winbond_spi_flash_params {
uint16_t id;
Expand Down Expand Up @@ -197,6 +203,38 @@ static int winbond_write(const struct spi_flash *flash, u32 offset, size_t len,
return ret;
}

static int winbond_sec_read(const struct spi_flash *flash, u32 offset,
size_t len, void *buf)
{
int ret;
u8 cmd[5];
u8 reg = (offset >> ADDR_W25_SEC_SHIFT) & 0xFF;
u8 addr = offset & 0xFF;

if ((reg != ADDR_W25_SEC1) &&
(reg != ADDR_W25_SEC2) &&
(reg != ADDR_W25_SEC3)) {
printk(BIOS_WARNING, "SF: Wrong security register\n");
return 1;
}

cmd[0] = CMD_W25_RD_SEC;
cmd[1] = 0x0;
cmd[2] = reg;
cmd[3] = addr;
cmd[4] = 0x0; /* dummy byte */

ret = spi_flash_cmd_read(&flash->spi, cmd, sizeof(cmd), buf, len);
if (ret) {
printk(BIOS_WARNING, "SF: Can't read sec register %d\n",
reg >> 4);
}

return ret;
}



static struct winbond_spi_flash stm;

struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
Expand Down Expand Up @@ -227,6 +265,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
stm.flash.internal_write = winbond_write;
stm.flash.internal_erase = spi_flash_cmd_erase;
stm.flash.internal_status = spi_flash_cmd_status;
stm.flash.internal_read_sec = winbond_sec_read;
#if CONFIG_SPI_FLASH_NO_FAST_READ
stm.flash.internal_read = spi_flash_cmd_read_slow;
#else
Expand Down
4 changes: 4 additions & 0 deletions src/include/spi_flash.h
Expand Up @@ -44,6 +44,8 @@ struct spi_flash {
int (*internal_erase)(const struct spi_flash *flash, u32 offset,
size_t len);
int (*internal_status)(const struct spi_flash *flash, u8 *reg);
int (*internal_read_sec)(const struct spi_flash *flash, u32 offset,
size_t len, void *buf);
};

void lb_spi_flash(struct lb_header *header);
Expand All @@ -65,6 +67,8 @@ int spi_flash_write(const struct spi_flash *flash, u32 offset, size_t len,
const void *buf);
int spi_flash_erase(const struct spi_flash *flash, u32 offset, size_t len);
int spi_flash_status(const struct spi_flash *flash, u8 *reg);
int spi_flash_read_sec(const struct spi_flash * flash, u32 offset, size_t len,
void *buf);
/*
* Some SPI controllers require exclusive access to SPI flash when volatile
* operations like erase or write are being performed. In such cases,
Expand Down
21 changes: 17 additions & 4 deletions src/mainboard/pcengines/apu2/Kconfig
Expand Up @@ -14,7 +14,8 @@
# GNU General Public License for more details.
#

if BOARD_PCENGINES_APU2 || BOARD_PCENGINES_APU3 || BOARD_PCENGINES_APU5
if BOARD_PCENGINES_APU2 || BOARD_PCENGINES_APU3 || BOARD_PCENGINES_APU4 || \
BOARD_PCENGINES_APU5

config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
Expand All @@ -30,7 +31,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select USE_BLOBS
select GENERIC_SPD_BIN
select PXE
select MEMTEST_DISABLE_SPD if MEMTEST_SECONDARY_PAYLOAD
select SPI_FLASH
select SPI_FLASH_WINBOND

config MAINBOARD_DIR
string
Expand All @@ -40,6 +42,7 @@ config VARIANT_DIR
string
default apu2 if BOARD_PCENGINES_APU2
default apu3 if BOARD_PCENGINES_APU3
default apu4 if BOARD_PCENGINES_APU4
default apu5 if BOARD_PCENGINES_APU5

config DEVICETREE
Expand All @@ -50,6 +53,7 @@ config MAINBOARD_PART_NUMBER
string
default "PC Engines apu2" if BOARD_PCENGINES_APU2
default "PC Engines apu3" if BOARD_PCENGINES_APU3
default "PC Engines apu4" if BOARD_PCENGINES_APU4
default "PC Engines apu5" if BOARD_PCENGINES_APU5

config MAX_CPUS
Expand All @@ -74,13 +78,18 @@ config AGESA_BINARY_PI_FILE

choice
prompt "J19 pins 1-10"
default APU2_PINMUX_UART_C
default APU2_PINMUX_UART_C if BOARD_PCENGINES_APU2 || \
BOARD_PCENGINES_APU3 || BOARD_PCENGINES_APU4
default APU2_PINMUX_UART_C if BOARD_PCENGINES_APU5


config APU2_PINMUX_OFF_C
bool "disable"

config APU2_PINMUX_GPIO0
bool "GPIO"
depends on BOARD_PCENGINES_APU2 || BOARD_PCENGINES_APU3 || \
BOARD_PCENGINES_APU4

config APU2_PINMUX_UART_C
bool "UART 0x3e8"
Expand All @@ -89,13 +98,17 @@ endchoice

choice
prompt "J19 pins 11-20"
default APU2_PINMUX_UART_D
default APU2_PINMUX_UART_D if BOARD_PCENGINES_APU2 || \
BOARD_PCENGINES_APU3 || BOARD_PCENGINES_APU4
default APU2_PINMUX_UART_D if BOARD_PCENGINES_APU5

config APU2_PINMUX_OFF_D
bool "disable"

config APU2_PINMUX_GPIO1
bool "GPIO"
depends on BOARD_PCENGINES_APU2 || BOARD_PCENGINES_APU3 || \
BOARD_PCENGINES_APU4

config APU2_PINMUX_UART_D
bool "UART 0x2e8"
Expand Down
3 changes: 3 additions & 0 deletions src/mainboard/pcengines/apu2/Kconfig.name
Expand Up @@ -4,5 +4,8 @@ config BOARD_PCENGINES_APU2
config BOARD_PCENGINES_APU3
bool "APU3"

config BOARD_PCENGINES_APU4
bool "APU4"

config BOARD_PCENGINES_APU5
bool "APU5"
@@ -1,4 +1,4 @@
Board name: PC Engines APU2
Board name: apu2 apu3 apu4 apu5
Board URL: http://www.pcengines.ch/apu2c2.htm
Category: half
ROM protocol: SPI
Expand Down
51 changes: 45 additions & 6 deletions src/mainboard/pcengines/apu2/mainboard.c
Expand Up @@ -32,13 +32,18 @@
#include <cpu/x86/msr.h>
#include <cpu/amd/mtrr.h>
#include <spd_bin.h>
#include <spi_flash.h>
#include <spi-generic.h>
#include "gpio_ftns.h"
#include "bios_knobs.h"

#define PM_RTC_CONTROL 0x56
#define PM_RTC_SHADOW 0x5B
#define PM_S_STATE_CONTROL 0xBA

#define SEC_REG_SERIAL_ADDR 0x1000
#define MAX_SERIAL_LEN 10

/***********************************************************
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
* This table is responsible for physically routing the PIC and
Expand Down Expand Up @@ -260,17 +265,15 @@ static void mainboard_final(void *chip_info)
* We will stuff a modified version of the first NICs (BDF 1:0.0) MAC address
* into the smbios serial number location.
*/
const char *smbios_mainboard_serial_number(void)
{
static char serial[10];
static int read_serial_from_nic(char *serial, size_t len) {
device_t nic_dev;
uintptr_t bar10;
u32 mac_addr = 0;
int i;

nic_dev = dev_find_slot(1, PCI_DEVFN(0, 0));
if ((serial[0] != 0) || !nic_dev)
return serial;
if (!serial || !nic_dev)
return -1;

/* Read in the last 3 bytes of NIC's MAC address. */
bar10 = pci_read_config32(nic_dev, 0x10);
Expand All @@ -284,7 +287,43 @@ const char *smbios_mainboard_serial_number(void)
mac_addr /= 4;
mac_addr -= 64;

snprintf(serial, sizeof(serial), "%d", mac_addr);
snprintf(serial, len, "%d", mac_addr);
return 0;
}

static int read_serial_from_flash(char *serial, size_t len) {
const struct spi_flash *flash = NULL;;
int ret;

flash = boot_device_spi_flash();
if (flash == NULL) {
printk(BIOS_WARNING, "Can't get boot flash device\n");
return -1;
}

ret = spi_flash_read_sec(flash, SEC_REG_SERIAL_ADDR, len, serial);
if (ret) {
printk(BIOS_WARNING, "Can't read security registers\n");
return ret;
}

return ret;
}

const char *smbios_mainboard_serial_number(void)
{
static char serial[MAX_SERIAL_LEN + 1] = { 0 }; /* extra slot for \0 */
int ret;

ret = read_serial_from_flash(serial, sizeof(serial)-1);
if (ret || (serial[0] == 0) || (serial[0] == 0xff)) {
ret = read_serial_from_nic(serial, sizeof(serial)-1);
if (ret) {
serial[0] = '0';
serial[1] = '\0';
}
}

return serial;
}

Expand Down
6 changes: 3 additions & 3 deletions src/mainboard/pcengines/apu2/romstage.c
Expand Up @@ -93,7 +93,7 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
data &= 0xFFFF0000;
data |= (0 + 1) << (0 * 4); // CLKREQ 0 to CLK0
data |= (1 + 1) << (1 * 4); // CLKREQ 1 to CLK1
#if CONFIG_BOARD_PCENGINES_APU2 || CONFIG_BOARD_PCENGINES_APU3
#if CONFIG_BOARD_PCENGINES_APU2 || CONFIG_BOARD_PCENGINES_APU3 || CONFIG_BOARD_PCENGINES_APU4
data |= (2 + 1) << (2 * 4); // CLKREQ 2 to CLK2 disabled on APU5
#endif
// make CLK3 to ignore CLKREQ# input
Expand Down Expand Up @@ -172,7 +172,7 @@ static void early_lpc_init(void)
//
// Configure output disabled, value low, pull up/down disabled
//
#if CONFIG_BOARD_PCENGINES_APU2 || CONFIG_BOARD_PCENGINES_APU3
#if CONFIG_BOARD_PCENGINES_APU2 || CONFIG_BOARD_PCENGINES_APU3 || CONFIG_BOARD_PCENGINES_APU4
configure_gpio(IOMUX_GPIO_32, Function0, GPIO_32, setting);
#endif
configure_gpio(IOMUX_GPIO_49, Function2, GPIO_49, setting);
Expand All @@ -182,7 +182,7 @@ static void early_lpc_init(void)
// Configure output enabled, value low, pull up/down disabled
//
setting = GPIO_OUTPUT_ENABLE;
#if CONFIG_BOARD_PCENGINES_APU3
#if CONFIG_BOARD_PCENGINES_APU3 || CONFIG_BOARD_PCENGINES_APU4
configure_gpio(IOMUX_GPIO_33, Function0, GPIO_33, setting);
#endif
configure_gpio(IOMUX_GPIO_57, Function1, GPIO_57, setting);
Expand Down
Binary file added src/mainboard/pcengines/apu2/sercon-port
Binary file not shown.
Binary file modified src/mainboard/pcengines/apu2/variants/apu2/bootorder
Binary file not shown.
6 changes: 0 additions & 6 deletions src/mainboard/pcengines/apu2/variants/apu3/board_info.txt

This file was deleted.

Binary file modified src/mainboard/pcengines/apu2/variants/apu3/bootorder
Binary file not shown.
Binary file not shown.
91 changes: 91 additions & 0 deletions src/mainboard/pcengines/apu2/variants/apu4/devicetree.cb
@@ -0,0 +1,91 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2013 Advanced Micro Devices, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
chip northbridge/amd/pi/00730F01/root_complex
device cpu_cluster 0 on
chip cpu/amd/pi/00730F01
device lapic 0 on end
end
end

device domain 0 on
subsystemid 0x1022 0x1410 inherit
chip northbridge/amd/pi/00730F01 # CPU side of HT root complex

chip northbridge/amd/pi/00730F01 # PCI side of HT root complex
device pci 0.0 on end # Root Complex
device pci 0.2 off end # IOMMU
device pci 1.0 off end # Internal Graphics P2P bridge 0x9804
device pci 1.1 off end # Internal Multimedia
device pci 2.0 on end # PCIe Host Bridge
device pci 2.1 on end # LAN1
device pci 2.2 on end # LAN2
device pci 2.3 on end # LAN3
device pci 2.4 on end # LAN4
device pci 2.5 on end # mPCIe slot 1
device pci 8.0 on end # Platform Security Processor
end #chip northbridge/amd/pi/00730F01

chip southbridge/amd/pi/hudson # it is under NB/SB Link, but on the same pci bus
device pci 10.0 on end # XHCI HC0 muxed with EHCI 2
device pci 11.0 on end # SATA
device pci 12.0 on end # USB EHCI0 usb[0:3] is connected
device pci 13.0 on end # USB EHCI1 usb[4:7]
device pci 14.0 on end # SM
device pci 14.3 on # LPC 0x439d
chip superio/nuvoton/nct5104d # SIO NCT5104D
register "irq_trigger_type" = "0"
device pnp 2e.0 off end
device pnp 2e.2 on
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.3 on
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.10 on
# UART C is conditionally turned on
io 0x60 = 0x3e8
irq 0x70 = 4
end
device pnp 2e.11 on
# UART D is conditionally turned on
io 0x60 = 0x2e8
irq 0x70 = 3
end
device pnp 2e.8 off end
device pnp 2e.f off end
# GPIO0 and GPIO1 are conditionally turned on
device pnp 2e.007 on end
device pnp 2e.107 on end
device pnp 2e.607 off end
device pnp 2e.e off end
end # SIO NCT5104D
end # LPC 0x439d

device pci 14.7 on end # SD
device pci 16.0 on end # USB EHCI2 usb[8:7] - muxed with XHCI
end #chip southbridge/amd/pi/hudson

device pci 18.0 on end
device pci 18.1 on end
device pci 18.2 on end
device pci 18.3 on end
device pci 18.4 on end
device pci 18.5 on end

end #chip northbridge/amd/pi/00730F01 # CPU side of HT root complex
end #domain
end #northbridge/amd/pi/00730F01/root_complex
5 changes: 0 additions & 5 deletions src/mainboard/pcengines/apu2/variants/apu5/board_info.txt

This file was deleted.

Binary file modified src/mainboard/pcengines/apu2/variants/apu5/bootorder
Binary file not shown.
1 change: 1 addition & 0 deletions src/southbridge/amd/pi/hudson/Makefile.inc
Expand Up @@ -39,6 +39,7 @@ ramstage-y += hda.c
ramstage-y += pci.c
ramstage-y += pcie.c
ramstage-y += sd.c
ramstage-$(CONFIG_SPI_FLASH) += spi.c
ramstage-$(CONFIG_SOUTHBRIDGE_AMD_PI_KERN) += gpio.c

ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
Expand Down
175 changes: 175 additions & 0 deletions src/southbridge/amd/pi/hudson/spi.c
@@ -0,0 +1,175 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2012 Advanced Micro Devices, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <arch/io.h>
#include <console/console.h>
#include <spi_flash.h>
#include <spi-generic.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>

#include <Proc/Fch/FchPlatform.h>

#define SPI_REG_OPCODE 0x0
#define SPI_REG_CNTRL02 0x2
#define CNTRL02_FIFO_RESET (1 << 4)
#define CNTRL02_EXEC_OPCODE (1 << 0)
#define SPI_REG_CNTRL03 0x3
#define CNTRL03_SPIBUSY (1 << 7)
#define SPI_REG_FIFO 0xc
#define SPI_REG_CNTRL11 0xd
#define CNTRL11_FIFOPTR_MASK 0x07
#define SPI_EXT_REG_INDX 0x1e
#define SPI_EXT_REG_TXCOUNT 0x5
#define SPI_EXT_REG_RXCOUNT 0x6
#define SPI_EXT_REG_DATA 0x1f

#if IS_ENABLED(CONFIG_SOUTHBRIDGE_AMD_AGESA_YANGTZE)
#define AMD_SB_SPI_TX_LEN 64
#else
#define AMD_SB_SPI_TX_LEN 8
#endif

static uintptr_t spibar;

static inline uint8_t spi_read(uint8_t reg)
{
return read8((void *)(spibar + reg));
}

static inline void spi_write(uint8_t reg, uint8_t val)
{
write8((void *)(spibar + reg), val);
}

static void reset_internal_fifo_pointer(void)
{
uint8_t reg8;

do {
reg8 = spi_read(SPI_REG_CNTRL02);
reg8 |= CNTRL02_FIFO_RESET;
spi_write(SPI_REG_CNTRL02, reg8);
} while (spi_read(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK);
}

static void execute_command(void)
{
uint8_t reg8;

reg8 = spi_read(SPI_REG_CNTRL02);
reg8 |= CNTRL02_EXEC_OPCODE;
spi_write(SPI_REG_CNTRL02, reg8);

while ((spi_read(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) &&
(spi_read(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY));
}

void spi_init(void)
{
device_t dev;

dev = dev_find_slot(0, PCI_DEVFN(0x14, 3));
spibar = pci_read_config32(dev, 0xA0) & ~0x1F;
}

unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len)
{
return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len);
}

static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
size_t bytesout, void *din, size_t bytesin)
{
/* First byte is cmd which can not being sent through FIFO. */
u8 cmd = *(u8 *)dout++;
size_t count;

bytesout--;

/*
* Check if this is a write command attempting to transfer more bytes
* than the controller can handle. Iterations for writes are not
* supported here because each SPI write command needs to be preceded
* and followed by other SPI commands, and this sequence is controlled
* by the SPI chip driver.
*/
if (bytesout > AMD_SB_SPI_TX_LEN) {
printk(BIOS_WARNING, "FCH SPI: Too much to write. Does your SPI chip driver use"
" spi_crop_chunk()?\n");
return -1;
}

spi_write(SPI_EXT_REG_INDX, SPI_EXT_REG_TXCOUNT);
spi_write(SPI_EXT_REG_DATA, bytesout);
spi_write(SPI_EXT_REG_INDX, SPI_EXT_REG_RXCOUNT);
spi_write(SPI_EXT_REG_DATA, bytesin);

spi_write(SPI_REG_OPCODE, cmd);

reset_internal_fifo_pointer();
for (count = 0; count < bytesout; count++, dout++) {
spi_write(SPI_REG_FIFO, *(uint8_t *)dout);
}

reset_internal_fifo_pointer();
execute_command();

reset_internal_fifo_pointer();
/* Skip the bytes we sent. */
for (count = 0; count < bytesout; count++) {
cmd = spi_read(SPI_REG_FIFO);
}

for (count = 0; count < bytesin; count++, din++) {
*(uint8_t *)din = spi_read(SPI_REG_FIFO);
}

return 0;
}

int chipset_volatile_group_begin(const struct spi_flash *flash)
{
if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))
return 0;

ImcSleep(NULL);
return 0;
}

int chipset_volatile_group_end(const struct spi_flash *flash)
{
if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM))
return 0;

ImcWakeup(NULL);
return 0;
}

static const struct spi_ctrlr spi_ctrlr = {
.xfer = spi_ctrlr_xfer,
.xfer_vector = spi_xfer_two_vectors,
};

int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
{
slave->bus = bus;
slave->cs = cs;
slave->ctrlr = &spi_ctrlr;
return 0;
}