x1000: spl: remove selectable boot option support

Now the SPL boots the Rockbox bootloader unconditionally, which
allows for some simplification.

Change-Id: Id75c82db25a87e0e9043bb0771f622b1fc9482fb
This commit is contained in:
Aidan MacDonald 2022-03-05 15:57:23 +00:00
parent 2810c549a6
commit 3ae4a98e3b
6 changed files with 65 additions and 241 deletions

View file

@ -1710,7 +1710,6 @@ target/mips/ingenic_x1000/fiiom3k/backlight-fiiom3k.c
target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c
target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c
target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
target/mips/ingenic_x1000/spl-nand-x1000.c
#endif /* FIIO_M3K */
@ -1720,7 +1719,6 @@ target/mips/ingenic_x1000/shanlingq1/backlight-shanlingq1.c
target/mips/ingenic_x1000/shanlingq1/button-shanlingq1.c
target/mips/ingenic_x1000/shanlingq1/lcd-shanlingq1.c
target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c
target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c
target/mips/ingenic_x1000/spl-nand-x1000.c
#endif /* SHANLING_Q1 */
@ -1730,7 +1728,6 @@ target/mips/ingenic_x1000/erosqnative/backlight-erosqnative.c
target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
target/mips/ingenic_x1000/erosqnative/power-erosqnative.c
target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c
target/mips/ingenic_x1000/spl-nand-x1000.c
#endif /* EROS_QN */

View file

@ -1,63 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "clk-x1000.h"
#include "spl-x1000.h"
#include "gpio-x1000.h"
/* TODO: get dual-boot working */
const struct spl_boot_option spl_boot_options[] = {
[BOOT_OPTION_ROCKBOX] = {
.storage_addr = 0x6800,
.storage_size = 102 * 1024,
.load_addr = X1000_DRAM_BASE,
.exec_addr = X1000_DRAM_BASE,
.flags = BOOTFLAG_UCLPACK,
},
};
int spl_get_boot_option(void)
{
return BOOT_OPTION_ROCKBOX;
}
void spl_error(void)
{
const uint32_t pin = (1 << 25);
/* Turn on backlight */
jz_clr(GPIO_INT(GPIO_C), pin);
jz_set(GPIO_MSK(GPIO_C), pin);
jz_clr(GPIO_PAT1(GPIO_C), pin);
jz_set(GPIO_PAT0(GPIO_C), pin);
while(1) {
/* Turn it off */
mdelay(100);
jz_set(GPIO_PAT0(GPIO_C), pin);
/* Turn it on */
mdelay(100);
jz_clr(GPIO_PAT0(GPIO_C), pin);
}
}

View file

@ -1,51 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "clk-x1000.h"
#include "spl-x1000.h"
#include "gpio-x1000.h"
const struct spl_boot_option spl_boot_options[] = {
[BOOT_OPTION_ROCKBOX] = {
.storage_addr = 0x6800,
.storage_size = 102 * 1024,
.load_addr = X1000_DRAM_BASE,
.exec_addr = X1000_DRAM_BASE,
.flags = BOOTFLAG_UCLPACK,
},
};
int spl_get_boot_option(void)
{
return BOOT_OPTION_ROCKBOX;
}
void spl_error(void)
{
/* Flash the buttonlight */
int level = 0;
while(1) {
gpio_set_function(GPIO_PC(24), GPIOF_OUTPUT(level));
mdelay(100);
level = 1 - level;
}
}

View file

@ -1,51 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 Aidan MacDonald
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "clk-x1000.h"
#include "spl-x1000.h"
#include "gpio-x1000.h"
const struct spl_boot_option spl_boot_options[] = {
[BOOT_OPTION_ROCKBOX] = {
.storage_addr = 0x6800,
.storage_size = 102 * 1024,
.load_addr = X1000_DRAM_BASE,
.exec_addr = X1000_DRAM_BASE,
.flags = BOOTFLAG_UCLPACK,
},
};
int spl_get_boot_option(void)
{
return BOOT_OPTION_ROCKBOX;
}
void spl_error(void)
{
/* Flash the backlight */
int level = 0;
while(1) {
gpio_set_function(GPIO_PC(25), GPIOF_OUTPUT(level));
mdelay(100);
level = 1 - level;
}
}

