diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2022-03-05 15:57:23 +0000 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-03-25 21:36:51 +0000 |
commit | 3ae4a98e3bbe4f2c449e614cda67efea129f16b1 (patch) | |
tree | 988ae180da68c8d21d4f37f2ffcad5b02007febe /firmware/target/mips | |
parent | 2810c549a65327c1d42cdacdf16247d3211ab75c (diff) | |
download | rockbox-3ae4a98e3bbe4f2c449e614cda67efea129f16b1.tar.gz rockbox-3ae4a98e3bbe4f2c449e614cda67efea129f16b1.zip |
x1000: spl: remove selectable boot option support
Now the SPL boots the Rockbox bootloader unconditionally, which
allows for some simplification.
Change-Id: Id75c82db25a87e0e9043bb0771f622b1fc9482fb
Diffstat (limited to 'firmware/target/mips')
5 files changed, 65 insertions, 238 deletions
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c deleted file mode 100644 index 9d7a1d118a..0000000000 --- a/firmware/target/mips/ingenic_x1000/erosqnative/spl-erosqnative.c +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "system.h" | ||
23 | #include "clk-x1000.h" | ||
24 | #include "spl-x1000.h" | ||
25 | #include "gpio-x1000.h" | ||
26 | |||
27 | /* TODO: get dual-boot working */ | ||
28 | |||
29 | const struct spl_boot_option spl_boot_options[] = { | ||
30 | [BOOT_OPTION_ROCKBOX] = { | ||
31 | .storage_addr = 0x6800, | ||
32 | .storage_size = 102 * 1024, | ||
33 | .load_addr = X1000_DRAM_BASE, | ||
34 | .exec_addr = X1000_DRAM_BASE, | ||
35 | .flags = BOOTFLAG_UCLPACK, | ||
36 | }, | ||
37 | }; | ||
38 | |||
39 | int spl_get_boot_option(void) | ||
40 | { | ||
41 | return BOOT_OPTION_ROCKBOX; | ||
42 | } | ||
43 | |||
44 | void spl_error(void) | ||
45 | { | ||
46 | const uint32_t pin = (1 << 25); | ||
47 | |||
48 | /* Turn on backlight */ | ||
49 | jz_clr(GPIO_INT(GPIO_C), pin); | ||
50 | jz_set(GPIO_MSK(GPIO_C), pin); | ||
51 | jz_clr(GPIO_PAT1(GPIO_C), pin); | ||
52 | jz_set(GPIO_PAT0(GPIO_C), pin); | ||
53 | |||
54 | while(1) { | ||
55 | /* Turn it off */ | ||
56 | mdelay(100); | ||
57 | jz_set(GPIO_PAT0(GPIO_C), pin); | ||
58 | |||
59 | /* Turn it on */ | ||
60 | mdelay(100); | ||
61 | jz_clr(GPIO_PAT0(GPIO_C), pin); | ||
62 | } | ||
63 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c deleted file mode 100644 index 771082b2a7..0000000000 --- a/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "system.h" | ||
23 | #include "clk-x1000.h" | ||
24 | #include "spl-x1000.h" | ||
25 | #include "gpio-x1000.h" | ||
26 | |||
27 | const struct spl_boot_option spl_boot_options[] = { | ||
28 | [BOOT_OPTION_ROCKBOX] = { | ||
29 | .storage_addr = 0x6800, | ||
30 | .storage_size = 102 * 1024, | ||
31 | .load_addr = X1000_DRAM_BASE, | ||
32 | .exec_addr = X1000_DRAM_BASE, | ||
33 | .flags = BOOTFLAG_UCLPACK, | ||
34 | }, | ||
35 | }; | ||
36 | |||
37 | int spl_get_boot_option(void) | ||
38 | { | ||
39 | return BOOT_OPTION_ROCKBOX; | ||
40 | } | ||
41 | |||
42 | void spl_error(void) | ||
43 | { | ||
44 | /* Flash the buttonlight */ | ||
45 | int level = 0; | ||
46 | while(1) { | ||
47 | gpio_set_function(GPIO_PC(24), GPIOF_OUTPUT(level)); | ||
48 | mdelay(100); | ||
49 | level = 1 - level; | ||
50 | } | ||
51 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c b/firmware/target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c deleted file mode 100644 index c0cc7df0dd..0000000000 --- a/firmware/target/mips/ingenic_x1000/shanlingq1/spl-shanlingq1.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "system.h" | ||
23 | #include "clk-x1000.h" | ||
24 | #include "spl-x1000.h" | ||
25 | #include "gpio-x1000.h" | ||
26 | |||
27 | const struct spl_boot_option spl_boot_options[] = { | ||
28 | [BOOT_OPTION_ROCKBOX] = { | ||
29 | .storage_addr = 0x6800, | ||
30 | .storage_size = 102 * 1024, | ||
31 | .load_addr = X1000_DRAM_BASE, | ||
32 | .exec_addr = X1000_DRAM_BASE, | ||
33 | .flags = BOOTFLAG_UCLPACK, | ||
34 | }, | ||
35 | }; | ||
36 | |||
37 | int spl_get_boot_option(void) | ||
38 | { | ||
39 | return BOOT_OPTION_ROCKBOX; | ||
40 | } | ||
41 | |||
42 | void spl_error(void) | ||
43 | { | ||
44 | /* Flash the backlight */ | ||
45 | int level = 0; | ||
46 | while(1) { | ||
47 | gpio_set_function(GPIO_PC(25), GPIOF_OUTPUT(level)); | ||
48 | mdelay(100); | ||
49 | level = 1 - level; | ||
50 | } | ||
51 | } | ||
diff --git a/firmware/target/mips/ingenic_x1000/spl-x1000.c b/firmware/target/mips/ingenic_x1000/spl-x1000.c index 1abbdcd7a4..05196e8270 100644 --- a/firmware/target/mips/ingenic_x1000/spl-x1000.c +++ b/firmware/target/mips/ingenic_x1000/spl-x1000.c | |||
@@ -34,16 +34,46 @@ | |||
34 | #include "ucl_decompress.h" | 34 | #include "ucl_decompress.h" |
35 | #include <string.h> | 35 | #include <string.h> |
36 | 36 | ||
37 | #if defined(FIIO_M3K) || defined(SHANLING_Q1) | 37 | #if defined(FIIO_M3K) |
38 | # define SPL_DDR_MEMORYSIZE 64 | 38 | /* Size of memory, either 64 or 32 is legal. */ |
39 | # define SPL_DDR_AUTOSR_EN 1 | 39 | # define SPL_DDR_MEMORYSIZE 64 |
40 | # define SPL_DDR_NEED_BYPASS 1 | 40 | /* Pin to flash on spl_error(). Should be a backlight. */ |
41 | # define SPL_ERROR_PIN GPIO_PC(24) | ||
42 | /* Address and size of the bootloader on the storage medium used by the SPL */ | ||
43 | # define BOOT_STORAGE_ADDR 0x6800 | ||
44 | # define BOOT_STORAGE_SIZE (102 * 1024) | ||
45 | #elif defined(SHANLING_Q1) | ||
46 | # define SPL_DDR_MEMORYSIZE 64 | ||
47 | # define SPL_ERROR_PIN GPIO_PC(25) | ||
48 | # define BOOT_STORAGE_ADDR 0x6800 | ||
49 | # define BOOT_STORAGE_SIZE (102 * 1024) | ||
41 | #elif defined(EROS_QN) | 50 | #elif defined(EROS_QN) |
42 | # define SPL_DDR_MEMORYSIZE 32 | 51 | # define SPL_DDR_MEMORYSIZE 32 |
43 | # define SPL_DDR_AUTOSR_EN 1 | 52 | # define SPL_ERROR_PIN GPIO_PC(25) |
44 | # define SPL_DDR_NEED_BYPASS 1 | 53 | # define BOOT_STORAGE_ADDR 0x6800 |
54 | # define BOOT_STORAGE_SIZE (102 * 1024) | ||
45 | #else | 55 | #else |
46 | # error "please define DRAM settings" | 56 | # error "please define SPL config" |
57 | #endif | ||
58 | |||
59 | /* Hardcode this since the SPL is considered part of the bootloader, | ||
60 | * and should never get built or updated separately. */ | ||
61 | #define BOOT_LOAD_ADDR X1000_DRAM_BASE | ||
62 | #define BOOT_EXEC_ADDR BOOT_LOAD_ADDR | ||
63 | |||
64 | /* Whether the bootloader is UCL-compressed */ | ||
65 | #ifndef SPL_USE_UCLPACK | ||
66 | # define SPL_USE_UCLPACK 1 | ||
67 | #endif | ||
68 | |||
69 | /* Whether auto-self-refresh should be enabled (seems it always should be?) */ | ||
70 | #ifndef SPL_DDR_AUTOSR_EN | ||
71 | # define SPL_DDR_AUTOSR_EN 1 | ||
72 | #endif | ||
73 | |||
74 | /* Whether DLL bypass is necessary (probably always?) */ | ||
75 | #ifndef SPL_DDR_NEED_BYPASS | ||
76 | # define SPL_DDR_NEED_BYPASS 1 | ||
47 | #endif | 77 | #endif |
48 | 78 | ||
49 | static void* heap = (void*)(X1000_SDRAM_BASE + X1000_SDRAM_SIZE); | 79 | static void* heap = (void*)(X1000_SDRAM_BASE + X1000_SDRAM_SIZE); |
@@ -55,6 +85,16 @@ void* spl_alloc(size_t count) | |||
55 | return heap; | 85 | return heap; |
56 | } | 86 | } |
57 | 87 | ||
88 | void spl_error(void) | ||
89 | { | ||
90 | int level = 0; | ||
91 | while(1) { | ||
92 | gpio_set_function(SPL_ERROR_PIN, GPIOF_OUTPUT(level)); | ||
93 | mdelay(100); | ||
94 | level = 1 - level; | ||
95 | } | ||
96 | } | ||
97 | |||
58 | static void init_ost(void) | 98 | static void init_ost(void) |
59 | { | 99 | { |
60 | /* NOTE: the prescaler needs to be the same as in system-x1000.c */ | 100 | /* NOTE: the prescaler needs to be the same as in system-x1000.c */ |
@@ -235,14 +275,14 @@ static int init_dram(void) | |||
235 | return 0; | 275 | return 0; |
236 | } | 276 | } |
237 | 277 | ||
238 | static void* get_load_buffer(const struct spl_boot_option* opt) | 278 | static void* get_load_buffer(void) |
239 | { | 279 | { |
240 | /* read to a temporary location if we need to decompress, | 280 | /* read to a temporary location if we need to decompress, |
241 | * otherwise simply read directly to the load address. */ | 281 | * otherwise simply read directly to the load address. */ |
242 | if(opt->flags & BOOTFLAG_UCLPACK) | 282 | if(SPL_USE_UCLPACK) |
243 | return spl_alloc(opt->storage_size); | 283 | return spl_alloc(BOOT_STORAGE_SIZE); |
244 | else | 284 | else |
245 | return (void*)opt->load_addr; | 285 | return (void*)BOOT_LOAD_ADDR; |
246 | } | 286 | } |
247 | 287 | ||
248 | /* Mapping of boot_sel[1:0] pins. | 288 | /* Mapping of boot_sel[1:0] pins. |
@@ -266,15 +306,10 @@ static uint32_t get_boot_sel(void) | |||
266 | return (*(uint32_t*)0xf40001ec) & 3; | 306 | return (*(uint32_t*)0xf40001ec) & 3; |
267 | } | 307 | } |
268 | 308 | ||
269 | typedef void(*entry_fn)(int, char**, int, int) __attribute__((noreturn)); | ||
270 | |||
271 | void spl_main(void) | 309 | void spl_main(void) |
272 | { | 310 | { |
273 | int rc, boot_option; | 311 | int rc; |
274 | const struct spl_boot_option* opt; | ||
275 | void* load_buffer; | 312 | void* load_buffer; |
276 | char** kargv = NULL; | ||
277 | int kargc = 0; | ||
278 | 313 | ||
279 | /* magic */ | 314 | /* magic */ |
280 | REG_CPM_PSWC0ST = 0x00; | 315 | REG_CPM_PSWC0ST = 0x00; |
@@ -298,14 +333,6 @@ void spl_main(void) | |||
298 | return; | 333 | return; |
299 | } | 334 | } |
300 | 335 | ||
301 | /* find out what we should boot */ | ||
302 | boot_option = spl_get_boot_option(); | ||
303 | opt = &spl_boot_options[boot_option]; | ||
304 | load_buffer = get_load_buffer(opt); | ||
305 | |||
306 | /* save the selection for later */ | ||
307 | set_boot_option(boot_option); | ||
308 | |||
309 | /* finish up clock init */ | 336 | /* finish up clock init */ |
310 | clk_init(); | 337 | clk_init(); |
311 | 338 | ||
@@ -314,44 +341,29 @@ void spl_main(void) | |||
314 | if(rc != 0) | 341 | if(rc != 0) |
315 | spl_error(); | 342 | spl_error(); |
316 | 343 | ||
317 | rc = spl_storage_read(opt->storage_addr, opt->storage_size, load_buffer); | 344 | load_buffer = get_load_buffer(); |
345 | rc = spl_storage_read(BOOT_STORAGE_ADDR, BOOT_STORAGE_SIZE, load_buffer); | ||
318 | if(rc != 0) | 346 | if(rc != 0) |
319 | spl_error(); | 347 | spl_error(); |
320 | 348 | ||
321 | /* handle compression */ | 349 | /* decompress */ |
322 | switch(opt->flags & BOOTFLAG_COMPRESSED) { | 350 | if(SPL_USE_UCLPACK) { |
323 | case BOOTFLAG_UCLPACK: { | 351 | uint32_t out_size = X1000_SDRAM_END - BOOT_LOAD_ADDR; |
324 | uint32_t out_size = X1000_SDRAM_END - opt->load_addr; | 352 | rc = ucl_unpack((uint8_t*)load_buffer, BOOT_STORAGE_SIZE, |
325 | rc = ucl_unpack((uint8_t*)load_buffer, opt->storage_size, | 353 | (uint8_t*)BOOT_LOAD_ADDR, &out_size); |
326 | (uint8_t*)opt->load_addr, &out_size); | 354 | } else { |
327 | } break; | 355 | rc = 0; |
328 | |||
329 | default: | ||
330 | break; | ||
331 | } | 356 | } |
332 | 357 | ||
333 | if(rc != 0) | 358 | if(rc != 0) |
334 | spl_error(); | 359 | spl_error(); |
335 | 360 | ||
336 | /* call the setup hook */ | ||
337 | if(opt->setup) { | ||
338 | rc = opt->setup(); | ||
339 | if(rc != 0) | ||
340 | spl_error(); | ||
341 | } | ||
342 | |||
343 | /* close off storage access */ | 361 | /* close off storage access */ |
344 | spl_storage_close(); | 362 | spl_storage_close(); |
345 | 363 | ||
346 | /* handle kernel command line, if specified */ | ||
347 | if(opt->cmdline) { | ||
348 | kargv = (char**)opt->cmdline_addr; | ||
349 | kargv[kargc++] = 0; | ||
350 | kargv[kargc++] = (char*)opt->cmdline; | ||
351 | } | ||
352 | |||
353 | /* jump to the entry point */ | 364 | /* jump to the entry point */ |
354 | entry_fn fn = (entry_fn)opt->exec_addr; | 365 | typedef void(*entry_fn)(void); |
366 | entry_fn fn = (entry_fn)BOOT_EXEC_ADDR; | ||
355 | commit_discard_idcache(); | 367 | commit_discard_idcache(); |
356 | fn(kargc, kargv, 0, 0); | 368 | fn(); |
357 | } | 369 | } |
diff --git a/firmware/target/mips/ingenic_x1000/spl-x1000.h b/firmware/target/mips/ingenic_x1000/spl-x1000.h index 40ea97a5b8..9ee1aa768e 100644 --- a/firmware/target/mips/ingenic_x1000/spl-x1000.h +++ b/firmware/target/mips/ingenic_x1000/spl-x1000.h | |||
@@ -26,23 +26,6 @@ | |||
26 | #include <stddef.h> | 26 | #include <stddef.h> |
27 | #include <stdint.h> | 27 | #include <stdint.h> |
28 | 28 | ||
29 | #define BOOTFLAG_COMPRESSED 0x0f /* mask for compression flags */ | ||
30 | #define BOOTFLAG_UCLPACK 0x01 /* image is compressed with 'uclpack' */ | ||
31 | |||
32 | struct spl_boot_option { | ||
33 | uint32_t storage_addr; /* image's location in storage */ | ||
34 | uint32_t storage_size; /* number of bytes to load */ | ||
35 | uint32_t load_addr; /* address to load image to */ | ||
36 | uint32_t exec_addr; /* address of the entry point */ | ||
37 | uint32_t flags; /* any special flags */ | ||
38 | const char* cmdline; /* command line; use NULL if not needed */ | ||
39 | uint32_t cmdline_addr; /* address to contain command line 'argv[]' */ | ||
40 | int(*setup)(void); /* setup hook, called before jumping to image */ | ||
41 | }; | ||
42 | |||
43 | /* array of boot option descriptions */ | ||
44 | extern const struct spl_boot_option spl_boot_options[]; | ||
45 | |||
46 | /* Memory allocator. Allocation starts from the top of DRAM and counts down. | 29 | /* Memory allocator. Allocation starts from the top of DRAM and counts down. |
47 | * Allocation sizes are rounded up to a multiple of the cacheline size, so | 30 | * Allocation sizes are rounded up to a multiple of the cacheline size, so |
48 | * the returned address is always suitably aligned for DMA. */ | 31 | * the returned address is always suitably aligned for DMA. */ |
@@ -58,9 +41,6 @@ extern int spl_storage_open(void); | |||
58 | extern void spl_storage_close(void); | 41 | extern void spl_storage_close(void); |
59 | extern int spl_storage_read(uint32_t addr, uint32_t length, void* buffer); | 42 | extern int spl_storage_read(uint32_t addr, uint32_t length, void* buffer); |
60 | 43 | ||
61 | /* Get the boot option selected by the user, eg. by a key press */ | ||
62 | extern int spl_get_boot_option(void); | ||
63 | |||
64 | /* Called on a fatal error -- it should do something visible to the user | 44 | /* Called on a fatal error -- it should do something visible to the user |
65 | * like flash the backlight repeatedly. */ | 45 | * like flash the backlight repeatedly. */ |
66 | extern void spl_error(void) __attribute__((noreturn)); | 46 | extern void spl_error(void) __attribute__((noreturn)); |