Expand Up
@@ -19,7 +19,7 @@
#include <libpayload.h>
#include <cbfs.h>
#include <curses.h>
#include "spi .h"
#include "spi_flash .h"
#include "version.h"
/*** defines ***/
Expand All
@@ -46,23 +46,39 @@
#define MPCIE1_SATA2 8
#define IPXE 9
#define RESET () outb(0x06, 0x0cf9)
/*** prototypes ***/
static void show_boot_device_list ( char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 line_cnt , u8 lineDef_cnt );
static void move_boot_list ( char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 line , u8 max_lines );
static void copy_list_line ( char * src , char * dest );
static int fetch_file_from_cbfs ( char * filename , char destination [MAX_DEVICES ][MAX_LENGTH ], u8 * line_count );
static int get_line_number (u8 line_start , u8 line_end , char key );
static void int_ids ( char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 line_cnt , u8 lineDef_cnt );
static inline int init_flash (void );
static inline int is_flash_locked (void );
static inline int lock_flash (void );
static inline int unlock_flash (void );
static void save_flash (char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 max_lines );
static void update_tag_value (char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 * max_lines , const char * tag , char value );
/*** local variables ***/
static u8 ipxe_toggle ;
static u8 usb_toggle ;
static u8 sga_toggle ;
static u8 spi_wp_toggle ;
#ifdef COREBOOT_LEGACY
static u8 console_toggle ;
static u8 ehci0_toggle ;
static u8 uartc_toggle ;
static u8 uartd_toggle ;
#endif
static char bootlist_def [MAX_DEVICES ][MAX_LENGTH ];
static char bootlist_map [MAX_DEVICES ][MAX_LENGTH ];
static char id [MAX_DEVICES ] = {0 };
static struct spi_flash * flash_device ;
static int flash_address ;
static u8 device_toggle [MAX_DEVICES ];
Expand All
@@ -72,13 +88,7 @@ static u8 device_toggle[MAX_DEVICES];
* 1) Display a list of boot devices
* 2) Chosen device will be moved to the top and reset shuffled down
* 3) Display the new boot order
* 4) Give the option to:
* - Restore order defaults,
* - Serial console disable / enable
* - Network / IPXE disable / enable
* - USB boot disable / enable
* - SgaBios disable / enable
* - Exit with or without saving order
* 4) Enable/disable the chosen option
*/
int main (void ) {
Expand All
@@ -91,7 +101,9 @@ int main(void) {
u8 line_start = 0 ;
u8 line_number = 0 ;
char * token ;
#ifndef COREBOOT_LEGACY
struct cbfs_handle * bootorder_handle ;
#endif
// Set to enabled because enable toggle is not (yet) implemented for these devices
device_toggle [SDCARD ] = 1 ;
Expand All
@@ -107,11 +119,23 @@ int main(void) {
printf ("\n### PC Engines apu2 setup %s ###\n" , SORTBOOTORDER_VER );
if (init_flash ()) {
printf ("Can't initialize flash device!\n" );
RESET ();
}
// Find out where the bootorder file is in rom
#ifndef COREBOOT_LEGACY
bootorder_handle = cbfs_get_handle ( CBFS_DEFAULT_MEDIA , BOOTORDER_FILE );
flash_address = bootorder_handle -> media_offset + bootorder_handle -> content_offset ;
if ((u32 )flash_address & 0xfff )
printf ("Warning: The bootorder file is not 4k aligned!\n" );
#else
char * tmp = cbfs_get_file_content ( CBFS_DEFAULT_MEDIA , BOOTORDER_FILE , CBFS_TYPE_RAW , NULL );
flash_address = (int )tmp ;
if ((u32 )tmp & 0xfff )
printf ("Warning: The bootorder file is not 4k aligned!\n" );
#endif
// Get required files from CBFS
fetch_file_from_cbfs ( BOOTORDER_FILE , bootlist , & max_lines );
Expand All
@@ -131,6 +155,26 @@ int main(void) {
token += strlen ("sgaen" );
sga_toggle = token ? strtoul (token , NULL , 10 ) : 0 ;
#ifdef COREBOOT_LEGACY
token = cbfs_find_string ("scon" , BOOTORDER_FILE );
token += strlen ("scon" );
console_toggle = token ? strtoul (token , NULL , 10 ) : 1 ;
token = cbfs_find_string ("ehcien" , BOOTORDER_FILE );
token += strlen ("ehcien" );
ehci0_toggle = token ? strtoul (token , NULL , 10 ) : 1 ;
token = cbfs_find_string ("uartc" , BOOTORDER_FILE );
token += strlen ("uartc" );
uartc_toggle = token ? strtoul (token , NULL , 10 ) : 0 ;
token = cbfs_find_string ("uartd" , BOOTORDER_FILE );
token += strlen ("uartd" );
uartd_toggle = token ? strtoul (token , NULL , 10 ) : 0 ;
#endif
spi_wp_toggle = is_flash_locked ();
show_boot_device_list ( bootlist , max_lines , bootlist_def_ln );
int_ids ( bootlist , max_lines , bootlist_def_ln );
Expand All
@@ -157,17 +201,50 @@ int main(void) {
case 'L' :
sga_toggle ^= 0x1 ;
break ;
case 'w' :
case 'W' :
if (spi_wp_toggle ) {
unlock_flash ();
} else {
lock_flash ();
}
spi_wp_toggle = is_flash_locked ();
break ;
#ifdef COREBOOT_LEGACY
case 't' :
case 'T' :
console_toggle ^= 0x1 ;
break ;
case 'o' :
case 'O' :
uartc_toggle ^= 0x1 ;
break ;
case 'p' :
case 'P' :
uartd_toggle ^= 0x1 ;
break ;
case 'h' :
case 'H' :
ehci0_toggle ^= 0x1 ;
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 , "sgaen" , sga_toggle + '0' );
#ifdef COREBOOT_LEGACY
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' );
update_tag_value (bootlist , & max_lines , "ehcien" , ehci0_toggle + '0' );
#endif
save_flash ( bootlist , max_lines );
// fall through to exit ...
case 'x' :
case 'X' :
printf ("\nExiting ..." );
outb ( 0x06 , 0x0cf9 ); /* reset */
RESET ();
break ;
default :
if (key >= 'a' && key <= 'j' ) {
Expand Down
Expand Up
@@ -251,8 +328,15 @@ static void show_boot_device_list( char buffer[MAX_DEVICES][MAX_LENGTH], u8 line
printf ("\n\n" );
printf (" r Restore boot order defaults\n" );
printf (" n Network/PXE boot - Currently %s\n" , (ipxe_toggle ) ? "Enabled" : "Disabled" );
printf (" l Serial console redirection - Currently %s\n" , (sga_toggle ) ? "Enabled" : "Disabled" );
printf (" u USB boot - Currently %s\n" , (usb_toggle ) ? "Enabled" : "Disabled" );
printf (" l Legacy console redirection - Currently %s\n" , (sga_toggle ) ? "Enabled" : "Disabled" );
#ifdef COREBOOT_LEGACY
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" );
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
@@ -337,13 +421,41 @@ static void move_boot_list( char buffer[MAX_DEVICES][MAX_LENGTH], u8 line, u8 ma
id [0 ] = ln ;
}
/*******************************************************************************/
static inline int init_flash (void )
{
flash_device = spi_flash_probe (0 , 0 , 0 , 0 );
if (!flash_device )
return -1 ;
return 0 ;
}
/*******************************************************************************/
static inline int is_flash_locked (void )
{
return spi_flash_is_locked (flash_device );
}
/*******************************************************************************/
static inline int lock_flash (void )
{
return spi_flash_lock (flash_device );
}
/*******************************************************************************/
static inline int unlock_flash (void )
{
return spi_flash_unlock (flash_device );
}
/*******************************************************************************/
static void save_flash (char buffer [MAX_DEVICES ][MAX_LENGTH ], u8 max_lines ) {
int i = 0 ;
int k = 0 ;
int j , ret ;
char cbfs_formatted_list [MAX_DEVICES * MAX_LENGTH ];
struct spi_flash * flash ;
u32 nvram_pos ;
// compact the table into the expected packed list
Expand All
@@ -356,28 +468,45 @@ static void save_flash(char buffer[MAX_DEVICES][MAX_LENGTH], u8 max_lines) {
k ++ ;
}
}
cbfs_formatted_list [i ++ ] = NUL ;
spi_init ();
flash = spi_flash_probe (0 , 0 , 0 , 0 );
if (!flash )
printf ("Could not find SPI device\n" );
else {
printf ("Erasing Flash size 0x%x @ 0x%x\n" , FLASH_SIZE_CHUNK , flash_address );
ret = flash -> spi_erase (flash , flash_address , FLASH_SIZE_CHUNK );
if (ret ) {
printf ("Erase failed, ret: %d\n" , ret );
// try to unlock the flash if it is locked
if (spi_flash_is_locked (flash_device )) {
spi_flash_unlock (flash_device );
if (spi_flash_is_locked (flash_device )) {
printf ("Flash is write protected. Exiting...\n" );
return ;
}
flash -> spi -> rw = SPI_WRITE_FLAG ;
printf ("Writing %d bytes @ 0x%x\n" , i , flash_address );
/* write first 512 bytes */
for (nvram_pos = 0 ; nvram_pos < (i & 0x1FC ); nvram_pos += 4 ) {
flash -> write (flash , nvram_pos + flash_address , sizeof (u32 ), (u32 * )(cbfs_formatted_list + nvram_pos ));
}
printf ("Erasing Flash size 0x%x @ 0x%x\n" , FLASH_SIZE_CHUNK , flash_address );
ret = spi_flash_erase (flash_device , flash_address , FLASH_SIZE_CHUNK );
if (ret ) {
printf ("Erase failed, ret: %d\n" , ret );
}
printf ("Writing %d bytes @ 0x%x\n" , i , flash_address );
// write first 512 bytes
for (nvram_pos = 0 ; nvram_pos < (i & 0xFFFC ); nvram_pos += 4 ) {
ret = spi_flash_write (flash_device , nvram_pos + flash_address , sizeof (u32 ), (u32 * )(cbfs_formatted_list + nvram_pos ));
if (ret ) {
printf ("Write failed, ret: %d\n" , ret );
}
/* write remaining filler characters in one run */
flash -> write (flash , nvram_pos + flash_address , sizeof (i % 4 ), (u32 * )(cbfs_formatted_list + nvram_pos ));
}
// write remaining filler characters in one run
ret = spi_flash_write (flash_device , nvram_pos + flash_address , sizeof (i % 4 ), (u32 * )(cbfs_formatted_list + nvram_pos ));
if (ret ) {
printf ("Write failed, ret: %d\n" , ret );
}
if (spi_wp_toggle ) {
printf ("Enabling flash write protect...\n" );
spi_flash_lock (flash_device );
}
spi_wp_toggle = spi_flash_is_locked (flash_device );
printf ("Done\n" );
}
/*******************************************************************************/
Expand Down