View file

@ -34,16 +34,46 @@
#include "ucl_decompress.h"
#include <string.h>
#if defined(FIIO_M3K) || defined(SHANLING_Q1)
#if defined(FIIO_M3K)
/* Size of memory, either 64 or 32 is legal. */
# define SPL_DDR_MEMORYSIZE 64
# define SPL_DDR_AUTOSR_EN 1
# define SPL_DDR_NEED_BYPASS 1
/* Pin to flash on spl_error(). Should be a backlight. */
# define SPL_ERROR_PIN GPIO_PC(24)
/* Address and size of the bootloader on the storage medium used by the SPL */
# define BOOT_STORAGE_ADDR 0x6800
# define BOOT_STORAGE_SIZE (102 * 1024)
#elif defined(SHANLING_Q1)
# define SPL_DDR_MEMORYSIZE 64
# define SPL_ERROR_PIN GPIO_PC(25)
# define BOOT_STORAGE_ADDR 0x6800
# define BOOT_STORAGE_SIZE (102 * 1024)
#elif defined(EROS_QN)
# define SPL_DDR_MEMORYSIZE 32
# define SPL_DDR_AUTOSR_EN 1
# define SPL_DDR_NEED_BYPASS 1
# define SPL_ERROR_PIN GPIO_PC(25)
# define BOOT_STORAGE_ADDR 0x6800
# define BOOT_STORAGE_SIZE (102 * 1024)
#else
# error "please define DRAM settings"
# error "please define SPL config"
#endif
/* Hardcode this since the SPL is considered part of the bootloader,
* and should never get built or updated separately. */
#define BOOT_LOAD_ADDR X1000_DRAM_BASE
#define BOOT_EXEC_ADDR BOOT_LOAD_ADDR
/* Whether the bootloader is UCL-compressed */
#ifndef SPL_USE_UCLPACK
# define SPL_USE_UCLPACK 1
#endif
/* Whether auto-self-refresh should be enabled (seems it always should be?) */
#ifndef SPL_DDR_AUTOSR_EN
# define SPL_DDR_AUTOSR_EN 1
#endif
/* Whether DLL bypass is necessary (probably always?) */
#ifndef SPL_DDR_NEED_BYPASS
# define SPL_DDR_NEED_BYPASS 1
#endif
static void* heap = (void*)(X1000_SDRAM_BASE + X1000_SDRAM_SIZE);
@ -55,6 +85,16 @@ void* spl_alloc(size_t count)
return heap;
}
void spl_error(void)
{
int level = 0;
while(1) {
gpio_set_function(SPL_ERROR_PIN, GPIOF_OUTPUT(level));
mdelay(100);
level = 1 - level;
}
}
static void init_ost(void)
{
/* NOTE: the prescaler needs to be the same as in system-x1000.c */
@ -235,14 +275,14 @@ static int init_dram(void)
return 0;
}
static void* get_load_buffer(const struct spl_boot_option* opt)
static void* get_load_buffer(void)
{
/* read to a temporary location if we need to decompress,
* otherwise simply read directly to the load address. */
if(opt->flags & BOOTFLAG_UCLPACK)
return spl_alloc(opt->storage_size);
if(SPL_USE_UCLPACK)
return spl_alloc(BOOT_STORAGE_SIZE);
else
return (void*)opt->load_addr;
return (void*)BOOT_LOAD_ADDR;
}
/* Mapping of boot_sel[1:0] pins.
@ -266,15 +306,10 @@ static uint32_t get_boot_sel(void)
return (*(uint32_t*)0xf40001ec) & 3;
}
typedef void(*entry_fn)(int, char**, int, int) __attribute__((noreturn));
void spl_main(void)
{
int rc, boot_option;
const struct spl_boot_option* opt;
int rc;
void* load_buffer;
char** kargv = NULL;
int kargc = 0;
/* magic */
REG_CPM_PSWC0ST = 0x00;
@ -298,14 +333,6 @@ void spl_main(void)
return;
}
/* find out what we should boot */
boot_option = spl_get_boot_option();
opt = &spl_boot_options[boot_option];
load_buffer = get_load_buffer(opt);
/* save the selection for later */
set_boot_option(boot_option);
/* finish up clock init */
clk_init();
@ -314,44 +341,29 @@ void spl_main(void)
if(rc != 0)
spl_error();
rc = spl_storage_read(opt->storage_addr, opt->storage_size, load_buffer);
load_buffer = get_load_buffer();
rc = spl_storage_read(BOOT_STORAGE_ADDR, BOOT_STORAGE_SIZE, load_buffer);
if(rc != 0)
spl_error();
/* handle compression */
switch(opt->flags & BOOTFLAG_COMPRESSED) {
case BOOTFLAG_UCLPACK: {
uint32_t out_size = X1000_SDRAM_END - opt->load_addr;
rc = ucl_unpack((uint8_t*)load_buffer, opt->storage_size,
(uint8_t*)opt->load_addr, &out_size);
} break;
default:
break;
/* decompress */
if(SPL_USE_UCLPACK) {
uint32_t out_size = X1000_SDRAM_END - BOOT_LOAD_ADDR;
rc = ucl_unpack((uint8_t*)load_buffer, BOOT_STORAGE_SIZE,
(uint8_t*)BOOT_LOAD_ADDR, &out_size);
} else {
rc = 0;
}
if(rc != 0)
spl_error();
/* call the setup hook */
if(opt->setup) {
rc = opt->setup();
if(rc != 0)
spl_error();
}
/* close off storage access */
spl_storage_close();
/* handle kernel command line, if specified */
if(opt->cmdline) {
kargv = (char**)opt->cmdline_addr;
kargv[kargc++] = 0;
kargv[kargc++] = (char*)opt->cmdline;
}
/* jump to the entry point */
entry_fn fn = (entry_fn)opt->exec_addr;
typedef void(*entry_fn)(void);
entry_fn fn = (entry_fn)BOOT_EXEC_ADDR;
commit_discard_idcache();
fn(kargc, kargv, 0, 0);
fn();
}

