[U-Boot] [PATCH] [ONENAND] Reduce OneNAND IPL code size v2

OneNAND IPL has common codes for RAM init, load data, and jump to 2nd bootloader, but it's common code used about 300~400 bytes. So board specific codes, such as lowlevel_init, can't has enough code. It make a difficult to implement OneNAND IPL.
This patch make this common code as small as possible. and give lowlevel_init can have more codes.
Signed-off-by: Kyungmin Park kyungmin.park@samsung.com --- diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S index e622338..132cc4a 100644 --- a/cpu/arm1136/start.S +++ b/cpu/arm1136/start.S @@ -33,23 +33,7 @@ .globl _start _start: b reset #ifdef CONFIG_ONENAND_IPL - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - ldr pc, _hang - -_hang: - .word do_hang - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 - .word 0x12345678 /* now 16*4=64 */ + . = _start + 64 /* now 16*4=64 */ #else ldr pc, _undefined_instruction ldr pc, _software_interrupt @@ -362,12 +346,7 @@ cpu_init_crit: /* * exception handlers */ -#ifdef CONFIG_ONENAND_IPL - .align 5 -do_hang: - ldr sp, _TEXT_BASE /* use 32 words about stack */ - bl hang /* hang and never return */ -#else /* !CONFIG_ONENAND IPL */ +#ifndef CONFIG_ONENAND_IPL .align 5 undefined_instruction: get_bad_stack diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index aff62d2..2440d8b 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -39,6 +39,7 @@ int print_info(void)
typedef int (init_fnc_t)(void);
+#ifdef CONFIG_USE_ONENAND_INIT init_fnc_t *init_sequence[] = { board_init, /* basic board dependent setup */ #ifdef CONFIG_SYS_PRINTF @@ -47,24 +48,23 @@ init_fnc_t *init_sequence[] = { #endif NULL, }; +#endif
void start_oneboot(void) { - init_fnc_t **init_fnc_ptr; uchar *buf; +#ifdef CONFIG_USE_ONENAND_INIT + init_fnc_t **init_fnc_ptr;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) hang(); } +#endif
buf = (uchar *) CONFIG_SYS_LOAD_ADDR;
- if (!onenand_read_block0(buf)) - buf += ONENAND_BLOCK_SIZE; - - if (buf == (uchar *)CONFIG_SYS_LOAD_ADDR) - hang(); + onenand_read_block0(buf);
/* go run U-Boot and never return */ printf("Starting OS Bootloader...\n"); @@ -73,9 +73,11 @@ void start_oneboot(void) /* should never come here */ }
+#ifdef CONFIG_USE_ONENAND_INIT void hang(void) { /* if board_hang() returns, hange here */ printf("X-Loader hangs\n"); for (;;); } +#endif diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index 3387998..438e58c 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -23,7 +23,7 @@
#include <linux/mtd/onenand_regs.h>
-#define ONENAND_BLOCK_SIZE 2048 +#define ONENAND_BLOCK_SIZE 0x20000
#ifndef CONFIG_SYS_PRINTF #define printf(format, args...) @@ -39,5 +39,5 @@
#define ONENAND_PAGE_SIZE 2048
-extern int onenand_read_block0(unsigned char *buf); +extern void onenand_read_block0(unsigned char *buf); #endif diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c index 6d04943..38703fb 100644 --- a/onenand_ipl/onenand_read.c +++ b/onenand_ipl/onenand_read.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2005-2008 Samsung Electronis + * (C) Copyright 2005-2008 Samsung Electronics * Kyungmin Park kyungmin.park@samsung.com * * See file CREDITS for list of people who contributed to this @@ -87,14 +87,16 @@ static inline int onenand_read_page(ulong block, ulong page,
#define ONENAND_START_PAGE 1 #define ONENAND_PAGES_PER_BLOCK 64 +#ifndef CONFIG_ONENAND_END_BLOCK +#define CONFIG_ONENAND_END_BLOCK 1 +#endif
/** * onenand_read_block - Read a block data to buf - * @return 0 on success */ -int onenand_read_block0(unsigned char *buf) +void onenand_read_block0(unsigned char *buf) { - int page, offset = 0; + int block, page, offset = 0; int pagesize = ONENAND_PAGE_SIZE;
/* MLC OneNAND has 4KiB page size */ @@ -103,12 +105,12 @@ int onenand_read_block0(unsigned char *buf)
/* NOTE: you must read page from page 1 of block 0 */ /* read the block page by page*/ - for (page = ONENAND_START_PAGE; - page < ONENAND_PAGES_PER_BLOCK; page++) { - - onenand_read_page(0, page, buf + offset, pagesize); - offset += pagesize; + page = ONENAND_START_PAGE; + for (block = 0; block < CONFIG_ONENAND_END_BLOCK; block++) { + for (; page < ONENAND_PAGES_PER_BLOCK; page++) { + onenand_read_page(block, page, buf + offset, pagesize); + offset += pagesize; + } + page = 0; } - - return 0; }

On Mon, Nov 10, 2008 at 01:53:46PM +0900, Kyungmin Park wrote:
OneNAND IPL has common codes for RAM init, load data, and jump to 2nd bootloader, but it's common code used about 300~400 bytes. So board specific codes, such as lowlevel_init, can't has enough code. It make a difficult to implement OneNAND IPL.
This patch make this common code as small as possible. and give lowlevel_init can have more codes.
Sorry for the delay; I missed this patch earlier.
Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S index e622338..132cc4a 100644 --- a/cpu/arm1136/start.S +++ b/cpu/arm1136/start.S @@ -33,23 +33,7 @@ .globl _start _start: b reset #ifdef CONFIG_ONENAND_IPL
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
-_hang:
- .word do_hang
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678 /* now 16*4=64 */
- . = _start + 64 /* now 16*4=64 */
#else
Can you do a branch-to-self here that will accomplish the same thing, without needing do_hang later?
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index aff62d2..2440d8b 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -39,6 +39,7 @@ int print_info(void)
typedef int (init_fnc_t)(void);
+#ifdef CONFIG_USE_ONENAND_INIT init_fnc_t *init_sequence[] = {
Is there anything that's going to use this? If not, just remove the code.
+#ifdef CONFIG_USE_ONENAND_INIT void hang(void) { /* if board_hang() returns, hange here */ printf("X-Loader hangs\n"); for (;;); } +#endif
X-Loader?
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index 3387998..438e58c 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -23,7 +23,7 @@
#include <linux/mtd/onenand_regs.h>
-#define ONENAND_BLOCK_SIZE 2048 +#define ONENAND_BLOCK_SIZE 0x20000
This doesn't seem to be referenced at all any more. Was the old value simply wrong?
-Scott

On Wed, Dec 10, 2008 at 5:50 AM, Scott Wood scottwood@freescale.com wrote:
On Mon, Nov 10, 2008 at 01:53:46PM +0900, Kyungmin Park wrote:
OneNAND IPL has common codes for RAM init, load data, and jump to 2nd bootloader, but it's common code used about 300~400 bytes. So board specific codes, such as lowlevel_init, can't has enough code. It make a difficult to implement OneNAND IPL.
This patch make this common code as small as possible. and give lowlevel_init can have more codes.
Sorry for the delay; I missed this patch earlier.
Signed-off-by: Kyungmin Park kyungmin.park@samsung.com
diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S index e622338..132cc4a 100644 --- a/cpu/arm1136/start.S +++ b/cpu/arm1136/start.S @@ -33,23 +33,7 @@ .globl _start _start: b reset #ifdef CONFIG_ONENAND_IPL
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
-_hang:
.word do_hang
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678 /* now 16*4=64 */
. = _start + 64 /* now 16*4=64 */
#else
Can you do a branch-to-self here that will accomplish the same thing, without needing do_hang later?
So I don't understand the meaning. In general in restricted environment, 1KiB bootloader. There's no room to handle exception.
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index aff62d2..2440d8b 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -39,6 +39,7 @@ int print_info(void)
typedef int (init_fnc_t)(void);
+#ifdef CONFIG_USE_ONENAND_INIT init_fnc_t *init_sequence[] = {
Is there anything that's going to use this? If not, just remove the code.
I just wonder if there are some user to use. If not no problem to remove.
+#ifdef CONFIG_USE_ONENAND_INIT void hang(void) { /* if board_hang() returns, hange here */ printf("X-Loader hangs\n"); for (;;); } +#endif
X-Loader?
It's code used at x-loader (cross nand bootloader).
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index 3387998..438e58c 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -23,7 +23,7 @@
#include <linux/mtd/onenand_regs.h>
-#define ONENAND_BLOCK_SIZE 2048 +#define ONENAND_BLOCK_SIZE 0x20000
This doesn't seem to be referenced at all any more. Was the old value simply wrong?
It's used at onenand_boot.c but now it's not. It's also no problem to remove.
Thank you, Kyungmin Park

On Wed, Dec 10, 2008 at 09:05:00AM +0900, Kyungmin Park wrote:
diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S index e622338..132cc4a 100644 --- a/cpu/arm1136/start.S +++ b/cpu/arm1136/start.S @@ -33,23 +33,7 @@ .globl _start _start: b reset #ifdef CONFIG_ONENAND_IPL
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
ldr pc, _hang
-_hang:
.word do_hang
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678
.word 0x12345678 /* now 16*4=64 */
. = _start + 64 /* now 16*4=64 */
#else
Can you do a branch-to-self here that will accomplish the same thing, without needing do_hang later?
So I don't understand the meaning. In general in restricted environment, 1KiB bootloader. There's no room to handle exception.
I don't mean to handle the exception, just to hang if one happens rather than going through the init code again. I don't see how 64 bytes full of branch-to-self instructions is going to take up any more space than 64 bytes of nothing.
Is there anything that's going to use this? If not, just remove the code.
I just wonder if there are some user to use. If not no problem to remove.
If nothing's using it, please remove it.
-Scott
participants (2)
-
Kyungmin Park
-
Scott Wood