17 changes: 17 additions & 0 deletions include/flash_access.h
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2017 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef FLASH_ACCESS_H
#define FLASH_ACCESS_H

Expand Down
17 changes: 17 additions & 0 deletions include/sec_reg_menu.h
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2017 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef SEC_REG_MENU_H
#define SEC_REG_MENU_H

Expand Down
30 changes: 26 additions & 4 deletions sortbootorder.c
Expand Up @@ -61,10 +61,17 @@ static u8 usb_toggle;
static u8 spi_wp_toggle;

static u8 console_toggle;

#ifndef TARGET_APU1
static u8 ehci0_toggle;
#endif

static u8 uartc_toggle;
static u8 uartd_toggle;

#ifndef TARGET_APU1
static u8 mpcie2_clk_toggle;
#endif

static char bootlist_def[MAX_DEVICES][MAX_LENGTH];
static char bootlist_map[MAX_DEVICES][MAX_LENGTH];
Expand Down Expand Up @@ -107,7 +114,11 @@ int main(void) {
noecho(); /* don't echo keystrokes */
#endif

#ifdef TARGET_APU1
printf("\n### PC Engines apu1 setup %s ###\n", SORTBOOTORDER_VER);
#else
printf("\n### PC Engines apu2 setup %s ###\n", SORTBOOTORDER_VER);
#endif

if (init_flash()) {
printf("Can't initialize flash device!\n");
Expand Down Expand Up @@ -145,9 +156,11 @@ int main(void) {
token += strlen("scon");
console_toggle = token ? strtoul(token, NULL, 10) : 1;

#ifndef TARGET_APU1
token = cbfs_find_string("ehcien", BOOTORDER_FILE);
token += strlen("ehcien");
ehci0_toggle = token ? strtoul(token, NULL, 10) : 1;
#endif

token = cbfs_find_string("uartc", BOOTORDER_FILE);
token += strlen("uartc");
Expand All @@ -157,10 +170,11 @@ int main(void) {
token += strlen("uartd");
uartd_toggle = token ? strtoul(token, NULL, 10) : 0;

#ifndef TARGET_APU1
token = cbfs_find_string("mpcie2_clk", BOOTORDER_FILE);
token += strlen("mpcie2_clk");
mpcie2_clk_toggle = token ? strtoul(token, NULL, 10) : 0;

#endif

spi_wp_toggle = is_flash_locked();

Expand Down Expand Up @@ -208,6 +222,7 @@ int main(void) {
case 'P':
uartd_toggle ^= 0x1;
break;
#ifndef TARGET_APU1
case 'm':
case 'M':
mpcie2_clk_toggle ^= 0x1;
Expand All @@ -219,15 +234,18 @@ int main(void) {
case 'Z':
handle_reg_sec_menu();
break;
#endif
case 's':
case 'S':
update_tag_value(bootlist, &max_lines, "pxen", ipxe_toggle + '0');
update_tag_value(bootlist, &max_lines, "usben", usb_toggle + '0');
update_tag_value(bootlist, &max_lines, "scon", console_toggle + '0');
update_tag_value(bootlist, &max_lines, "uartc", uartc_toggle + '0');
update_tag_value(bootlist, &max_lines, "uartd", uartd_toggle + '0');
#ifndef TARGET_APU1
update_tag_value(bootlist, &max_lines, "mpcie2_clk", mpcie2_clk_toggle + '0');
update_tag_value(bootlist, &max_lines, "ehcien", ehci0_toggle + '0');
#endif
save_flash(flash_address, bootlist, max_lines, spi_wp_toggle);
// fall through to exit ...
case 'x':
Expand Down Expand Up @@ -323,8 +341,10 @@ static void show_boot_device_list( char buffer[MAX_DEVICES][MAX_LENGTH], u8 line
printf(" t Serial console - Currently %s\n", (console_toggle) ? "Enabled" : "Disabled");
printf(" o UART C - Currently %s\n", (uartc_toggle) ? "Enabled" : "Disabled");
printf(" p UART D - Currently %s\n", (uartd_toggle) ? "Enabled" : "Disabled");
#ifndef TARGET_APU1
printf(" m Force mPCIe2 slot CLK (GPP3 PCIe) - Currently %s\n", (mpcie2_clk_toggle) ? "Enabled" : "Disabled");
printf(" h EHCI0 controller - Currently %s\n", (ehci0_toggle) ? "Enabled" : "Disabled");
#endif
printf(" w Enable BIOS write protect - Currently %s\n", (spi_wp_toggle) ? "Enabled" : "Disabled");
printf(" x Exit setup without save\n");
printf(" s Save configuration and exit\n");
Expand Down Expand Up @@ -353,7 +373,7 @@ static int fetch_file_from_cbfs( char *filename, char destination[MAX_DEVICES][M

cbfs_dat = (char *) cbfs_get_file_content( CBFS_DEFAULT_MEDIA, filename, CBFS_TYPE_RAW, &cbfs_length );
if (!cbfs_dat) {
printf("Error: file [%%s] not found!\n");
printf("Error: file [%s] not found!\n", filename);
return 1;
}

Expand Down Expand Up @@ -463,12 +483,13 @@ static void refresh_tag_values(u8 max_lines)
token += strlen("scon");
console_toggle = strtoul(token, NULL, 10);
}

#ifndef TARGET_APU1
token = strstr(&(bootlist_def[i][0]), "ehcien");
if(token) {
token += strlen("ehcien");
ehci0_toggle = strtoul(token, NULL, 10);
}
#endif

token = strstr(&(bootlist_def[i][0]), "uartc");
if(token) {
Expand All @@ -481,11 +502,12 @@ static void refresh_tag_values(u8 max_lines)
token += strlen("uartd");
uartd_toggle = strtoul(token, NULL, 10);
}

#ifndef TARGET_APU1
token = strstr(&(bootlist_def[i][0]), "mpcie2_clk");
if(token) {
token += strlen("mpcie2_clk");
mpcie2_clk_toggle = strtoul(token, NULL, 10);
}
#endif
}
}
130 changes: 125 additions & 5 deletions spi/macronix.c
Expand Up @@ -50,6 +50,13 @@
#define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature */

#define MACRONIX_SR_WIP (1 << 0) /* Write-in-Progress */
#define MACRONIX_SR_WEN (1 << 0)
#define MACRONIX_SR_BP0 (1 << 2)
#define MACRONIX_SR_BP1 (1 << 3)
#define MACRONIX_SR_BP2 (1 << 4)
#define MACRONIX_SR_BP3 (1 << 5)
#define MACRONIX_SR_SRWD (1 << 7)


struct macronix_spi_flash_params {
u16 idcode;
Expand Down Expand Up @@ -187,6 +194,109 @@ static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len)
return spi_flash_cmd_erase(flash, CMD_MX25XX_SE, offset, len);
}

static int macronix_set_lock_flags(struct spi_flash *flash, int lock)
{
int ret;
u8 cmd;
u8 status;

flash->spi->rw = SPI_WRITE_FLAG;
ret = spi_claim_bus(flash->spi);
if (ret) {
spi_debug("SF: Unable to claim SPI bus\n");
return ret;
}

ret = spi_flash_cmd(flash->spi, CMD_MX25XX_RDSR, &status, 1);
if (ret) {
goto out;
}

if (lock) {
status |= MACRONIX_SR_BP3 | MACRONIX_SR_BP2 | MACRONIX_SR_BP1 | MACRONIX_SR_BP0;
} else {
status &= ~(MACRONIX_SR_BP3 | MACRONIX_SR_BP2 | MACRONIX_SR_BP1 | MACRONIX_SR_BP0);
}


ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0);
if (ret < 0) {
spi_debug("SF: Enabling Write failed\n");
goto out;
}

cmd = CMD_MX25XX_WRSR;
ret = spi_flash_cmd_write(flash->spi, &cmd, sizeof(cmd), &status, sizeof(status));
if (ret < 0) {
spi_debug("SF: Status register write failed\n");
goto out;
}

spi_flash_cmd_wait_ready(flash, 100);

ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WRDI, NULL, 0);
if (ret < 0) {
spi_debug("SF: Status register write disable failed\n");
goto out;
}

ret = spi_flash_cmd_wait_ready(flash, 100);
out:
spi_release_bus(flash->spi);
return ret;
}


static int macronix_unlock(struct spi_flash *flash)
{
return macronix_set_lock_flags(flash, 0);
}

static int macronix_lock(struct spi_flash *flash)
{
return macronix_set_lock_flags(flash, 1);
}

static int macronix_is_locked(struct spi_flash *flash)
{
u8 status = 0;

spi_flash_cmd(flash->spi, CMD_MX25XX_RDSR, &status, 1);

if ((status & (MACRONIX_SR_BP3 | MACRONIX_SR_BP2 | MACRONIX_SR_BP1 | MACRONIX_SR_BP0))
== (MACRONIX_SR_BP3 | MACRONIX_SR_BP2 | MACRONIX_SR_BP1 | MACRONIX_SR_BP0)) {
return 1;
}

return 0;
}

static int macronix_sec_read(struct spi_flash *flash, u32 offset, size_t len, void *buf)
{
// TODO
return 0;
}

static int macronix_sec_program(struct spi_flash *flash, u32 offset, size_t len, const void *buf)
{
// TODO
return 0;
}

static int macronix_sec_sts(struct spi_flash *flash)
{
// TODO
return 0;
}

static int macronix_sec_lock(struct spi_flash *flash, u8 reg)
{
// TODO
return 0;
}



struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
{
const struct macronix_spi_flash_params *params;
Expand Down Expand Up @@ -214,14 +324,24 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
mcx->params = params;
mcx->flash.spi = spi;
mcx->flash.name = params->name;

mcx->flash.write = macronix_write;
mcx->flash.spi_erase = macronix_erase;
#if CONFIG_SPI_FLASH_NO_FAST_READ
mcx->flash.read = spi_flash_cmd_read_slow;
#else
mcx->flash.lock = macronix_lock;
mcx->flash.unlock = macronix_unlock;
mcx->flash.is_locked = macronix_is_locked;
/* The following are not yet implemented.
* Implement to enable BIOS WP and Security Registers support.
*/
mcx->flash.sec_sts = macronix_sec_sts;
mcx->flash.sec_read = macronix_sec_read;
mcx->flash.sec_prog = macronix_sec_program;
mcx->flash.sec_lock = macronix_sec_lock;

//#if CONFIG_SPI_FLASH_NO_FAST_READ
// mcx->flash.read = spi_flash_cmd_read_slow;
//#else
mcx->flash.read = spi_flash_cmd_read_fast;
#endif
//#endif
mcx->flash.sector_size = params->page_size * params->pages_per_sector;
mcx->flash.size = mcx->flash.sector_size * params->sectors_per_block *
params->nr_blocks;
Expand Down
22 changes: 13 additions & 9 deletions spi/spi.c
Expand Up @@ -18,6 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -37,7 +38,6 @@ static u32 spibar;
//
// Support for YANGTZEE FCH spi controller
//
#define FCH_YANGTZEE

#ifdef SPI_TRACE_ENABLED
#define SPI_TRACE(...) printf( __VA_ARGS__);
Expand Down Expand Up @@ -171,16 +171,18 @@ int spi_xfer(struct spi_slave *slave,
//
#else

#define FIFO_SIZE_OLD 8

static void reset_internal_fifo_pointer(void)
{
do {
writeb(spibar + 2, readb(spibar + 2) | 0x10);
writeb(readb(spibar + 2) | 0x10, spibar + 2);
} while (readb(spibar + 0xD) & 0x7);
}

static void execute_command(void)
{
writeb(spibar + 2, readb(spibar + 2) | 1);
writeb(readb(spibar + 2) | 1, spibar + 2);

while ((readb(spibar + 2) & 1) && (readb(spibar+3) & 0x80));
}
Expand All @@ -189,9 +191,9 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
unsigned int bitsout, void *din, unsigned int bitsin)
{
/* First byte is cmd which can not being sent through FIFO. */
u32 cmd = *(u32 *)dout++;
u8 cmd = *(u8 *)dout++;
u8 readoffby1;
u32 readwrite;
u8 readwrite;
u8 bytesout, bytesin;
u8 count;

Expand All @@ -202,12 +204,12 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
readoffby1 = bytesout ? 0 : 1;

readwrite = (bytesin + readoffby1) << 4 | bytesout;
writeb(spibar + 1, readwrite);
writeb(spibar + 0, cmd);
writeb(readwrite, spibar + 1);
writeb(cmd, spibar + 0);

reset_internal_fifo_pointer();
for (count = 0; count < bytesout; count++, dout++) {
writeb(spibar + 0x0C, *(u32 *)dout);
writeb(*(u8 *)dout, spibar + 0x0C);
}

reset_internal_fifo_pointer();
Expand All @@ -216,13 +218,15 @@ int spi_xfer(struct spi_slave *slave, const void *dout,
reset_internal_fifo_pointer();
/* Skip the bytes we sent. */
for (count = 0; count < bytesout; count++) {
cmd = readb(spibar + 0x0C);
readb(spibar + 0x0C);
}

//reset_internal_fifo_pointer();
for (count = 0; count < bytesin; count++, din++) {
*(u8 *)din = readb(spibar + 0x0C);
}

return 0;
}
#endif

Expand Down
13 changes: 13 additions & 0 deletions spi/spi_flash_internal.h
Expand Up @@ -3,6 +3,19 @@
*
* Copyright (C) 2008 Atmel Corporation
* Copyright (c) 2014 Sage Electronic Engineering, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

/* Common parameters -- kind of high, but they should only occur when there
Expand Down
17 changes: 17 additions & 0 deletions utils/flash_access.c
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2017 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#define CONFIG_SPI_FLASH_NO_FAST_READ

#include <spi/spi_flash.h>
Expand Down
17 changes: 17 additions & 0 deletions utils/sec_reg_menu.c
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2017 PC Engines GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <libpayload.h>
#include <curses.h>
#include <flash_access.h>
Expand Down