View file

@ -26,23 +26,6 @@
#include <stddef.h>
#include <stdint.h>
#define BOOTFLAG_COMPRESSED 0x0f /* mask for compression flags */
#define BOOTFLAG_UCLPACK 0x01 /* image is compressed with 'uclpack' */
struct spl_boot_option {
uint32_t storage_addr; /* image's location in storage */
uint32_t storage_size; /* number of bytes to load */
uint32_t load_addr; /* address to load image to */
uint32_t exec_addr; /* address of the entry point */
uint32_t flags; /* any special flags */
const char* cmdline; /* command line; use NULL if not needed */
uint32_t cmdline_addr; /* address to contain command line 'argv[]' */
int(*setup)(void); /* setup hook, called before jumping to image */
};
/* array of boot option descriptions */
extern const struct spl_boot_option spl_boot_options[];
/* Memory allocator. Allocation starts from the top of DRAM and counts down.
* Allocation sizes are rounded up to a multiple of the cacheline size, so
* the returned address is always suitably aligned for DMA. */
@ -58,9 +41,6 @@ extern int spl_storage_open(void);
extern void spl_storage_close(void);
extern int spl_storage_read(uint32_t addr, uint32_t length, void* buffer);
/* Get the boot option selected by the user, eg. by a key press */
extern int spl_get_boot_option(void);
/* Called on a fatal error -- it should do something visible to the user
* like flash the backlight repeatedly. */
extern void spl_error(void) __attribute__((noreturn));