u-boot: import OpenMoko uboot from OE

git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3014 311d38ba-8fff-0310-9ca6-ca027cbcb966
This commit is contained in:
Marcin Juszkiewicz 2007-10-29 11:00:19 +00:00
parent ce1e498f5d
commit 70abc059eb
63 changed files with 26669 additions and 77 deletions

View File

@ -1,18 +0,0 @@
require uboot-gta01_svn.bb
PROVIDES = ""
TARGET_LDFLAGS = ""
do_compile () {
chmod +x board/neo1973/gta01/split_by_variant.sh
oe_runmake gta01bv3_config
oe_runmake clean
oe_runmake tools
}
do_deploy () {
install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
}
do_deploy[dirs] = "${S}"
addtask deploy before do_package after do_install

View File

@ -0,0 +1,52 @@
This patch makes creation of the BBT optional for the s3c24x0 platform.
It adds:
- a new platform-independent NAND-wide flag NAND_DONT_CREATE_BBT
- one user of this flag, namely s3c24x0
Experimental.
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/cpu/arm920t/s3c24x0/nand.c
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c 2007-02-16 23:53:29.000000000 +0100
+++ u-boot/cpu/arm920t/s3c24x0/nand.c 2007-02-16 23:53:54.000000000 +0100
@@ -169,7 +169,7 @@
nand->eccmode = NAND_ECC_SOFT;
#ifdef CONFIG_S3C2410_NAND_BBT
- nand->options = NAND_USE_FLASH_BBT;
+ nand->options = NAND_USE_FLASH_BBT | NAND_DONT_CREATE_BBT;
#else
nand->options = 0;
#endif
Index: u-boot/drivers/nand/nand_bbt.c
===================================================================
--- u-boot.orig/drivers/nand/nand_bbt.c 2007-02-16 23:53:36.000000000 +0100
+++ u-boot/drivers/nand/nand_bbt.c 2007-02-16 23:53:54.000000000 +0100
@@ -678,7 +678,8 @@
}
create:
/* Create the bad block table by scanning the device ? */
- if (!(td->options & NAND_BBT_CREATE))
+ if (!(td->options & NAND_BBT_CREATE) ||
+ (this->options & NAND_DONT_CREATE_BBT))
continue;
/* Create the table in memory by scanning the chip(s) */
Index: u-boot/include/linux/mtd/nand.h
===================================================================
--- u-boot.orig/include/linux/mtd/nand.h 2007-02-16 23:53:08.000000000 +0100
+++ u-boot/include/linux/mtd/nand.h 2007-02-16 23:53:54.000000000 +0100
@@ -187,7 +187,8 @@
* This can only work if we have the ecc bytes directly behind the
* data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
#define NAND_HWECC_SYNDROME 0x00020000
-
+/* Do not create an BBT if none is found. Overrides NAND_BBT_CREATE. */
+#define NAND_DONT_CREATE_BBT 0x00040000
/* Options set by nand scan */
/* Nand scan has allocated oob_buf */

View File

@ -0,0 +1,69 @@
Scan also the second OOB page for bad block information.
board/neo1973/gta01/nand.c (board_nand_init): added board-specific badblock
pattern which sets NAND_BBT_SCAN2NDPAGE
drivers/nand/nand_base.c (nand_block_bad): also consider the second page in a
block if NAND_BBT_SCAN2NDPAGE is set
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/board/neo1973/gta01/nand.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/nand.c
+++ u-boot/board/neo1973/gta01/nand.c
@@ -113,9 +113,23 @@
}
+/* Derived from drivers/nand/nand_bbt.c:smallpage_flashbased */
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr badblock_pattern = {
+ .options =
+ NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES | NAND_BBT_SCAN2NDPAGE,
+ .offs = 5,
+ .len = 1,
+ .pattern = scan_ff_pattern
+};
+
+
int board_nand_init(struct nand_chip *nand)
{
nand->read_otp = samsung_nand_read_otp;
nand->write_otp = samsung_nand_write_otp;
+ nand->badblock_pattern = &badblock_pattern;
return s3c24x0_nand_init(nand);
}
Index: u-boot/drivers/nand/nand_base.c
===================================================================
--- u-boot.orig/drivers/nand/nand_base.c
+++ u-boot/drivers/nand/nand_base.c
@@ -421,7 +421,7 @@
*
* Check, if the block is bad.
*/
-static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+static int nand_block_bad_page(struct mtd_info *mtd, loff_t ofs, int getchip)
{
int page, chipnr, res = 0;
struct nand_chip *this = mtd->priv;
@@ -460,6 +460,18 @@
return res;
}
+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (nand_block_bad_page(mtd, ofs, getchip))
+ return 1;
+ if (this->badblock_pattern->options & NAND_BBT_SCAN2NDPAGE &&
+ nand_block_bad_page(mtd, ofs+(1 << this->page_shift), getchip))
+ return 1;
+ return 0;
+}
+
/**
* nand_default_block_markbad - [DEFAULT] mark a block bad
* @mtd: MTD device structure

View File

@ -0,0 +1,98 @@
Auto-detect whether we're booting from RAM or NAND, and act accordingly. This
allows us to use the same u-boot binary for all boot modes.
include/configs/neo1973.h: introduced new config option
CONFIG_LL_INIT_NAND_ONLY to perform low-level initialization only when
booting from NAND
include/configs/neo1973.h: got rid of BUILD_FOR_RAM
cpu/arm920t/start.S: detect if we need to boot from NAND at run time (i.e., if
we're running at address 0)
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -157,18 +157,26 @@
str r1, [r0]
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
- /*
- * we do sys-critical inits only at reboot,
- * not when booting from ram!
- */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+#ifndef CONFIG_LL_INIT_NAND_ONLY
bl cpu_init_crit
#endif
+#endif
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
-#ifndef CONFIG_S3C2410_NAND_BOOT
-relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
+
+#ifdef CONFIG_S3C2410_NAND_BOOT
+ /* are we running from NAND ? */
+#define BWSCON 0x48000000
+ ldr r1, =BWSCON /* Z = CPU booted from NAND */
+ ldr r1, [r1]
+ tst r1, #6 /* BWSCON[2:1] = OM[1:0] */
+ teqeq r0, #0 /* Z &= running at address 0 */
+ beq nand_load
+#endif /* CONFIG_S3C2410_NAND_BOOT */
+
+relocate: /* relocate U-Boot to RAM */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq done_relocate
@@ -188,10 +196,13 @@
ldr pc, _done_relocate /* jump to relocated code */
_done_relocate:
.word done_relocate
-done_relocate:
-#else /* NAND_BOOT */
-relocate:
-copy_myself:
+
+#ifdef CONFIG_S3C2410_NAND_BOOT
+nand_load:
+#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_NAND_ONLY)
+ bl cpu_init_crit
+#endif
+
/* mov r10, lr */
@ reset NAND
@@ -275,7 +286,8 @@
#endif
1: b 1b
done_nand_read:
-#endif /* NAND_BOOT */
+#endif /* CONFIG_S3C2410_NAND_BOOT */
+done_relocate:
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -26,14 +26,10 @@
#ifndef __CONFIG_H
#define __CONFIG_H
-#if defined(BUILD_FOR_RAM)
-/* If we want to start u-boot from inside RAM */
-#define CONFIG_SKIP_LOWLEVEL_INIT 1
-#else
-/* we want to start u-boot directly from within NAND flash */
+/* we want to be able to start u-boot directly from within NAND flash */
+#define CONFIG_LL_INIT_NAND_ONLY
#define CONFIG_S3C2410_NAND_BOOT 1
#define CONFIG_S3C2410_NAND_SKIP_BAD 1
-#endif
#define CFG_UBOOT_SIZE 0x40000 /* size of u-boot, for NAND loading */

View File

@ -0,0 +1,62 @@
This patch allows us to boot from anywhere in RAM. It mainly sets the stage
for later patches. The only real changes here is the better handling of already
cached code (e.g., if we were started by a previous instance of u-boot), and
that we drop CONFIG_SKIP_RELOCATE_UBOOT from neo1973.h
cpu/arm920t/start.S: if not relocating, instead of going straight to
stack_setup, jump to done_relocate, which may perform other setup tasks
cpu/arm920t/start.S: after relocating, flush the cache and jump to the new code
include/configs/neo1973.h: remove CONFIG_SKIP_RELOCATE_UBOOT
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -171,7 +171,7 @@ relocate: /* relocate U-Boot to RAM
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
- beq stack_setup
+ beq done_relocate
ldr r2, _armboot_start
ldr r3, _bss_start
@@ -181,8 +181,14 @@ relocate: /* relocate U-Boot to RAM
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
- cmp r0, r2 /* until source end addreee [r2] */
+ cmp r0, r2 /* until source end address [r2] */
ble copy_loop
+ mov r0, #0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c7, c7, 0
+ ldr pc, _done_relocate /* jump to relocated code */
+_done_relocate:
+ .word done_relocate
+done_relocate:
#else /* NAND_BOOT */
relocate:
copy_myself:
@@ -270,7 +276,7 @@ notmatch:
1: b 1b
done_nand_read:
#endif /* NAND_BOOT */
-#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
stack_setup:
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -28,7 +28,6 @@
#if defined(BUILD_FOR_RAM)
/* If we want to start u-boot from inside RAM */
-#define CONFIG_SKIP_RELOCATE_UBOOT 1
#define CONFIG_SKIP_LOWLEVEL_INIT 1
#else
/* we want to start u-boot directly from within NAND flash */

View File

@ -0,0 +1,769 @@
board/neo1973/bootmenu.c: simple configurable boot menu
board/neo1973/neo1973.c (neo1973_new_second): return 1 if a new second has
started since the last call
board/neo1973/neo1973.c (neo1973_on_key_pressed): return 1 if the $POWER key is
pressed
board/neo1973/neo1973.c (board_late_init): make use of neo1973_new_second and
neo1973_on_key_pressed
board/neo1973/neo1973.h: added function prototypes
u-boot/board/neo1973/neo1973.c (board_late_init): enter the boot menu when
"AUX" was pressed at least half the time
u-boot/board/neo1973/neo1973.c (board_late_init): minor code cleanup
u-boot/common/console.c, include/console.h: added "console_poll_hook" to be
called when waiting for console in put in "getc" and "tstc"
board/neo1973/neo1973.c (board_late_init): poll for the boot menu also on RAM
boot, reset, or unknown cause
board/neo1973/neo1973.c (board_late_init): don't look for the power key if
woken up by the charger
board/neo1973/neo1973.h, board/neo1973/neo1973.c, board/neo1973/bootmenu.c:
renamed neo1973_911_key_pressed to neo1973_aux_key_pressed
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/board/neo1973/common/bootmenu.c
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/common/bootmenu.c
@@ -0,0 +1,120 @@
+/*
+ * bootmenu.c - Boot menu
+ *
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner@openmoko.org>
+ * All Rights Reserved
+ *
+ * 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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <common.h>
+#include <environment.h>
+#include <bootmenu.h>
+#include <asm/atomic.h>
+
+#ifdef CONFIG_USBD_DFU
+#include "usbdcore.h"
+#include "usb_dfu.h"
+#endif
+
+#include "neo1973.h"
+
+
+#define DEBOUNCE_LOOPS 1000 /* wild guess */
+
+
+static int debounce(int (*fn)(void), int *last)
+{
+ int on, i;
+
+again:
+ on = fn();
+ if (on != *last)
+ for (i = DEBOUNCE_LOOPS; i; i--)
+ if (on != fn())
+ goto again;
+ *last = on;
+ return on;
+}
+
+
+static int aux_key(void *user)
+{
+ static int last_aux = -1;
+
+ return debounce(neo1973_aux_key_pressed, &last_aux);
+}
+
+
+static int on_key(void *user)
+{
+ static int last_on = -1;
+
+ return debounce(neo1973_on_key_pressed, &last_on);
+}
+
+
+static void factory_reset(void *user)
+{
+ default_env();
+ run_command("dynpart", 0);
+ run_command("bootd", 0);
+}
+
+
+static int seconds(void *user)
+{
+ return neo1973_new_second();
+}
+
+
+static int system_idle(void)
+{
+#ifdef CONFIG_USBD_DFU
+ if (system_dfu_state)
+ return *system_dfu_state == DFU_STATE_appIDLE;
+#endif
+ return 1;
+}
+
+
+static void poweroff_if_idle(void *user)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (system_idle())
+ neo1973_poweroff();
+ local_irq_restore(flags);
+}
+
+
+static struct bootmenu_setup bootmenu_setup = {
+ .next_key = aux_key,
+ .enter_key = on_key,
+ .seconds = seconds,
+ .idle_action = poweroff_if_idle,
+};
+
+
+void neo1973_bootmenu(void)
+{
+ bootmenu_add("Boot", NULL, "bootd");
+ bootmenu_init(&bootmenu_setup);
+ bootmenu_add("Factory reset", factory_reset, NULL);
+ bootmenu();
+}
Index: u-boot/board/neo1973/gta01/gta01.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/gta01.c
+++ u-boot/board/neo1973/gta01/gta01.c
@@ -229,10 +229,15 @@ int board_late_init(void)
extern unsigned char booted_from_nand;
unsigned char tmp;
char buf[32];
+ int menu_vote = 0; /* <= 0: no, > 0: yes */
+ int seconds = 0;
/* Initialize the Power Management Unit with a safe register set */
pcf50606_init();
+ /* if there's no other reason, must be regular reset */
+ neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
+
if (!booted_from_nand)
goto woken_by_reset;
@@ -242,45 +247,41 @@ int board_late_init(void)
setenv("pcf50606_int1", buf);
if (tmp & PCF50606_INT1_ALARM) {
- /* we've been woken up by RTC alarm or charger insert, boot */
+ /* we've been woken up by RTC alarm, boot */
neo1973_wakeup_cause = NEO1973_WAKEUP_ALARM;
goto continue_boot;
}
if (tmp & PCF50606_INT1_EXTONR) {
+ /* we've been woken up by charger insert */
neo1973_wakeup_cause = NEO1973_WAKEUP_CHARGER;
}
if (tmp & PCF50606_INT1_ONKEYF) {
- int seconds = 0;
- neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
/* we've been woken up by a falling edge of the onkey */
+ neo1973_wakeup_cause = NEO1973_WAKEUP_POWER_KEY;
+ }
- /* we can't just setenv(bootdelay,-1) because that would
- * accidentially become permanent if the user does saveenv */
- if (neo1973_911_key_pressed())
- nobootdelay = 1;
-
- while (1) {
- u_int8_t int1, oocs;
-
- oocs = pcf50606_reg_read(PCF50606_REG_OOCS);
- if (oocs & PFC50606_OOCS_ONKEY)
- break;
-
- int1 = pcf50606_reg_read(PCF50606_REG_INT1);
- if (int1 & PCF50606_INT1_SECOND)
- seconds++;
-
- if (seconds >= POWER_KEY_SECONDS)
- goto continue_boot;
- }
- /* Power off if minimum number of seconds not reached */
- neo1973_poweroff();
+ if (neo1973_wakeup_cause == NEO1973_WAKEUP_CHARGER) {
+ /* if we still think it was only a charger insert, boot */
+ goto continue_boot;
}
woken_by_reset:
- /* if there's no other reason, must be regular reset */
- neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
+
+ while (neo1973_wakeup_cause == NEO1973_WAKEUP_RESET ||
+ neo1973_on_key_pressed()) {
+ if (neo1973_aux_key_pressed())
+ menu_vote++;
+ else
+ menu_vote--;
+
+ if (neo1973_new_second())
+ seconds++;
+ if (seconds >= POWER_KEY_SECONDS)
+ goto continue_boot;
+ }
+ /* Power off if minimum number of seconds not reached */
+ neo1973_poweroff();
continue_boot:
jbt6k74_init();
@@ -304,6 +305,11 @@ continue_boot:
}
#endif
+ if (menu_vote > 0) {
+ neo1973_bootmenu();
+ nobootdelay = 1;
+ }
+
return 0;
}
@@ -369,7 +375,17 @@ void neo1973_vibrator(int on)
#endif
}
-int neo1973_911_key_pressed(void)
+int neo1973_new_second(void)
+{
+ return pcf50606_reg_read(PCF50606_REG_INT1) & PCF50606_INT1_SECOND;
+}
+
+int neo1973_on_key_pressed(void)
+{
+ return !(pcf50606_reg_read(PCF50606_REG_OOCS) & PFC50606_OOCS_ONKEY);
+}
+
+int neo1973_aux_key_pressed(void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
if (gpio->GPFDAT & (1 << 6))
Index: u-boot/board/neo1973/gta01/Makefile
===================================================================
--- u-boot.orig/board/neo1973/gta01/Makefile
+++ u-boot/board/neo1973/gta01/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
-OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o
+OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
SOBJS := ../common/lowlevel_init.o
.PHONY: all
Index: u-boot/board/neo1973/common/neo1973.h
===================================================================
--- u-boot.orig/board/neo1973/common/neo1973.h
+++ u-boot/board/neo1973/common/neo1973.h
@@ -29,4 +29,10 @@ int neo1973_911_key_pressed(void);
const char *neo1973_get_charge_status(void);
int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd);
+int neo1973_new_second(void);
+int neo1973_on_key_pressed(void);
+int neo1973_aux_key_pressed(void);
+
+void neo1973_bootmenu(void);
+
#endif
Index: u-boot/common/console.c
===================================================================
--- u-boot.orig/common/console.c
+++ u-boot/common/console.c
@@ -160,8 +160,12 @@ void fprintf (int file, const char *fmt,
/** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
+void (*console_poll_hook)(int activity);
+
int getc (void)
{
+ while (console_poll_hook && !tstc());
+
if (gd->flags & GD_FLG_DEVINIT) {
/* Get from the standard input */
return fgetc (stdin);
@@ -171,7 +175,7 @@ int getc (void)
return serial_getc ();
}
-int tstc (void)
+static int do_tstc (void)
{
if (gd->flags & GD_FLG_DEVINIT) {
/* Test the standard input */
@@ -182,6 +186,16 @@ int tstc (void)
return serial_tstc ();
}
+int tstc (void)
+{
+ int ret;
+
+ ret = do_tstc();
+ if (console_poll_hook)
+ console_poll_hook(ret);
+ return ret;
+}
+
void putc (const char c)
{
#ifdef CONFIG_SILENT_CONSOLE
Index: u-boot/include/console.h
===================================================================
--- u-boot.orig/include/console.h
+++ u-boot/include/console.h
@@ -33,6 +33,8 @@
extern device_t *stdio_devices[] ;
extern char *stdio_names[MAX_FILES] ;
+extern void (*console_poll_hook)(int activity);
+
int console_realloc(int top);
#endif
Index: u-boot/common/Makefile
===================================================================
--- u-boot.orig/common/Makefile
+++ u-boot/common/Makefile
@@ -50,7 +50,8 @@ COBJS = main.o ACEX1K.o altera.o bedbug.
memsize.o miiphybb.o miiphyutil.o \
s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
usb.o usb_kbd.o usb_storage.o \
- virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o
+ virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o \
+ bootmenu.o
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS))
Index: u-boot/common/bootmenu.c
===================================================================
--- /dev/null
+++ u-boot/common/bootmenu.c
@@ -0,0 +1,311 @@
+/*
+ * bootmenu.c - Boot menu
+ *
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner@openmoko.org>
+ * All Rights Reserved
+ *
+ * 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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include <common.h>
+
+#ifdef CFG_BOOTMENU
+
+#include <malloc.h>
+#include <devices.h>
+#include <console.h>
+#include <bootmenu.h>
+
+
+extern const char version_string[];
+
+
+#define ANSI_CLEAR "\e[2J"
+#define ANSI_REVERSE "\e[7m"
+#define ANSI_NORMAL "\e[m"
+#define ANSI_GOTOYX "\e[%d;%dH"
+
+/*
+ * MIN_BOOT_MENU_TIMEOUT ensures that users can't by accident set the timeout
+ * unusably short.
+ */
+#define MIN_BOOT_MENU_TIMEOUT 10 /* 10 seconds */
+#define BOOT_MENU_TIMEOUT 60 /* 60 seconds */
+#define AFTER_COMMAND_WAIT 3 /* wait (2,3] after running commands */
+#define MAX_MENU_ITEMS 10 /* cut off after that many */
+
+#define TOP_ROW 2
+#define MENU_0_ROW (TOP_ROW+5)
+
+
+struct option {
+ const char *label;
+ void (*fn)(void *user); /* run_command if NULL */
+ void *user;
+};
+
+
+static const struct bootmenu_setup *setup;
+static struct option options[MAX_MENU_ITEMS];
+static int num_options = 0;
+static int max_width = 0;
+
+static device_t *bm_con;
+
+
+static void bm_printf(const char *fmt, ...)
+{
+ va_list args;
+ char printbuffer[CFG_PBSIZE];
+
+ va_start(args, fmt);
+ vsprintf(printbuffer, fmt, args);
+ va_end(args);
+
+ bm_con->puts(printbuffer);
+}
+
+
+static char *get_option(int n)
+{
+ char name[] = "menu_XX";
+
+ sprintf(name+5, "%d", n);
+ return getenv(name);
+}
+
+
+static void print_option(const struct option *option, int reverse)
+{
+ int n = option-options;
+
+ bm_printf(ANSI_GOTOYX, MENU_0_ROW+n, 1);
+ if (reverse)
+ bm_printf(ANSI_REVERSE);
+ bm_printf(" %-*s ", max_width, option->label);
+ if (reverse)
+ bm_printf(ANSI_NORMAL);
+}
+
+
+static int get_var_positive_int(char *var, int default_value)
+{
+ const char *s;
+ char *end;
+ int n;
+
+ s = getenv(var);
+ if (!s)
+ return default_value;
+ n = simple_strtoul(s, &end, 0);
+ if (!*s || *end || n < 1)
+ return default_value;
+ return n;
+}
+
+
+static void show_bootmenu(void)
+{
+ const struct option *option;
+
+ bm_printf(ANSI_CLEAR ANSI_GOTOYX "%s", TOP_ROW, 1, version_string);
+ bm_printf(ANSI_GOTOYX "*** BOOT MENU ***", TOP_ROW+3, 1);
+ bm_printf(ANSI_GOTOYX, MENU_0_ROW, 1);
+
+ for (option = options; option != options+num_options; option++)
+ print_option(option, option == options);
+
+ bm_printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
+}
+
+
+static void redirect_console(int grab)
+{
+ static device_t *orig_stdout, *orig_stderr;
+
+ if (grab) {
+ orig_stdout = stdio_devices[stdout];
+ orig_stderr = stdio_devices[stderr];
+ stdio_devices[stdout] = bm_con;
+ stdio_devices[stderr] = bm_con;
+ }
+ else {
+ /*
+ * Make this conditional, because the command may also change
+ * the console.
+ */
+ if (stdio_devices[stdout] == bm_con)
+ stdio_devices[stdout] = orig_stdout;
+ if (stdio_devices[stderr] == bm_con)
+ stdio_devices[stderr] = orig_stderr;
+ }
+}
+
+
+static void do_option(const struct option *option)
+{
+ int seconds, aux;
+
+ bm_printf(ANSI_CLEAR ANSI_GOTOYX, 1, 1);
+ redirect_console(1);
+
+ if (option->fn)
+ option->fn(option->user);
+ else
+ run_command(option->user, 0);
+
+ redirect_console(0);
+ seconds = get_var_positive_int("after_command_wait",
+ AFTER_COMMAND_WAIT);
+ if (seconds)
+ bm_printf("\nPress [AUX] to %s.",
+ option ? "return to boot menu" : "power off");
+ aux = 1; /* require up-down transition */
+ while (seconds) {
+ int tmp;
+
+ tmp = setup->next_key(setup->user);
+ if (tmp && !aux)
+ break;
+ aux = tmp;
+ if (setup->seconds(setup->user))
+ seconds--;
+ }
+ if (!option)
+ setup->idle_action(setup->idle_action);
+ show_bootmenu();
+}
+
+
+static void bootmenu_hook(int activity)
+{
+ static int aux = 1, on = 1;
+ static const struct option *option = options;
+ static int seconds = 0;
+ int tmp;
+
+ if (activity)
+ seconds = 0;
+ tmp = setup->next_key(setup->user);
+ if (tmp && !aux) {
+ print_option(option, 0);
+ option++;
+ if (option == options+num_options)
+ option = options;
+ print_option(option, 1);
+ seconds = 0;
+ }
+ aux = tmp;
+ tmp = setup->enter_key(setup->user);
+ if (tmp && !on) {
+ do_option(option);
+ option = options;
+ seconds = 0;
+ }
+ on = tmp;
+ if (setup->seconds(setup->user)) {
+ int timeout;
+
+ timeout = get_var_positive_int("boot_menu_timeout",
+ BOOT_MENU_TIMEOUT);
+ if (timeout < MIN_BOOT_MENU_TIMEOUT)
+ timeout = MIN_BOOT_MENU_TIMEOUT;
+ if (++seconds > timeout) {
+ setup->idle_action(setup->idle_action);
+ seconds = 0;
+ }
+ }
+}
+
+
+static device_t *find_console(const char *name)
+{
+ int i;
+
+ for (i = 1; i != ListNumItems(devlist); i++) {
+ device_t *dev = ListGetPtrToItem(devlist, i);
+
+ if (!strcmp(name, dev->name))
+ if (dev->flags & DEV_FLAGS_OUTPUT)
+ return dev;
+ }
+ return NULL;
+}
+
+
+void bootmenu_add(const char *label, void (*fn)(void *user), void *user)
+{
+ int len;
+
+ options[num_options].label = label;
+ options[num_options].fn = fn;
+ options[num_options].user = user;
+ num_options++;
+
+ len = strlen(label);
+ if (len > max_width)
+ max_width = len;
+}
+
+
+void bootmenu_init(struct bootmenu_setup *__setup)
+{
+ int n;
+
+ setup = __setup;
+ for (n = 1; n != MAX_MENU_ITEMS+1; n++) {
+ const char *spec, *colon;
+
+ spec = get_option(n);
+ if (!spec)
+ continue;
+ colon = strchr(spec, ':');
+ if (!colon)
+ bootmenu_add(spec, NULL, (char *) spec);
+ else {
+ char *label;
+ int len = colon-spec;
+
+ label = malloc(len+1);
+ if (!label)
+ return;
+ memcpy(label, spec, len);
+ label[len] = 0;
+ bootmenu_add(label, NULL, (char *) colon+1);
+ }
+ }
+}
+
+
+void bootmenu(void)
+{
+ bm_con = find_console("vga");
+ if (bm_con && bm_con->start && bm_con->start() < 0)
+ bm_con = NULL;
+ if (!bm_con)
+ bm_con = stdio_devices[stdout];
+ if (!bm_con)
+ return;
+#if 0
+ console_assign(stdout, "vga");
+ console_assign(stderr, "vga");
+#endif
+ show_bootmenu();
+ console_poll_hook = bootmenu_hook;
+}
+
+#endif /* CFG_BOOTMENU */
Index: u-boot/include/bootmenu.h
===================================================================
--- /dev/null
+++ u-boot/include/bootmenu.h
@@ -0,0 +1,71 @@
+/*
+ * bootmenu.h - Boot menu
+ *
+ * Copyright (C) 2006-2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner@openmoko.org>
+ * All Rights Reserved
+ *
+ * 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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef BOOTMENU_H
+#define BOOTMENU_H
+
+#define MIN_BOOT_MENU_TIMEOUT 10 /* 10 seconds */
+#define BOOT_MENU_TIMEOUT 60 /* 60 seconds */
+#define AFTER_COMMAND_WAIT 3 /* wait (2,3] after running commands */
+#define MAX_MENU_ITEMS 10 /* cut off after that many */
+
+
+struct bootmenu_setup {
+ /* non-zero while the "next" key is being pressed */
+ int (*next_key)(void *user);
+
+ /* non-zero while the "enter" key is being pressed */
+ int (*enter_key)(void *user);
+
+ /* return the number of seconds that have passed since the last call
+ to "seconds". It's okay to limit the range to [0, 1]. */
+ int (*seconds)(void *user);
+
+ /* action to take if the boot menu times out */
+ void (*idle_action)(void *user);
+
+ /* user-specific data, passes "as is" to the functions above */
+ void *user;
+};
+
+
+/*
+ * Initialize the menu from the environment.
+ */
+
+void bootmenu_init(struct bootmenu_setup *setup);
+
+/*
+ * To add entries on top of the boot menu, call bootmenu_add before
+ * bootmenu_init. To add entries at the end, call it after bootmenu_init.
+ * If "fn" is NULL, the command specified in "user" is executed.
+ */
+
+void bootmenu_add(const char *label, void (*fn)(void *user), void *user);
+
+/*
+ * Run the boot menu.
+ */
+
+void bootmenu(void);
+
+#endif /* !BOOTMENU_H */
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -160,6 +160,8 @@
/* valid baudrates */
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#define CFG_BOOTMENU
+
/*-----------------------------------------------------------------------
* Stack sizes
*

View File

@ -0,0 +1,58 @@
common/cmd_mem.c: new command "unzip srcaddr dstaddr [dstsize]" to unzip from
memory to memory, and option CONFIG_UNZIP to enable it
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/common/cmd_mem.c
===================================================================
--- u-boot.orig/common/cmd_mem.c
+++ u-boot/common/cmd_mem.c
@@ -1148,6 +1148,34 @@ int do_mem_crc (cmd_tbl_t *cmdtp, int fl
}
#endif /* CONFIG_CRC32_VERIFY */
+
+#ifdef CONFIG_UNZIP
+int gunzip (void *, int, unsigned char *, unsigned long *);
+
+int do_unzip ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ unsigned long src, dst;
+ unsigned long src_len = ~0UL, dst_len = ~0UL;
+ int err;
+
+ switch (argc) {
+ case 4:
+ dst_len = simple_strtoul(argv[3], NULL, 16);
+ /* fall through */
+ case 3:
+ src = simple_strtoul(argv[1], NULL, 16);
+ dst = simple_strtoul(argv[2], NULL, 16);
+ break;
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ return !!gunzip((void *) dst, dst_len, (void *) src, &src_len);
+}
+#endif /* CONFIG_UNZIP */
+
+
/**************************************************/
#if (CONFIG_COMMANDS & CFG_CMD_MEMORY)
U_BOOT_CMD(
@@ -1251,5 +1279,13 @@ U_BOOT_CMD(
);
#endif /* CONFIG_MX_CYCLIC */
+#ifdef CONFIG_UNZIP
+U_BOOT_CMD(
+ unzip, 4, 1, do_unzip,
+ "unzip - unzip a memory region\n",
+ "srcaddr dstaddr [dstsize]\n"
+);
+#endif /* CONFIG_UNZIP */
+
#endif
#endif /* CFG_CMD_MEMORY */

View File

@ -0,0 +1,127 @@
drivers/cfb_console.c: added processing of ANSI escape sequences \e[2J, \e[m,
\e[7m, and \e[row;colH
drivers/cfb_console.c (video_putc): make \r return to the beginning of the line
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/drivers/cfb_console.c
===================================================================
--- u-boot.orig/drivers/cfb_console.c
+++ u-boot/drivers/cfb_console.c
@@ -181,6 +181,7 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the
#include <version.h>
#include <linux/types.h>
+#include <linux/ctype.h>
#include <devices.h>
#include <video_font.h>
#ifdef CFG_CMD_DATE
@@ -676,10 +677,96 @@ static void console_newline (void)
/*****************************************************************************/
+static enum {
+ CS_NORMAL = 0,
+ CS_ESC,
+ CS_NUM1,
+ CS_NUM2,
+} state = 0;
+
+static int num1, num2;
+
+
+static void swap_drawing_colors(void)
+{
+ eorx = fgx;
+ fgx = bgx;
+ bgx = eorx;
+ eorx = fgx ^ bgx;
+}
+
+
+static void process_sequence(char c)
+{
+ static int inverted = 0;
+ int i, inv;
+
+ switch (c) {
+ case 'J':
+ /* assume num1 == 2 */
+ for (i = 0; i != CONSOLE_ROWS; i++)
+ console_scrollup();
+ break;
+ case 'H':
+ if (num1 > CONSOLE_ROWS || num2 > CONSOLE_COLS)
+ break;
+ console_col = num2 ? num2-1 : 0;
+ console_row = num1 ? num1-1 : 0;
+ break;
+ case 'm':
+ inv = num1 == 7;
+ if (num1 && !inv)
+ break;
+ if (inverted != inv)
+ swap_drawing_colors();
+ inverted = inv;
+ break;
+ }
+}
+
+
+static void escape_sequence(char c)
+{
+ switch (state) {
+ case CS_ESC:
+ state = c == '[' ? CS_NUM1 : CS_NORMAL;
+ num1 = num2 = 0;
+ break;
+ case CS_NUM1:
+ if (isdigit(c))
+ num1 = num1*10+c-'0';
+ else if (c == ';')
+ state = CS_NUM2;
+ else {
+ process_sequence(c);
+ state = CS_NORMAL;
+ }
+ break;
+ case CS_NUM2:
+ if (isdigit(c))
+ num2 = num2*10+c-'0';
+ else {
+ process_sequence(c);
+ state = CS_NORMAL;
+ }
+ default:
+ /* can't happen */;
+ }
+}
+
+
void video_putc (const char c)
{
+ if (state) {
+ escape_sequence(c);
+ CURSOR_SET;
+ return;
+ }
+
switch (c) {
- case 13: /* ignore */
+ case 13: /* return to beginning of line */
+ CURSOR_OFF;
+ console_col = 0;
break;
case '\n': /* next line */
@@ -698,6 +785,10 @@ void video_putc (const char c)
console_back ();
break;
+ case '\e':
+ state = CS_ESC;
+ break;
+
default: /* draw the char */
video_putchar (console_col * VIDEO_FONT_WIDTH,
console_row * VIDEO_FONT_HEIGHT,

View File

@ -0,0 +1,101 @@
common/env_common.c (default_env): new function that resets the environment to
the default value
common/env_common.c (env_relocate): use default_env instead of own copy
common/env_nand.c (env_relocate_spec): use default_env instead of own copy
include/environment.h: added default_env prototype
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/common/env_common.c
===================================================================
--- u-boot.orig/common/env_common.c
+++ u-boot/common/env_common.c
@@ -202,6 +202,25 @@ uchar *env_get_addr (int index)
}
}
+void default_env(void)
+{
+ if (sizeof(default_environment) > ENV_SIZE)
+ {
+ puts ("*** Error - default environment is too large\n\n");
+ return;
+ }
+
+ memset (env_ptr, 0, sizeof(env_t));
+ memcpy (env_ptr->data,
+ default_environment,
+ sizeof(default_environment));
+#ifdef CFG_REDUNDAND_ENVIRONMENT
+ env_ptr->flags = 0xFF;
+#endif
+ env_crc_update ();
+ gd->env_valid = 1;
+}
+
void env_relocate (void)
{
DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
@@ -245,23 +264,8 @@ void env_relocate (void)
gd->env_valid = 0;
#endif
- if (gd->env_valid == 0) {
- if (sizeof(default_environment) > ENV_SIZE)
- {
- puts ("*** Error - default environment is too large\n\n");
- return;
- }
-
- memset (env_ptr, 0, sizeof(env_t));
- memcpy (env_ptr->data,
- default_environment,
- sizeof(default_environment));
-#ifdef CFG_REDUNDAND_ENVIRONMENT
- env_ptr->flags = 0xFF;
-#endif
- env_crc_update ();
- gd->env_valid = 1;
- }
+ if (gd->env_valid == 0)
+ default_env();
else {
env_relocate_spec ();
}
Index: u-boot/common/env_nand.c
===================================================================
--- u-boot.orig/common/env_nand.c
+++ u-boot/common/env_nand.c
@@ -313,19 +313,7 @@ void env_relocate_spec (void)
static void use_default()
{
puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
-
- if (default_environment_size > CFG_ENV_SIZE){
- puts ("*** Error - default environment is too large\n\n");
- return;
- }
-
- memset (env_ptr, 0, sizeof(env_t));
- memcpy (env_ptr->data,
- default_environment,
- default_environment_size);
- env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
- gd->env_valid = 1;
-
+ default_env();
}
#endif
Index: u-boot/include/environment.h
===================================================================
--- u-boot.orig/include/environment.h
+++ u-boot/include/environment.h
@@ -107,4 +107,7 @@ typedef struct environment_s {
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;
+
+void default_env(void);
+
#endif /* _ENVIRONMENT_H_ */

View File

@ -0,0 +1,22 @@
common/cmd_nand.c (yes): if the environment variable "dontask" is set to "y" or
"Y", non-interactively assume the answer was "yes". In all other cases, ask.
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/common/cmd_nand.c
===================================================================
--- u-boot.orig/common/cmd_nand.c
+++ u-boot/common/cmd_nand.c
@@ -165,8 +165,12 @@ out:
static int yes(void)
{
+ char *s;
char c;
+ s = getenv("dontask");
+ if (s && (s[0] =='y' || s[0] == 'Y') && !s[1])
+ return 1;
c = getc();
if (c != 'y' && c != 'Y')
return 0;

View File

@ -0,0 +1,139 @@
common/cmd_nand.c: globalized arg_off_size
include/util.h: new header to convenience functions, such as arg_off_size
common/cmd_dynenv.c (do_dynenv): use arg_off_size to sanity-check offset and to
allow use of partition name
common/cmd_dynenv.c (do_dynenv): indicate in no uncertain terms when an update
would not work due to Flash bits already cleared
common/cmd_dynenv.c (do_dynenv): update CFG_ENV_OFFSET after successful "dynenv
set", so that we can write the new environment without having to reboot
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/common/cmd_nand.c
===================================================================
--- u-boot.orig/common/cmd_nand.c
+++ u-boot/common/cmd_nand.c
@@ -100,7 +100,7 @@ static inline int str2long(char *p, ulon
return (*p != '\0' && *endptr == '\0') ? 1 : 0;
}
-static int
+int
arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
{
int idx = nand_curr_device;
Index: u-boot/include/util.h
===================================================================
--- /dev/null
+++ u-boot/include/util.h
@@ -0,0 +1,33 @@
+/*
+ * util.h - Convenience functions
+ *
+ * (C) Copyright 2006-2007 OpenMoko, Inc.
+ * Author: Werner Almesberger <werner@openmoko.org>
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include "nand.h"
+
+
+/* common/cmd_nand.c */
+int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
+ ulong *size);
+
+#endif /* UTIL_H */
Index: u-boot/common/cmd_dynenv.c
===================================================================
--- u-boot.orig/common/cmd_dynenv.c
+++ u-boot/common/cmd_dynenv.c
@@ -23,6 +23,7 @@
#include <malloc.h>
#include <environment.h>
#include <nand.h>
+#include <util.h>
#include <asm/errno.h>
#if defined(CFG_ENV_OFFSET_OOB)
@@ -39,8 +40,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
if (!buf)
return -ENOMEM;
+ ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
if (!strcmp(cmd, "get")) {
- ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
if (buf[0] == 'E' && buf[1] == 'N' &&
buf[2] == 'V' && buf[3] == '0')
@@ -49,7 +50,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
printf("No dynamic environment marker in OOB block 0\n");
} else if (!strcmp(cmd, "set")) {
- unsigned long addr;
+ unsigned long addr, dummy;
+
if (argc < 3)
goto usage;
@@ -57,7 +59,23 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
buf[1] = 'N';
buf[2] = 'V';
buf[3] = '0';
- addr = simple_strtoul(argv[2], NULL, 16);
+
+ if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) {
+ printf("Offset or partition name expected\n");
+ goto fail;
+ }
+ if (!ret) {
+ uint8_t tmp[4];
+ int i;
+
+ memcpy(&tmp, &addr, 4);
+ for (i = 0; i != 4; i++)
+ if (tmp[i] & ~buf[i+4]) {
+ printf("ERROR: erase OOB block to "
+ "write this value\n");
+ goto fail;
+ }
+ }
memcpy(buf+4, &addr, 4);
printf("%02x %02x %02x %02x - %02x %02x %02x %02x\n",
@@ -65,6 +83,8 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
buf[4], buf[5], buf[6], buf[7]);
ret = mtd->write_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
+ if (!ret)
+ CFG_ENV_OFFSET = addr;
} else
goto usage;
@@ -72,8 +92,9 @@ int do_dynenv(cmd_tbl_t *cmdtp, int flag
return ret;
usage:
- free(buf);
printf("Usage:\n%s\n", cmdtp->usage);
+fail:
+ free(buf);
return 1;
}

View File

@ -0,0 +1,40 @@
Index: u-boot/board/neo1973/neo1973.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/gta01.c
+++ u-boot/board/neo1973/gta01/gta01.c
@@ -68,8 +68,12 @@ DECLARE_GLOBAL_DATA_PTR;
#define U_M_PDIV 0x2
#define U_M_SDIV 0x3
+#define VALID_WAKEUP_REASONS (PCF50606_INT1_ONKEYF | PCF50606_INT1_ALARM)
+
unsigned int neo1973_wakeup_cause;
extern int nobootdelay;
+static unsigned char int1;
+
static inline void delay (unsigned long loops)
{
@@ -179,6 +183,13 @@ int board_init (void)
#error Please define GTA01 version
#endif
+ i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
+ int1 = pcf50606_reg_read(PCF50606_REG_INT1);
+ if (!(int1 & VALID_WAKEUP_REASONS) && !neo1973_aux_key_pressed()) {
+ pcf50606_reg_write(PCF50606_REG_OOCC1, PCF50606_OOCC1_GOSTDBY);
+ while (1);
+ }
+
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_NEO1973_GTA01;
@@ -200,7 +211,7 @@ int board_late_init(void)
pcf50606_init();
/* obtain wake-up reason, save INT1 in environment */
- tmp = pcf50606_reg_read(PCF50606_REG_INT1);
+ tmp = int1; //pcf50606_reg_read(PCF50606_REG_INT1);
sprintf(buf, "0x%02x", tmp);
setenv("pcf50606_int1", buf);

View File

@ -0,0 +1,56 @@
drivers/cfb_console.c: include asm/byteorder.h for le32_to_cpu and friends
[ shouldn't someone else have found this long ago ? ]
include/configs/neo1973.h (CONFIG_COMMANDS): add CFG_CMD_BMP
include/configs/neo1973.h: enable splash screen and BMP support
include/configs/neo1973.h: remove #if 1 ... #endif around video definitions
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/drivers/cfb_console.c
===================================================================
--- u-boot.orig/drivers/cfb_console.c
+++ u-boot/drivers/cfb_console.c
@@ -191,6 +191,7 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the
#if (CONFIG_COMMANDS & CFG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
#include <watchdog.h>
#include <bmp_layout.h>
+#include <asm/byteorder.h>
#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */
/*****************************************************************************/
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -86,6 +86,7 @@
/* CFG_CMD_IRQ | */ \
CFG_CMD_BOOTD | \
CFG_CMD_CONSOLE | \
+ CFG_CMD_BMP | \
CFG_CMD_ASKENV | \
CFG_CMD_RUN | \
CFG_CMD_ECHO | \
@@ -244,19 +245,21 @@
/* we have a board_late_init() function */
#define BOARD_LATE_INIT 1
-#if 1
#define CONFIG_VIDEO
#define CONFIG_VIDEO_S3C2410
#define CONFIG_CFB_CONSOLE
#define CONFIG_VIDEO_LOGO
+#define CONFIG_SPLASH_SCREEN
+#define CFG_VIDEO_LOGO_MAX_SIZE (640*480+1024+100) /* 100 = slack */
+#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_UNZIP
#define VIDEO_KBD_INIT_FCT 0
#define VIDEO_TSTC_FCT serial_tstc
#define VIDEO_GETC_FCT serial_getc
#define LCD_VIDEO_ADDR 0x33d00000
-#endif
#define CONFIG_S3C2410_NAND_BBT 1

View File

@ -0,0 +1,198 @@
This patch adds support for CFG_ENV_OFFSET_PATCHED and
CFG_ENV_OFFSET_OOB.
Both try to solve the problem of fixing the environment location in NAND flash
at compile time, which doesn't work well if the NAND flash has a bad block at
exactly that location.
CFG_ENV_OFFSET_PATCHED puts the environment in a global variable. You can then
use the linker script to put that variable to a fixed location in the u-boot
image. Then you can use bianry patching during the production flash process.
The idea of CFG_ENV_OFFSET_OOB is to store the environment offset in the NAND
OOB data of block 0. We can do this in case the vendor makes a guarantee that
block 0 never is a factory-default bad block.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/common/env_nand.c
===================================================================
--- u-boot.orig/common/env_nand.c
+++ u-boot/common/env_nand.c
@@ -271,6 +271,33 @@
ulong total;
int ret;
+#if defined(CFG_ENV_OFFSET_OOB)
+ struct mtd_info *mtd = &nand_info[0];
+ struct nand_chip *this = mtd->priv;
+ int buf_len;
+ uint8_t *buf;
+
+ buf_len = (1 << this->bbt_erase_shift);
+ buf_len += (buf_len >> this->page_shift) * mtd->oobsize;
+ buf = malloc(buf_len);
+ if (!buf)
+ return;
+
+ nand_read_raw(mtd, buf, 0, mtd->oobblock, mtd->oobsize);
+ if (buf[mtd->oobblock + 8 + 0] == 'E' &&
+ buf[mtd->oobblock + 8 + 1] == 'N' &&
+ buf[mtd->oobblock + 8 + 2] == 'V' &&
+ buf[mtd->oobblock + 8 + 3] == '0') {
+ CFG_ENV_OFFSET = *((unsigned long *) &buf[mtd->oobblock + 8 + 4]);
+ /* fall through to the normal environment reading code below */
+ free(buf);
+ puts("Found Environment offset in OOB..\n");
+ } else {
+ free(buf);
+ return use_default();
+ }
+#endif
+
total = CFG_ENV_SIZE;
ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
if (ret || total != CFG_ENV_SIZE)
Index: u-boot/common/environment.c
===================================================================
--- u-boot.orig/common/environment.c
+++ u-boot/common/environment.c
@@ -29,6 +29,12 @@
#undef __ASSEMBLY__
#include <environment.h>
+#if defined(CFG_ENV_OFFSET_PATCHED)
+unsigned long env_offset = CFG_ENV_OFFSET_PATCHED;
+#elif defined(CFG_ENV_OFFSET_OOB)
+unsigned long env_offset = CFG_ENV_OFFSET_OOB;
+#endif
+
/*
* Handle HOSTS that have prepended
* crap on symbol names, not TARGETS.
Index: u-boot/include/environment.h
===================================================================
--- u-boot.orig/include/environment.h
+++ u-boot/include/environment.h
@@ -70,6 +70,10 @@
#endif /* CFG_ENV_IS_IN_FLASH */
#if defined(CFG_ENV_IS_IN_NAND)
+#if defined(CFG_ENV_OFFSET_PATCHED) || defined(CFG_ENV_OFFSET_OOB)
+extern unsigned long env_offset;
+#define CFG_ENV_OFFSET env_offset
+#else
# ifndef CFG_ENV_OFFSET
# error "Need to define CFG_ENV_OFFSET when using CFG_ENV_IS_IN_NAND"
# endif
@@ -82,6 +86,7 @@
# ifdef CFG_ENV_IS_EMBEDDED
# define ENV_IS_EMBEDDED 1
# endif
+#endif /* CFG_ENV_NAND_PATCHED */
#endif /* CFG_ENV_IS_IN_NAND */
Index: u-boot/common/Makefile
===================================================================
--- u-boot.orig/common/Makefile
+++ u-boot/common/Makefile
@@ -31,7 +31,7 @@
cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
cmd_cache.o cmd_console.o \
cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
- cmd_eeprom.o cmd_elf.o cmd_ext2.o \
+ cmd_dynenv.o cmd_eeprom.o cmd_elf.o cmd_ext2.o \
cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
cmd_load.o cmd_log.o \
Index: u-boot/common/cmd_dynenv.c
===================================================================
--- /dev/null
+++ u-boot/common/cmd_dynenv.c
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2006-2007 OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <environment.h>
+#include <nand.h>
+#include <asm/errno.h>
+
+#if defined(CFG_ENV_OFFSET_OOB)
+
+int do_dynenv(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ struct mtd_info *mtd = &nand_info[0];
+ int ret, size = 8;
+ uint8_t *buf;
+
+ char *cmd = argv[1];
+
+ buf = malloc(mtd->oobsize);
+ if (!buf)
+ return -ENOMEM;
+
+ if (!strcmp(cmd, "get")) {
+ ret = mtd->read_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
+
+ if (buf[0] == 'E' && buf[1] == 'N' &&
+ buf[2] == 'V' && buf[3] == '0')
+ printf("0x%08x\n", *((u_int32_t *) &buf[4]));
+ else
+ printf("No dynamic environment marker in OOB block 0\n");
+
+ } else if (!strcmp(cmd, "set")) {
+ unsigned long addr;
+ if (argc < 3)
+ goto usage;
+
+ buf[0] = 'E';
+ buf[1] = 'N';
+ buf[2] = 'V';
+ buf[3] = '0';
+ addr = simple_strtoul(argv[2], NULL, 16);
+ memcpy(buf+4, &addr, 4);
+
+ printf("%02x %02x %02x %02x - %02x %02x %02x %02x\n",
+ buf[0], buf[1], buf[2], buf[3],
+ buf[4], buf[5], buf[6], buf[7]);
+
+ ret = mtd->write_oob(mtd, 8, size, (size_t *) &size, (u_char *) buf);
+ } else
+ goto usage;
+
+ free(buf);
+ return ret;
+
+usage:
+ free(buf);
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(dynenv, 3, 1, do_dynenv,
+ "dynenv - dynamically placed (NAND) environment\n",
+ "dynenv set off - set enviromnent offset\n"
+ "dynenv get - get environment offset\n");
+
+#endif /* CFG_ENV_OFFSET_OOB */

View File

@ -0,0 +1,17 @@
This patch adds the hex-printing of the file size read by 'ext2load'
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot.git/common/cmd_ext2.c
===================================================================
--- u-boot.git.orig/common/cmd_ext2.c 2007-01-02 18:26:17.000000000 +0100
+++ u-boot.git/common/cmd_ext2.c 2007-01-02 18:26:27.000000000 +0100
@@ -279,7 +279,7 @@
/* Loading ok, update default load address */
load_addr = addr;
- printf ("\n%ld bytes read\n", filelen);
+ printf ("\n%ld (0x%lx) bytes read\n", filelen, filelen);
sprintf(buf, "%lX", filelen);
setenv("filesize", buf);

View File

@ -0,0 +1,229 @@
board/neo1973/lowlevel_foo.S: http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.S
board/neo1973/lowlevel_foo.lds: http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.lds
board/neo1973/Makefile: added building of lowlevel_foo.bin (based on
http://people.openmoko.org/laforge/tmp/bbt-20070206/lowlevel_foo.build.sh)
Index: u-boot/board/neo1973/common/lowlevel_foo.S
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/common/lowlevel_foo.S
@@ -0,0 +1,82 @@
+
+_start:
+ b reset
+undefvec:
+ b undefvec
+swivec:
+ b swivec
+pabtvec:
+ b pabtvec
+dabtvec:
+ b dabtvec
+rsvdvec:
+ b rsvdvec
+irqvec:
+ b irqvec
+fiqvec:
+ b fiqvec
+
+reset:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+/* turn off the watchdog */
+#define pWTCON 0x53000000
+#define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
+#define INTSUBMSK 0x4A00001C
+#define CLKDIVN 0x4C000014 /* clock divisor register */
+
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ mov r1, #0xffffffff
+ ldr r0, =INTMSK
+ str r1, [r0]
+ ldr r1, =0x3ff
+ ldr r0, =INTSUBMSK
+ str r1, [r0]
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+
+ bl cpu_init_crit
+ ldr r0,=TEXT_BASE
+ mov pc, r0
+
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 2 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+ bl lowlevel_init
+ mov lr, ip
+ mov pc, lr
+
Index: u-boot/board/neo1973/common/lowlevel_foo.lds
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/common/lowlevel_foo.lds
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ lowlevel_foo.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}
Index: u-boot/board/neo1973/gta01/Makefile
===================================================================
--- u-boot.orig/board/neo1973/gta01/Makefile
+++ u-boot/board/neo1973/gta01/Makefile
@@ -28,14 +28,31 @@
OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o
SOBJS := ../common/lowlevel_init.o
+.PHONY: all
+
+all: $(LIB) lowevel_foo.bin
+
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
+lowlevel_foo.o: ../common/lowlevel_foo.S
+ $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
+ -o lowlevel_foo.o ../common/lowlevel_foo.S
+
+lowlevel_foo: lowlevel_foo.o ../common/lowlevel_init.o ../common/lowlevel_foo.lds
+ $(LD) -T ../common/lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
+ ../common/lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
+
+lowevel_foo.bin: lowlevel_foo
+ $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
+ lowlevel_foo lowlevel_foo.bin
+
+
clean:
- rm -f $(SOBJS) $(OBJS)
+ rm -f $(SOBJS) $(OBJS) lowlevel_foo lowlevel_foo.o
distclean: clean
- rm -f $(LIB) core *.bak .depend
+ rm -f $(LIB) core *.bak .depend lowlevel_foo.bin
#########################################################################
Index: u-boot/board/qt2410/Makefile
===================================================================
--- u-boot.orig/board/qt2410/Makefile
+++ u-boot/board/qt2410/Makefile
@@ -28,14 +28,31 @@
OBJS := qt2410.o flash.o
SOBJS := lowlevel_init.o
+.PHONY: all
+
+all: $(LIB) lowevel_foo.bin
+
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
+lowlevel_foo.o: ../neo1973/common/lowlevel_foo.S
+ $(CC) -c -DTEXT_BASE=0x33F80000 -march=armv4 \
+ -o lowlevel_foo.o ../neo1973/common/lowlevel_foo.S
+
+lowlevel_foo: lowlevel_foo.o lowlevel_init.o \
+ ../neo1973/common/lowlevel_foo.lds
+ $(LD) -T ../neo1973/common/lowlevel_foo.lds -Ttext 0x33f80000 -Bstatic \
+ lowlevel_init.o lowlevel_foo.o -o lowlevel_foo
+
+lowevel_foo.bin: lowlevel_foo
+ $(CROSS_COMPILE)objcopy --gap-fill=0xff -O binary \
+ lowlevel_foo lowlevel_foo.bin
+
clean:
- rm -f $(SOBJS) $(OBJS)
+ rm -f $(SOBJS) $(OBJS) lowlevel_foo lowlevel_foo.o
distclean: clean
- rm -f $(LIB) core *.bak .depend
+ rm -f $(LIB) core *.bak .depend lowlevel_foo.bin
#########################################################################

View File

@ -0,0 +1,17 @@
Index: git/tools/Makefile
===================================================================
--- git.orig/tools/Makefile 2007-10-03 16:51:38.000000000 +0100
+++ git/tools/Makefile 2007-10-03 16:52:03.000000000 +0100
@@ -114,9 +114,9 @@
#
# Use native tools and options
#
-CPPFLAGS = -idirafter $(SRCTREE)/include \
- -idirafter $(OBJTREE)/include2 \
- -idirafter $(OBJTREE)/include \
+CPPFLAGS = -I$(SRCTREE)/include \
+ -I$(OBJTREE)/include2 \
+ -I$(OBJTREE)/include \
-DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
CFLAGS = $(HOST_CFLAGS) $(CPPFLAGS) -O
AFLAGS = -D__ASSEMBLY__ $(CPPFLAGS)

View File

@ -0,0 +1,73 @@
board/neo1973/neo1973.c (board_late_init): moved MMC power-up to separate
function
cpu/arm920t/s3c24x0/mmc.c (mmc_init): call mmc_power_up and return -ENODEV
immediately if there is no card
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/board/neo1973/neo1973.c
===================================================================
--- u-boot.orig/board/neo1973/neo1973.c
+++ u-boot/board/neo1973/neo1973.c
@@ -223,6 +223,19 @@ int board_init (void)
return 0;
}
+int mmc_power_up(void)
+{
+#if defined(CONFIG_ARCH_GTA01B_v4)
+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+ /* check if sd card is inserted, and power-up if it is */
+ if (gpio->GPFDAT & (1 << 5))
+ return 0;
+ gpio->GPBDAT &= ~(1 << 2);
+#endif /* !CONFIG_ARCH_GTA01B_v4 */
+ return 1;
+}
+
int board_late_init(void)
{
unsigned char tmp;
@@ -289,14 +302,8 @@ continue_boot:
/* switch on the backlight */
neo1973_backlight(1);
-#if defined(CONFIG_ARCH_GTA01B_v4)
- {
- /* check if sd card is inserted, and power-up if it is */
- S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
- if (!(gpio->GPFDAT & (1 << 5)))
- gpio->GPBDAT &= ~(1 << 2);
- }
-#endif
+ /* check if sd card is inserted, and power-up if it is */
+ mmc_power_up();
return 0;
}
Index: u-boot/cpu/arm920t/s3c24x0/mmc.c
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/mmc.c
+++ u-boot/cpu/arm920t/s3c24x0/mmc.c
@@ -381,6 +381,11 @@ static void print_sd_cid(const struct sd
cid->crc >> 1, cid->crc & 1);
}
+int __attribute__((weak)) mmc_power_up(void)
+{
+ return 1;
+}
+
int mmc_init(int verbose)
{
int retries, rc = -ENODEV;
@@ -393,6 +398,8 @@ int mmc_init(int verbose)
debug("mmc_init(PCLK=%u)\n", get_PCLK());
clk_power->CLKCON |= (1 << 9);
+ if (!mmc_power_up())
+ return -ENODEV;
/* S3C2410 has some bug that prevents reliable operation at higher speed */
//sdi->SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */

View File

@ -0,0 +1,30 @@
This patch makes nand_block_checkbad check both the BBT and the actual
OOB data. This avoids accidently passing blocks as good when BBT and
OOB markers are not synchronized, e.g., before "nand createbbt".
Experimental.
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/drivers/nand/nand_base.c
===================================================================
--- u-boot.orig/drivers/nand/nand_base.c
+++ u-boot/drivers/nand/nand_base.c
@@ -517,11 +517,14 @@ static int nand_block_checkbad (struct m
{
struct nand_chip *this = mtd->priv;
- if (!this->bbt)
- return this->block_bad(mtd, ofs, getchip);
+ if (this->block_bad(mtd, ofs, getchip))
+ return 1;
/* Return info from the table */
- return nand_isbad_bbt (mtd, ofs, allowbbt);
+ if (this->bbt && nand_isbad_bbt (mtd, ofs, allowbbt))
+ return 1;
+
+ return 0;
}
/**

View File

@ -0,0 +1,126 @@
This patch adds user-requested BBT creation. It includes the following changes:
- common/cmd_nand.c: move yes/no decision to separate function
- do_nand: ask for confirmation for "nand erase"
- do_nand: add command "nand createbbt" to erase NAND and create a new BBT
Experimental.
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/common/cmd_nand.c
===================================================================
--- u-boot.orig/common/cmd_nand.c 2007-02-16 23:53:28.000000000 +0100
+++ u-boot/common/cmd_nand.c 2007-02-16 23:53:57.000000000 +0100
@@ -163,6 +163,17 @@
return 0;
}
+static int yes(void)
+{
+ char c;
+
+ c = getc();
+ if (c != 'y' && c != 'Y')
+ return 0;
+ c = getc();
+ return c == '\r' || c == '\n';
+}
+
int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
int i, dev, ret;
@@ -228,7 +239,8 @@
strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
strcmp(cmd, "biterr") != 0 &&
- strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
+ strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 &&
+ strcmp(cmd, "createbbt") != 0 )
goto usage;
/* the following commands operate on the current device */
@@ -283,13 +295,23 @@
"are sure of what you are doing!\n"
"\nReally scrub this NAND flash? <y/N>\n");
- if (getc() == 'y' && getc() == '\r') {
+ if (yes()) {
opts.scrub = 1;
} else {
puts("scrub aborted\n");
return -1;
}
}
+ else {
+ if (opts.length == nand->size) {
+ puts("Really erase everything ? <y/N>\n");
+ if (!yes()) {
+ puts("erase aborted\n");
+ return -1;
+ }
+ }
+ }
+
ret = nand_erase_opts(nand, &opts);
printf("%s\n", ret ? "ERROR" : "OK");
@@ -458,6 +480,33 @@
return 0;
}
+ if (strcmp(cmd, "createbbt") == 0) {
+ struct nand_chip *nand_chip = nand->priv;
+ nand_erase_options_t opts;
+
+ puts("Create BBT and erase everything ? <y/N>\n");
+ if (!yes()) {
+ puts("createbbt aborted\n");
+ return -1;
+ }
+ memset(&opts, 0, sizeof(opts));
+ opts.length = nand->size;
+ if (nand_erase_opts(nand, &opts)) {
+ puts("Erase failed\n");
+ return 1;
+ }
+ nand_chip->options &= ~NAND_DONT_CREATE_BBT;
+ puts("Creating BBT. Please wait ...");
+ if (nand_default_bbt(nand)) {
+ puts("\nFailed\n");
+ return 1;
+ }
+ else {
+ puts("\n");
+ return 0;
+ }
+ }
+
usage:
printf("Usage:\n%s\n", cmdtp->usage);
return 1;
@@ -478,7 +527,8 @@
"nand markbad off - mark bad block at offset (UNSAFE)\n"
"nand biterr off - make a bit error at offset (UNSAFE)\n"
"nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
- "nand unlock [offset] [size] - unlock section\n");
+ "nand unlock [offset] [size] - unlock section\n"
+ "nand createbbt - create bad block table\n");
static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
ulong offset, ulong addr, char *cmd)
Index: u-boot/drivers/nand/nand_bbt.c
===================================================================
--- u-boot.orig/drivers/nand/nand_bbt.c 2007-02-16 23:53:54.000000000 +0100
+++ u-boot/drivers/nand/nand_bbt.c 2007-02-16 23:53:57.000000000 +0100
@@ -795,7 +795,8 @@
len = mtd->size >> (this->bbt_erase_shift + 2);
/* Allocate memory (2bit per block) */
- this->bbt = kmalloc (len, GFP_KERNEL);
+ if (!this->bbt)
+ this->bbt = kmalloc (len, GFP_KERNEL);
if (!this->bbt) {
printk (KERN_ERR "nand_scan_bbt: Out of memory\n");
return -ENOMEM;

View File

@ -0,0 +1,354 @@
This patch adds support for 'dynamic partitions'. This basically
works as follows:
* The nand code generates a bad-block-table at the first scan of the chip
* The dynamic partition code calculates the raw partition sizes based on
the bad block table. E.g. if you have a partition of size 0x30000, and there are
two bad blocks (0x4000 each) in it, the raw size will increase to 0x38000, and the
following partitions get shifted towards the end of flash.
Please note that currently the desired partition sizes are stored at compile-time
in an array in drivers/nand/nand_bbt.c, so this definitely needs to change before
submitting/merging upstream.
In order to calculate the partiton map (and set mtdparts accordingly), you can use
the 'dynpart' command at the prompt. Use 'saveenv' to make the setting permanent.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/drivers/nand/nand_bbt.c
===================================================================
--- u-boot.orig/drivers/nand/nand_bbt.c
+++ u-boot/drivers/nand/nand_bbt.c
@@ -1044,9 +1044,86 @@
switch ((int)res) {
case 0x00: return 0;
case 0x01: return 1;
+ case 0x03: return 1;
case 0x02: return allowbbt ? 0 : 1;
}
return 1;
}
+#if defined(CONFIG_NAND_DYNPART)
+
+extern unsigned int dynpart_size[];
+extern char *dynpart_names[];
+
+#define MTDPARTS_MAX_SIZE 512
+
+
+static int skip_offs(const struct nand_chip *this, unsigned int offs)
+{
+ int block = (int) (offs >> (this->bbt_erase_shift - 1));
+ u_int8_t bbt = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
+
+ return bbt == 3;
+}
+
+int nand_create_mtd_dynpart(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ int part;
+ char *mtdparts;
+ unsigned int cur_offs = 0;
+
+ mtdparts = malloc(MTDPARTS_MAX_SIZE); /* FIXME: bounds checking */
+ if (!mtdparts)
+ return -ENOMEM;
+
+ sprintf(mtdparts, "mtdparts=" CFG_NAND_DYNPART_MTD_KERNEL_NAME ":");
+
+ for (part = 0; dynpart_size[part] != 0; part++) {
+ unsigned int bb_delta = 0;
+ unsigned int offs = 0;
+ char mtdpart[32];
+
+ for (offs = cur_offs;
+ offs < cur_offs + dynpart_size[part] + bb_delta;
+ offs += mtd->erasesize) {
+ if (skip_offs(this, offs))
+ bb_delta += mtd->erasesize;
+ }
+
+ /*
+ * Absorb bad blocks immediately following this partition also
+ * into the partition, in order to make next partition start
+ * with a good block. This simplifies handling of the
+ * environment partition.
+ */
+ while (offs < this->chipsize && skip_offs(this, offs)) {
+ bb_delta += mtd->erasesize;
+ offs += mtd->erasesize;
+ }
+
+ if (cur_offs + dynpart_size[part] + bb_delta > this->chipsize)
+ dynpart_size[part] = this->chipsize - cur_offs - bb_delta;
+#if 0
+ printf("partition %u: start = 0x%08x, end=%08x size=%08x, size_inc_bb=%08x\n",
+ part, cur_offs, cur_offs + dynpart_size[part] + bb_delta,
+ dynpart_size[part], dynpart_size[part] + bb_delta);
+#endif
+ cur_offs += dynpart_size[part] + bb_delta;
+ sprintf(mtdpart, "0x%.8x(%.16s),", dynpart_size[part] + bb_delta,
+ dynpart_names[part]);
+ mtdpart[sizeof(mtdpart)-1] = '\0';
+ strncat(mtdparts, mtdpart,
+ MTDPARTS_MAX_SIZE-strlen(mtdparts)-1);
+ }
+
+ mtdparts[strlen(mtdparts)-1] = '\0';
+ printf("mtdparts %s\n", mtdparts);
+ setenv("mtdparts", mtdparts);
+
+ free(mtdparts);
+ return 0;
+}
+#endif /* CONFIG_NAND_DYNPART */
+
#endif
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -99,7 +99,7 @@
CFG_CMD_ELF | \
CFG_CMD_MISC | \
/* CFG_CMD_USB | */ \
- /* CFG_CMD_JFFS2 | */ \
+ CFG_CMD_JFFS2 | \
CFG_CMD_DIAG | \
/* CFG_CMD_HWFLOW | */ \
CFG_CMD_SAVES | \
@@ -212,13 +212,13 @@
#define CONFIG_FAT 1
#define CONFIG_SUPPORT_VFAT
-#if 0
+#if 1
/* JFFS2 driver */
#define CONFIG_JFFS2_CMDLINE 1
#define CONFIG_JFFS2_NAND 1
#define CONFIG_JFFS2_NAND_DEV 0
-#define CONFIG_JFFS2_NAND_OFF 0x634000
-#define CONFIG_JFFS2_NAND_SIZE 0x39cc000
+//#define CONFIG_JFFS2_NAND_OFF 0x634000
+//#define CONFIG_JFFS2_NAND_SIZE 0x39cc000
#endif
/* ATAG configuration */
@@ -257,4 +257,9 @@
#define CONFIG_DRIVER_PCF50606 1
+#define MTDIDS_DEFAULT "nand0=neo1973-nand"
+#define MTPARTS_DEFAULT "neo1973-nand:256k(u-boot),16k(u-boot_env),2M(kernel),640k(splash),-(jffs2)"
+#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand"
+#define CONFIG_NAND_DYNPART
+
#endif /* __CONFIG_H */
Index: u-boot/common/cmd_jffs2.c
===================================================================
--- u-boot.orig/common/cmd_jffs2.c
+++ u-boot/common/cmd_jffs2.c
@@ -1841,6 +1841,29 @@
return NULL;
}
+/* Return the 'net size' of the partition (i.e. excluding any bad blocks) */
+unsigned int nand_net_part_size(struct part_info *part)
+{
+ struct mtd_info *mtd;
+ unsigned int offs;
+ unsigned int bb_delta = 0;
+
+ if (!part || !part->dev || !part->dev->id ||
+ part->dev->id->num >= CFG_MAX_NAND_DEVICE)
+ return 0;
+
+ mtd = &nand_info[part->dev->id->num];
+
+ for (offs = part->offset; offs < part->offset + part->size;
+ offs += mtd->erasesize) {
+ if (nand_isbad_bbt(mtd, offs, 0))
+ bb_delta += mtd->erasesize;
+ }
+
+ return part->size - bb_delta;
+}
+
+
/***************************************************/
/* U-boot commands */
/***************************************************/
@@ -2132,6 +2155,24 @@
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
+
+#if defined(CONFIG_NAND_DYNPART)
+extern int nand_create_mtd_dynpart(struct mtd_info *mtd);
+
+int do_dynpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+#if 0
+ int i = simple_strtoul(argv[1], NULL, 0);
+ if (i >= CFG_MAX_NAND_DEVICE)
+ return -EINVAL;
+#endif
+ nand_create_mtd_dynpart(&nand_info[0]);
+
+ return 0;
+}
+#endif /* CONFIG_NAND_DYNPART */
+
+
#endif /* #ifdef CONFIG_JFFS2_CMDLINE */
/***************************************************/
@@ -2197,6 +2238,15 @@
"<name> := '(' NAME ')'\n"
"<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)\n"
);
+
+#if defined(CONFIG_NAND_DYNPART)
+U_BOOT_CMD(
+ dynpart, 1, 1, do_dynpart,
+ "dynpart\t- dynamically calculate partition table based on BBT\n",
+ "\n"
+ " - sets 'mtdparts' according to BBT\n");
+#endif /* CONFIG_NAND_DYNPART */
+
#endif /* #ifdef CONFIG_JFFS2_CMDLINE */
/***************************************************/
Index: u-boot/common/cmd_nand.c
===================================================================
--- u-boot.orig/common/cmd_nand.c
+++ u-boot/common/cmd_nand.c
@@ -101,7 +101,7 @@
}
int
-arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
+arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size, int net)
{
int idx = nand_curr_device;
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
@@ -122,10 +122,17 @@
printf("'%s' is not a number\n", argv[1]);
return -1;
}
- if (*size > part->size)
- *size = part->size;
+ if (*size > part->size) {
+ if (net)
+ *size = nand_net_part_size(part);
+ else
+ *size = part->size;
+ }
} else {
- *size = part->size;
+ if (net)
+ *size = nand_net_part_size(part);
+ else
+ *size = part->size;
}
idx = dev->id->num;
*nand = nand_info[idx];
@@ -261,7 +268,7 @@
printf("\nNAND %s: ", scrub ? "scrub" : "erase");
/* skip first two or three arguments, look for offset and size */
- if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
+ if (arg_off_size(argc - o, argv + o, nand, &off, &size, 0) != 0)
return 1;
memset(&opts, 0, sizeof(opts));
@@ -323,7 +330,7 @@
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
printf("\nNAND %s: ", read ? "read" : "write");
- if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
+ if (arg_off_size(argc - 3, argv + 3, nand, &off, &size, 1) != 0)
return 1;
s = strchr(cmd, '.');
@@ -445,7 +452,7 @@
}
if (strcmp(cmd, "unlock") == 0) {
- if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
+ if (arg_off_size(argc - 2, argv + 2, nand, &off, &size, 0) < 0)
return 1;
if (!nand_unlock(nand, off, size)) {
Index: u-boot/common/cmd_dynenv.c
===================================================================
--- u-boot.orig/common/cmd_dynenv.c
+++ u-boot/common/cmd_dynenv.c
@@ -60,7 +60,7 @@
buf[2] = 'V';
buf[3] = '0';
- if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) {
+ if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy, 1) < 0) {
printf("Offset or partition name expected\n");
goto fail;
}
Index: u-boot/include/util.h
===================================================================
--- u-boot.orig/include/util.h
+++ u-boot/include/util.h
@@ -28,6 +28,6 @@
/* common/cmd_nand.c */
int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
- ulong *size);
+ ulong *size, int net);
#endif /* UTIL_H */
Index: u-boot/board/qt2410/qt2410.c
===================================================================
--- u-boot.orig/board/qt2410/qt2410.c
+++ u-boot/board/qt2410/qt2410.c
@@ -126,3 +126,9 @@
return 0;
}
+
+unsigned int dynpart_size[] = {
+ CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
+char *dynpart_names[] = {
+ "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
+
Index: u-boot/board/neo1973/gta01/gta01.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/gta01.c
+++ u-boot/board/neo1973/gta01/gta01.c
@@ -429,3 +434,14 @@
return 0;
}
+
+/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
+ "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
+ images: 640*480*2*2 = 1228800 < 1245184. */
+
+unsigned int dynpart_size[] = {
+ CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
+char *dynpart_names[] = {
+ "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
+
+
Index: u-boot/include/configs/qt2410.h
===================================================================
--- u-boot.orig/include/configs/qt2410.h
+++ u-boot/include/configs/qt2410.h
@@ -283,5 +283,7 @@
#define MTDIDS_DEFAULT "nand0=qt2410-nand"
#define MTPARTS_DEFAULT "qt2410-nand:192k(u-boot),8k(u-boot_env),2M(kernel),2M(splash),-(jffs2)"
+#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "qt2410-nand"
+#define CONFIG_NAND_DYNPART
#endif /* __CONFIG_H */

View File

@ -0,0 +1,302 @@
Index: u-boot/common/cmd_nand.c
===================================================================
--- u-boot.orig/common/cmd_nand.c
+++ u-boot/common/cmd_nand.c
@@ -392,6 +392,14 @@
else
ret = nand->write_oob(nand, off, size, &size,
(u_char *) addr);
+ } else if (s != NULL && !strcmp(s, ".otp")) {
+ /* read out-of-band data */
+ if (read)
+ ret = nand->read_otp(nand, off, size, &size,
+ (u_char *) addr);
+ else
+ ret = nand->write_otp(nand, off, size, &size,
+ (u_char *) addr);
} else {
if (read)
ret = nand_read(nand, off, &size, (u_char *)addr);
@@ -527,8 +535,9 @@
"nand - NAND sub-system\n",
"info - show available NAND devices\n"
"nand device [dev] - show or set current device\n"
- "nand read[.jffs2] - addr off|partition size\n"
- "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
+ "nand read[.jffs2, .oob, .otp] addr off|partition size\n"
+ "nand write[.jffs2, .oob, .otp] addr off|partiton size\n"
+ " - read/write `size' bytes starting\n"
" at offset `off' to/from memory address `addr'\n"
"nand erase [clean] [off size] - erase `size' bytes from\n"
" offset `off' (entire device if not specified)\n"
Index: u-boot/cpu/arm920t/s3c24x0/nand.c
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/nand.c
+++ u-boot/cpu/arm920t/s3c24x0/nand.c
@@ -205,7 +205,7 @@
}
#endif
-int board_nand_init(struct nand_chip *nand)
+int s3c24x0_nand_init(struct nand_chip *nand)
{
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
Index: u-boot/drivers/nand/nand_base.c
===================================================================
--- u-boot.orig/drivers/nand/nand_base.c
+++ u-boot/drivers/nand/nand_base.c
@@ -2042,6 +2042,32 @@
}
#endif
+/*
+ * See nand_read_oob and nand_write_oob
+ */
+
+static int nand_read_otp(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (!this->read_otp)
+ return -ENOSYS;
+ return this->read_otp(mtd, from, len, retlen, buf);
+
+}
+
+static int nand_write_otp(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (!this->write_otp)
+ return -ENOSYS;
+ return this->write_otp(mtd, to, len, retlen, buf);
+}
+
+
/**
* single_erease_cmd - [GENERIC] NAND standard block erase command function
* @mtd: MTD device structure
@@ -2613,6 +2639,8 @@
mtd->write_ecc = nand_write_ecc;
mtd->read_oob = nand_read_oob;
mtd->write_oob = nand_write_oob;
+ mtd->read_otp = nand_read_otp;
+ mtd->write_otp = nand_write_otp;
/* XXX U-BOOT XXX */
#if 0
mtd->readv = NULL;
Index: u-boot/include/linux/mtd/mtd.h
===================================================================
--- u-boot.orig/include/linux/mtd/mtd.h
+++ u-boot/include/linux/mtd/mtd.h
@@ -95,6 +95,9 @@
int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+ int (*read_otp) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+ int (*write_otp) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+
/*
* Methods to access the protection register area, present in some
* flash devices. The user data is one time programmable but the
Index: u-boot/include/linux/mtd/nand.h
===================================================================
--- u-boot.orig/include/linux/mtd/nand.h
+++ u-boot/include/linux/mtd/nand.h
@@ -307,6 +307,10 @@
void (*enable_hwecc)(struct mtd_info *mtd, int mode);
void (*erase_cmd)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd);
+ int (*read_otp)(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen, u_char *buf);
+ int (*write_otp) (struct mtd_info *mtd, loff_t to,
+ size_t len, size_t *retlen, const u_char *buf);
int eccmode;
int eccsize;
int eccbytes;
Index: u-boot/board/neo1973/gta01/Makefile
===================================================================
--- u-boot.orig/board/neo1973/gta01/Makefile
+++ u-boot/board/neo1973/gta01/Makefile
@@ -25,7 +25,7 @@
LIB = lib$(BOARD).a
-OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
+OBJS := gta01.o pcf50606.o nand.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o ../common/bootmenu.o
SOBJS := ../common/lowlevel_init.o
.PHONY: all
Index: u-boot/board/neo1973/gta01/nand.c
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/gta01/nand.c
@@ -0,0 +1,121 @@
+/*
+ * nand.c - Board-specific NAND setup
+ *
+ * Copyright (C) 2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner@openmoko.org>
+ * All Rights Reserved
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include "config.h" /* nand.h needs NAND_MAX_CHIPS */
+#include "linux/mtd/mtd.h"
+#include "linux/mtd/nand.h"
+#include "asm/errno.h"
+
+
+int s3c24x0_nand_init(struct nand_chip *nand);
+
+
+static void samsung_nand_begin_otp(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+
+ /* @@@FIXME: this is ugly - we select the NAND chip to send the
+ mode switch commands, knowing that it will be switched off later */
+ this->select_chip(mtd, 0);
+ /* "magic" mode change */
+ this->cmdfunc(mtd, 0x30, -1, -1);
+ this->cmdfunc(mtd, 0x65, -1, -1);
+}
+
+
+static void samsung_nand_end_otp(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+
+ /* read/write deselected the chip so now we need to select again */
+ this->select_chip(mtd, 0);
+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+ this->select_chip(mtd, -1);
+}
+
+
+static loff_t otp_page[] = {
+ 0x15, /* 00-XX-00-00, with XX = 15h-19h */
+ 0x16,
+ 0x17,
+ 0x18,
+ 0x19,
+ 0x1b, /* 00-1B-00-00 */
+};
+
+#define OTP_PAGES (sizeof(otp_page)/sizeof(*otp_page))
+
+
+static int convert_otp_address(loff_t *addr, size_t *len)
+{
+ int page;
+
+ if (*len && *addr >> 9 != (*addr+*len-1) >> 9)
+ return -EINVAL;
+ if (*len > 512)
+ return -EINVAL;
+ page = *addr >> 9;
+ if (page >= OTP_PAGES)
+ return -EINVAL;
+ *addr = otp_page[page] << 9;
+ return 0;
+}
+
+
+static int samsung_nand_read_otp(struct mtd_info *mtd, loff_t from,
+ size_t len, size_t *retlen, u_char *buf)
+{
+ int ret;
+
+ ret = convert_otp_address(&from, &len);
+ if (ret)
+ return ret;
+ samsung_nand_begin_otp(mtd);
+ ret = mtd->read(mtd, from, len, retlen, buf);
+ samsung_nand_end_otp(mtd);
+ return ret;
+}
+
+
+static int samsung_nand_write_otp(struct mtd_info *mtd, loff_t to,
+ size_t len, size_t *retlen, const u_char *buf)
+{
+ int ret;
+
+ ret = convert_otp_address(&to, &len);
+ if (ret)
+ return ret;
+ samsung_nand_begin_otp(mtd);
+ ret = mtd->write(mtd, to, len, retlen, buf);
+ samsung_nand_end_otp(mtd);
+ return ret;
+}
+
+
+int board_nand_init(struct nand_chip *nand)
+{
+ nand->read_otp = samsung_nand_read_otp;
+ nand->write_otp = samsung_nand_write_otp;
+ return s3c24x0_nand_init(nand);
+}
Index: u-boot/board/neo1973/gta02/nand.c
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/gta02/nand.c
@@ -0,0 +1,39 @@
+/*
+ * nand.c - Board-specific NAND setup
+ *
+ * Copyright (C) 2007 by OpenMoko, Inc.
+ * Written by Werner Almesberger <werner@openmoko.org>
+ * All Rights Reserved
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include "config.h" /* nand.h needs NAND_MAX_CHIPS */
+#include "linux/mtd/mtd.h"
+#include "linux/mtd/nand.h"
+
+
+int s3c24x0_nand_init(struct nand_chip *nand);
+
+
+/* Add OTP et al later */
+
+
+int board_nand_init(struct nand_chip *nand)
+{
+ return s3c24x0_nand_init(nand);
+}

View File

@ -0,0 +1,23 @@
Re-introduce the 'nand read.oob' and 'nand write.oob' commands
that used to exist with the legacy NAND code
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot.git/common/cmd_nand.c
===================================================================
--- u-boot.git.orig/common/cmd_nand.c 2007-01-26 15:41:13.000000000 +0100
+++ u-boot.git/common/cmd_nand.c 2007-01-26 15:49:37.000000000 +0100
@@ -351,6 +351,14 @@
opts.quiet = quiet;
ret = nand_write_opts(nand, &opts);
}
+ } else if (s != NULL && !strcmp(s, ".oob")) {
+ /* read out-of-band data */
+ if (read)
+ ret = nand->read_oob(nand, off, size, &size,
+ (u_char *) addr);
+ else
+ ret = nand->write_oob(nand, off, size, &size,
+ (u_char *) addr);
} else {
if (read)
ret = nand_read(nand, off, &size, (u_char *)addr);

View File

@ -0,0 +1,316 @@
Index: u-boot/drivers/usbtty.c
===================================================================
--- u-boot.orig/drivers/usbtty.c
+++ u-boot/drivers/usbtty.c
@@ -66,7 +66,7 @@
/*
* Defines
*/
-#define NUM_CONFIGS 1
+#define NUM_CONFIGS 2
#define MAX_INTERFACES 2
#define NUM_ENDPOINTS 3
#define ACM_TX_ENDPOINT 3
@@ -192,8 +192,7 @@
#endif
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG,
- .bmAttributes =
- BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+ .bmAttributes = BMATTRIBUTE_RESERVED,
.bMaxPower = USBTTY_MAXPOWER
},
/* Interface 1 */
@@ -294,6 +293,120 @@
.func_dfu = DFU_FUNC_DESC,
#endif
},
+ {
+ .configuration_desc ={
+ .bLength =
+ sizeof(struct usb_configuration_descriptor),
+ .bDescriptorType = USB_DT_CONFIG,
+ .wTotalLength =
+ cpu_to_le16(sizeof(struct acm_config_desc)
+#ifdef CONFIG_USBD_DFU
+ - sizeof(struct usb_interface_descriptor)
+ - sizeof(struct usb_dfu_func_descriptor)
+#endif
+ ),
+ .bNumInterfaces = NUM_ACM_INTERFACES,
+ .bConfigurationValue = 2,
+ .iConfiguration = STR_CONFIG,
+ .bmAttributes = BMATTRIBUTE_RESERVED,
+ .bMaxPower = 50, /* 100mA */
+ },
+ /* Interface 1 */
+ .interface_desc = {
+ .bLength = sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0x01,
+ .bInterfaceClass =
+ COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
+ .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS,
+ .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL,
+ .iInterface = STR_CTRL_INTERFACE,
+ },
+ .usb_class_header = {
+ .bFunctionLength =
+ sizeof(struct usb_class_header_function_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_ST_HEADER,
+ .bcdCDC = cpu_to_le16(110),
+ },
+ .usb_class_call_mgt = {
+ .bFunctionLength =
+ sizeof(struct usb_class_call_management_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_ST_CMF,
+ .bmCapabilities = 0x00,
+ .bDataInterface = 0x01,
+ },
+ .usb_class_acm = {
+ .bFunctionLength =
+ sizeof(struct usb_class_abstract_control_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_ST_ACMF,
+ .bmCapabilities = 0x00,
+ },
+ .usb_class_union = {
+ .bFunctionLength =
+ sizeof(struct usb_class_union_function_descriptor),
+ .bDescriptorType = CS_INTERFACE,
+ .bDescriptorSubtype = USB_ST_UF,
+ .bMasterInterface = 0x00,
+ .bSlaveInterface0 = 0x01,
+ },
+ .notification_endpoint = {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x01 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize
+ = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+ .bInterval = 0xFF,
+ },
+
+ /* Interface 2 */
+ .data_class_interface = {
+ .bLength =
+ sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0x01,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 0x02,
+ .bInterfaceClass =
+ COMMUNICATIONS_INTERFACE_CLASS_DATA,
+ .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE,
+ .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE,
+ .iInterface = STR_DATA_INTERFACE,
+ },
+ .data_endpoints = {
+ {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x02 | USB_DIR_OUT,
+ .bmAttributes =
+ USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize =
+ cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+ .bInterval = 0xFF,
+ },
+ {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x03 | USB_DIR_IN,
+ .bmAttributes =
+ USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize =
+ cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE),
+ .bInterval = 0xFF,
+ },
+ },
+ /* We don't add the DFU functional descriptor here since we only
+ * want to do DFU in the high-current charging mode for safety reasons */
+ },
+
};
static struct rs232_emu rs232_desc={
@@ -330,8 +443,7 @@
.bNumInterfaces = NUM_GSERIAL_INTERFACES,
.bConfigurationValue = 1,
.iConfiguration = STR_CONFIG,
- .bmAttributes =
- BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+ .bmAttributes = BMATTRIBUTE_RESERVED,
.bMaxPower = USBTTY_MAXPOWER
},
.interface_desc = {
@@ -384,6 +496,68 @@
},
},
},
+ {
+ .configuration_desc ={
+ .bLength = sizeof(struct usb_configuration_descriptor),
+ .bDescriptorType = USB_DT_CONFIG,
+ .wTotalLength =
+ cpu_to_le16(sizeof(struct gserial_config_desc)),
+ .bNumInterfaces = NUM_GSERIAL_INTERFACES,
+ .bConfigurationValue = 1,
+ .iConfiguration = STR_CONFIG,
+ .bmAttributes = BMATTRIBUTE_RESERVED,
+ .bMaxPower = 50
+ },
+ .interface_desc = {
+ {
+ .bLength =
+ sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = NUM_ENDPOINTS,
+ .bInterfaceClass =
+ COMMUNICATIONS_INTERFACE_CLASS_VENDOR,
+ .bInterfaceSubClass =
+ COMMUNICATIONS_NO_SUBCLASS,
+ .bInterfaceProtocol =
+ COMMUNICATIONS_NO_PROTOCOL,
+ .iInterface = STR_DATA_INTERFACE
+ },
+ },
+ .data_endpoints = {
+ {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x01 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize =
+ cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE),
+ .bInterval= 0xFF,
+ },
+ {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x02 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize =
+ cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE),
+ .bInterval = 0xFF,
+ },
+ {
+ .bLength =
+ sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0x03 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize =
+ cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE),
+ .bInterval = 0xFF,
+ },
+ },
+ },
};
/*
@@ -679,12 +853,14 @@
bus_instance->maxpacketsize = 64;
bus_instance->serial_number_str = serial_number;
- /* configuration instance */
- memset (config_instance, 0,
- sizeof (struct usb_configuration_instance));
- config_instance->interfaces = interface_count;
- config_instance->configuration_descriptor = configuration_descriptor;
- config_instance->interface_instance_array = interface_instance;
+ /* configuration instances */
+ for (i = 0; i < NUM_CONFIGS; i++) {
+ memset(&config_instance[i], 0, sizeof(config_instance));
+ config_instance[i].interfaces = interface_count;
+ /* FIXME: this breaks for the non-ACM case */
+ config_instance[i].configuration_descriptor = &acm_configuration_descriptors[i];
+ config_instance[i].interface_instance_array = interface_instance;
+ }
/* interface instance */
memset (interface_instance, 0,
@@ -1043,9 +1219,17 @@
usbtty_configured_flag = 0;
break;
case DEVICE_CONFIGURED:
+ printf("DEVICE_CONFIGURED: %u\n", device->configuration);
+ if (device->configuration == 1)
+ udc_ctrl(UDC_CTRL_500mA_ENABLE, 1);
+ else
+ udc_ctrl(UDC_CTRL_500mA_ENABLE, 0);
usbtty_configured_flag = 1;
break;
-
+ case DEVICE_DE_CONFIGURED:
+ printf("DEVICE_DE_CONFIGURED\n");
+ udc_ctrl(UDC_CTRL_500mA_ENABLE, 0);
+ break;
case DEVICE_ADDRESS_ASSIGNED:
usbtty_init_endpoints ();
Index: u-boot/drivers/usbtty.h
===================================================================
--- u-boot.orig/drivers/usbtty.h
+++ u-boot/drivers/usbtty.h
@@ -60,7 +60,7 @@
#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS
#define USBTTY_BCD_DEVICE 0x00
-#define USBTTY_MAXPOWER 0x00
+#define USBTTY_MAXPOWER 250 /* 500mA */
#define STR_LANG 0x00
#define STR_MANUFACTURER 0x01
Index: u-boot/board/neo1973/common/udc.c
===================================================================
--- u-boot.orig/board/neo1973/common/udc.c
+++ u-boot/board/neo1973/common/udc.c
@@ -2,6 +2,7 @@
#include <common.h>
#include <usbdcore.h>
#include <s3c2410.h>
+#include <pcf50606.h>
void udc_ctrl(enum usbd_event event, int param)
{
@@ -17,6 +18,13 @@
gpio->GPBDAT &= ~(1 << 9);
#endif
break;
+ case UDC_CTRL_500mA_ENABLE:
+#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4) || \
+ defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \
+ defined(CONFIG_ARCH_GTA01B_v4)
+ pcf50606_charge_autofast(param);
+#endif
+ break;
default:
break;
}
Index: u-boot/include/usbdcore.h
===================================================================
--- u-boot.orig/include/usbdcore.h
+++ u-boot/include/usbdcore.h
@@ -686,8 +686,8 @@
enum usbd_event {
UDC_CTRL_PULLUP_ENABLE,
+ UDC_CTRL_500mA_ENABLE,
};
void udc_ctrl(enum usbd_event event, int param);
#endif
-#endif

View File

@ -0,0 +1,137 @@
Provide a place where the loader can patch the binary, such that it executes a
command string from RAM. We use this for automated installs, where we can thus
use the same u-boot binary for all stages.
include/configs/neo1973.h: new option CFG_PREBOOT_OVERRIDE to allow setting of
the preboot command in memory
cpu/arm920t/start.S: added variable "preboot_override" at known location
(_start+0x40)
common/main.c (main_loop): if preboot_override is set, execute the command
string found there
common/env_common.c (env_relocate): if preboot_override is set, always use the
default environment
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -77,6 +77,14 @@ _fiq: .word fiq
*************************************************************************
*/
+
+/* Must follow the .balign above, so we get a well-known address ! */
+#ifdef CFG_PREBOOT_OVERRIDE
+.globl preboot_override
+preboot_override:
+ .word 0
+#endif
+
#ifdef CONFIG_S3C2410_NAND_BOOT
.globl booted_from_nand
booted_from_nand:
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -207,6 +207,7 @@
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_SIZE 0x4000 /* 16k Total Size of Environment Sector */
#define CFG_ENV_OFFSET_OOB 1 /* Location of ENV stored in block 0 OOB */
+#define CFG_PREBOOT_OVERRIDE 1 /* allow preboot from memory */
#define NAND_MAX_CHIPS 1
#define CFG_NAND_BASE 0x4e000000
Index: u-boot/common/main.c
===================================================================
--- u-boot.orig/common/main.c
+++ u-boot/common/main.c
@@ -85,6 +85,11 @@ int do_mdm_init = 0;
extern void mdm_init(void); /* defined in board.c */
#endif
+#ifdef CFG_PREBOOT_OVERRIDE
+extern char *preboot_override;
+#endif
+
+
/***************************************************************************
* Watch for 'delay' seconds for autoboot stop or autoboot delay string.
* returns: 0 - no key string, allow autoboot
@@ -306,8 +311,8 @@ void main_loop (void)
char *s;
int bootdelay;
#endif
-#ifdef CONFIG_PREBOOT
- char *p;
+#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
+ char *p = NULL;
#endif
#ifdef CONFIG_BOOTCOUNT_LIMIT
unsigned long bootcount = 0;
@@ -364,8 +369,23 @@ void main_loop (void)
install_auto_complete();
#endif
+#if defined(CONFIG_PREBOOT) || defined(CFG_PREBOOT_OVERRIDE)
#ifdef CONFIG_PREBOOT
- if ((p = getenv ("preboot")) != NULL) {
+ p = getenv ("preboot");
+#endif
+#ifdef CFG_PREBOOT_OVERRIDE
+ if (preboot_override) {
+ /* for convenience, preboot_override may end in \n, not \0 */
+ p = strchr(preboot_override, '\n');
+ if (p)
+ *p = 0;
+ /* make sure we can overwrite the load area if we want to */
+ p = strdup(preboot_override);
+ /* clean the image in case we want to flash it */
+ preboot_override = NULL;
+ }
+#endif /* CFG_PREBOOT_OVERRIDE */
+ if (p) {
# ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
# endif
@@ -381,7 +401,7 @@ void main_loop (void)
disable_ctrlc(prev); /* restore Control C checking */
# endif
}
-#endif /* CONFIG_PREBOOT */
+#endif /* CONFIG_PREBOOT || CFG_PREBOOT_OVERRIDE */
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
Index: u-boot/common/env_common.c
===================================================================
--- u-boot.orig/common/env_common.c
+++ u-boot/common/env_common.c
@@ -37,6 +37,10 @@
# define SHOW_BOOT_PROGRESS(arg)
#endif
+#ifdef CFG_PREBOOT_OVERRIDE
+extern char *preboot_override;
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_AMIGAONEG3SE
@@ -234,7 +238,14 @@ void env_relocate (void)
puts ("*** Warning - bad CRC, using default environment\n\n");
SHOW_BOOT_PROGRESS (-1);
#endif
+ }
+
+#ifdef CFG_PREBOOT_OVERRIDE
+ if (preboot_override)
+ gd->env_valid = 0;
+#endif
+ if (gd->env_valid == 0) {
if (sizeof(default_environment) > ENV_SIZE)
{
puts ("*** Error - default environment is too large\n\n");

View File

@ -0,0 +1,31 @@
include/configs/neo1973.h: increase heap from 128 kB to 400 kB, for BMP image
decompression
[ note: increasing it to 512 kB trips over something. note sure what.
find out. ]
include/configs/neo1973.h: raise number of command line arguments from 16 to 64
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -54,7 +54,8 @@
/*
* Size of malloc() pool
*/
-#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
+#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 400*1024)
+ /* >> CFG_VIDEO_LOGO_MAX_SIZE */
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
/*
@@ -142,7 +143,7 @@
#endif
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
-#define CFG_MAXARGS 16 /* max number of command args */
+#define CFG_MAXARGS 64 /* max number of command args */
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */
#define CFG_MEMTEST_START 0x30000000 /* memtest works on */

View File

@ -0,0 +1,76 @@
# just some local hacks
uboot-machtypes.patch
ext2load_hex.patch
uboot-mokoversion.patch
# those we want to get mainline
uboot-s3c2410-warnings-fix.patch
uboot-strtoul.patch
uboot-cramfs_but_no_jffs2.patch
nand-read_write_oob.patch
uboot-arm920t-gd_in_irq.patch
uboot-arm920_s3c2410_irq_demux.patch
uboot-s3c2410-nand.patch
uboot-cmd_s3c2410.patch
uboot-s3c2410-mmc.patch
env_nand_oob.patch
dynenv-harden.patch
uboot-s3c2410_fb.patch
uboot-20061030-qt2410.patch
uboot-20061030-neo1973.patch
# under construction, but intended for mainline
uboot-s3c2410-misccr-definitions.patch
boot-from-ram-reloc.patch
boot-from-ram-and-nand.patch
wakeup-reason-nand-only.patch
uboot-neo1973-resume.patch
# this will be somewhat more difficult
nand-dynamic_partitions.patch
uboot-s3c2410-norelocate_irqvec_cpy.patch
uboot-usbtty-acm.patch
uboot-s3c2410_udc.patch
# those need to be cleaned up
bbt-create-optional.patch
nand-createbbt.patch
dontask.patch
nand-badisbad.patch
uboot-bbt-quiet.patch
# splash screen
raise-limits.patch
splashimage-command.patch
cmd-unzip.patch
enable-splash-bmp.patch
# for automated installation
preboot-override.patch
lowlevel_foo.patch
# move these later, once the dust has settled
default-env.patch
console-ansi.patch
boot-menu.patch
# those have to be implemented fully
uboot-dfu.patch
uboot-neo1973-defaultenv.patch
uboot-nand-markbad-reallybad.patch
usbdcore-multiple_configs.patch
neo1973-chargefast.patch
uboot-s3c2440.patch
uboot-smdk2440.patch
uboot-hxd8.patch
uboot-license.patch
uboot-gta02.patch
uboot-s3c2443.patch
uboot-smdk2443.patch
# for review, merge soon
unbusy-i2c.patch

View File

@ -0,0 +1,24 @@
drivers/cfb_console.c (video_logo): if "splashimage" doesn't contain an
address, use its content as a command
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/drivers/cfb_console.c
===================================================================
--- u-boot.orig/drivers/cfb_console.c
+++ u-boot/drivers/cfb_console.c
@@ -1121,7 +1121,13 @@ static void *video_logo (void)
ulong addr;
if ((s = getenv ("splashimage")) != NULL) {
- addr = simple_strtoul (s, NULL, 16);
+ char *end;
+
+ addr = simple_strtoul (s, &end, 16);
+ if (*end) {
+ run_command(s, 0);
+ return video_fb_address;
+ }
if (video_display_bitmap (addr, 0, 0) == 0) {
return ((void *) (video_fb_address));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
This patch adds a IRQ demultiplexer callback to the arm920 cpu core code,
plus a stub implementation of it for the S3C2410.
Index: u-boot.git/cpu/arm920t/interrupts.c
===================================================================
--- u-boot.git.orig/cpu/arm920t/interrupts.c 2007-02-05 22:49:11.000000000 +0100
+++ u-boot.git/cpu/arm920t/interrupts.c 2007-02-05 23:19:01.000000000 +0100
@@ -161,11 +161,16 @@
void do_irq (struct pt_regs *pt_regs)
{
-#if defined (CONFIG_USE_IRQ) && defined (CONFIG_ARCH_INTEGRATOR)
+#if defined (CONFIG_USE_IRQ)
+#if defined (ARM920_IRQ_CALLBACK)
+ ARM920_IRQ_CALLBACK();
+ return;
+#elif defined (CONFIG_ARCH_INTEGRATOR)
/* ASSUMED to be a timer interrupt */
/* Just clear it - count handled in */
/* integratorap.c */
*(volatile ulong *)(CFG_TIMERBASE + 0x0C) = 0;
+#endif /* ARCH_INTEGRATOR */
#else
printf ("interrupt request\n");
show_regs (pt_regs);
Index: u-boot.git/cpu/arm920t/s3c24x0/interrupts.c
===================================================================
--- u-boot.git.orig/cpu/arm920t/s3c24x0/interrupts.c 2007-02-05 22:49:11.000000000 +0100
+++ u-boot.git/cpu/arm920t/s3c24x0/interrupts.c 2007-02-05 23:21:35.000000000 +0100
@@ -216,4 +216,13 @@
/*NOTREACHED*/
}
+#ifdef CONFIG_USE_IRQ
+void s3c2410_irq(void)
+{
+ S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
+ u_int32_t intpnd = irq->INTPND;
+
+}
+#endif /* USE_IRQ */
+
#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */
Index: u-boot.git/include/common.h
===================================================================
--- u-boot.git.orig/include/common.h 2007-02-05 22:49:11.000000000 +0100
+++ u-boot.git/include/common.h 2007-02-05 23:19:01.000000000 +0100
@@ -452,6 +452,8 @@
ulong get_PCI_freq (void);
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
+void s3c2410_irq(void);
+#define ARM920_IRQ_CALLBACK s3c2410_irq
ulong get_FCLK (void);
ulong get_HCLK (void);
ulong get_PCLK (void);

View File

@ -0,0 +1,28 @@
This patch allows us to use the 'gd' pointer (and thus environment
and everything else associated with it) from interrupt context on
arm920t.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S 2007-02-24 02:35:38.000000000 +0100
+++ u-boot/cpu/arm920t/start.S 2007-02-24 02:36:01.000000000 +0100
@@ -474,12 +474,12 @@
.macro irq_save_user_regs
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0-r12
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^ @ Calling SP, LR
- str lr, [r8, #0] @ Save calling PC
+ add r7, sp, #S_PC
+ stmdb r7, {sp, lr}^ @ Calling SP, LR
+ str lr, [r7, #0] @ Save calling PC
mrs r6, spsr
- str r6, [r8, #4] @ Save CPSR
- str r0, [r8, #8] @ Save OLD_R0
+ str r6, [r7, #4] @ Save CPSR
+ str r0, [r7, #8] @ Save OLD_R0
mov r0, sp
.endm

View File

@ -0,0 +1,43 @@
This patch makes the u-boot NAND BBT code a bit more quiet
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/drivers/nand/nand_bbt.c
===================================================================
--- u-boot.orig/drivers/nand/nand_bbt.c 2007-02-16 23:54:02.000000000 +0100
+++ u-boot/drivers/nand/nand_bbt.c 2007-02-16 23:54:05.000000000 +0100
@@ -157,10 +157,6 @@
this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06);
continue;
}
- /* Leave it for now, if its matured we can move this
- * message to MTD_DEBUG_LEVEL0 */
- printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
- ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
/* Factory marked bad or worn out ? */
if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
@@ -229,14 +225,12 @@
if (td->options & NAND_BBT_VERSION) {
nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
td->version[0] = buf[mtd->oobblock + td->veroffs];
- printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
}
/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
md->version[0] = buf[mtd->oobblock + md->veroffs];
- printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
}
return 1;
@@ -374,8 +368,6 @@
for (i = 0; i < chips; i++) {
if (td->pages[i] == -1)
printk (KERN_WARNING "Bad block table not found for chip %d\n", i);
- else
- printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
}
return 0;
}

View File

@ -0,0 +1,175 @@
This patch adds a new 's3c2410' command which currently supports 's3c2410 speed
{set,get,list} and thus allows dynamic change of the CPU clock.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/cpu/arm920t/s3c24x0/Makefile
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile 2007-02-24 15:14:00.000000000 +0100
+++ u-boot/cpu/arm920t/s3c24x0/Makefile 2007-02-24 15:21:02.000000000 +0100
@@ -26,7 +26,7 @@
LIB = $(obj)lib$(SOC).a
COBJS = i2c.o interrupts.o serial.o speed.o \
- usb_ohci.o nand_read.o nand.o
+ usb_ohci.o nand_read.o nand.o cmd_s3c2410.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
Index: u-boot/cpu/arm920t/s3c24x0/cmd_s3c2410.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot/cpu/arm920t/s3c24x0/cmd_s3c2410.c 2007-02-24 15:22:17.000000000 +0100
@@ -0,0 +1,152 @@
+/*
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Boot support
+ */
+#include <common.h>
+#include <command.h>
+#include <net.h> /* for print_IPaddr */
+#include <s3c2410.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if (CONFIG_COMMANDS & CFG_CMD_BDI)
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define MHZ 1000000
+
+static void print_cpu_speed(void)
+{
+ printf("FCLK = %u MHz, HCLK = %u MHz, PCLK = %u MHz\n",
+ get_FCLK()/MHZ, get_HCLK()/MHZ, get_PCLK()/MHZ);
+}
+
+struct s3c2410_pll_speed {
+ u_int16_t mhz;
+ u_int32_t mpllcon;
+ u_int32_t clkdivn;
+};
+
+#define CLKDIVN_1_1_1 0x00
+#define CLKDIVN_1_2_2 0x02
+#define CLKDIVN_1_2_4 0x03
+#define CLKDIVN_1_4_4 0x04
+
+static const struct s3c2410_pll_speed pll_configs[] = {
+ {
+ .mhz = 50,
+ .mpllcon = ((0x5c << 12) + (0x4 << 4) + 0x2),
+ .clkdivn = CLKDIVN_1_1_1,
+ },
+ {
+ .mhz = 101,
+ .mpllcon = ((0x7f << 12) + (0x2 << 4) + 0x2),
+ .clkdivn = CLKDIVN_1_2_2,
+ },
+ {
+ .mhz = 202,
+ .mpllcon = ((0x90 << 12) + (0x7 << 4) + 0x0),
+ .clkdivn = CLKDIVN_1_2_4,
+ },
+ {
+ .mhz = 266,
+ .mpllcon = ((0x7d << 12) + (0x1 << 4) + 0x1),
+ .clkdivn = CLKDIVN_1_2_4,
+ },
+};
+
+static void list_cpu_speeds(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(pll_configs); i++)
+ printf("%u MHz\n", pll_configs[i].mhz);
+}
+
+static int reconfig_mpll(u_int16_t mhz)
+{
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pll_configs); i++) {
+ if (pll_configs[i].mhz == mhz) {
+ /* to reduce PLL lock time, adjust the LOCKTIME register */
+ clk_power->LOCKTIME = 0xFFFFFF;
+
+ /* configure MPLL */
+ clk_power->MPLLCON = pll_configs[i].mpllcon;
+ clk_power->UPLLCON = ((0x78 << 12) + (0x2 << 4) + 0x3),
+ clk_power->CLKDIVN = pll_configs[i].clkdivn;
+
+ /* If we changed the speed, we need to re-configure
+ * the serial baud rate generator */
+ serial_setbrg();
+ return 0;
+ }
+ }
+ return -1;
+}
+
+int do_s3c2410 ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ if (!strcmp(argv[1], "speed")) {
+ if (argc < 2)
+ goto out_help;
+ if (!strcmp(argv[2], "get"))
+ print_cpu_speed();
+ else if (!strcmp(argv[2], "list"))
+ list_cpu_speeds();
+ else if (!strcmp(argv[2], "set")) {
+ unsigned long mhz;
+ if (argc < 3)
+ goto out_help;
+
+ mhz = simple_strtoul(argv[3], NULL, 10);
+
+ if (reconfig_mpll(mhz) < 0)
+ printf("error, speed %uMHz unknown\n", mhz);
+ else
+ print_cpu_speed();
+ } else
+ goto out_help;
+ } else {
+out_help:
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------- */
+
+
+U_BOOT_CMD(
+ s3c2410, 4, 1, do_s3c2410,
+ "s3c2410 - SoC specific commands\n",
+ "speed get - display current PLL speed config\n"
+ "s3c2410 speed list - display supporte PLL speed configs\n"
+ "s3c2410 speed set - set PLL speed\n"
+);
+
+#endif

View File

@ -0,0 +1,41 @@
Fix building with CRAMFS but not JFFS2 support
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/fs/cramfs/cramfs.c
===================================================================
--- u-boot.orig/fs/cramfs/cramfs.c 2007-02-17 11:46:26.000000000 +0100
+++ u-boot/fs/cramfs/cramfs.c 2007-02-17 11:54:36.000000000 +0100
@@ -27,7 +27,7 @@
#include <common.h>
#include <malloc.h>
-#if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
+#if (CONFIG_COMMANDS & CFG_CMD_CRAMFS)
#include <asm/byteorder.h>
#include <linux/stat.h>
Index: u-boot/common/cmd_jffs2.c
===================================================================
--- u-boot.orig/common/cmd_jffs2.c 2007-02-17 11:47:51.000000000 +0100
+++ u-boot/common/cmd_jffs2.c 2007-02-17 14:08:25.000000000 +0100
@@ -170,10 +170,19 @@
static struct mtd_device *current_dev = NULL;
static u8 current_partnum = 0;
+#ifdef CFG_CMD_CRAMFS
extern int cramfs_check (struct part_info *info);
extern int cramfs_load (char *loadoffset, struct part_info *info, char *filename);
extern int cramfs_ls (struct part_info *info, char *filename);
extern int cramfs_info (struct part_info *info);
+#else
+/* defining empty macros for function names is ugly but avoids ifdef clutter
+ * all over the code */
+#define cramfs_check(x) (0)
+#define cramfs_load(x,y,z) (-1)
+#define cramfs_ls(x,y) (0)
+#define cramfs_info(x) (0)
+#endif
static struct part_info* jffs2_part_info(struct mtd_device *dev, unsigned int part_num);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,712 @@
Index: u-boot/common/Makefile
===================================================================
--- u-boot.orig/common/Makefile
+++ u-boot/common/Makefile
@@ -34,7 +34,7 @@
cmd_dynenv.o cmd_eeprom.o cmd_elf.o cmd_ext2.o \
cmd_fat.o cmd_fdc.o cmd_fdt.o cmd_fdos.o cmd_flash.o cmd_fpga.o \
cmd_i2c.o cmd_ide.o cmd_immap.o cmd_itest.o cmd_jffs2.o \
- cmd_load.o cmd_log.o \
+ cmd_license.o cmd_load.o cmd_log.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
cmd_nand.o cmd_net.o cmd_nvedit.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
Index: u-boot/common/cmd_license.c
===================================================================
--- /dev/null
+++ u-boot/common/cmd_license.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2007 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_LICENSE)
+
+#define LICENSE_MAX 20480
+#include <command.h>
+#include <malloc.h>
+#include <license.h>
+int gunzip(void *, int, unsigned char *, unsigned long *);
+
+int do_license(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ char *tok, *dst = malloc(LICENSE_MAX);
+ unsigned long len = LICENSE_MAX;
+
+ if (!dst)
+ return -1;
+
+ if (gunzip(dst, LICENSE_MAX, gpl_gz, &len) != 0) {
+ printf("Error uncompressing license text\n");
+ free(dst);
+ return -1;
+ }
+ puts(dst);
+ free(dst);
+
+ return 0;
+}
+
+U_BOOT_CMD(license, 1, 1, do_license,
+ "license - print GPL license text\n",
+ NULL);
+
+#endif /* CFG_CMD_LICENSE */
Index: u-boot/include/cmd_confdefs.h
===================================================================
--- u-boot.orig/include/cmd_confdefs.h
+++ u-boot/include/cmd_confdefs.h
@@ -75,6 +75,7 @@
#define CFG_CMD_FPGA 0x0000010000000000ULL /* FPGA configuration Support */
#define CFG_CMD_HWFLOW 0x0000020000000000ULL /* RTS/CTS hw flow control */
#define CFG_CMD_SAVES 0x0000040000000000ULL /* save S record dump */
+#define CFG_CMD_LICENSE 0x0000080000000000ULL /* Display GPL License */
#define CFG_CMD_SPI 0x0000100000000000ULL /* SPI utility */
#define CFG_CMD_FDOS 0x0000200000000000ULL /* Floppy DOS support */
#define CFG_CMD_VFD 0x0000400000000000ULL /* VFD support (TRAB) */
Index: u-boot/include/license.h
===================================================================
--- /dev/null
+++ u-boot/include/license.h
@@ -0,0 +1,584 @@
+/* bin2header converting 'gpl.gz' */
+unsigned char gpl_gz[] = {
+ 0x1f, 0x8b, 0x08, 0x08, 0xb2, 0x10, 0x0d, 0x46, 0x00, 0x03,
+ 0x67, 0x70, 0x6c, 0x00, 0x9d, 0x5b, 0x5d, 0x77, 0xdb, 0x46,
+ 0x92, 0x7d, 0x4e, 0xff, 0x8a, 0x3e, 0x7e, 0x89, 0x74, 0x0e,
+ 0xc3, 0xc4, 0x9e, 0x9d, 0xdd, 0x49, 0xfc, 0x44, 0x49, 0x94,
+ 0xcd, 0x1d, 0x99, 0x52, 0x48, 0xca, 0x8e, 0x1f, 0x41, 0xb2,
+ 0x29, 0x62, 0x0c, 0x02, 0x5c, 0x7c, 0x48, 0xe6, 0xbf, 0xdf,
+ 0x7b, 0xab, 0xba, 0x81, 0x06, 0x49, 0x25, 0xb3, 0x9b, 0x93,
+ 0xc4, 0x16, 0x09, 0x54, 0xd7, 0x77, 0xdd, 0xaa, 0x2e, 0xfd,
+ 0xf0, 0x83, 0xc5, 0x3f, 0x1f, 0xa6, 0x8f, 0xf6, 0xc3, 0x78,
+ 0x3a, 0x9e, 0x8d, 0xee, 0xec, 0xc3, 0xe3, 0xd5, 0xdd, 0xe4,
+ 0xda, 0xe2, 0xbf, 0xf1, 0x74, 0x3e, 0x36, 0x3f, 0xc8, 0x03,
+ 0xf8, 0xe7, 0xb3, 0x2b, 0xab, 0xb4, 0xc8, 0xed, 0xbb, 0x81,
+ 0xfd, 0xef, 0x26, 0x77, 0xf6, 0xed, 0xaf, 0xbf, 0xbe, 0x35,
+ 0xc6, 0x5e, 0x17, 0xfb, 0x43, 0x99, 0x3e, 0x6d, 0x6b, 0x7b,
+ 0x71, 0x7d, 0x89, 0x0f, 0xff, 0xf1, 0xeb, 0x40, 0xbe, 0xb2,
+ 0xb7, 0xa5, 0x73, 0x76, 0x5e, 0x6c, 0xea, 0x97, 0xa4, 0x74,
+ 0xf6, 0xb6, 0x68, 0xf2, 0x75, 0x52, 0x83, 0xc0, 0xc0, 0x4e,
+ 0xf2, 0xd5, 0x70, 0x60, 0xec, 0xdf, 0xf9, 0x4c, 0x92, 0x7f,
+ 0xcb, 0xd2, 0xdc, 0xce, 0x6b, 0x3c, 0x5d, 0x0f, 0xec, 0x6d,
+ 0xba, 0xa9, 0xb7, 0xf6, 0x36, 0x2b, 0x8a, 0x72, 0x60, 0xaf,
+ 0x8a, 0xaa, 0xe6, 0xf3, 0x9f, 0x46, 0xf6, 0x97, 0x77, 0x6f,
+ 0xdf, 0xfe, 0xf2, 0xd3, 0xdb, 0xbf, 0xfd, 0xf2, 0xd6, 0x3e,
+ 0xce, 0x47, 0xc6, 0x8e, 0x9f, 0x5d, 0x79, 0x28, 0xc0, 0x45,
+ 0x5a, 0xd9, 0xbd, 0x2b, 0x77, 0x69, 0x5d, 0xbb, 0xb5, 0xad,
+ 0x0b, 0xbb, 0x02, 0x3b, 0x36, 0xc9, 0xd7, 0x76, 0x9d, 0x56,
+ 0x75, 0x99, 0x2e, 0x9b, 0xda, 0x59, 0x3c, 0xbb, 0xc4, 0xd1,
+ 0x3b, 0x7e, 0x99, 0xba, 0xca, 0xd8, 0x62, 0x63, 0xeb, 0x2d,
+ 0xde, 0xcc, 0xd2, 0x95, 0xcb, 0x2b, 0x67, 0xd7, 0xc5, 0xaa,
+ 0xd9, 0xb9, 0x1c, 0xe7, 0xe3, 0x79, 0xbb, 0xda, 0x26, 0xf9,
+ 0x53, 0x9a, 0x3f, 0xd9, 0xb4, 0x26, 0xf9, 0xbc, 0xa8, 0x6d,
+ 0x92, 0x65, 0xc5, 0x8b, 0x5b, 0x0f, 0x0d, 0xd4, 0x21, 0xfa,
+ 0x78, 0x28, 0x5d, 0xb2, 0x5b, 0x66, 0x0e, 0x0a, 0xb0, 0x8b,
+ 0xad, 0x0b, 0x94, 0x2a, 0xbb, 0x29, 0x4a, 0xbb, 0x03, 0xdf,
+ 0xb6, 0x0a, 0x92, 0xf3, 0xbf, 0xb5, 0xab, 0xd2, 0xa7, 0x5c,
+ 0x39, 0xac, 0x93, 0x6f, 0xf8, 0xf0, 0x25, 0x39, 0xd8, 0x43,
+ 0xd1, 0x94, 0x66, 0x03, 0xc1, 0xd7, 0xc5, 0x8e, 0xdf, 0x54,
+ 0x5b, 0x79, 0x1e, 0xcc, 0x0b, 0x0b, 0x10, 0xae, 0x1e, 0x5a,
+ 0x7b, 0x75, 0x00, 0xdf, 0x79, 0x5d, 0x26, 0x15, 0xf8, 0xab,
+ 0x71, 0x96, 0x18, 0xcb, 0xe5, 0xae, 0x4c, 0x32, 0xfb, 0xd0,
+ 0x2c, 0x71, 0xb4, 0xb9, 0xf3, 0x82, 0x80, 0xdd, 0x34, 0xaf,
+ 0x5d, 0xbe, 0xd6, 0xa3, 0x9e, 0x9a, 0x04, 0x0a, 0xae, 0x61,
+ 0x07, 0x1e, 0x65, 0xff, 0xec, 0x28, 0x7e, 0x67, 0x02, 0xcf,
+ 0x3f, 0xfd, 0x84, 0x47, 0x76, 0xe4, 0xb3, 0x6a, 0xf0, 0x18,
+ 0x0f, 0x6d, 0xc5, 0xc1, 0x11, 0x7c, 0x56, 0x04, 0x85, 0x5a,
+ 0xc0, 0x63, 0x65, 0x9b, 0x0a, 0xbe, 0x31, 0xa4, 0x26, 0xd2,
+ 0xca, 0xf4, 0x59, 0xb3, 0x81, 0xb5, 0x64, 0xbf, 0xcf, 0xa0,
+ 0x7c, 0x1e, 0x2e, 0xfa, 0x11, 0x1b, 0xb8, 0xbe, 0x97, 0x98,
+ 0xce, 0x4b, 0x7e, 0xac, 0x22, 0x0d, 0xe6, 0x22, 0x4d, 0x92,
+ 0x1f, 0x6c, 0x81, 0x77, 0x4a, 0xbb, 0x2f, 0x8b, 0xa7, 0x32,
+ 0xd9, 0xd9, 0x97, 0x6d, 0x41, 0xca, 0x4d, 0xbd, 0x2d, 0xca,
+ 0x0a, 0x5a, 0xda, 0xc1, 0x0f, 0xf0, 0xa4, 0x69, 0x2a, 0x35,
+ 0x1f, 0x58, 0xba, 0x98, 0x17, 0x3b, 0xe7, 0x5f, 0x7b, 0xcd,
+ 0x23, 0x7b, 0xc2, 0xad, 0x0a, 0xb8, 0x0b, 0xd4, 0xb7, 0x3c,
+ 0x98, 0xa0, 0xec, 0x3b, 0x57, 0x41, 0x40, 0xfb, 0x8a, 0x60,
+ 0x69, 0x5e, 0xd5, 0x2e, 0x59, 0x0f, 0x2f, 0xad, 0xfd, 0x5a,
+ 0x34, 0x76, 0x95, 0xe4, 0x22, 0xeb, 0xc1, 0x2a, 0x2f, 0xa2,
+ 0x79, 0xcf, 0x70, 0x05, 0x03, 0x16, 0xc5, 0x90, 0x4e, 0xf3,
+ 0x65, 0xeb, 0x72, 0xfb, 0x02, 0xbd, 0xee, 0x5d, 0xf2, 0x8d,
+ 0xca, 0x10, 0xa5, 0x06, 0x46, 0x06, 0xfc, 0x8a, 0x0c, 0x95,
+ 0x6e, 0xe3, 0xca, 0x92, 0xd2, 0x40, 0x01, 0xde, 0x7e, 0x03,
+ 0xba, 0xa4, 0xd9, 0x97, 0x38, 0x1f, 0x02, 0xde, 0x37, 0xaf,
+ 0x71, 0x56, 0x9d, 0xb8, 0x5e, 0x6c, 0xd2, 0xa4, 0xa6, 0x53,
+ 0x98, 0x6d, 0xf2, 0xac, 0x06, 0x8e, 0x9c, 0x23, 0x0a, 0x1d,
+ 0x8d, 0x98, 0x13, 0xfe, 0xec, 0x85, 0x77, 0x9d, 0xf2, 0x49,
+ 0x3c, 0xc1, 0x48, 0x38, 0x41, 0x49, 0xcf, 0x38, 0xda, 0xa6,
+ 0x1b, 0x92, 0xb6, 0x2f, 0x69, 0xb5, 0xbd, 0x1c, 0xb4, 0x47,
+ 0x41, 0x96, 0x95, 0x4b, 0x9f, 0x49, 0xa4, 0x29, 0x57, 0x24,
+ 0xbd, 0x86, 0x61, 0x4a, 0x51, 0xd8, 0x93, 0x43, 0xa8, 0xd5,
+ 0x26, 0xbc, 0x08, 0x9f, 0xc5, 0x8f, 0xd1, 0xab, 0x7c, 0xc6,
+ 0x3b, 0x6a, 0xcf, 0x19, 0xf1, 0x3a, 0x7c, 0xcf, 0x82, 0xc7,
+ 0x95, 0x72, 0x49, 0x22, 0xb9, 0xcd, 0xdd, 0x8b, 0xf2, 0x1b,
+ 0xf4, 0xfe, 0x5e, 0x7d, 0x28, 0x90, 0xfb, 0x96, 0x17, 0x2f,
+ 0x2d, 0xdd, 0x75, 0x41, 0x9a, 0x15, 0x29, 0x43, 0xcf, 0x95,
+ 0x58, 0x67, 0x51, 0xf0, 0xd5, 0xda, 0xad, 0x6a, 0x8d, 0x1c,
+ 0x49, 0x70, 0x95, 0x58, 0x25, 0x77, 0x91, 0x2e, 0x4b, 0x47,
+ 0x4d, 0xad, 0xe8, 0x44, 0x95, 0x92, 0x87, 0x32, 0x96, 0xe9,
+ 0xda, 0xc0, 0x57, 0x99, 0x9d, 0xa8, 0x4c, 0x97, 0x4b, 0xa4,
+ 0xfb, 0x43, 0x94, 0x12, 0x19, 0xa7, 0x47, 0x57, 0xdf, 0xf4,
+ 0xab, 0x82, 0x56, 0x29, 0x19, 0xb7, 0xa5, 0x08, 0xa8, 0x4f,
+ 0x0d, 0xcd, 0x42, 0xdf, 0xe9, 0x9d, 0x82, 0x88, 0xae, 0xb2,
+ 0xa4, 0x16, 0xe2, 0x2b, 0x57, 0xd6, 0x09, 0x04, 0xc6, 0x13,
+ 0x7b, 0x7c, 0x99, 0x2e, 0xd3, 0x2c, 0xad, 0x53, 0x9f, 0x86,
+ 0x48, 0x59, 0x35, 0x6a, 0xce, 0x5a, 0x34, 0xd6, 0xe4, 0x80,
+ 0x1c, 0x79, 0xf5, 0xef, 0x8a, 0x75, 0xba, 0xa1, 0xfb, 0x8a,
+ 0x2a, 0x6e, 0xf1, 0x85, 0xfb, 0x9e, 0xec, 0xf6, 0x19, 0x1e,
+ 0xf2, 0x4f, 0x9c, 0x25, 0x57, 0x35, 0xab, 0xad, 0x4d, 0x82,
+ 0xca, 0xa1, 0xab, 0xad, 0x63, 0xd4, 0x19, 0xfc, 0x54, 0xa7,
+ 0x22, 0xb1, 0xa4, 0x0c, 0xbb, 0x71, 0x20, 0x24, 0xe7, 0x34,
+ 0x48, 0x03, 0x4f, 0xa9, 0xf7, 0x3f, 0x78, 0x47, 0x0a, 0x52,
+ 0x39, 0x94, 0xc3, 0xb4, 0xd2, 0x69, 0x41, 0xf4, 0xca, 0x30,
+ 0xb2, 0xf4, 0xd5, 0xa1, 0x46, 0x99, 0xbc, 0x7b, 0xe4, 0xce,
+ 0x78, 0xe5, 0x20, 0x01, 0x36, 0x68, 0x5d, 0x2d, 0x72, 0x2f,
+ 0x7c, 0x6b, 0x22, 0xcf, 0x03, 0x9d, 0x11, 0x5c, 0xa2, 0xe5,
+ 0xa3, 0xda, 0xc2, 0x25, 0xf0, 0xcc, 0x2e, 0x38, 0x03, 0x8a,
+ 0x0a, 0x53, 0x90, 0x50, 0x55, 0x87, 0xc1, 0xdf, 0xd2, 0xd2,
+ 0x04, 0xd3, 0x30, 0x86, 0xdd, 0x39, 0x2f, 0x81, 0xdf, 0xa3,
+ 0x84, 0xd5, 0x2f, 0xb0, 0x69, 0xed, 0xf6, 0xd5, 0x6f, 0xf6,
+ 0xe2, 0xed, 0xa5, 0x94, 0x25, 0xad, 0x92, 0x7d, 0xad, 0xc3,
+ 0x2d, 0xcd, 0xc5, 0xbb, 0x4b, 0xe8, 0x0f, 0x71, 0xee, 0xdd,
+ 0x24, 0x2a, 0x4c, 0x2f, 0xdb, 0x14, 0x4a, 0xa5, 0x8e, 0x2a,
+ 0xf9, 0x32, 0x73, 0x4f, 0x08, 0x73, 0x29, 0x78, 0x95, 0x14,
+ 0x63, 0x5f, 0xf1, 0x06, 0xb1, 0x85, 0x41, 0xf3, 0x67, 0xa9,
+ 0x42, 0x62, 0xc6, 0xf8, 0x3c, 0xe1, 0x7a, 0x94, 0x55, 0xd0,
+ 0x10, 0x6d, 0xe1, 0x12, 0x5a, 0x4c, 0xb2, 0x27, 0xd2, 0xad,
+ 0x17, 0x85, 0x54, 0x19, 0x2c, 0x10, 0x48, 0x1d, 0x5e, 0xa2,
+ 0x31, 0x38, 0xbc, 0x77, 0x38, 0x23, 0x0a, 0x77, 0xa1, 0x08,
+ 0x37, 0x74, 0xdc, 0xaa, 0xc6, 0x6b, 0x55, 0x6b, 0x0a, 0xcd,
+ 0xa6, 0x79, 0x81, 0xf7, 0x4b, 0x16, 0xa1, 0x83, 0x1c, 0x29,
+ 0xd2, 0xf5, 0x6a, 0x0d, 0x0c, 0x31, 0xd9, 0x9c, 0x94, 0x18,
+ 0x61, 0x3e, 0x95, 0x34, 0x8c, 0xcf, 0x77, 0x8e, 0xa7, 0xb8,
+ 0xac, 0xd2, 0x5a, 0xb0, 0x4f, 0x90, 0x8f, 0xc1, 0x61, 0x4e,
+ 0xfe, 0x8c, 0xcf, 0x16, 0x55, 0xec, 0x41, 0x60, 0xd7, 0x9b,
+ 0x0c, 0xcc, 0xbc, 0x04, 0xe7, 0x10, 0x07, 0x0a, 0x25, 0x9d,
+ 0x27, 0x16, 0x30, 0x49, 0x9a, 0x27, 0xd9, 0x00, 0x67, 0xa8,
+ 0x48, 0xac, 0x31, 0x50, 0x04, 0x2a, 0xfb, 0x4e, 0x4a, 0x69,
+ 0x59, 0xac, 0x9b, 0x95, 0xb2, 0x21, 0x35, 0x84, 0xd6, 0x85,
+ 0x77, 0x92, 0x00, 0x52, 0x73, 0x46, 0xd3, 0xd3, 0x0a, 0x11,
+ 0x2d, 0xe3, 0xcb, 0xd1, 0x8f, 0x78, 0x60, 0xdf, 0xd4, 0x52,
+ 0x60, 0xd4, 0x5d, 0x6e, 0xf9, 0x75, 0x76, 0x18, 0xc8, 0x21,
+ 0x71, 0x7a, 0x22, 0x4b, 0xf5, 0x16, 0x88, 0x02, 0x95, 0x1b,
+ 0x67, 0xa1, 0xda, 0x53, 0x97, 0x35, 0x4a, 0x88, 0x48, 0xef,
+ 0x6b, 0xe3, 0x9e, 0x5f, 0xd7, 0x2c, 0xb3, 0xf0, 0x3b, 0xe6,
+ 0x56, 0xc9, 0x20, 0xcf, 0x45, 0xba, 0x96, 0xf3, 0xd7, 0xcc,
+ 0x8e, 0xa5, 0x4a, 0x8c, 0xfa, 0x15, 0xdc, 0x81, 0x85, 0x11,
+ 0xc1, 0x99, 0xa8, 0xd2, 0xdb, 0xc2, 0x49, 0x21, 0xd2, 0x7c,
+ 0x9d, 0x3e, 0xa7, 0xeb, 0x86, 0x4c, 0xd9, 0x62, 0x29, 0x89,
+ 0x44, 0x0f, 0x69, 0xe1, 0x0c, 0x22, 0x3e, 0xb7, 0x0e, 0xbe,
+ 0xb9, 0x92, 0x68, 0x93, 0x3a, 0xb4, 0xed, 0xc8, 0xe0, 0x4f,
+ 0x94, 0x21, 0x57, 0x27, 0xe5, 0x61, 0xe8, 0x93, 0x26, 0x7c,
+ 0x82, 0xee, 0x02, 0x33, 0x8b, 0xf3, 0x88, 0xc6, 0x77, 0xc9,
+ 0x9a, 0x58, 0xc6, 0xae, 0x32, 0x97, 0x78, 0x0e, 0xa1, 0x02,
+ 0x2f, 0x90, 0x86, 0xdf, 0xb2, 0x85, 0x50, 0x6b, 0x75, 0x4d,
+ 0xef, 0x5a, 0x3f, 0x7a, 0xb4, 0xc1, 0x2c, 0x8f, 0x8f, 0xa9,
+ 0xf7, 0xf6, 0xb9, 0x44, 0x70, 0xd9, 0x30, 0x40, 0xb0, 0x3d,
+ 0xed, 0xdf, 0x46, 0xae, 0xd4, 0xa7, 0x02, 0x12, 0x6a, 0xd6,
+ 0x24, 0x4d, 0x06, 0x0a, 0x24, 0x18, 0x74, 0xe9, 0xcb, 0xfb,
+ 0xba, 0x51, 0x6f, 0x5b, 0x29, 0x18, 0xd8, 0x14, 0x04, 0x7b,
+ 0x02, 0xf5, 0xfe, 0x02, 0x1a, 0xe3, 0xdb, 0xc5, 0x78, 0xf6,
+ 0x69, 0x6e, 0x47, 0xd3, 0x1b, 0x7b, 0x7d, 0x3f, 0xbd, 0x99,
+ 0x2c, 0x26, 0xf7, 0xd3, 0xb9, 0xbd, 0xbd, 0x9f, 0xe1, 0xc7,
+ 0x87, 0xaf, 0x93, 0xe9, 0x87, 0x81, 0xbd, 0x99, 0xcc, 0x17,
+ 0xb3, 0xc9, 0xd5, 0x23, 0xbf, 0x92, 0x07, 0x3f, 0xdd, 0xdf,
+ 0x4c, 0x6e, 0x27, 0xd7, 0x23, 0x7e, 0x40, 0xde, 0x7f, 0x19,
+ 0x0a, 0x6e, 0x3a, 0x07, 0x94, 0xbc, 0x37, 0x8a, 0xae, 0x21,
+ 0x80, 0xa2, 0x98, 0x97, 0xa2, 0xfc, 0xe6, 0x13, 0x03, 0x71,
+ 0x21, 0xac, 0x56, 0x99, 0x84, 0x9a, 0x61, 0xe9, 0xdd, 0x67,
+ 0x89, 0x77, 0x57, 0xfa, 0x44, 0x97, 0x75, 0xb6, 0x45, 0xc6,
+ 0xda, 0x52, 0x25, 0x07, 0x0f, 0x6c, 0x77, 0xc0, 0x9f, 0x50,
+ 0x7a, 0x97, 0x36, 0xd6, 0xa6, 0x69, 0xcb, 0x8f, 0xaa, 0x30,
+ 0xa0, 0xe4, 0xf3, 0xe8, 0x62, 0xa8, 0x5a, 0x7f, 0xf3, 0xa0,
+ 0xfc, 0xbd, 0x01, 0x76, 0x76, 0xd0, 0xdb, 0xc0, 0x08, 0x64,
+ 0x69, 0xd9, 0x97, 0xaa, 0x10, 0xc9, 0x40, 0xee, 0x25, 0xed,
+ 0xc1, 0x25, 0xdf, 0x88, 0x28, 0xcb, 0x44, 0x83, 0x59, 0x4e,
+ 0x0e, 0xd4, 0xcc, 0xce, 0xa1, 0xcc, 0x59, 0x97, 0x8a, 0xc8,
+ 0xd1, 0x37, 0xa4, 0x41, 0xba, 0x60, 0x35, 0x7d, 0x86, 0xc1,
+ 0xe0, 0x5e, 0x42, 0x45, 0x99, 0xef, 0x04, 0xce, 0x92, 0x97,
+ 0xdf, 0x34, 0xa4, 0x53, 0xe1, 0x05, 0x92, 0xe3, 0x58, 0x7d,
+ 0xd6, 0xab, 0xcd, 0x7b, 0x73, 0x8f, 0xb2, 0xdd, 0x17, 0xa5,
+ 0x78, 0x81, 0x60, 0x89, 0x81, 0xf1, 0x0c, 0xb4, 0x1d, 0x04,
+ 0x25, 0x60, 0x7a, 0x8f, 0x3d, 0xa6, 0x0a, 0x19, 0xb7, 0x2d,
+ 0xcd, 0x6b, 0xa6, 0x0e, 0xca, 0x2f, 0x16, 0x33, 0x19, 0x42,
+ 0xb3, 0x49, 0x9e, 0xa8, 0xb2, 0x8b, 0x8f, 0x48, 0x8c, 0xc8,
+ 0x03, 0x1b, 0xa8, 0x78, 0xd0, 0xbe, 0xc0, 0x03, 0x05, 0xba,
+ 0xaf, 0xb2, 0x86, 0xd0, 0x9d, 0x47, 0x14, 0x0d, 0x5d, 0x1d,
+ 0x80, 0xd6, 0x7f, 0x9d, 0x9b, 0x60, 0x19, 0xfb, 0x26, 0x3e,
+ 0xfd, 0x0d, 0x81, 0xe7, 0x98, 0x99, 0xdc, 0x07, 0x86, 0x64,
+ 0xb8, 0x64, 0xbd, 0x2e, 0x9d, 0x64, 0xc9, 0xa4, 0xb2, 0x6f,
+ 0x50, 0x3a, 0xde, 0xc0, 0xa1, 0x47, 0xc8, 0xee, 0xcf, 0x8a,
+ 0x0f, 0x0a, 0xaf, 0x57, 0xe2, 0xaa, 0xd7, 0xc2, 0xa2, 0x27,
+ 0xa4, 0x60, 0x49, 0xe2, 0xce, 0x0e, 0x1f, 0xab, 0x77, 0x78,
+ 0x77, 0x78, 0xaf, 0x19, 0x56, 0x40, 0x59, 0x53, 0x57, 0xa9,
+ 0x44, 0x3c, 0x0a, 0x28, 0xa8, 0x07, 0x57, 0x49, 0x98, 0x2c,
+ 0x37, 0xa6, 0x6c, 0xf2, 0x13, 0xd5, 0xfb, 0x9c, 0x1c, 0x80,
+ 0x8e, 0x5b, 0x0f, 0x3c, 0x60, 0x13, 0x6a, 0x48, 0xa3, 0xc8,
+ 0x02, 0xc5, 0x2e, 0x7e, 0xc5, 0x44, 0x50, 0xbd, 0xc8, 0x89,
+ 0xb6, 0x37, 0x72, 0x20, 0x6d, 0x2b, 0x25, 0x40, 0xb2, 0x68,
+ 0x5a, 0x4b, 0x41, 0xb4, 0x27, 0x8e, 0x66, 0xc2, 0xc9, 0x17,
+ 0xc8, 0x82, 0x6e, 0x4f, 0xe4, 0x95, 0x4b, 0x4f, 0x82, 0x84,
+ 0x45, 0xe6, 0x96, 0x0e, 0xf0, 0x5c, 0xf2, 0x16, 0xe4, 0x3c,
+ 0xc3, 0xf1, 0xe5, 0xd0, 0x7c, 0x51, 0x7c, 0x63, 0x5b, 0x27,
+ 0x2b, 0x1b, 0xa2, 0x6d, 0xd2, 0xaa, 0x78, 0x4a, 0x28, 0x3b,
+ 0xad, 0x90, 0xeb, 0xc2, 0x69, 0x21, 0x78, 0x3b, 0x54, 0x0c,
+ 0x93, 0x1c, 0xfe, 0x9d, 0x76, 0x35, 0x40, 0x35, 0x4f, 0xe6,
+ 0xc7, 0x2a, 0x86, 0x31, 0x34, 0x6f, 0x8c, 0xad, 0x89, 0x9a,
+ 0xd3, 0x5c, 0x22, 0x64, 0x87, 0x22, 0xd0, 0x00, 0x87, 0x21,
+ 0xf8, 0x90, 0xe5, 0x5d, 0x07, 0x7f, 0x0d, 0x55, 0xb3, 0x4f,
+ 0x57, 0x4d, 0xd1, 0x54, 0x99, 0x9e, 0x8e, 0x9c, 0x23, 0xa9,
+ 0x1c, 0xbe, 0x8b, 0x4f, 0xf6, 0x0c, 0x74, 0xd4, 0x17, 0x08,
+ 0x21, 0x10, 0xc1, 0x33, 0x19, 0x3f, 0x65, 0xba, 0x48, 0xf3,
+ 0x99, 0xc7, 0x0b, 0xb1, 0xca, 0x92, 0x74, 0x07, 0xad, 0x80,
+ 0xe9, 0x50, 0xf8, 0xdf, 0xdb, 0x6f, 0xce, 0xed, 0x19, 0x12,
+ 0xf4, 0x00, 0x0f, 0xee, 0x8c, 0xbe, 0x56, 0x85, 0x82, 0x45,
+ 0xf8, 0xc3, 0xe6, 0xb8, 0x97, 0x09, 0xb5, 0xef, 0xa3, 0xf0,
+ 0xc9, 0xb2, 0x72, 0x39, 0x4e, 0x61, 0x29, 0x83, 0x6c, 0x2d,
+ 0x69, 0xc3, 0x67, 0x04, 0x43, 0x76, 0xdd, 0x61, 0x84, 0x03,
+ 0xfa, 0xaa, 0x83, 0x23, 0x88, 0x28, 0x21, 0xb1, 0xf9, 0x73,
+ 0x4c, 0x92, 0x15, 0xb0, 0xae, 0xc2, 0xb6, 0xee, 0x69, 0x98,
+ 0xaa, 0xb5, 0x92, 0x36, 0x3a, 0x82, 0x5d, 0x3d, 0x8c, 0x41,
+ 0xaa, 0xdd, 0x1e, 0x2a, 0x04, 0x47, 0xe6, 0xfd, 0x5a, 0x83,
+ 0x39, 0x74, 0x6b, 0x7a, 0x92, 0xe2, 0xbb, 0x83, 0xa7, 0x92,
+ 0x78, 0x98, 0x58, 0xec, 0x7d, 0x86, 0xa1, 0xcc, 0x2d, 0x3a,
+ 0x8a, 0xe0, 0x17, 0x6b, 0xee, 0xf7, 0xd0, 0x97, 0x07, 0xcc,
+ 0x2c, 0x9e, 0xf3, 0xae, 0xf3, 0x1c, 0x0f, 0xef, 0x84, 0xa2,
+ 0x4a, 0x55, 0x9e, 0x77, 0x98, 0x90, 0x31, 0x7d, 0x66, 0x33,
+ 0x9a, 0xd9, 0xf0, 0x44, 0x23, 0x65, 0x71, 0xa7, 0xec, 0xbe,
+ 0x9a, 0x8a, 0x07, 0xbe, 0x94, 0xaa, 0x9f, 0xc6, 0x38, 0x53,
+ 0x52, 0x7b, 0x3f, 0x11, 0xfa, 0x04, 0x6f, 0xcf, 0x94, 0x92,
+ 0xb9, 0x17, 0xee, 0xad, 0x49, 0x96, 0x88, 0xdb, 0x33, 0x7e,
+ 0x09, 0xd7, 0x00, 0xde, 0xde, 0x39, 0xa7, 0x4e, 0xa2, 0x52,
+ 0x54, 0x2e, 0x2a, 0xe3, 0xbf, 0x51, 0x07, 0xd6, 0x26, 0x97,
+ 0x5d, 0x0f, 0xb0, 0x4a, 0x9a, 0x4a, 0x1b, 0x88, 0x16, 0x32,
+ 0x6e, 0xd2, 0x4c, 0xcb, 0xe7, 0x0a, 0xba, 0x15, 0xc5, 0x42,
+ 0x46, 0x86, 0xb7, 0x77, 0x39, 0xa1, 0x51, 0x31, 0xaf, 0x4a,
+ 0x4c, 0x87, 0x16, 0x53, 0xf4, 0xad, 0x39, 0x47, 0x29, 0x84,
+ 0x0c, 0xb4, 0x66, 0xb3, 0xe5, 0x1d, 0x4f, 0x9f, 0x1a, 0x2a,
+ 0x1f, 0xcb, 0x13, 0x3e, 0xc4, 0x37, 0xa9, 0x80, 0x96, 0x6c,
+ 0xa4, 0x2f, 0x28, 0xc7, 0x47, 0x96, 0xef, 0x6c, 0x91, 0xd3,
+ 0x49, 0xe6, 0x05, 0xc5, 0x59, 0xbe, 0x15, 0xfc, 0x55, 0xd6,
+ 0x6d, 0x59, 0x97, 0xcf, 0x2a, 0x2d, 0x75, 0x94, 0xeb, 0x28,
+ 0x05, 0x7a, 0xc3, 0x0a, 0x0d, 0x79, 0x4f, 0x50, 0x77, 0xb1,
+ 0x61, 0x0f, 0xd4, 0x03, 0x54, 0xc8, 0x11, 0x89, 0x3f, 0x25,
+ 0xa1, 0x16, 0x82, 0x3f, 0xb3, 0x44, 0x49, 0x34, 0xa6, 0xe5,
+ 0xba, 0xa5, 0x42, 0x07, 0x7a, 0x0d, 0x09, 0x84, 0xd2, 0xaf,
+ 0xe2, 0xaf, 0x2e, 0x03, 0x72, 0x6f, 0x55, 0x1f, 0x0a, 0x7d,
+ 0x0e, 0xbf, 0x12, 0x58, 0x09, 0x50, 0xbb, 0xd6, 0xc9, 0x8c,
+ 0x34, 0x07, 0x1c, 0x4e, 0x95, 0x09, 0xcb, 0x10, 0xf2, 0x8c,
+ 0x17, 0x1e, 0x89, 0x16, 0x09, 0x36, 0x6a, 0x09, 0x55, 0x95,
+ 0xf4, 0x51, 0xf9, 0x12, 0x96, 0x2a, 0x59, 0x52, 0x43, 0x16,
+ 0x66, 0x44, 0xd0, 0xf5, 0xe4, 0xf5, 0x88, 0xa0, 0x60, 0xc4,
+ 0x34, 0xf7, 0x0c, 0x71, 0xc2, 0x54, 0xae, 0x51, 0x69, 0x4b,
+ 0x66, 0x0b, 0xe9, 0x0b, 0xc1, 0x5d, 0xca, 0x24, 0x5f, 0xd2,
+ 0x28, 0x00, 0x4a, 0x74, 0x68, 0xf5, 0xa7, 0x3c, 0x2f, 0x1a,
+ 0x64, 0x17, 0x8e, 0x00, 0x7d, 0x11, 0x96, 0xa0, 0xe8, 0x65,
+ 0x3c, 0x7b, 0x36, 0xe3, 0x25, 0x42, 0xc0, 0x7f, 0xf0, 0x7a,
+ 0xeb, 0x73, 0x41, 0x48, 0x8b, 0xf6, 0x65, 0x10, 0x10, 0x58,
+ 0xeb, 0x1f, 0x3e, 0x0a, 0x94, 0x8f, 0xf6, 0x85, 0xcb, 0x6e,
+ 0x5e, 0x21, 0xb3, 0x35, 0x89, 0xf8, 0x08, 0xd5, 0xab, 0xc7,
+ 0x07, 0x6d, 0x8b, 0xb9, 0x84, 0xc2, 0x71, 0xc0, 0xf8, 0x32,
+ 0xea, 0xb2, 0x2c, 0xd4, 0x2f, 0x92, 0xb3, 0xd2, 0xeb, 0x16,
+ 0xf6, 0x39, 0x75, 0x2f, 0x47, 0x39, 0x51, 0xa8, 0x74, 0x08,
+ 0xef, 0x62, 0xfc, 0x7d, 0xe5, 0x24, 0x5d, 0xfd, 0xc6, 0x02,
+ 0xdb, 0x2b, 0xd9, 0x75, 0xe5, 0xb2, 0x4d, 0x98, 0x38, 0x06,
+ 0x1b, 0x80, 0x37, 0x21, 0xc1, 0x5a, 0x27, 0x25, 0xbd, 0xf5,
+ 0x04, 0x55, 0xbe, 0x0e, 0x09, 0xf2, 0x9e, 0xca, 0x07, 0x9a,
+ 0xc4, 0x7a, 0x19, 0x28, 0x48, 0x73, 0x8a, 0x10, 0xfe, 0xa7,
+ 0x49, 0x4b, 0x9d, 0xc0, 0x28, 0xc5, 0x23, 0x62, 0xc3, 0x4b,
+ 0xd3, 0x4e, 0x4d, 0xe4, 0xd1, 0x9d, 0x8e, 0x14, 0x64, 0x22,
+ 0xe7, 0x8b, 0x49, 0xeb, 0xae, 0x72, 0x64, 0x17, 0x1d, 0xd2,
+ 0x8a, 0x9a, 0x94, 0x50, 0x00, 0xdf, 0x27, 0x68, 0x02, 0x6d,
+ 0xe5, 0xfc, 0xd8, 0x45, 0xf4, 0xc3, 0x66, 0x52, 0x5e, 0x51,
+ 0x2c, 0xf4, 0x6a, 0x64, 0x0e, 0xa4, 0x2c, 0x71, 0xf2, 0xb0,
+ 0x24, 0x1f, 0x49, 0x55, 0xe4, 0xa0, 0x26, 0x73, 0x5c, 0x22,
+ 0xa3, 0x52, 0x00, 0x62, 0x07, 0x3b, 0xf8, 0x70, 0xe5, 0x10,
+ 0x7c, 0x74, 0x33, 0x1e, 0x50, 0x79, 0xb8, 0xb7, 0x83, 0x8a,
+ 0x9f, 0xd9, 0x85, 0xd5, 0x0c, 0x84, 0x38, 0x04, 0xd5, 0xb0,
+ 0x04, 0x3c, 0x12, 0xa1, 0x03, 0x4e, 0xb1, 0x64, 0x50, 0xdd,
+ 0xc9, 0x59, 0xa0, 0xb2, 0xb5, 0xec, 0x4b, 0x24, 0x1d, 0xe5,
+ 0x23, 0x99, 0x76, 0x24, 0xd5, 0xd1, 0xd1, 0x9c, 0x38, 0x37,
+ 0x75, 0xfb, 0x82, 0x39, 0xf2, 0xb9, 0x2a, 0xd9, 0x45, 0x5a,
+ 0xc1, 0xdb, 0x92, 0x79, 0xa4, 0xc3, 0xd4, 0x0c, 0xa3, 0x9d,
+ 0x49, 0x5a, 0xf5, 0x6a, 0x8a, 0x39, 0xae, 0x29, 0x92, 0x57,
+ 0x63, 0xbc, 0xe9, 0x6b, 0x96, 0xd2, 0x08, 0x2d, 0xa1, 0x7f,
+ 0x2b, 0x24, 0x21, 0xd3, 0xd7, 0x80, 0x4e, 0x7f, 0xbb, 0x61,
+ 0x88, 0x76, 0x79, 0x8a, 0x01, 0x02, 0x16, 0x46, 0x0b, 0xf1,
+ 0x9d, 0xf3, 0x70, 0x6f, 0x7a, 0x43, 0xd3, 0x96, 0xfe, 0x98,
+ 0x80, 0x31, 0x1b, 0x29, 0x16, 0x3a, 0x0c, 0xc1, 0x07, 0xd2,
+ 0x7a, 0xaa, 0x58, 0xa5, 0x7b, 0x4a, 0xca, 0x35, 0x6a, 0x81,
+ 0xd8, 0x1f, 0x2f, 0xd9, 0x17, 0x56, 0x69, 0x1d, 0x8d, 0x2d,
+ 0xf0, 0xe2, 0x20, 0xba, 0x23, 0x20, 0xa7, 0x32, 0x7c, 0xaf,
+ 0xdb, 0x7c, 0xe9, 0xf5, 0x24, 0xb5, 0x88, 0xb8, 0x28, 0x9a,
+ 0xfe, 0x09, 0x4e, 0xad, 0x6a, 0x13, 0x0f, 0x8e, 0xf0, 0x98,
+ 0x36, 0x77, 0x25, 0xaf, 0x33, 0x00, 0x02, 0x84, 0x59, 0x1d,
+ 0x03, 0xe0, 0xb9, 0xf7, 0x16, 0x56, 0xda, 0x4a, 0xdf, 0xd0,
+ 0x1d, 0x25, 0xdd, 0x8d, 0x71, 0xdf, 0x5d, 0xa9, 0xcd, 0x6f,
+ 0x18, 0x9b, 0xe9, 0x64, 0x88, 0x03, 0x8c, 0xec, 0xac, 0xb2,
+ 0xa3, 0xfe, 0xa9, 0x28, 0x81, 0xe6, 0x32, 0xce, 0x32, 0x42,
+ 0x37, 0x55, 0x9d, 0x45, 0x02, 0x90, 0x79, 0x92, 0xb3, 0xb3,
+ 0x48, 0xf5, 0x1a, 0x67, 0xc7, 0x44, 0x97, 0x3c, 0x3d, 0x51,
+ 0x4b, 0x81, 0xac, 0x6f, 0x79, 0x54, 0x0e, 0x6a, 0xe5, 0x1c,
+ 0x21, 0x73, 0x0c, 0xb5, 0x24, 0x3f, 0xca, 0x87, 0x7f, 0x02,
+ 0x44, 0x2e, 0xf9, 0x73, 0x62, 0x9f, 0x8b, 0xac, 0xe1, 0x44,
+ 0x7f, 0x83, 0xa6, 0xb7, 0xaa, 0x8b, 0x12, 0x7d, 0x95, 0x4f,
+ 0xe9, 0x9d, 0x7c, 0x0a, 0x7d, 0xbb, 0x24, 0xb4, 0x2c, 0x43,
+ 0xfa, 0x8b, 0xb8, 0xd3, 0xac, 0x29, 0x3e, 0xcd, 0x26, 0xe5,
+ 0x6c, 0x91, 0xfb, 0xdb, 0x9f, 0x23, 0xf5, 0x63, 0x11, 0x8e,
+ 0xb9, 0x67, 0x07, 0xa9, 0xb5, 0x34, 0xa0, 0x9f, 0x77, 0x97,
+ 0x2c, 0x51, 0xc5, 0xf2, 0x5f, 0x9c, 0xa8, 0x84, 0x09, 0x38,
+ 0xac, 0xb7, 0x6a, 0x6a, 0xc9, 0x37, 0x04, 0x64, 0x67, 0xca,
+ 0xaf, 0x99, 0x87, 0x88, 0x7b, 0x2b, 0x3c, 0xbc, 0xb3, 0x02,
+ 0xa2, 0x5e, 0xc3, 0x50, 0x48, 0x06, 0x1c, 0x98, 0xf9, 0x98,
+ 0xd2, 0x81, 0x06, 0x34, 0xd0, 0xc1, 0xa7, 0xd1, 0x0a, 0x25,
+ 0x79, 0x4f, 0xb4, 0x02, 0xff, 0x6d, 0xad, 0xc1, 0xcf, 0x32,
+ 0x27, 0xa5, 0xae, 0xd4, 0x89, 0xb2, 0xd4, 0xc1, 0x1d, 0x22,
+ 0x03, 0x00, 0xea, 0x27, 0xd6, 0x72, 0x32, 0xa9, 0xf8, 0xa9,
+ 0xeb, 0x41, 0x06, 0x3e, 0xe6, 0x43, 0xd4, 0x46, 0x33, 0x85,
+ 0x3f, 0x01, 0x82, 0x5a, 0x6a, 0xfa, 0xe2, 0x88, 0x81, 0xbd,
+ 0xf1, 0x56, 0xa0, 0x56, 0xec, 0x92, 0x32, 0x85, 0xff, 0x37,
+ 0x61, 0x2c, 0xd4, 0x8d, 0x08, 0x59, 0x73, 0x14, 0x8c, 0xbd,
+ 0x87, 0x0a, 0x07, 0x2d, 0x20, 0x3b, 0x95, 0x2c, 0x69, 0xe3,
+ 0x49, 0x10, 0xf7, 0xc0, 0x3e, 0x27, 0x59, 0xaa, 0xe4, 0xa0,
+ 0xb3, 0x0c, 0xd9, 0xb9, 0x96, 0xe9, 0x9b, 0xca, 0x75, 0x70,
+ 0x49, 0x29, 0xd7, 0x34, 0x5d, 0x57, 0x21, 0xf8, 0x48, 0x12,
+ 0xc2, 0x61, 0xe0, 0xf1, 0xb8, 0x07, 0x50, 0x39, 0xef, 0xb2,
+ 0x74, 0xfc, 0x9c, 0xeb, 0x6d, 0x9e, 0xe0, 0x22, 0x7f, 0xbd,
+ 0x15, 0x1a, 0x04, 0x16, 0x3f, 0x57, 0x06, 0xa8, 0xed, 0x15,
+ 0x17, 0xfb, 0xeb, 0x40, 0x8a, 0xb0, 0xea, 0x5e, 0x28, 0x1c,
+ 0x6b, 0x3c, 0x2a, 0xd1, 0xc7, 0xc6, 0xe9, 0xd9, 0x41, 0x70,
+ 0x9f, 0xd6, 0xdf, 0x7f, 0xcf, 0x06, 0xaf, 0xeb, 0x5f, 0x25,
+ 0xf9, 0x7f, 0xd8, 0x60, 0xf5, 0x9a, 0x77, 0xa5, 0x39, 0x55,
+ 0xa0, 0x99, 0x22, 0x6a, 0x59, 0x05, 0x9e, 0xfa, 0xc2, 0x2c,
+ 0x06, 0xd2, 0xd2, 0x7f, 0x74, 0x0b, 0xf5, 0x8a, 0xc8, 0x84,
+ 0x28, 0x32, 0x3c, 0x4b, 0x32, 0xf0, 0x92, 0x6b, 0x3e, 0xf3,
+ 0x28, 0xc6, 0xdf, 0xd9, 0xea, 0x74, 0x60, 0x23, 0xc3, 0xc3,
+ 0x9c, 0x40, 0x94, 0x99, 0x12, 0x5d, 0xdb, 0xc9, 0xb4, 0x23,
+ 0x4c, 0x11, 0x58, 0xf4, 0xf8, 0x7e, 0xcb, 0x5f, 0x0c, 0xb5,
+ 0xfe, 0x3a, 0x78, 0x45, 0xde, 0x16, 0x9f, 0x26, 0xad, 0xd7,
+ 0xb1, 0x2b, 0x87, 0x5e, 0x4a, 0x9d, 0xee, 0xd8, 0x79, 0xb3,
+ 0x0c, 0xd5, 0x61, 0xa9, 0xda, 0xf7, 0xc8, 0xa5, 0x77, 0x3d,
+ 0xb6, 0xe9, 0x92, 0x8a, 0x0e, 0xc4, 0x94, 0x17, 0xb9, 0x14,
+ 0x54, 0x73, 0xec, 0xda, 0xca, 0xc9, 0x87, 0x78, 0x15, 0xe7,
+ 0xe7, 0xb4, 0xfd, 0xc6, 0x0c, 0xfa, 0x94, 0xeb, 0xd0, 0x5b,
+ 0xe9, 0x19, 0x62, 0xa6, 0x75, 0x20, 0xd7, 0x86, 0xbe, 0x9e,
+ 0x6e, 0xe4, 0x74, 0x3d, 0x32, 0xdc, 0xc6, 0x9c, 0xf0, 0x85,
+ 0xcf, 0x71, 0x48, 0xc3, 0x56, 0x29, 0xed, 0x9a, 0x16, 0x34,
+ 0x76, 0x59, 0x53, 0x49, 0x63, 0x92, 0x54, 0x55, 0xb1, 0x4a,
+ 0xc3, 0x3c, 0x0c, 0x21, 0x90, 0xd0, 0xf1, 0xdd, 0x26, 0xcd,
+ 0x53, 0x9d, 0xb4, 0xb2, 0xcd, 0xf2, 0xcf, 0x6b, 0x1e, 0x2e,
+ 0xd3, 0xbd, 0x5e, 0x27, 0xb3, 0x60, 0x9b, 0x50, 0xbf, 0xc8,
+ 0x5c, 0xea, 0xc7, 0x64, 0x02, 0x7b, 0x38, 0x1f, 0xcf, 0xb2,
+ 0x24, 0x06, 0x0e, 0x9d, 0x44, 0x90, 0xf2, 0x23, 0x0c, 0xff,
+ 0x4c, 0xa5, 0x13, 0xdb, 0x99, 0x6a, 0xef, 0xc4, 0xe2, 0x2e,
+ 0x60, 0xd9, 0xc1, 0x89, 0x3c, 0x71, 0xb8, 0xc8, 0x05, 0x1f,
+ 0xab, 0x86, 0x1f, 0xc7, 0xf1, 0x2e, 0x4f, 0xae, 0x06, 0xdb,
+ 0x49, 0x4f, 0x8b, 0x69, 0xe3, 0xd7, 0x2e, 0xd8, 0xb5, 0xeb,
+ 0xb4, 0xd0, 0x53, 0x86, 0x8e, 0x96, 0xd2, 0x80, 0x18, 0xda,
+ 0xe9, 0xb2, 0x8b, 0x84, 0x5d, 0xf2, 0x2f, 0x41, 0x00, 0x3b,
+ 0x78, 0xb4, 0xa0, 0xd3, 0x0b, 0x95, 0x90, 0x1c, 0x7f, 0x83,
+ 0x1b, 0xbb, 0x4c, 0xa1, 0x49, 0xc5, 0x34, 0x7e, 0xe9, 0x25,
+ 0x34, 0xa8, 0x51, 0xa5, 0xf6, 0xac, 0xd5, 0xa1, 0xaa, 0x01,
+ 0xdd, 0x64, 0xc6, 0xc4, 0xc4, 0xdb, 0x97, 0x9f, 0x8d, 0x12,
+ 0xb4, 0xda, 0xe4, 0x82, 0x5b, 0x84, 0xe7, 0xf6, 0x28, 0xe3,
+ 0x51, 0x7b, 0xe2, 0x23, 0x54, 0xe6, 0xcc, 0x7d, 0xed, 0xa1,
+ 0xc8, 0x6f, 0x4e, 0xd0, 0x42, 0x44, 0x9d, 0x10, 0x2b, 0x8a,
+ 0x00, 0xde, 0xd5, 0xf8, 0x31, 0x99, 0x38, 0x3a, 0xf8, 0x33,
+ 0xa0, 0x2e, 0x47, 0xfb, 0x6d, 0x0c, 0x41, 0xc7, 0x89, 0xbf,
+ 0x88, 0x16, 0x6f, 0x90, 0x29, 0xb5, 0x47, 0xb5, 0xe1, 0x2d,
+ 0x4b, 0xb8, 0x8e, 0xd4, 0x4c, 0x2e, 0x8f, 0x08, 0x9c, 0x78,
+ 0x5f, 0x80, 0xdb, 0x02, 0x46, 0x85, 0x18, 0xbe, 0x68, 0x04,
+ 0xe7, 0x57, 0xe6, 0x1c, 0xac, 0xec, 0x65, 0x49, 0x5e, 0x51,
+ 0x10, 0x1f, 0x37, 0x4f, 0xdb, 0x28, 0xb7, 0xa7, 0xfe, 0xbe,
+ 0x5c, 0x67, 0x9c, 0xbb, 0x3d, 0x7a, 0xa6, 0x68, 0xa3, 0x24,
+ 0x22, 0x72, 0x34, 0x2d, 0x8a, 0x94, 0x21, 0x90, 0xe1, 0x3f,
+ 0x3a, 0xc8, 0x40, 0x27, 0xd2, 0x31, 0x90, 0x0e, 0x6b, 0xd0,
+ 0xfd, 0xc9, 0x08, 0x5d, 0xe1, 0x6b, 0x0c, 0x5a, 0x7a, 0x50,
+ 0xc2, 0xa8, 0xa3, 0xd2, 0x79, 0xdd, 0xf7, 0x3d, 0xc7, 0xb8,
+ 0xd2, 0x3e, 0xf9, 0x4a, 0x1f, 0xb2, 0x79, 0x84, 0x54, 0x78,
+ 0x95, 0xc9, 0xf1, 0x12, 0x9c, 0x62, 0x5f, 0x1b, 0x81, 0x38,
+ 0x2f, 0x02, 0x06, 0x8b, 0x57, 0x8f, 0x7f, 0xfd, 0x74, 0xa6,
+ 0x4f, 0x5e, 0x2a, 0xa9, 0x0b, 0xca, 0x45, 0x51, 0xd2, 0xb0,
+ 0x0a, 0xd4, 0xbe, 0x96, 0xb1, 0x88, 0xa4, 0xb4, 0x63, 0xef,
+ 0xd2, 0xf3, 0x0c, 0x5b, 0xa6, 0x0d, 0xc3, 0xa0, 0x5f, 0x22,
+ 0x68, 0xb9, 0x11, 0x6a, 0x73, 0xab, 0x4e, 0xac, 0x44, 0x19,
+ 0xe1, 0x8e, 0x5d, 0xac, 0xcb, 0x02, 0x11, 0x00, 0x5a, 0x34,
+ 0x11, 0x6c, 0x2f, 0xdf, 0xc2, 0xda, 0x42, 0x5a, 0x76, 0xab,
+ 0x37, 0x2d, 0x63, 0x12, 0x39, 0x62, 0x25, 0x76, 0x37, 0x4c,
+ 0xc5, 0x81, 0x01, 0xb4, 0x83, 0xbc, 0xe5, 0xc2, 0xbf, 0x9b,
+ 0x26, 0xd3, 0xc4, 0x92, 0xa5, 0x09, 0x5a, 0x47, 0x31, 0xdd,
+ 0xdf, 0xd5, 0x74, 0xa1, 0xbb, 0x8b, 0x7b, 0x4d, 0x7a, 0xe4,
+ 0xbe, 0x3e, 0x6a, 0xc1, 0xaa, 0x94, 0x23, 0xc9, 0x70, 0x33,
+ 0x2d, 0x9e, 0xe3, 0x77, 0x2d, 0x24, 0xd7, 0xb6, 0xe2, 0x13,
+ 0x13, 0x8b, 0x87, 0xf3, 0x02, 0xf3, 0x89, 0x0d, 0xbe, 0x0e,
+ 0x6d, 0xfb, 0xf7, 0xb8, 0x7e, 0xa0, 0x87, 0x0c, 0xfe, 0x8a,
+ 0x61, 0x38, 0x0d, 0xaa, 0xab, 0xe3, 0x9b, 0x0f, 0xdd, 0xbb,
+ 0x61, 0xc3, 0x9b, 0x84, 0xa6, 0xac, 0x94, 0x1b, 0xba, 0x6d,
+ 0xba, 0x4c, 0x6b, 0x1d, 0xd4, 0x67, 0xc9, 0x4b, 0x7b, 0x75,
+ 0xef, 0xfb, 0xc4, 0x53, 0x79, 0x94, 0x0e, 0x6a, 0x4b, 0xc1,
+ 0x8b, 0xe9, 0xe5, 0x41, 0x6f, 0xc5, 0x64, 0x5a, 0xd1, 0xc3,
+ 0xd7, 0x47, 0xa3, 0xfb, 0x0b, 0x3f, 0x5e, 0x7c, 0x75, 0xc4,
+ 0x7e, 0xa9, 0xa3, 0x1d, 0xde, 0x36, 0xae, 0x5a, 0xaf, 0xd1,
+ 0xf3, 0x13, 0x3f, 0xd2, 0xed, 0xd9, 0xb8, 0x16, 0xfc, 0xca,
+ 0x3b, 0x6a, 0xce, 0x1b, 0xc3, 0x8a, 0xd1, 0xff, 0xe5, 0x56,
+ 0x4f, 0x39, 0x6e, 0xd9, 0x37, 0x47, 0x4a, 0x3c, 0xea, 0x70,
+ 0xfc, 0x9e, 0xc3, 0x7f, 0x0e, 0xf5, 0x16, 0xa5, 0x4e, 0x77,
+ 0xce, 0xe3, 0x93, 0x3f, 0x43, 0xfa, 0x7f, 0x21, 0x71, 0x1d,
+ 0x6f, 0x34, 0x1c, 0x05, 0x90, 0x77, 0x7e, 0x76, 0xc8, 0x21,
+ 0x1a, 0x43, 0x46, 0x33, 0xe1, 0x16, 0xd9, 0x7f, 0xa3, 0x6b,
+ 0x22, 0x1a, 0xc4, 0xfd, 0x49, 0x62, 0x74, 0xbb, 0x1f, 0xf8,
+ 0x42, 0x74, 0x4b, 0x2a, 0xaa, 0x79, 0x97, 0xed, 0x5e, 0xb9,
+ 0x09, 0x0d, 0xfb, 0x13, 0x3e, 0x3d, 0xa5, 0x28, 0x0c, 0x7e,
+ 0x6e, 0xb9, 0x69, 0x4a, 0xb9, 0xad, 0xea, 0x6d, 0x9b, 0xf8,
+ 0x16, 0xac, 0x1b, 0xa9, 0xff, 0x68, 0xdb, 0x5e, 0xd3, 0xe7,
+ 0x56, 0x9f, 0x00, 0xc4, 0xaf, 0xa1, 0x8a, 0xad, 0x5c, 0x70,
+ 0x0d, 0x4d, 0x3f, 0x92, 0xfc, 0x7a, 0x8a, 0x82, 0x24, 0x34,
+ 0xb6, 0xf8, 0xff, 0x8a, 0x76, 0xea, 0x22, 0xd0, 0x5f, 0x28,
+ 0x45, 0xd9, 0x58, 0xe4, 0x38, 0x6a, 0xc8, 0xfe, 0x6b, 0x68,
+ 0x27, 0x1b, 0xad, 0xeb, 0x32, 0x4d, 0x41, 0x88, 0xb6, 0xf7,
+ 0x02, 0xac, 0x01, 0x68, 0xda, 0xff, 0xd5, 0xac, 0x9f, 0x64,
+ 0x92, 0xa7, 0x18, 0x25, 0x6a, 0x4e, 0xf5, 0xc2, 0xd9, 0x00,
+ 0x88, 0xb2, 0xe0, 0xb8, 0xf0, 0xd0, 0xc6, 0xdb, 0x33, 0xdc,
+ 0x1e, 0x70, 0x5c, 0x63, 0x2f, 0xf4, 0xaa, 0x79, 0x97, 0xfa,
+ 0xbd, 0x42, 0x7f, 0x59, 0x8d, 0x70, 0x6d, 0x5c, 0x75, 0x39,
+ 0x30, 0x91, 0x17, 0x0a, 0x16, 0x16, 0x3d, 0x8a, 0x23, 0xd0,
+ 0x77, 0x2e, 0xfc, 0xf2, 0x0b, 0x85, 0x52, 0xae, 0x00, 0xfc,
+ 0x04, 0x90, 0xa0, 0x5b, 0x0e, 0x07, 0x77, 0x99, 0xfa, 0x32,
+ 0x94, 0x69, 0xae, 0xf9, 0x21, 0x4c, 0x6a, 0x0f, 0xf4, 0xdb,
+ 0x23, 0x8e, 0x62, 0x64, 0xa0, 0x97, 0x6d, 0x1a, 0xcb, 0x2c,
+ 0x17, 0x1c, 0x7d, 0xf2, 0xdc, 0xb6, 0x32, 0xbe, 0xfe, 0xae,
+ 0xee, 0x5b, 0xf8, 0xe5, 0x27, 0xbe, 0x1e, 0x4f, 0xf4, 0x0b,
+ 0x0f, 0xc6, 0x2b, 0xae, 0xec, 0xc0, 0xbd, 0xaa, 0x74, 0xd7,
+ 0x64, 0x08, 0x53, 0xa7, 0x57, 0x45, 0x7a, 0x7d, 0x81, 0x1a,
+ 0xf2, 0xe4, 0x61, 0x65, 0x97, 0xf5, 0x4d, 0x7c, 0x69, 0x13,
+ 0x6d, 0xea, 0x39, 0xd8, 0x52, 0x86, 0xef, 0xd1, 0x6b, 0xbe,
+ 0xf2, 0x9f, 0x18, 0x91, 0xc8, 0x3b, 0x38, 0xe6, 0x2b, 0xb1,
+ 0xe7, 0xef, 0xfc, 0x4f, 0xd7, 0x92, 0x92, 0x60, 0xdd, 0x76,
+ 0x75, 0xa6, 0x68, 0x32, 0xc5, 0x71, 0xba, 0x1f, 0x6a, 0xcb,
+ 0xe2, 0x80, 0x2e, 0xe1, 0xf0, 0x93, 0xec, 0x13, 0x44, 0xc1,
+ 0x1d, 0xc1, 0x84, 0x70, 0x0a, 0x92, 0x9f, 0xa2, 0xde, 0x42,
+ 0x76, 0x70, 0x8a, 0xf6, 0x7a, 0xcd, 0x5f, 0xb0, 0xac, 0x51,
+ 0x16, 0x56, 0xdc, 0xcf, 0x90, 0xa1, 0x7d, 0xfb, 0x13, 0xba,
+ 0x48, 0x01, 0x15, 0x90, 0x43, 0x45, 0x94, 0xcc, 0x23, 0x7d,
+ 0x85, 0x5f, 0xf7, 0xa4, 0x33, 0x80, 0xab, 0xa0, 0xde, 0x25,
+ 0x94, 0x44, 0xec, 0xac, 0x73, 0xa8, 0xb8, 0xce, 0xc9, 0x63,
+ 0x4b, 0x26, 0x43, 0xde, 0xa7, 0x97, 0x2c, 0x5a, 0xed, 0x34,
+ 0x48, 0x8c, 0xfc, 0x27, 0xec, 0x2b, 0x84, 0x8b, 0xae, 0x7c,
+ 0x4e, 0xe6, 0x51, 0xf8, 0xeb, 0xd6, 0x65, 0x04, 0xd2, 0xda,
+ 0x0b, 0x73, 0x8d, 0x2e, 0xd7, 0xa0, 0x74, 0x02, 0xf2, 0xb4,
+ 0xf4, 0x0a, 0x09, 0x06, 0xe3, 0xaa, 0xc9, 0x12, 0x64, 0xda,
+ 0xb4, 0x5c, 0x35, 0xbb, 0x4a, 0xb2, 0xb6, 0x66, 0xb8, 0x65,
+ 0x92, 0x75, 0x29, 0xdc, 0xc5, 0xe4, 0xa3, 0x2d, 0x54, 0xa3,
+ 0x33, 0xc9, 0x70, 0x9b, 0x12, 0x1e, 0x8a, 0x2e, 0x25, 0x8e,
+ 0xb6, 0x56, 0xfd, 0xf6, 0x64, 0xae, 0x2e, 0x64, 0xe2, 0x63,
+ 0x79, 0x7f, 0x3a, 0xe9, 0x4d, 0xdc, 0xf6, 0x4d, 0x29, 0x19,
+ 0xec, 0xcc, 0xc8, 0x0d, 0x96, 0x69, 0x7c, 0x7d, 0x96, 0x9f,
+ 0x34, 0xea, 0xa3, 0xd5, 0x93, 0xaa, 0x5b, 0xaa, 0xe0, 0x98,
+ 0x1f, 0xae, 0x7a, 0xf0, 0xc3, 0x33, 0x99, 0xd6, 0x85, 0x2d,
+ 0x3d, 0x3f, 0xaa, 0xd3, 0xb9, 0x41, 0x5a, 0x1f, 0xfc, 0x5d,
+ 0x90, 0x91, 0x59, 0xb6, 0x3e, 0xf9, 0xbe, 0x7f, 0xf8, 0x36,
+ 0xf1, 0x0d, 0x0d, 0xa5, 0x8b, 0x38, 0x0c, 0x77, 0x7c, 0x7e,
+ 0x8d, 0x86, 0x42, 0x3f, 0x95, 0x9e, 0x62, 0xed, 0x77, 0x30,
+ 0xbb, 0xfe, 0xba, 0x67, 0x62, 0xc5, 0xfc, 0x83, 0x76, 0xbc,
+ 0x6a, 0x52, 0xba, 0x3e, 0x33, 0x89, 0x96, 0xf8, 0xbd, 0x2e,
+ 0x67, 0x04, 0xef, 0xdf, 0xcb, 0x40, 0x9e, 0x0a, 0xb3, 0xf6,
+ 0x93, 0xd8, 0xd1, 0x15, 0x78, 0xbe, 0xdb, 0xc7, 0x31, 0x4f,
+ 0xdc, 0xea, 0x40, 0x58, 0x6b, 0xd6, 0xf1, 0xc7, 0xb4, 0x9d,
+ 0xf8, 0x0b, 0x2f, 0xf0, 0x4b, 0xb9, 0x81, 0xe4, 0x6a, 0xdf,
+ 0x09, 0x4b, 0x6e, 0x6d, 0x82, 0xb7, 0x4b, 0xea, 0xf2, 0x2d,
+ 0x89, 0xac, 0x22, 0xfa, 0x7c, 0x5e, 0xe4, 0x3a, 0xef, 0xae,
+ 0x24, 0x71, 0xca, 0x56, 0xcb, 0x2a, 0x6a, 0xd9, 0x12, 0x80,
+ 0x25, 0x79, 0xe9, 0xbd, 0x9f, 0xa1, 0x36, 0xfb, 0xf6, 0xb2,
+ 0x57, 0x36, 0xa8, 0x7e, 0x5e, 0x17, 0xb9, 0x1a, 0x60, 0x8d,
+ 0xea, 0xb3, 0x96, 0xb5, 0x52, 0xd9, 0xb3, 0xb2, 0xd5, 0x56,
+ 0x7c, 0x86, 0x60, 0x50, 0xca, 0x7b, 0x6f, 0x56, 0xd0, 0xf2,
+ 0x1a, 0xf8, 0xeb, 0x92, 0x91, 0x67, 0x52, 0x97, 0x4f, 0xda,
+ 0x6d, 0x09, 0x9f, 0x06, 0x7d, 0x25, 0xd4, 0x44, 0xbc, 0x2d,
+ 0x52, 0xc1, 0x84, 0x8b, 0xa3, 0xa8, 0x89, 0xdd, 0x54, 0xf6,
+ 0xe1, 0xc8, 0x28, 0x4f, 0xe1, 0x70, 0x5f, 0xb6, 0x9b, 0x5e,
+ 0x7c, 0x8f, 0xb8, 0x84, 0x1a, 0xdc, 0xb3, 0x06, 0xc0, 0xd2,
+ 0x9d, 0x56, 0x2b, 0xad, 0xaa, 0x55, 0x7d, 0x92, 0x9e, 0x59,
+ 0xe5, 0xfe, 0x31, 0x0c, 0x37, 0x6b, 0xc7, 0x53, 0x8a, 0x9f,
+ 0xfd, 0xc6, 0xeb, 0x51, 0xc2, 0x4a, 0xab, 0x68, 0x77, 0x82,
+ 0x97, 0x07, 0x61, 0x31, 0x54, 0xda, 0xa2, 0x92, 0x39, 0xcb,
+ 0xf7, 0xa6, 0x74, 0x95, 0xce, 0xf9, 0x97, 0x87, 0xee, 0x5a,
+ 0x2b, 0xee, 0xd2, 0x35, 0x45, 0x77, 0x68, 0xe4, 0x64, 0x91,
+ 0x88, 0x49, 0x51, 0x1a, 0xaf, 0xaa, 0xc7, 0xc7, 0x69, 0x17,
+ 0x20, 0x09, 0x3d, 0x59, 0xaf, 0x75, 0xea, 0x40, 0x1f, 0x80,
+ 0xb5, 0x9f, 0x1c, 0x1f, 0xdf, 0x6f, 0xe5, 0xfa, 0xbc, 0x27,
+ 0x62, 0xb4, 0xf1, 0x82, 0xb2, 0xa6, 0x17, 0x71, 0x46, 0xf3,
+ 0x70, 0x2b, 0xca, 0x40, 0xd7, 0x32, 0x93, 0xba, 0xff, 0x6a,
+ 0xef, 0x37, 0x01, 0x74, 0x98, 0x93, 0x0b, 0x06, 0xd8, 0xa1,
+ 0x13, 0x30, 0x9d, 0x22, 0x34, 0x73, 0x34, 0x95, 0x3f, 0xc0,
+ 0xad, 0x59, 0x11, 0x73, 0xbd, 0x99, 0x5a, 0x25, 0x5a, 0x5c,
+ 0xa3, 0x54, 0x0c, 0x8c, 0x5f, 0x20, 0x80, 0x79, 0x41, 0x52,
+ 0x49, 0x3e, 0x8f, 0x58, 0x44, 0x98, 0xc3, 0x29, 0xc3, 0x78,
+ 0xd1, 0xdf, 0x3d, 0x2e, 0x8b, 0xf5, 0xc9, 0x8a, 0x81, 0x58,
+ 0xf5, 0xd7, 0xa1, 0xac, 0xc1, 0xbc, 0xba, 0x85, 0x4e, 0x4d,
+ 0x85, 0xd5, 0x8b, 0xd2, 0x3d, 0xa7, 0x72, 0x75, 0xab, 0x26,
+ 0xe7, 0x42, 0xf3, 0xb3, 0xfe, 0xfe, 0x45, 0x65, 0xbc, 0xed,
+ 0x5f, 0x59, 0x47, 0x57, 0x08, 0x40, 0x10, 0xcb, 0x68, 0xc2,
+ 0x9f, 0x10, 0x6f, 0x4e, 0xd9, 0x62, 0x1a, 0x12, 0x3b, 0xf4,
+ 0x4b, 0x14, 0xf8, 0x94, 0xb9, 0x1d, 0xbc, 0x57, 0xfb, 0xb4,
+ 0x94, 0x95, 0xf5, 0x30, 0x64, 0xaa, 0x18, 0xb7, 0xfe, 0x0d,
+ 0xfd, 0xcd, 0x08, 0x72, 0x08, 0xd8, 0xc9, 0xbd, 0x05, 0xbc,
+ 0xb0, 0x76, 0x70, 0xb1, 0x4c, 0x32, 0xbc, 0x6e, 0x1b, 0xc9,
+ 0x11, 0xed, 0xf6, 0xa4, 0x5e, 0x72, 0xc0, 0x11, 0x65, 0xfd,
+ 0x51, 0xb0, 0xb5, 0x27, 0x46, 0x53, 0x71, 0xba, 0xca, 0x69,
+ 0x23, 0x4d, 0x08, 0x1b, 0x37, 0x10, 0x9a, 0x69, 0x31, 0x3c,
+ 0x91, 0x37, 0xbb, 0xa5, 0x2b, 0xbb, 0xdd, 0xd0, 0xd0, 0x1a,
+ 0xcb, 0x2c, 0x67, 0x23, 0xbd, 0xfa, 0xd1, 0xb3, 0x27, 0x7d,
+ 0x84, 0x66, 0xca, 0x68, 0x9b, 0xce, 0x17, 0xda, 0x37, 0xcc,
+ 0xdd, 0xdc, 0xd2, 0x2a, 0x03, 0x85, 0x37, 0x83, 0xae, 0x89,
+ 0x93, 0x8a, 0x1d, 0x16, 0x34, 0xba, 0xd1, 0x79, 0x34, 0x3e,
+ 0xed, 0xe3, 0xe9, 0xb0, 0x21, 0x16, 0xee, 0x07, 0x03, 0x53,
+ 0x45, 0x19, 0x56, 0x06, 0x7a, 0x47, 0x05, 0x03, 0x77, 0x3b,
+ 0x7a, 0x74, 0x07, 0x73, 0xc6, 0x1d, 0x4e, 0x64, 0xef, 0xae,
+ 0x33, 0x54, 0x09, 0x87, 0x73, 0x2a, 0x38, 0xba, 0x22, 0x3b,
+ 0xb4, 0x0b, 0x2c, 0x45, 0x80, 0xf9, 0xe1, 0x15, 0xb6, 0xa6,
+ 0xe7, 0xb9, 0x39, 0xf7, 0xeb, 0x18, 0xba, 0xb7, 0xf4, 0xcb,
+ 0x30, 0x60, 0xc7, 0xb0, 0x7f, 0x1a, 0x45, 0x87, 0x40, 0x85,
+ 0x93, 0xe5, 0x13, 0x59, 0x84, 0xd3, 0xf4, 0x1b, 0x6f, 0xa0,
+ 0x56, 0xfe, 0xf6, 0xae, 0x17, 0xc1, 0x47, 0x98, 0x5a, 0x3d,
+ 0x4d, 0x2e, 0x88, 0x19, 0x62, 0xae, 0x5f, 0x1e, 0x8c, 0xdf,
+ 0x9f, 0x27, 0x7a, 0xef, 0x1a, 0x69, 0x8f, 0x0c, 0xdb, 0x22,
+ 0xd0, 0xde, 0x46, 0xc6, 0x69, 0xee, 0x2f, 0x34, 0x7f, 0x74,
+ 0xdc, 0x6b, 0xf1, 0xfa, 0x5e, 0x7e, 0x7d, 0xa3, 0xd8, 0x39,
+ 0x06, 0x59, 0x65, 0xa4, 0x1c, 0xb4, 0x23, 0xc6, 0xaa, 0xdd,
+ 0x76, 0xf6, 0xbf, 0xa2, 0xc1, 0x1a, 0x26, 0x7a, 0x97, 0x11,
+ 0x06, 0x22, 0x0f, 0x2e, 0xbf, 0xee, 0x78, 0xe1, 0xba, 0xf8,
+ 0x53, 0x91, 0x64, 0x12, 0xdd, 0x12, 0x7b, 0xe5, 0x73, 0x70,
+ 0x3b, 0x45, 0x05, 0x48, 0x39, 0x8d, 0xae, 0xf2, 0xe2, 0xfd,
+ 0x6e, 0x06, 0x20, 0x1f, 0x85, 0x5f, 0xee, 0xe9, 0xfd, 0xca,
+ 0x8c, 0x52, 0x2a, 0x76, 0x45, 0xdb, 0xb2, 0xf3, 0x97, 0x7e,
+ 0x74, 0xb1, 0x61, 0x8d, 0x04, 0xe3, 0xcb, 0x48, 0xfb, 0xca,
+ 0x93, 0xe6, 0x93, 0xec, 0xd0, 0xfd, 0x96, 0xd3, 0xf4, 0xde,
+ 0x7e, 0x19, 0xcd, 0x66, 0xa3, 0xe9, 0xe2, 0xab, 0xd8, 0xff,
+ 0xed, 0xd0, 0x5e, 0x8d, 0xaf, 0x47, 0x8f, 0xf3, 0xb1, 0x5d,
+ 0x7c, 0x1c, 0xdb, 0x87, 0xd9, 0xfd, 0x87, 0xd9, 0xe8, 0x93,
+ 0x9d, 0xcc, 0xc3, 0x4a, 0xec, 0x8d, 0xbd, 0x9d, 0x8d, 0xc7,
+ 0xf6, 0xfe, 0xd6, 0x5e, 0x7f, 0x1c, 0xcd, 0x3e, 0x8c, 0x07,
+ 0x7c, 0x6e, 0x36, 0xe6, 0x13, 0x31, 0x2d, 0x2e, 0xc8, 0x46,
+ 0x04, 0xf0, 0xd4, 0xbd, 0xfc, 0x3c, 0xfe, 0x63, 0x31, 0x9e,
+ 0x2e, 0xec, 0xc3, 0x78, 0xf6, 0x69, 0xb2, 0x58, 0x80, 0xda,
+ 0xd5, 0x57, 0x3b, 0x7a, 0x78, 0x00, 0xf1, 0xd1, 0xd5, 0xdd,
+ 0xd8, 0xde, 0x8d, 0xbe, 0x40, 0x9b, 0xe3, 0x3f, 0xae, 0xc7,
+ 0x0f, 0x0b, 0xfb, 0xe5, 0xe3, 0x78, 0x6a, 0xee, 0x49, 0xfe,
+ 0xcb, 0x04, 0xfc, 0xcc, 0x17, 0x23, 0xbe, 0x30, 0x99, 0xda,
+ 0x2f, 0xb3, 0xc9, 0x62, 0x32, 0xfd, 0x20, 0x04, 0xb9, 0x85,
+ 0x3b, 0x9b, 0x7c, 0xf8, 0xb8, 0xb0, 0x1f, 0xef, 0xef, 0x6e,
+ 0xc6, 0x33, 0x59, 0xd5, 0xfd, 0x19, 0xa7, 0xcb, 0x8b, 0xf6,
+ 0x61, 0x34, 0x5b, 0x4c, 0xc6, 0x73, 0x03, 0x3e, 0x3e, 0x4f,
+ 0x6e, 0xfa, 0x42, 0xbd, 0x19, 0xcd, 0xc1, 0xf6, 0x1b, 0xfb,
+ 0x65, 0xb2, 0xf8, 0x78, 0xff, 0xb8, 0x68, 0x99, 0xa7, 0x70,
+ 0xa3, 0xe9, 0x57, 0xfb, 0xcf, 0xc9, 0xf4, 0x66, 0x60, 0xc7,
+ 0x13, 0x21, 0x34, 0xfe, 0xe3, 0x61, 0x36, 0x9e, 0x43, 0x7e,
+ 0x03, 0xda, 0x93, 0x4f, 0xe0, 0x78, 0x8c, 0x2f, 0x27, 0xd3,
+ 0xeb, 0xbb, 0xc7, 0x1b, 0xd9, 0x02, 0xbe, 0x02, 0x85, 0xe9,
+ 0xfd, 0x02, 0x7a, 0x82, 0x64, 0xe0, 0x73, 0x71, 0x2f, 0xaa,
+ 0x09, 0xcf, 0x06, 0xea, 0x60, 0x06, 0xf4, 0xcd, 0xa7, 0xf1,
+ 0x0c, 0xfa, 0x9b, 0x2e, 0x46, 0x57, 0x93, 0xbb, 0x09, 0x8e,
+ 0xe4, 0xda, 0xf0, 0xed, 0x64, 0x31, 0xc5, 0x11, 0xb2, 0x5c,
+ 0x3c, 0x52, 0xce, 0xaf, 0x1f, 0xef, 0x46, 0x10, 0xe2, 0x71,
+ 0xf6, 0x70, 0x3f, 0x1f, 0x73, 0x7c, 0x43, 0x15, 0x82, 0x08,
+ 0x14, 0x3e, 0x9b, 0xcc, 0xff, 0x69, 0x47, 0x73, 0xe3, 0x15,
+ 0xfb, 0xfb, 0xe3, 0xa8, 0x25, 0x04, 0xed, 0x82, 0xc6, 0xa7,
+ 0xd1, 0xf4, 0x5a, 0x0c, 0x75, 0x64, 0x48, 0x8a, 0x6b, 0xbf,
+ 0xde, 0x3f, 0xb2, 0x6a, 0x40, 0xee, 0xbb, 0x1b, 0x3e, 0x60,
+ 0xc2, 0x03, 0x54, 0xd4, 0xd8, 0xde, 0x8c, 0x6f, 0xc7, 0xd7,
+ 0x8b, 0xc9, 0x67, 0x98, 0x17, 0x4f, 0xe2, 0x98, 0xf9, 0xe3,
+ 0xa7, 0xb1, 0xd7, 0xf7, 0x7c, 0x21, 0x0a, 0xba, 0xbb, 0xb3,
+ 0xd3, 0xf1, 0x35, 0xf8, 0x1d, 0xcd, 0xbe, 0xda, 0xf9, 0x78,
+ 0xf6, 0x79, 0x72, 0x4d, 0x3d, 0x98, 0xd9, 0xf8, 0x61, 0x34,
+ 0x81, 0xfa, 0xb9, 0x20, 0x3d, 0x9b, 0x91, 0xca, 0xfd, 0x54,
+ 0x73, 0xcb, 0xbb, 0x21, 0x8d, 0x07, 0x2f, 0x19, 0x7f, 0xa6,
+ 0x0f, 0x3c, 0x4e, 0xef, 0x28, 0xed, 0x6c, 0xfc, 0xfb, 0x23,
+ 0xe4, 0x39, 0xe3, 0x09, 0xa4, 0x31, 0xfa, 0x00, 0x6f, 0xa3,
+ 0x32, 0x23, 0xbb, 0x9b, 0x2f, 0x13, 0x1c, 0x4e, 0x0b, 0x1d,
+ 0x1b, 0x7f, 0x20, 0xaf, 0xe0, 0x8b, 0xce, 0xf8, 0x5f, 0xe1,
+ 0x46, 0xf7, 0xf6, 0xd3, 0xe8, 0xab, 0x6e, 0x65, 0x7f, 0xf5,
+ 0xee, 0x01, 0x36, 0xdb, 0xb5, 0xed, 0xbe, 0x57, 0xc0, 0x29,
+ 0x3a, 0xef, 0x1c, 0x5d, 0xdd, 0x53, 0x07, 0x57, 0xe0, 0x67,
+ 0x22, 0x6c, 0x81, 0x11, 0x2a, 0x84, 0x26, 0xba, 0x19, 0x7d,
+ 0x1a, 0x7d, 0x18, 0xcf, 0x07, 0xa6, 0x75, 0x02, 0x39, 0xda,
+ 0x6f, 0x92, 0x0f, 0xec, 0xfc, 0x61, 0x7c, 0x3d, 0xe1, 0x5f,
+ 0xf0, 0x3d, 0x5c, 0x0f, 0xb6, 0xbe, 0x53, 0xad, 0x20, 0x8a,
+ 0x7e, 0x7f, 0xa4, 0x15, 0xf1, 0x81, 0x27, 0x62, 0x47, 0x30,
+ 0x27, 0x45, 0xa3, 0x1f, 0x7a, 0x93, 0x31, 0x06, 0xe9, 0x6b,
+ 0xd3, 0xe0, 0x23, 0x38, 0xfb, 0x38, 0x2e, 0x2f, 0xba, 0xb3,
+ 0x8f, 0xfc, 0x8f, 0x7e, 0x71, 0x77, 0x3f, 0xa7, 0xb3, 0xe1,
+ 0x90, 0xc5, 0xc8, 0x0a, 0xc7, 0xf8, 0xf3, 0x6a, 0xcc, 0xa7,
+ 0x67, 0xe3, 0x29, 0xf4, 0x25, 0xe1, 0x34, 0xba, 0xbe, 0x7e,
+ 0x9c, 0x21, 0xb4, 0xf8, 0x04, 0xdf, 0x00, 0x37, 0xf3, 0x47,
+ 0x04, 0xdb, 0x64, 0x2a, 0x46, 0x31, 0x94, 0x57, 0xa2, 0x79,
+ 0x32, 0xbb, 0x09, 0xf1, 0x24, 0x7a, 0xb6, 0xb7, 0xa3, 0xc9,
+ 0xdd, 0xe3, 0xec, 0xc4, 0xc7, 0x70, 0xf2, 0x3d, 0x54, 0x48,
+ 0x92, 0xe2, 0x6b, 0xad, 0x41, 0x82, 0x93, 0xcd, 0x2f, 0x07,
+ 0xe2, 0x03, 0x76, 0x72, 0x8b, 0xa3, 0xae, 0x3f, 0x7a, 0xeb,
+ 0xd9, 0x5e, 0xd4, 0x7e, 0xb5, 0x1f, 0x61, 0x8a, 0xab, 0x31,
+ 0x1e, 0x1b, 0xdd, 0x7c, 0x9e, 0x30, 0xf3, 0xe8, 0x39, 0x06,
+ 0xb1, 0x30, 0x9f, 0x78, 0x9d, 0xdc, 0x7b, 0x0a, 0x5e, 0x8f,
+ 0xed, 0x4e, 0x3f, 0xa2, 0x44, 0x9f, 0x3f, 0xb3, 0xbd, 0x6f,
+ 0xfe, 0x17, 0x84, 0xf3, 0x1b, 0xef, 0x12, 0x3b, 0x00, 0x00,
+
+};
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h
+++ u-boot/include/configs/neo1973_gta01.h
@@ -110,6 +110,7 @@
CFG_CMD_MMC | \
CFG_CMD_FAT | \
CFG_CMD_EXT2 | \
+ CFG_CMD_LICENSE | \
0)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
Index: u-boot/include/configs/hxd8.h
===================================================================
--- u-boot.orig/include/configs/hxd8.h
+++ u-boot/include/configs/hxd8.h
@@ -110,6 +110,7 @@
CFG_CMD_MMC | \
CFG_CMD_FAT | \
CFG_CMD_EXT2 | \
+ CFG_CMD_LICENSE | \
0)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
Index: u-boot/include/configs/smdk2440.h
===================================================================
--- u-boot.orig/include/configs/smdk2440.h
+++ u-boot/include/configs/smdk2440.h
@@ -110,6 +110,7 @@
CFG_CMD_PORTIO | \
CFG_CMD_REGINFO | \
CFG_CMD_SAVES | \
+ CFG_CMD_LICENSE | \
CFG_CMD_USB)
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
Index: u-boot/tools/setlocalversion
===================================================================
--- u-boot.orig/tools/setlocalversion 2007-03-26 14:42:58.000000000 +0200
+++ u-boot/tools/setlocalversion 2007-03-26 14:46:47.000000000 +0200
@@ -20,3 +20,5 @@
printf '%s' -dirty
fi
fi
+
+printf '%s' -moko9

View File

@ -0,0 +1,20 @@
This patch makes sure that the 'nand markbad' command does not only mark a block
'bad' in the bad-block table, but _also_ marks it bad in the OOB area.
we need this to preserve the bad block status when re-creating the bad block table
at some later point.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/drivers/nand/nand_base.c
===================================================================
--- u-boot.orig/drivers/nand/nand_base.c 2007-03-01 12:47:31.000000000 +0100
+++ u-boot/drivers/nand/nand_base.c 2007-03-01 12:48:08.000000000 +0100
@@ -481,7 +481,7 @@
/* Do we have a flash based bad block table ? */
if (this->options & NAND_USE_FLASH_BBT)
- return nand_update_bbt (mtd, ofs);
+ nand_update_bbt (mtd, ofs);
/* We write two bytes, so we dont have to mess with 16 bit access */
ofs += mtd->oobsize + (this->badblockpos & ~0x01);

View File

@ -0,0 +1,31 @@
Index: u-boot/include/configs/neo1973_gta01.h
===================================================================
--- u-boot.orig/include/configs/neo1973_gta01.h 2007-02-27 00:43:16.000000000 +0100
+++ u-boot/include/configs/neo1973_gta01.h 2007-02-27 00:47:49.000000000 +0100
@@ -115,8 +115,8 @@
#include <cmd_confdefs.h>
#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTARGS "rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8"
-#define CONFIG_BOOTCOMMAND "nand read.e 0x32000000 0x34000 0x200000; bootm 0x32000000"
+#define CONFIG_BOOTARGS ""
+#define CONFIG_BOOTCOMMAND "setenv bootargs ${bootargs_base} ${mtdparts}; nand read.e 0x32000000 kernel; bootm 0x32000000"
#define CONFIG_DOS_PARTITION 1
@@ -181,11 +181,14 @@
#define CONFIG_USBD_PRODUCTID_CDCACM 0x5119 /* CDC ACM */
#define CONFIG_USBD_MANUFACTURER "OpenMoko, Inc"
#define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader " U_BOOT_VERSION
-#define CONFIG_EXTRA_ENV_SETTINGS "usbtty=cdc_acm\0"
#define CONFIG_USBD_DFU 1
#define CONFIG_USBD_DFU_XFER_SIZE 4096 /* 0x4000 */
#define CONFIG_USBD_DFU_INTERFACE 2
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "usbtty=cdc_acm\0" \
+ "bootargs_base=rootfstype=jffs2 root=/dev/mtdblock4 console=ttySAC0,115200 console=tty0 loglevel=8\0" \
+ ""
/*-----------------------------------------------------------------------
* Physical Memory Map

View File

@ -0,0 +1,113 @@
Resume support for low-level uboot code, Version 5
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S 2007-02-28 03:51:24.000000000 +0100
+++ u-boot/cpu/arm920t/start.S 2007-03-01 02:43:47.000000000 +0100
@@ -158,18 +158,68 @@
str r1, [r0]
# endif
+ /* default FCLK is 202 MHz ! */
+#define LOCKTIME 0x4c000000
+#define UPLLCON 0x4c000008
+//#define MPLLCFG ((0x90 << 12) + (0x2 << 4) + 0x2)
+#define MPLLCFG ((0x90 << 12) + (0x7 << 4) + 0x0)
+#define UPLLCFG ((0x78 << 12) + (0x2 << 4) + 0x3)
+ ldr r0, =LOCKTIME
+ mov r1, #0xffffff
+ str r1, [r0]
+
+ ldr r0, =UPLLCON
+ ldr r1, =UPLLCFG
+ str r1, [r0]
+
+ /* Page 7-19, seven nops between UPLL and MPLL */
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ ldr r1, =MPLLCFG
+ str r1, [r0, #-4] /* MPLLCON */
+
/* FCLK:HCLK:PCLK = 1:2:4 */
- /* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
+
+#if 1
+ /* enable uart */
+ ldr r0, =0x4c00000c /* clkcon */
+ ldr r1, =0x7fff0 /* all clocks on */
+ str r1, [r0]
+
+ /* gpio UART0 init */
+ ldr r0, =0x56000070
+ mov r1, #0xaa
+ str r1, [r0]
+
+ /* init uart */
+ ldr r0, =0x50000000
+ mov r1, #0x03
+ str r1, [r0]
+ ldr r1, =0x245
+ str r1, [r0, #0x04]
+ mov r1, #0x01
+ str r1, [r0, #0x08]
+ mov r1, #0x00
+ str r1, [r0, #0x0c]
+ mov r1, #0x1a
+ str r1, [r0, #0x28]
+#endif
+
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#ifndef CONFIG_LL_INIT_NAND_ONLY
bl cpu_init_crit
#endif
-#endif
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
adr r0, _start /* r0 <- current position of code */
@@ -202,9 +252,33 @@
#ifdef CONFIG_S3C2410_NAND_BOOT
nand_load:
+ /* take sdram out of power down */
+ ldr r0, =0x56000080 /* misccr */
+ ldr r1, [ r0 ]
+ bic r1, r1, #(S3C2410_MISCCR_nEN_SCLK0 | S3C2410_MISCCR_nEN_SCLK1 | S3C2410_MISCCR_nEN_SCLKE)
+ str r1, [ r0 ]
+
+ /* ensure signals stabalise */
+ mov r1, #128
+1: subs r1, r1, #1
+ bpl 1b
+
#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) && defined(CONFIG_LL_INIT_NAND_ONLY)
bl cpu_init_crit
#endif
+#if defined(CONFIG_S3C2410)
+ /* ensure some refresh has happened */
+ ldr r1, =0xfffff
+1: subs r1, r1, #1
+ bpl 1b
+
+ /* test for resume */
+ ldr r1, =0x560000B4 /* gstatus2 */
+ ldr r0, [ r1 ]
+ tst r0, #0x02 /* is this resume from power down */
+ ldrne pc, [r1, #4] /* gstatus3 */
+#endif /* CONFIG_S3C2410 */
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
/* mov r10, lr */

View File

@ -0,0 +1,45 @@
Index: u-boot/include/s3c2410.h
===================================================================
--- u-boot.orig/include/s3c2410.h
+++ u-boot/include/s3c2410.h
@@ -233,4 +233,40 @@ static inline S3C2410_SDI * S3C2410_GetB
rINTPND;\
}
/* Wait until rINTPND is changed for the case that the ISR is very short. */
+
+#define S3C2410_MISCCR_USBDEV (0<<3)
+#define S3C2410_MISCCR_USBHOST (1<<3)
+
+#define S3C2410_MISCCR_CLK0_MPLL (0<<4)
+#define S3C2410_MISCCR_CLK0_UPLL (1<<4)
+#define S3C2410_MISCCR_CLK0_FCLK (2<<4)
+#define S3C2410_MISCCR_CLK0_HCLK (3<<4)
+#define S3C2410_MISCCR_CLK0_PCLK (4<<4)
+#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
+#define S3C2410_MISCCR_CLK0_MASK (7<<4)
+
+#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
+#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
+#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
+#define S3C2410_MISCCR_CLK1_HCLK (3<<8)
+#define S3C2410_MISCCR_CLK1_PCLK (4<<8)
+#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
+#define S3C2410_MISCCR_CLK1_MASK (7<<8)
+
+#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
+#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
+
+#define S3C2410_MISCCR_nRSTCON (1<<16)
+
+#define S3C2410_MISCCR_nEN_SCLK0 (1<<17)
+#define S3C2410_MISCCR_nEN_SCLK1 (1<<18)
+#define S3C2410_MISCCR_nEN_SCLKE (1<<19)
+#define S3C2410_MISCCR_SDSLEEP (7<<17)
+
+#define S3C2410_CLKSLOW_UCLK_OFF (1<<7)
+#define S3C2410_CLKSLOW_MPLL_OFF (1<<5)
+#define S3C2410_CLKSLOW_SLOW (1<<4)
+#define S3C2410_CLKSLOW_SLOWVAL(x) (x)
+#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7)
+
#endif /*__S3C2410_H__*/

View File

@ -0,0 +1,818 @@
This patch adds MMC/SD support to the S3C2410 SoC code in
u-boot
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/cpu/arm920t/s3c24x0/Makefile
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile
+++ u-boot/cpu/arm920t/s3c24x0/Makefile
@@ -26,7 +26,7 @@
LIB = $(obj)lib$(SOC).a
COBJS = i2c.o interrupts.o serial.o speed.o \
- usb_ohci.o nand_read.o nand.o cmd_s3c2410.o
+ usb_ohci.o nand_read.o nand.o mmc.o cmd_s3c2410.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
Index: u-boot/cpu/arm920t/s3c24x0/mmc.c
===================================================================
--- /dev/null
+++ u-boot/cpu/arm920t/s3c24x0/mmc.c
@@ -0,0 +1,531 @@
+/*
+ * u-boot S3C2410 MMC/SD card driver
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
+ * (C) 2005-2005 Thomas Kleffel
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <common.h>
+#include <mmc.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <s3c2410.h>
+#include <part.h>
+#include <fat.h>
+
+#ifdef CONFIG_MMC
+
+#define CONFIG_MMC_WIDE
+
+static S3C2410_SDI *sdi;
+
+static block_dev_desc_t mmc_dev;
+
+block_dev_desc_t * mmc_get_dev(int dev)
+{
+ return ((block_dev_desc_t *)&mmc_dev);
+}
+
+/*
+ * FIXME needs to read cid and csd info to determine block size
+ * and other parameters
+ */
+static uchar mmc_buf[MMC_BLOCK_SIZE];
+static mmc_csd_t mmc_csd;
+static int mmc_ready = 0;
+static int wide = 0;
+
+
+#define CMD_F_RESP 0x01
+#define CMD_F_RESP_LONG 0x02
+
+static u_int32_t *mmc_cmd(ushort cmd, ulong arg, ushort flags)
+{
+ static u_int32_t resp[5];
+
+ u_int32_t ccon, csta;
+ u_int32_t csta_rdy_bit = S3C2410_SDICMDSTAT_CMDSENT;
+
+ memset(resp, 0, sizeof(resp));
+
+ debug("mmc_cmd CMD%d arg=0x%08x flags=%x\n", cmd, arg, flags);
+
+ sdi->SDICSTA = 0xffffffff;
+ sdi->SDIDSTA = 0xffffffff;
+ sdi->SDIFSTA = 0xffffffff;
+
+ sdi->SDICARG = arg;
+
+ ccon = cmd & S3C2410_SDICMDCON_INDEX;
+ ccon |= S3C2410_SDICMDCON_SENDERHOST|S3C2410_SDICMDCON_CMDSTART;
+
+ if (flags & CMD_F_RESP) {
+ ccon |= S3C2410_SDICMDCON_WAITRSP;
+ csta_rdy_bit = S3C2410_SDICMDSTAT_RSPFIN; /* 1 << 9 */
+ }
+
+ if (flags & CMD_F_RESP_LONG)
+ ccon |= S3C2410_SDICMDCON_LONGRSP;
+
+ sdi->SDICCON = ccon;
+
+ while (1) {
+ csta = sdi->SDICSTA;
+ if (csta & csta_rdy_bit)
+ break;
+ if (csta & S3C2410_SDICMDSTAT_CMDTIMEOUT) {
+ printf("===============> MMC CMD Timeout\n");
+ sdi->SDICSTA |= S3C2410_SDICMDSTAT_CMDTIMEOUT;
+ break;
+ }
+ }
+
+ debug("final MMC CMD status 0x%x\n", csta);
+
+ sdi->SDICSTA |= csta_rdy_bit;
+
+ if (flags & CMD_F_RESP) {
+ resp[0] = sdi->SDIRSP0;
+ resp[1] = sdi->SDIRSP1;
+ resp[2] = sdi->SDIRSP2;
+ resp[3] = sdi->SDIRSP3;
+ }
+
+ return resp;
+}
+
+#define FIFO_FILL(host) ((host->SDIFSTA & S3C2410_SDIFSTA_COUNTMASK) >> 2)
+
+static int mmc_block_read(uchar *dst, ulong src, ulong len)
+{
+ u_int32_t dcon, fifo;
+ u_int32_t *dst_u32 = (u_int32_t *)dst;
+ u_int32_t *resp;
+
+ if (len == 0)
+ return 0;
+
+ debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, len);
+
+ /* set block len */
+ resp = mmc_cmd(MMC_CMD_SET_BLOCKLEN, len, CMD_F_RESP);
+ sdi->SDIBSIZE = len;
+
+ //sdi->SDIPRE = 0xff;
+
+ /* setup data */
+ dcon = (len >> 9) & S3C2410_SDIDCON_BLKNUM;
+ dcon |= S3C2410_SDIDCON_BLOCKMODE;
+ dcon |= S3C2410_SDIDCON_RXAFTERCMD|S3C2410_SDIDCON_XFER_RXSTART;
+ if (wide)
+ dcon |= S3C2410_SDIDCON_WIDEBUS;
+ sdi->SDIDCON = dcon;
+
+ /* send read command */
+ resp = mmc_cmd(MMC_CMD_READ_BLOCK, src, CMD_F_RESP);
+
+ while (len > 0) {
+ u_int32_t sdidsta = sdi->SDIDSTA;
+ fifo = FIFO_FILL(sdi);
+ if (sdidsta & (S3C2410_SDIDSTA_FIFOFAIL|
+ S3C2410_SDIDSTA_CRCFAIL|
+ S3C2410_SDIDSTA_RXCRCFAIL|
+ S3C2410_SDIDSTA_DATATIMEOUT)) {
+ printf("mmc_block_read: err SDIDSTA=0x%08x\n", sdidsta);
+ return -EIO;
+ }
+
+ while (fifo--) {
+ //debug("dst_u32 = 0x%08x\n", dst_u32);
+ *(dst_u32++) = sdi->SDIDAT;
+ if (len >= 4)
+ len -= 4;
+ else {
+ len = 0;
+ break;
+ }
+ }
+ }
+
+ debug("waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA);
+ while (!(sdi->SDIDSTA & (1 << 4))) {}
+ debug("done waiting for SDIDSTA (currently 0x%08x\n", sdi->SDIDSTA);
+
+ sdi->SDIDCON = 0;
+
+ if (!(sdi->SDIDSTA & S3C2410_SDIDSTA_XFERFINISH))
+ debug("mmc_block_read; transfer not finished!\n");
+
+ return 0;
+}
+
+static int mmc_block_write(ulong dst, uchar *src, int len)
+{
+ printf("MMC block write not yet supported on S3C2410!\n");
+ return -1;
+}
+
+
+int mmc_read(ulong src, uchar *dst, int size)
+{
+ ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+ ulong mmc_block_size, mmc_block_address;
+
+ if (size == 0)
+ return 0;
+
+ if (!mmc_ready) {
+ printf("Please initialize the MMC first\n");
+ return -1;
+ }
+
+ mmc_block_size = MMC_BLOCK_SIZE;
+ mmc_block_address = ~(mmc_block_size - 1);
+
+ src -= CFG_MMC_BASE;
+ end = src + size;
+ part_start = ~mmc_block_address & src;
+ part_end = ~mmc_block_address & end;
+ aligned_start = mmc_block_address & src;
+ aligned_end = mmc_block_address & end;
+
+ /* all block aligned accesses */
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if (part_start) {
+ part_len = mmc_block_size - part_start;
+ debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
+ return -1;
+
+ memcpy(dst, mmc_buf+part_start, part_len);
+ dst += part_len;
+ src += part_len;
+ }
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ for (; src < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
+ debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_read((uchar *)(dst), src, mmc_block_size)) < 0)
+ return -1;
+ }
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if (part_end && src < end) {
+ debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
+ return -1;
+
+ memcpy(dst, mmc_buf, part_end);
+ }
+ return 0;
+}
+
+int mmc_write(uchar *src, ulong dst, int size)
+{
+ ulong end, part_start, part_end, part_len, aligned_start, aligned_end;
+ ulong mmc_block_size, mmc_block_address;
+
+ if (size == 0)
+ return 0;
+
+ if (!mmc_ready) {
+ printf("Please initialize the MMC first\n");
+ return -1;
+ }
+
+ mmc_block_size = MMC_BLOCK_SIZE;
+ mmc_block_address = ~(mmc_block_size - 1);
+
+ dst -= CFG_MMC_BASE;
+ end = dst + size;
+ part_start = ~mmc_block_address & dst;
+ part_end = ~mmc_block_address & end;
+ aligned_start = mmc_block_address & dst;
+ aligned_end = mmc_block_address & end;
+
+ /* all block aligned accesses */
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if (part_start) {
+ part_len = mmc_block_size - part_start;
+ debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ (ulong)src, dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0)
+ return -1;
+
+ memcpy(mmc_buf+part_start, src, part_len);
+ if ((mmc_block_write(aligned_start, mmc_buf, mmc_block_size)) < 0)
+ return -1;
+
+ dst += part_len;
+ src += part_len;
+ }
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ for (; dst < aligned_end; src += mmc_block_size, dst += mmc_block_size) {
+ debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_write(dst, (uchar *)src, mmc_block_size)) < 0)
+ return -1;
+
+ }
+ debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if (part_end && dst < end) {
+ debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n",
+ src, (ulong)dst, end, part_start, part_end, aligned_start, aligned_end);
+ if ((mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0)
+ return -1;
+
+ memcpy(mmc_buf, src, part_end);
+ if ((mmc_block_write(aligned_end, mmc_buf, mmc_block_size)) < 0)
+ return -1;
+
+ }
+ return 0;
+}
+
+ulong mmc_bread(int dev_num, ulong blknr, ulong blkcnt, void *dst)
+{
+ int mmc_block_size = MMC_BLOCK_SIZE;
+ ulong src = blknr * mmc_block_size + CFG_MMC_BASE;
+
+ mmc_read(src, dst, blkcnt*mmc_block_size);
+ return blkcnt;
+}
+
+/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code
+ that expects it to be shifted. */
+static u_int16_t rca = MMC_DEFAULT_RCA >> 16;
+
+static u_int32_t mmc_size(const struct mmc_csd *csd)
+{
+ u_int32_t block_len, mult, blocknr;
+
+ block_len = csd->read_bl_len << 12;
+ mult = csd->c_size_mult1 << 8;
+ blocknr = (csd->c_size+1) * mult;
+
+ return blocknr * block_len;
+}
+
+struct sd_cid {
+ char pnm_0; /* product name */
+ char oid_1; /* OEM/application ID */
+ char oid_0;
+ uint8_t mid; /* manufacturer ID */
+ char pnm_4;
+ char pnm_3;
+ char pnm_2;
+ char pnm_1;
+ uint8_t psn_2; /* product serial number */
+ uint8_t psn_1;
+ uint8_t psn_0; /* MSB */
+ uint8_t prv; /* product revision */
+ uint8_t crc; /* CRC7 checksum, b0 is unused and set to 1 */
+ uint8_t mdt_1; /* manufacturing date, LSB, RRRRyyyy yyyymmmm */
+ uint8_t mdt_0; /* MSB */
+ uint8_t psn_3; /* LSB */
+};
+
+static void print_mmc_cid(mmc_cid_t *cid)
+{
+ printf("MMC found. Card desciption is:\n");
+ printf("Manufacturer ID = %02x%02x%02x\n",
+ cid->id[0], cid->id[1], cid->id[2]);
+ printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev);
+ cid->hwrev = cid->fwrev = 0; /* null terminate string */
+ printf("Product Name = %s\n",cid->name);
+ printf("Serial Number = %02x%02x%02x\n",
+ cid->sn[0], cid->sn[1], cid->sn[2]);
+ printf("Month = %d\n",cid->month);
+ printf("Year = %d\n",1997 + cid->year);
+}
+
+static void print_sd_cid(const struct sd_cid *cid)
+{
+ printf("Manufacturer: 0x%02x, OEM \"%c%c\"\n",
+ cid->mid, cid->oid_0, cid->oid_1);
+ printf("Product name: \"%c%c%c%c%c\", revision %d.%d\n",
+ cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4,
+ cid->prv >> 4, cid->prv & 15);
+ printf("Serial number: %u\n",
+ cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 |
+ cid->psn_3);
+ printf("Manufacturing date: %d/%d\n",
+ cid->mdt_1 & 15,
+ 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4));
+ printf("CRC: 0x%02x, b0 = %d\n",
+ cid->crc >> 1, cid->crc & 1);
+}
+
+int mmc_init(int verbose)
+{
+ int retries, rc = -ENODEV;
+ int is_sd = 0;
+ u_int32_t *resp;
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+ sdi = S3C2410_GetBase_SDI();
+
+ debug("mmc_init(PCLK=%u)\n", get_PCLK());
+
+ clk_power->CLKCON |= (1 << 9);
+
+ /* S3C2410 has some bug that prevents reliable operation at higher speed */
+ //sdi->SDIPRE = 0x3e; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
+ sdi->SDIPRE = 0x02; /* SDCLK = PCLK/2 / (SDIPRE+1) = 396kHz */
+ sdi->SDIBSIZE = 512;
+ sdi->SDIDTIMER = 0xffff;
+ sdi->SDIIMSK = 0x0;
+ sdi->SDICON = S3C2410_SDICON_FIFORESET|S3C2440_SDICON_MMCCLOCK;
+ udelay(125000); /* FIXME: 74 SDCLK cycles */
+
+ mmc_csd.c_size = 0;
+
+ /* reset */
+ retries = 10;
+ resp = mmc_cmd(MMC_CMD_RESET, 0, 0);
+
+ printf("trying to detect SD Card...\n");
+ while (retries--) {
+ udelay(100000);
+ resp = mmc_cmd(55, 0x00000000, CMD_F_RESP);
+ resp = mmc_cmd(41, 0x00300000, CMD_F_RESP);
+
+ if (resp[0] & (1 << 31)) {
+ is_sd = 1;
+ break;
+ }
+ }
+
+ if (retries == 0 && !is_sd) {
+ retries = 10;
+ printf("failed to detect SD Card, trying MMC\n");
+ resp = mmc_cmd(MMC_CMD_SEND_OP_COND, 0x00ffc000, CMD_F_RESP);
+ while (retries-- && resp && !(resp[4] & 0x80)) {
+ debug("resp %x %x\n", resp[0], resp[1]);
+ udelay(50);
+ resp = mmc_cmd(1, 0x00ffff00, CMD_F_RESP);
+ }
+ }
+
+ /* try to get card id */
+ resp = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, CMD_F_RESP|CMD_F_RESP_LONG);
+ if (resp) {
+ if (!is_sd) {
+ /* TODO configure mmc driver depending on card
+ attributes */
+ mmc_cid_t *cid = (mmc_cid_t *)resp;
+
+ if (verbose)
+ print_mmc_cid(cid);
+ sprintf((char *) mmc_dev.vendor,
+ "Man %02x%02x%02x Snr %02x%02x%02x",
+ cid->id[0], cid->id[1], cid->id[2],
+ cid->sn[0], cid->sn[1], cid->sn[2]);
+ sprintf((char *) mmc_dev.product,"%s",cid->name);
+ sprintf((char *) mmc_dev.revision,"%x %x",
+ cid->hwrev, cid->fwrev);
+ }
+ else {
+ struct sd_cid *cid = (struct sd_cid *) resp;
+
+ if (verbose)
+ print_sd_cid(cid);
+ sprintf((char *) mmc_dev.vendor,
+ "Man %02 OEM %c%c \"%c%c%c%c%c\"",
+ cid->mid, cid->oid_0, cid->oid_1,
+ cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3,
+ cid->pnm_4);
+ sprintf((char *) mmc_dev.product, "%d",
+ cid->psn_0 << 24 | cid->psn_1 << 16 |
+ cid->psn_2 << 8 | cid->psn_3);
+ sprintf((char *) mmc_dev.revision, "%d.%d",
+ cid->prv >> 4, cid->prv & 15);
+ }
+
+ /* fill in device description */
+ mmc_dev.if_type = IF_TYPE_MMC;
+ mmc_dev.part_type = PART_TYPE_DOS;
+ mmc_dev.dev = 0;
+ mmc_dev.lun = 0;
+ mmc_dev.type = 0;
+ /* FIXME fill in the correct size (is set to 32MByte) */
+ mmc_dev.blksz = 512;
+ mmc_dev.lba = 0x10000;
+ mmc_dev.removable = 0;
+ mmc_dev.block_read = mmc_bread;
+
+ /* MMC exists, get CSD too */
+ resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, CMD_F_RESP);
+ if (is_sd)
+ rca = resp[0] >> 16;
+
+ resp = mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, CMD_F_RESP|CMD_F_RESP_LONG);
+ if (resp) {
+ mmc_csd_t *csd = (mmc_csd_t *)resp;
+ memcpy(&mmc_csd, csd, sizeof(csd));
+ rc = 0;
+ mmc_ready = 1;
+ /* FIXME add verbose printout for csd */
+ printf("READ_BL_LEN=%u, C_SIZE_MULT=%u, C_SIZE=%u\n",
+ csd->read_bl_len, csd->c_size_mult1, csd->c_size);
+ printf("size = %u\n", mmc_size(csd));
+ }
+ }
+
+ resp = mmc_cmd(MMC_CMD_SELECT_CARD, rca<<16, CMD_F_RESP);
+
+#ifdef CONFIG_MMC_WIDE
+ if (is_sd) {
+ resp = mmc_cmd(55, rca<<16, CMD_F_RESP);
+ resp = mmc_cmd(6, 0x02, CMD_F_RESP);
+ wide = 1;
+ }
+#endif
+
+ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */
+
+ return rc;
+}
+
+int
+mmc_ident(block_dev_desc_t *dev)
+{
+ return 0;
+}
+
+int
+mmc2info(ulong addr)
+{
+ /* FIXME hard codes to 32 MB device */
+ if (addr >= CFG_MMC_BASE && addr < CFG_MMC_BASE + 0x02000000)
+ return 1;
+
+ return 0;
+}
+
+#endif /* CONFIG_MMC */
Index: u-boot/include/asm-arm/arch-s3c24x0/mmc.h
===================================================================
--- /dev/null
+++ u-boot/include/asm-arm/arch-s3c24x0/mmc.h
@@ -0,0 +1,112 @@
+/*
+ * linux/drivers/mmc/mmc_pxa.h
+ *
+ * Author: Vladimir Shebordaev, Igor Oblakov
+ * Copyright: MontaVista Software Inc.
+ *
+ * $Id: mmc_pxa.h,v 0.3.1.6 2002/09/25 19:25:48 ted Exp ted $
+ *
+ * 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.
+ */
+#ifndef __MMC_PXA_P_H__
+#define __MMC_PXA_P_H__
+
+#include <asm/arch/regs-sdi.h>
+
+#define MMC_DEFAULT_RCA (1<<16)
+
+#define MMC_BLOCK_SIZE 512
+#define MMC_CMD_RESET 0
+#define MMC_CMD_SEND_OP_COND 1
+#define MMC_CMD_ALL_SEND_CID 2
+#define MMC_CMD_SET_RCA 3
+#define MMC_CMD_SELECT_CARD 7
+#define MMC_CMD_SEND_CSD 9
+#define MMC_CMD_SEND_CID 10
+#define MMC_CMD_SEND_STATUS 13
+#define MMC_CMD_SET_BLOCKLEN 16
+#define MMC_CMD_READ_BLOCK 17
+#define MMC_CMD_RD_BLK_MULTI 18
+#define MMC_CMD_WRITE_BLOCK 24
+
+#define MMC_MAX_BLOCK_SIZE 512
+
+#define MMC_R1_IDLE_STATE 0x01
+#define MMC_R1_ERASE_STATE 0x02
+#define MMC_R1_ILLEGAL_CMD 0x04
+#define MMC_R1_COM_CRC_ERR 0x08
+#define MMC_R1_ERASE_SEQ_ERR 0x01
+#define MMC_R1_ADDR_ERR 0x02
+#define MMC_R1_PARAM_ERR 0x04
+
+#define MMC_R1B_WP_ERASE_SKIP 0x0002
+#define MMC_R1B_ERR 0x0004
+#define MMC_R1B_CC_ERR 0x0008
+#define MMC_R1B_CARD_ECC_ERR 0x0010
+#define MMC_R1B_WP_VIOLATION 0x0020
+#define MMC_R1B_ERASE_PARAM 0x0040
+#define MMC_R1B_OOR 0x0080
+#define MMC_R1B_IDLE_STATE 0x0100
+#define MMC_R1B_ERASE_RESET 0x0200
+#define MMC_R1B_ILLEGAL_CMD 0x0400
+#define MMC_R1B_COM_CRC_ERR 0x0800
+#define MMC_R1B_ERASE_SEQ_ERR 0x1000
+#define MMC_R1B_ADDR_ERR 0x2000
+#define MMC_R1B_PARAM_ERR 0x4000
+
+typedef struct mmc_cid
+{
+ /* FIXME: BYTE_ORDER */
+ uchar year:4,
+ month:4;
+ uchar sn[3];
+ uchar fwrev:4,
+ hwrev:4;
+ uchar name[6];
+ uchar id[3];
+} mmc_cid_t;
+
+typedef struct mmc_csd
+{
+ uchar ecc:2,
+ file_format:2,
+ tmp_write_protect:1,
+ perm_write_protect:1,
+ copy:1,
+ file_format_grp:1;
+ uint64_t content_prot_app:1,
+ rsvd3:4,
+ write_bl_partial:1,
+ write_bl_len:4,
+ r2w_factor:3,
+ default_ecc:2,
+ wp_grp_enable:1,
+ wp_grp_size:5,
+ erase_grp_mult:5,
+ erase_grp_size:5,
+ c_size_mult1:3,
+ vdd_w_curr_max:3,
+ vdd_w_curr_min:3,
+ vdd_r_curr_max:3,
+ vdd_r_curr_min:3,
+ c_size:12,
+ rsvd2:2,
+ dsr_imp:1,
+ read_blk_misalign:1,
+ write_blk_misalign:1,
+ read_bl_partial:1;
+
+ ushort read_bl_len:4,
+ ccc:12;
+ uchar tran_speed;
+ uchar nsac;
+ uchar taac;
+ uchar rsvd1:2,
+ spec_vers:4,
+ csd_structure:2;
+} mmc_csd_t;
+
+
+#endif /* __MMC_PXA_P_H__ */
Index: u-boot/include/asm-arm/arch-s3c24x0/regs-sdi.h
===================================================================
--- /dev/null
+++ u-boot/include/asm-arm/arch-s3c24x0/regs-sdi.h
@@ -0,0 +1,110 @@
+/* linux/include/asm/arch-s3c2410/regs-sdi.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * 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.
+ *
+ * S3C2410 MMC/SDIO register definitions
+ *
+ * Changelog:
+ * 18-Aug-2004 Ben Dooks Created initial file
+ * 29-Nov-2004 Koen Martens Added some missing defines, fixed duplicates
+ * 29-Nov-2004 Ben Dooks Updated Koen's patch
+*/
+
+#ifndef __ASM_ARM_REGS_SDI
+#define __ASM_ARM_REGS_SDI "regs-sdi.h"
+
+#define S3C2440_SDICON_SDRESET (1<<8)
+#define S3C2440_SDICON_MMCCLOCK (1<<5)
+#define S3C2410_SDICON_BYTEORDER (1<<4)
+#define S3C2410_SDICON_SDIOIRQ (1<<3)
+#define S3C2410_SDICON_RWAITEN (1<<2)
+#define S3C2410_SDICON_FIFORESET (1<<1)
+#define S3C2410_SDICON_CLOCKTYPE (1<<0)
+
+#define S3C2410_SDICMDCON_ABORT (1<<12)
+#define S3C2410_SDICMDCON_WITHDATA (1<<11)
+#define S3C2410_SDICMDCON_LONGRSP (1<<10)
+#define S3C2410_SDICMDCON_WAITRSP (1<<9)
+#define S3C2410_SDICMDCON_CMDSTART (1<<8)
+#define S3C2410_SDICMDCON_SENDERHOST (1<<6)
+#define S3C2410_SDICMDCON_INDEX (0x3f)
+
+#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12)
+#define S3C2410_SDICMDSTAT_CMDSENT (1<<11)
+#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
+#define S3C2410_SDICMDSTAT_RSPFIN (1<<9)
+#define S3C2410_SDICMDSTAT_XFERING (1<<8)
+#define S3C2410_SDICMDSTAT_INDEX (0xff)
+
+#define S3C2440_SDIDCON_DS_BYTE (0<<22)
+#define S3C2440_SDIDCON_DS_HALFWORD (1<<22)
+#define S3C2440_SDIDCON_DS_WORD (2<<22)
+#define S3C2410_SDIDCON_IRQPERIOD (1<<21)
+#define S3C2410_SDIDCON_TXAFTERRESP (1<<20)
+#define S3C2410_SDIDCON_RXAFTERCMD (1<<19)
+#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18)
+#define S3C2410_SDIDCON_BLOCKMODE (1<<17)
+#define S3C2410_SDIDCON_WIDEBUS (1<<16)
+#define S3C2410_SDIDCON_DMAEN (1<<15)
+#define S3C2410_SDIDCON_STOP (1<<14)
+#define S3C2440_SDIDCON_DATSTART (1<<14)
+#define S3C2410_SDIDCON_DATMODE (3<<12)
+#define S3C2410_SDIDCON_BLKNUM (0x7ff)
+
+/* constants for S3C2410_SDIDCON_DATMODE */
+#define S3C2410_SDIDCON_XFER_READY (0<<12)
+#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
+#define S3C2410_SDIDCON_XFER_RXSTART (2<<12)
+#define S3C2410_SDIDCON_XFER_TXSTART (3<<12)
+
+#define S3C2410_SDIDCNT_BLKNUM_MASK (0xFFF)
+#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12)
+
+#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10)
+#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
+#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */
+#define S3C2410_SDIDSTA_CRCFAIL (1<<7)
+#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6)
+#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5)
+#define S3C2410_SDIDSTA_XFERFINISH (1<<4)
+#define S3C2410_SDIDSTA_BUSYFINISH (1<<3)
+#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */
+#define S3C2410_SDIDSTA_TXDATAON (1<<1)
+#define S3C2410_SDIDSTA_RXDATAON (1<<0)
+
+#define S3C2440_SDIFSTA_FIFORESET (1<<16)
+#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */
+#define S3C2410_SDIFSTA_TFDET (1<<13)
+#define S3C2410_SDIFSTA_RFDET (1<<12)
+#define S3C2410_SDIFSTA_TFHALF (1<<11)
+#define S3C2410_SDIFSTA_TFEMPTY (1<<10)
+#define S3C2410_SDIFSTA_RFLAST (1<<9)
+#define S3C2410_SDIFSTA_RFFULL (1<<8)
+#define S3C2410_SDIFSTA_RFHALF (1<<7)
+#define S3C2410_SDIFSTA_COUNTMASK (0x7f)
+
+#define S3C2410_SDIIMSK_RESPONSECRC (1<<17)
+#define S3C2410_SDIIMSK_CMDSENT (1<<16)
+#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15)
+#define S3C2410_SDIIMSK_RESPONSEND (1<<14)
+#define S3C2410_SDIIMSK_READWAIT (1<<13)
+#define S3C2410_SDIIMSK_SDIOIRQ (1<<12)
+#define S3C2410_SDIIMSK_FIFOFAIL (1<<11)
+#define S3C2410_SDIIMSK_CRCSTATUS (1<<10)
+#define S3C2410_SDIIMSK_DATACRC (1<<9)
+#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8)
+#define S3C2410_SDIIMSK_DATAFINISH (1<<7)
+#define S3C2410_SDIIMSK_BUSYFINISH (1<<6)
+#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */
+#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4)
+#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3)
+#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2)
+#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1)
+#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0)
+
+#endif /* __ASM_ARM_REGS_SDI */
Index: u-boot/include/s3c24x0.h
===================================================================
--- u-boot.orig/include/s3c24x0.h
+++ u-boot/include/s3c24x0.h
@@ -637,13 +637,7 @@
S3C24X0_REG32 SDIDCNT;
S3C24X0_REG32 SDIDSTA;
S3C24X0_REG32 SDIFSTA;
-#ifdef __BIG_ENDIAN
- S3C24X0_REG8 res[3];
- S3C24X0_REG8 SDIDAT;
-#else
- S3C24X0_REG8 SDIDAT;
- S3C24X0_REG8 res[3];
-#endif
+ S3C24X0_REG32 SDIDAT;
S3C24X0_REG32 SDIIMSK;
} /*__attribute__((__packed__))*/ S3C2410_SDI;
@@ -1123,11 +1117,7 @@
#define rSDIDatCnt (*(volatile unsigned *)0x5A000030)
#define rSDIDatSta (*(volatile unsigned *)0x5A000034)
#define rSDIFSTA (*(volatile unsigned *)0x5A000038)
-#ifdef __BIG_ENDIAN
-#define rSDIDAT (*(volatile unsigned char *)0x5A00003F)
-#else
-#define rSDIDAT (*(volatile unsigned char *)0x5A00003C)
-#endif
+#define rSDIDAT (*(volatile unsigned *)0x5A00003C)
#define rSDIIntMsk (*(volatile unsigned *)0x5A000040)
#endif

View File

@ -0,0 +1,525 @@
This patch adds NAND (including boot-from-NAND via steppingstone) support to
the S3C2410 SoC code in u-boot
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/cpu/arm920t/s3c24x0/Makefile
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/Makefile 2007-02-28 03:47:44.000000000 +0100
+++ u-boot/cpu/arm920t/s3c24x0/Makefile 2007-03-01 14:29:32.000000000 +0100
@@ -26,7 +26,7 @@
LIB = $(obj)lib$(SOC).a
COBJS = i2c.o interrupts.o serial.o speed.o \
- usb_ohci.o
+ usb_ohci.o nand_read.o nand.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
Index: u-boot/cpu/arm920t/s3c24x0/nand.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot/cpu/arm920t/s3c24x0/nand.c 2007-03-01 14:30:27.000000000 +0100
@@ -0,0 +1,225 @@
+/*
+ * (C) Copyright 2006 OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if 0
+#define DEBUGN printf
+#else
+#define DEBUGN(x, args ...) {}
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+#if !defined(CFG_NAND_LEGACY)
+
+#include <nand.h>
+#include <s3c2410.h>
+
+#define __REGb(x) (*(volatile unsigned char *)(x))
+#define __REGi(x) (*(volatile unsigned int *)(x))
+
+#define NF_BASE 0x4e000000
+#define NFCONF __REGi(NF_BASE + 0x0)
+#define NFCMD __REGb(NF_BASE + 0x4)
+#define NFADDR __REGb(NF_BASE + 0x8)
+#define NFDATA __REGb(NF_BASE + 0xc)
+#define NFSTAT __REGb(NF_BASE + 0x10)
+#define NFECC0 __REGb(NF_BASE + 0x14)
+#define NFECC1 __REGb(NF_BASE + 0x15)
+#define NFECC2 __REGb(NF_BASE + 0x16)
+
+#define S3C2410_NFCONF_EN (1<<15)
+#define S3C2410_NFCONF_512BYTE (1<<14)
+#define S3C2410_NFCONF_4STEP (1<<13)
+#define S3C2410_NFCONF_INITECC (1<<12)
+#define S3C2410_NFCONF_nFCE (1<<11)
+#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
+#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
+#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
+
+static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ DEBUGN("hwcontrol(): 0x%02x: ", cmd);
+
+ switch (cmd) {
+ case NAND_CTL_SETNCE:
+ NFCONF &= ~S3C2410_NFCONF_nFCE;
+ DEBUGN("NFCONF=0x%08x\n", NFCONF);
+ break;
+ case NAND_CTL_CLRNCE:
+ NFCONF |= S3C2410_NFCONF_nFCE;
+ DEBUGN("NFCONF=0x%08x\n", NFCONF);
+ break;
+ case NAND_CTL_SETALE:
+ chip->IO_ADDR_W = NF_BASE + 0x8;
+ DEBUGN("SETALE\n");
+ break;
+ case NAND_CTL_SETCLE:
+ chip->IO_ADDR_W = NF_BASE + 0x4;
+ DEBUGN("SETCLE\n");
+ break;
+ default:
+ chip->IO_ADDR_W = NF_BASE + 0xc;
+ break;
+ }
+ return;
+}
+
+static int s3c2410_dev_ready(struct mtd_info *mtd)
+{
+ DEBUGN("dev_ready\n");
+ return (NFSTAT & 0x01);
+}
+
+static void s3c2410_cmdfunc(struct mtd_info *mtd, unsigned cmd,
+ int column, int page_addr)
+{
+ DEBUGN("cmdfunc(): 0x%02x, col=%d, page=%d\n", cmd, column, page_addr);
+
+ switch (cmd) {
+ case NAND_CMD_READ0:
+ case NAND_CMD_READ1:
+ case NAND_CMD_READOOB:
+ NFCMD = cmd;
+ NFADDR = column & 0xff;
+ NFADDR = page_addr & 0xff;
+ NFADDR = (page_addr >> 8) & 0xff;
+ NFADDR = (page_addr >> 16) & 0xff;
+ break;
+ case NAND_CMD_READID:
+ NFCMD = cmd;
+ NFADDR = 0;
+ break;
+ case NAND_CMD_PAGEPROG:
+ NFCMD = cmd;
+ printf("PAGEPROG not implemented\n");
+ break;
+ case NAND_CMD_ERASE1:
+ NFCMD = cmd;
+ NFADDR = page_addr & 0xff;
+ NFADDR = (page_addr >> 8) & 0xff;
+ NFADDR = (page_addr >> 16) & 0xff;
+ break;
+ case NAND_CMD_ERASE2:
+ NFCMD = cmd;
+ break;
+ case NAND_CMD_SEQIN:
+ printf("SEQIN not implemented\n");
+ break;
+ case NAND_CMD_STATUS:
+ NFCMD = cmd;
+ break;
+ case NAND_CMD_RESET:
+ NFCMD = cmd;
+ break;
+ default:
+ break;
+ }
+
+ while (!s3c2410_dev_ready(mtd));
+}
+
+#ifdef CONFIG_S3C2410_NAND_HWECC
+void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd ,mode);
+ NFCONF |= S3C2410_NFCONF_INITECC;
+}
+
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+{
+ ecc_code[0] = NFECC0;
+ ecc_code[1] = NFECC1;
+ ecc_code[2] = NFECC2;
+ DEBUGN("s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
+
+ return 0;
+}
+
+int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
+{
+ if (read_ecc[0] == calc_ecc[0] &&
+ read_ecc[1] == calc_ecc[1] &&
+ read_ecc[2] == calc_ecc[2])
+ return 0;
+
+ printf("s3c2410_nand_correct_data: not implemented\n");
+ return -1;
+}
+#endif
+
+int board_nand_init(struct nand_chip *nand)
+{
+ u_int32_t cfg;
+ u_int8_t tacls, twrph0, twrph1;
+ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
+
+ DEBUGN("board_nand_init()\n");
+
+ clk_power->CLKCON |= (1 << 4);
+
+ /* initialize hardware */
+ twrph0 = 3; twrph1 = 0; tacls = 0;
+
+ cfg = S3C2410_NFCONF_EN;
+ cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
+ cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
+ cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
+
+ NFCONF = cfg;
+ //NFCONF = 0xf842;
+
+ /* initialize nand_chip data structure */
+ nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e00000c;
+
+ /* read_buf and write_buf are default */
+ /* read_byte and write_byte are default */
+
+ /* hwcontrol always must be implemented */
+ nand->hwcontrol = s3c2410_hwcontrol;
+
+ nand->dev_ready = s3c2410_dev_ready;
+
+#ifdef CONFIG_S3C2410_NAND_HWECC
+ nand->enable_hwecc = s3c2410_nand_enable_hwecc;
+ nand->calculate_ecc = s3c2410_nand_calculate_ecc;
+ nand->correct_data = s3c2410_nand_correct_data;
+ nand->eccmode = NAND_ECC_HW3_512;
+#else
+ nand->eccmode = NAND_ECC_SOFT;
+#endif
+
+#ifdef CONFIG_S3C2410_NAND_BBT
+ nand->options = NAND_USE_FLASH_BBT;
+#else
+ nand->options = 0;
+#endif
+
+ DEBUGN("end of nand_init\n");
+
+ return 0;
+}
+
+#else
+ #error "U-Boot legacy NAND support not available for S3C2410"
+#endif
+#endif
Index: u-boot/cpu/arm920t/s3c24x0/nand_read.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ u-boot/cpu/arm920t/s3c24x0/nand_read.c 2007-02-28 03:51:24.000000000 +0100
@@ -0,0 +1,98 @@
+/*
+ * nand_read.c: Simple NAND read functions for booting from NAND
+ *
+ * This is used by cpu/arm920/start.S assembler code,
+ * and the board-specific linker script must make sure this
+ * file is linked within the first 4kB of NAND flash.
+ *
+ * Taken from GPLv2 licensed vivi bootloader,
+ * Copyright (C) 2002 MIZI Research, Inc.
+ *
+ * Author: Hwang, Chideok <hwang@mizi.com>
+ * Date : $Date: 2004/02/04 10:37:37 $
+ *
+ * u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_S3C2410_NAND_BOOT
+
+#define __REGb(x) (*(volatile unsigned char *)(x))
+#define __REGi(x) (*(volatile unsigned int *)(x))
+#define NF_BASE 0x4e000000
+#define NFCONF __REGi(NF_BASE + 0x0)
+#define NFCMD __REGb(NF_BASE + 0x4)
+#define NFADDR __REGb(NF_BASE + 0x8)
+#define NFDATA __REGb(NF_BASE + 0xc)
+#define NFSTAT __REGb(NF_BASE + 0x10)
+
+#define BUSY 1
+inline void wait_idle(void)
+{
+ int i;
+
+ while (!(NFSTAT & BUSY))
+ for (i=0; i<10; i++);
+}
+
+#define NAND_SECTOR_SIZE 512
+#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
+#define NAND_PAGE_SIZE 0x4000
+
+/* low level nand read function */
+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+
+ if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
+ return -1; /* invalid alignment */
+
+ /* chip Enable */
+ NFCONF &= ~0x800;
+ for (i=0; i<10; i++);
+
+ for (i=start_addr; i < (start_addr + size);) {
+#ifdef CONFIG_S3C2410_NAND_SKIP_BAD
+ if (start_addr % NAND_PAGE_SIZE == 0) {
+ unsigned char data;
+ NFCMD = 0x50;
+ NFADDR = 517&0xf;
+ NFADDR = (i >> 9) & 0xff;
+ NFADDR = (i >> 17) & 0xff;
+ NFADDR = (i >> 25) & 0xff;
+ wait_idle();
+ data = (NFDATA & 0xff);
+ if (data != 0xff) {
+ /* Bad block */
+ i += NAND_PAGE_SIZE;
+ size += NAND_PAGE_SIZE;
+ continue;
+ }
+ }
+#endif
+ /* READ0 */
+ NFCMD = 0;
+
+ /* Write Address */
+ NFADDR = i & 0xff;
+ NFADDR = (i >> 9) & 0xff;
+ NFADDR = (i >> 17) & 0xff;
+ NFADDR = (i >> 25) & 0xff;
+
+ wait_idle();
+
+ for (j=0; j < NAND_SECTOR_SIZE; j++, i++) {
+ *buf = (NFDATA & 0xff);
+ buf++;
+ }
+ }
+
+ /* chip Disable */
+ NFCONF |= 0x800; /* chip disable */
+
+ return 0;
+}
+
+#endif /* CONFIG_S3C2410_NAND_BOOT */
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S 2007-02-28 03:47:44.000000000 +0100
+++ u-boot/cpu/arm920t/start.S 2007-03-01 14:29:22.000000000 +0100
@@ -5,6 +5,10 @@
* Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
* Copyright (c) 2002 Gary Jennejohn <gj@denx.de>
*
+ * S3C2410 NAND portions
+ * Copyright (c) 2001 MIZI Research, Inc.
+ * Copyright (c) 2006 OpenMoko, Inc. (Harald Welte <laforge@openmmoko.org>
+ *
* See file CREDITS for list of people who contributed to this
* project.
*
@@ -27,6 +31,7 @@
#include <config.h>
#include <version.h>
+#include <s3c2410.h>
/*
@@ -161,6 +166,7 @@
#endif
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+#ifndef CONFIG_S3C2410_NAND_BOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
@@ -177,6 +183,93 @@
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
+#else /* NAND_BOOT */
+relocate:
+copy_myself:
+ /* mov r10, lr */
+
+ @ reset NAND
+ mov r1, #S3C2410_NAND_BASE
+ ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0
+ str r2, [r1, #oNFCONF]
+ ldr r2, [r1, #oNFCONF]
+ bic r2, r2, #0x800 @ enable chip
+ str r2, [r1, #oNFCONF]
+ mov r2, #0xff @ RESET command
+ strb r2, [r1, #oNFCMD]
+ mov r3, #0 @ wait
+1: add r3, r3, #0x1
+ cmp r3, #0xa
+ blt 1b
+2: ldr r2, [r1, #oNFSTAT] @ wait ready
+ tst r2, #0x1
+ beq 2b
+ ldr r2, [r1, #oNFCONF]
+ orr r2, r2, #0x800 @ disable chip
+ str r2, [r1, #oNFCONF]
+
+#if 0
+ @ get ready to call C functions (for nand_read())
+ ldr sp, DW_STACK_START @ setup stack pointer
+ mov fp, #0 @ no previous frame, so fp=0
+#else
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+#endif
+
+ @ copy u-boot to RAM
+ ldr r0, _TEXT_BASE
+ mov r1, #0x0
+ mov r2, #CFG_UBOOT_SIZE
+ bl nand_read_ll
+
+ tst r0, #0x0
+ beq ok_nand_read
+#ifdef CONFIG_DEBUG_LL
+bad_nand_read:
+ ldr r0, STR_FAIL
+ ldr r1, SerBase
+ bl PrintWord
+1: b 1b @ infinite loop
+#endif
+
+ok_nand_read:
+#ifdef CONFIG_DEBUG_LL
+ ldr r0, STR_OK
+ ldr r1, SerBase
+ bl PrintWord
+#endif
+
+ @ verify
+ mov r0, #0
+ @ldr r1, =0x33f00000
+ ldr r1, _TEXT_BASE
+ mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
+go_next:
+ ldr r3, [r0], #4
+ ldr r4, [r1], #4
+ teq r3, r4
+ bne notmatch
+ subs r2, r2, #4
+ beq done_nand_read
+ bne go_next
+notmatch:
+#ifdef CONFIG_DEBUG_LL
+ sub r0, r0, #4
+ ldr r1, SerBase
+ bl PrintHexWord
+ ldr r0, STR_FAIL
+ ldr r1, SerBase
+ bl PrintWord
+#endif
+1: b 1b
+done_nand_read:
+#endif /* NAND_BOOT */
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
Index: u-boot/include/s3c2410.h
===================================================================
--- u-boot.orig/include/s3c2410.h 2007-02-28 03:51:24.000000000 +0100
+++ u-boot/include/s3c2410.h 2007-03-01 14:29:22.000000000 +0100
@@ -38,12 +38,6 @@
#define S3C2410_ECCSIZE 512
#define S3C2410_ECCBYTES 3
-typedef enum {
- S3C24X0_UART0,
- S3C24X0_UART1,
- S3C24X0_UART2
-} S3C24X0_UARTS_NR;
-
/* S3C2410 device base addresses */
#define S3C24X0_MEMCTL_BASE 0x48000000
#define S3C24X0_USB_HOST_BASE 0x49000000
@@ -65,9 +59,23 @@
#define S3C2410_SDI_BASE 0x5A000000
+#define oNFCONF 0x00
+#define oNFCMD 0x04
+#define oNFADDR 0x08
+#define oNFDATA 0x0C
+#define oNFSTAT 0x10
+#define oNFECC 0x14
+
+#ifndef __ASSEMBLER__
+
/* include common stuff */
#include <s3c24x0.h>
+typedef enum {
+ S3C24X0_UART0,
+ S3C24X0_UART1,
+ S3C24X0_UART2
+} S3C24X0_UARTS_NR;
static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
{
@@ -142,6 +150,7 @@
return (S3C2410_SDI * const)S3C2410_SDI_BASE;
}
+#endif
/* ISR */
#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))

View File

@ -0,0 +1,32 @@
If we've somehow magically make u-boot end up in RAM (JTAG, ...), then that RAM
is mapped to 0x30000000 and not 0, so we need to copy the interrupt vectors, etc.
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -332,7 +332,23 @@ done_nand_read:
strb r1, [r0]
#endif /* CONFIG_S3C2410_NAND_BOOT */
done_relocate:
-#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+
+#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C2410)
+ /* In the case of the S3C2410, if we've somehow magically (JTAG, ...)
+ ended up in RAM, then that ram is mapped to 0x30000000 and not 0.
+ So we need to copy the interrupt vectors, etc. */
+
+ mov r0, #0
+ ldr r1, _TEXT_BASE
+ mov r2, #0x40
+irqvec_cpy_next:
+ ldr r3, [r1], #4
+ str r3, [r0], #4
+ subs r2, r2, #4
+ bne irqvec_cpy_next
+#endif /* CONFIG_USE_IRQ */
+
+#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
/* Set up the stack */
stack_setup:

View File

@ -0,0 +1,98 @@
Index: u-boot/include/s3c2410.h
===================================================================
--- u-boot.orig/include/s3c2410.h 2007-02-16 23:53:20.000000000 +0100
+++ u-boot/include/s3c2410.h 2007-02-16 23:53:21.000000000 +0100
@@ -69,75 +69,75 @@
#include <s3c24x0.h>
-static inline S3C24X0_MEMCTL * const S3C24X0_GetBase_MEMCTL(void)
+static inline S3C24X0_MEMCTL * S3C24X0_GetBase_MEMCTL(void)
{
return (S3C24X0_MEMCTL * const)S3C24X0_MEMCTL_BASE;
}
-static inline S3C24X0_USB_HOST * const S3C24X0_GetBase_USB_HOST(void)
+static inline S3C24X0_USB_HOST * S3C24X0_GetBase_USB_HOST(void)
{
return (S3C24X0_USB_HOST * const)S3C24X0_USB_HOST_BASE;
}
-static inline S3C24X0_INTERRUPT * const S3C24X0_GetBase_INTERRUPT(void)
+static inline S3C24X0_INTERRUPT * S3C24X0_GetBase_INTERRUPT(void)
{
return (S3C24X0_INTERRUPT * const)S3C24X0_INTERRUPT_BASE;
}
-static inline S3C24X0_DMAS * const S3C24X0_GetBase_DMAS(void)
+static inline S3C24X0_DMAS * S3C24X0_GetBase_DMAS(void)
{
return (S3C24X0_DMAS * const)S3C24X0_DMA_BASE;
}
-static inline S3C24X0_CLOCK_POWER * const S3C24X0_GetBase_CLOCK_POWER(void)
+static inline S3C24X0_CLOCK_POWER * S3C24X0_GetBase_CLOCK_POWER(void)
{
return (S3C24X0_CLOCK_POWER * const)S3C24X0_CLOCK_POWER_BASE;
}
-static inline S3C24X0_LCD * const S3C24X0_GetBase_LCD(void)
+static inline S3C24X0_LCD * S3C24X0_GetBase_LCD(void)
{
return (S3C24X0_LCD * const)S3C24X0_LCD_BASE;
}
-static inline S3C2410_NAND * const S3C2410_GetBase_NAND(void)
+static inline S3C2410_NAND * S3C2410_GetBase_NAND(void)
{
return (S3C2410_NAND * const)S3C2410_NAND_BASE;
}
-static inline S3C24X0_UART * const S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
+static inline S3C24X0_UART * S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)
{
return (S3C24X0_UART * const)(S3C24X0_UART_BASE + (nr * 0x4000));
}
-static inline S3C24X0_TIMERS * const S3C24X0_GetBase_TIMERS(void)
+static inline S3C24X0_TIMERS * S3C24X0_GetBase_TIMERS(void)
{
return (S3C24X0_TIMERS * const)S3C24X0_TIMER_BASE;
}
-static inline S3C24X0_USB_DEVICE * const S3C24X0_GetBase_USB_DEVICE(void)
+static inline S3C24X0_USB_DEVICE * S3C24X0_GetBase_USB_DEVICE(void)
{
return (S3C24X0_USB_DEVICE * const)S3C24X0_USB_DEVICE_BASE;
}
-static inline S3C24X0_WATCHDOG * const S3C24X0_GetBase_WATCHDOG(void)
+static inline S3C24X0_WATCHDOG * S3C24X0_GetBase_WATCHDOG(void)
{
return (S3C24X0_WATCHDOG * const)S3C24X0_WATCHDOG_BASE;
}
-static inline S3C24X0_I2C * const S3C24X0_GetBase_I2C(void)
+static inline S3C24X0_I2C * S3C24X0_GetBase_I2C(void)
{
return (S3C24X0_I2C * const)S3C24X0_I2C_BASE;
}
-static inline S3C24X0_I2S * const S3C24X0_GetBase_I2S(void)
+static inline S3C24X0_I2S * S3C24X0_GetBase_I2S(void)
{
return (S3C24X0_I2S * const)S3C24X0_I2S_BASE;
}
-static inline S3C24X0_GPIO * const S3C24X0_GetBase_GPIO(void)
+static inline S3C24X0_GPIO * S3C24X0_GetBase_GPIO(void)
{
return (S3C24X0_GPIO * const)S3C24X0_GPIO_BASE;
}
-static inline S3C24X0_RTC * const S3C24X0_GetBase_RTC(void)
+static inline S3C24X0_RTC * S3C24X0_GetBase_RTC(void)
{
return (S3C24X0_RTC * const)S3C24X0_RTC_BASE;
}
-static inline S3C2410_ADC * const S3C2410_GetBase_ADC(void)
+static inline S3C2410_ADC * S3C2410_GetBase_ADC(void)
{
return (S3C2410_ADC * const)S3C2410_ADC_BASE;
}
-static inline S3C24X0_SPI * const S3C24X0_GetBase_SPI(void)
+static inline S3C24X0_SPI * S3C24X0_GetBase_SPI(void)
{
return (S3C24X0_SPI * const)S3C24X0_SPI_BASE;
}
-static inline S3C2410_SDI * const S3C2410_GetBase_SDI(void)
+static inline S3C2410_SDI * S3C2410_GetBase_SDI(void)
{
return (S3C2410_SDI * const)S3C2410_SDI_BASE;
}

View File

@ -0,0 +1,215 @@
Index: u-boot/drivers/Makefile
===================================================================
--- u-boot.orig/drivers/Makefile
+++ u-boot/drivers/Makefile
@@ -52,7 +52,7 @@
ks8695eth.o \
pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o \
rpx_pcmcia.o \
- fsl_i2c.o
+ fsl_i2c.o s3c2410_fb.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
Index: u-boot/drivers/s3c2410_fb.c
===================================================================
--- /dev/null
+++ u-boot/drivers/s3c2410_fb.c
@@ -0,0 +1,166 @@
+/*
+ * (C) Copyright 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_VIDEO_S3C2410)
+
+#include <video_fb.h>
+#include "videomodes.h"
+#include <s3c2410.h>
+/*
+ * Export Graphic Device
+ */
+GraphicDevice smi;
+
+#define VIDEO_MEM_SIZE 0x200000 /* 480x640x16bit = 614400 bytes */
+
+extern void board_video_init(GraphicDevice *pGD);
+
+/*******************************************************************************
+ *
+ * Init video chip with common Linux graphic modes (lilo)
+ */
+void *video_hw_init (void)
+{
+ S3C24X0_LCD * const lcd = S3C24X0_GetBase_LCD();
+ GraphicDevice *pGD = (GraphicDevice *)&smi;
+ int videomode;
+ unsigned long t1, hsynch, vsynch;
+ char *penv;
+ int tmp, i, bits_per_pixel;
+ struct ctfb_res_modes *res_mode;
+ struct ctfb_res_modes var_mode;
+ unsigned char videoout;
+
+ /* Search for video chip */
+ printf("Video: ");
+
+ tmp = 0;
+
+ videomode = CFG_DEFAULT_VIDEO_MODE;
+ /* get video mode via environment */
+ if ((penv = getenv ("videomode")) != NULL) {
+ /* deceide if it is a string */
+ if (penv[0] <= '9') {
+ videomode = (int) simple_strtoul (penv, NULL, 16);
+ tmp = 1;
+ }
+ } else {
+ tmp = 1;
+ }
+ if (tmp) {
+ /* parameter are vesa modes */
+ /* search params */
+ for (i = 0; i < VESA_MODES_COUNT; i++) {
+ if (vesa_modes[i].vesanr == videomode)
+ break;
+ }
+ if (i == VESA_MODES_COUNT) {
+ printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
+ i = 0;
+ }
+ res_mode =
+ (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+ resindex];
+ bits_per_pixel = vesa_modes[i].bits_per_pixel;
+ } else {
+
+ res_mode = (struct ctfb_res_modes *) &var_mode;
+ bits_per_pixel = video_get_params (res_mode, penv);
+ }
+
+ /* calculate hsynch and vsynch freq (info only) */
+ t1 = (res_mode->left_margin + res_mode->xres +
+ res_mode->right_margin + res_mode->hsync_len) / 8;
+ t1 *= 8;
+ t1 *= res_mode->pixclock;
+ t1 /= 1000;
+ hsynch = 1000000000L / t1;
+ t1 *=
+ (res_mode->upper_margin + res_mode->yres +
+ res_mode->lower_margin + res_mode->vsync_len);
+ t1 /= 1000;
+ vsynch = 1000000000L / t1;
+
+ /* fill in Graphic device struct */
+ sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+ res_mode->yres, bits_per_pixel, (hsynch / 1000),
+ (vsynch / 1000));
+ printf ("%s\n", pGD->modeIdent);
+ pGD->winSizeX = res_mode->xres;
+ pGD->winSizeY = res_mode->yres;
+ pGD->plnSizeX = res_mode->xres;
+ pGD->plnSizeY = res_mode->yres;
+ switch (bits_per_pixel) {
+ case 8:
+ pGD->gdfBytesPP = 1;
+ pGD->gdfIndex = GDF__8BIT_INDEX;
+ break;
+ case 15:
+ pGD->gdfBytesPP = 2;
+ pGD->gdfIndex = GDF_15BIT_555RGB;
+ break;
+ case 16:
+ pGD->gdfBytesPP = 2;
+ pGD->gdfIndex = GDF_16BIT_565RGB;
+ break;
+ case 24:
+ pGD->gdfBytesPP = 3;
+ pGD->gdfIndex = GDF_24BIT_888RGB;
+ break;
+ }
+
+ /* statically configure settings */
+ pGD->winSizeX = pGD->plnSizeX = 480;
+ pGD->winSizeY = pGD->plnSizeY = 640;
+ pGD->gdfBytesPP = 2;
+ pGD->gdfIndex = GDF_16BIT_565RGB;
+
+ pGD->frameAdrs = LCD_VIDEO_ADDR;
+ pGD->memSize = VIDEO_MEM_SIZE;
+
+ board_video_init(pGD);
+
+ lcd->LCDSADDR1 = pGD->frameAdrs >> 1;
+
+ /* This marks the end of the frame buffer. */
+ lcd->LCDSADDR2 = (lcd->LCDSADDR1&0x1fffff) + (pGD->winSizeX+0) * pGD->winSizeY;
+ lcd->LCDSADDR3 = pGD->winSizeX;
+
+ /* Clear video memory */
+ memset(pGD->frameAdrs, 0, pGD->memSize);
+
+ /* Enable Display */
+ lcd->LCDCON1 |= 0x01; /* ENVID = 1 */
+
+ return ((void*)&smi);
+}
+
+void
+video_set_lut (unsigned int index, /* color number */
+ unsigned char r, /* red */
+ unsigned char g, /* green */
+ unsigned char b /* blue */
+ )
+{
+}
+
+#endif /* CONFIG_VIDEO_S3C2410 */
Index: u-boot/drivers/cfb_console.c
===================================================================
--- u-boot.orig/drivers/cfb_console.c
+++ u-boot/drivers/cfb_console.c
@@ -141,6 +141,14 @@
#endif
/*****************************************************************************/
+/* Defines for the S3C2410 driver */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_S3C2410
+/* it actually is little-endian, but the host CPU, too ! */
+//#define VIDEO_FB_LITTLE_ENDIAN
+#endif
+
+/*****************************************************************************/
/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */
/*****************************************************************************/
#include <video_fb.h>
@@ -307,6 +315,11 @@
#define SHORTSWAP32(x) (x)
#endif
+#ifdef CONFIG_VIDEO_S3C2410
+#undef SHORTSWAP32
+#define SHORTSWAP32(x) ((((x) & 0xffff) << 16) | (((x) >> 16) & 0xffff))
+#endif
+
#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
#define PRINTD(x) printf(x)
#else

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,256 @@
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -35,6 +35,8 @@
#include <s3c2410.h>
#elif defined(CONFIG_S3C2440)
#include <s3c2440.h>
+#elif defined(CONFIG_S3C2443)
+#include <s3c2443.h>
#endif
@@ -164,9 +166,15 @@
# define UPLLCON_val ((0x3c << 12) + (0x4 << 4) + 0x2)
# define CLKDIVN_val 7 /* FCLK:HCLK:PCLK = 1:3:6 */
# define CAMDIVN 0x4C000018
+#elif defined(CONFIG_S3C2443)
+# define INTSUBMSK_val 0x1fffffff
+# define EPLLCON_val ((40 << 16) | (1 << 8) | (1)) /* 96 MHz */
+# define MPLLCON_val ((81 << 16) | (2 << 8) | (0)) /* 1068 MHz */
+# define CLKDIV0_val ((8 << 9) | (1 << 4) | (1 << 3) | (1 << 2)
#endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+ defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443)
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
@@ -177,7 +185,7 @@
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
-# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
+# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443)
ldr r1, =INTSUBMSK_val
ldr r0, =INTSUBMSK
str r1, [r0]
@@ -196,6 +204,43 @@
mcr p15, 0, r1, c1, c0, 0
+#if defined(CONFIG_S3C2443)
+#define LOCKCON0 0x4c000000
+#define LOCKCON1 0x4c000004
+#define MPLLCON 0x4c000010
+#define EPLLCON 0x4c000018
+
+ ldr r0, =CLKDIV0
+ ldr r1, =CLKDIV0_val
+ str r1, [r0]
+
+ /* set safe (way too long) locktime for both PLLs */
+ ldr r0, =LOCKCON0
+ mov r1, #0xffffff
+ str r1, [r0]
+ ldr r0, =LOCKCON1
+ str r1, [r0]
+
+ /* configure MPLL */
+ ldr r0, =MPLLCON
+ ldr r1, =MPLLCON_val
+ str r1, [r0]
+
+ /* select MPLL clock out for SYSCLK */
+ ldr r0, =CLKSRC
+ ldr r1, [r0]
+ orr r1, r1, #0x10
+ str r1, [r0]
+
+#if 0
+ /* configure EPLL */
+ ldr r0, =EPLLCON
+ ldr r1, =EPLLCON_val
+ str r1, [r0]
+#endif
+
+
+#else /* i.e. 2440, 2410 and 2440 */
#define LOCKTIME 0x4c000000
#define UPLLCON 0x4c000008
@@ -223,6 +268,7 @@
ldr r0, =CLKDIVN
mov r1, #CLKDIVN_val
str r1, [r0]
+#endif
#if 1
/* enable uart */
@@ -249,7 +295,7 @@
str r1, [r0, #0x28]
#endif
-#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 */
+#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 || CONFIG_S3C2443 */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#ifndef CONFIG_LL_INIT_NAND_ONLY
Index: u-boot/cpu/arm920t/s3c24x0/interrupts.c
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/interrupts.c
+++ u-boot/cpu/arm920t/s3c24x0/interrupts.c
@@ -31,7 +31,8 @@
#include <common.h>
#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || \
- defined(CONFIG_S3C2440) || defined (CONFIG_TRAB)
+ defined(CONFIG_S3C2440) || defined(CONFIG_S3C2443) || \
+ defined (CONFIG_TRAB)
#include <arm920t.h>
#if defined(CONFIG_S3C2400)
@@ -40,6 +41,8 @@
#include <s3c2410.h>
#elif defined(CONFIG_S3C2440)
#include <s3c2440.h>
+#elif defined(CONFIG_S3C2443)
+#include <s3c2443.h>
#endif
int timer_load_val = 0;
@@ -186,6 +189,7 @@
#elif defined(CONFIG_SBC2410X) || \
defined(CONFIG_SMDK2410) || \
defined(CONFIG_SMDK2440) || \
+ defined(CONFIG_SMDK2443) || \
defined(CONFIG_VCMA9)
tbclk = CFG_HZ;
#else
Index: u-boot/drivers/usbdcore_s3c2410.c
===================================================================
--- u-boot.orig/drivers/usbdcore_s3c2410.c
+++ u-boot/drivers/usbdcore_s3c2410.c
@@ -24,7 +24,8 @@
#include <config.h>
-#if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)) && defined(CONFIG_USB_DEVICE)
+#if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || \
+ defined(CONFIG_S3C2443)) && defined(CONFIG_USB_DEVICE)
#include <common.h>
Index: u-boot/include/s3c2443.h
===================================================================
--- /dev/null
+++ u-boot/include/s3c2443.h
@@ -0,0 +1,106 @@
+/*
+ * (C) Copyright 2007 OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __S3C2443_H
+#define __S3C2443_H
+
+#include <s3c24x0.h>
+
+/* CLOCK & POWER MANAGEMENT (see S3C2443 manual chapter 2) */
+typedef struct {
+ S3C24X0_REG32 LOCKCON0;
+ S3C24X0_REG32 LOCKCON1;
+ S3C24X0_REG32 OSCSET;
+ S3C24X0_REG32 res1;
+ S3C24X0_REG32 MPLLCON;
+ S3C24X0_REG32 res2;
+ S3C24X0_REG32 EPLLCON;
+ S3C24X0_REG32 res3;
+ S3C24X0_REG32 CLKSRC;
+ S3C24X0_REG32 CLKDIV0;
+ S3C24X0_REG32 CLKDIV1;
+ S3C24X0_REG32 res4;
+ S3C24X0_REG32 HCLKCON;
+ S3C24X0_REG32 PCLKCON;
+ S3C24X0_REG32 SCLKCON;
+ S3C24X0_REG32 res5;
+ S3C24X0_REG32 PWRMODE;
+ S3C24X0_REG32 SWRST;
+ S3C24X0_REG32 res6[2];
+ S3C24X0_REG32 BUSPRI0;
+ S3C24X0_REG32 res7[3];
+} /*__attribute__((__packed__))*/ S3C2443_CLOCK_POWER;
+
+/* NAND FLASH (see S3C2443 manual chapter 7) */
+typedef struct {
+ S3C24X0_REG32 NFCONF;
+ S3C24X0_REG32 NFCONT;
+ S3C24X0_REG32 NFCMD;
+ S3C24X0_REG32 NFADDR;
+ S3C24X0_REG32 NFDATA;
+ S3C24X0_REG32 NFMECCD0;
+ S3C24X0_REG32 NFMECCD1;
+ S3C24X0_REG32 NFSECCD;
+ S3C24X0_REG32 NFSBLK;
+ S3C24X0_REG32 NFEBLK;
+ S3C24X0_REG32 NFSTAT;
+ S3C24X0_REG32 NFECCERR0;
+ S3C24X0_REG32 NFECCERR1;
+ S3C24X0_REG32 NFMECC0;
+ S3C24X0_REG32 NFMECC1;
+ S3C24X0_REG32 NFSECC;
+ S3C24X0_REG32 NFMLCBITPT;
+} /*__attribute__((__packed__))*/ S3C2443_NAND;
+
+/* STATIC MEMORY (see S3C2443 manual chapter 5) */
+struct s3c2443_sm_bank {
+ S3C24X0_REG32 SMBIDCYR;
+ S3C24X0_REG32 SMBWSTRDR;
+ S3C24X0_REG32 SMBWSTWRR;
+ S3C24X0_REG32 SMBWSTOENR;
+ S3C24X0_REG32 SMBWSTWENR;
+ S3C24X0_REG32 SMBCR;
+ S3C24X0_REG32 SMBSR;
+ S3C24X0_REG32 SMBWSTBRDR;
+};
+
+typedef struct {
+ struct s3c2443_sm_bank bank[5]; /* 0x4f000000..0x4f0000bf */
+ S3C24X0_REG32 res[0x40]; /* 0x4f0000c0..0x4f0000ff */
+ S3C24X0_REG32 SMBONETYPER;
+ S3C24X0_REG32 SMCSR;
+ S3C24X0_REG32 SMCCR;
+} /*__attribute__((__packed__))*/ S3C2443_SMEM;
+
+
+/* MOBILE DRAM (see S3C2443 manual chapter 6) */
+typedef struct {
+ S3C24X0_REG32 BANKCFG;
+ S3C24X0_REG32 BANKCON1;
+ S3C24X0_REG32 BANKCON2;
+ S3C24X0_REG32 BANKCON3;
+ S3C24X0_REG32 REFRESH;
+ S3C24X0_REG32 TIMEOUT;
+} /*__attribute__((__packed__))*/ S3C2443_MDRAM
+
+#endif /* __S3C2443_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
Make simple_strtoul work with upper-case hex numbers.
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/lib_generic/vsprintf.c
===================================================================
--- u-boot.orig/lib_generic/vsprintf.c
+++ u-boot/lib_generic/vsprintf.c
@@ -25,21 +25,22 @@ unsigned long simple_strtoul(const char
{
unsigned long result = 0,value;
- if (*cp == '0') {
- cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
- base = 16;
- cp++;
- }
- if (!base) {
- base = 8;
- }
- }
if (!base) {
base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ } else if (base == 16) {
+ if (cp[0] == '0' && toupper(cp[1]) == 'X')
+ cp += 2;
}
- while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
- ? toupper(*cp) : *cp)-'A'+10) < base) {
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
result = result*base + value;
cp++;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
board/neo1973/gta01/gta01.c: added logic to detect pending PMU interrupts
board/neo1973/gta01/gta01.c (neo1973_new_second, neo1973_on_key_pressed): only
poll PMU if there is a pending interrupt
board/neo1973/gta01/pcf50606.c (pcf50606_initial_regs): cleared (unmasked)
SECONDM in INT1M
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/board/neo1973/gta01/gta01.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/gta01.c
+++ u-boot/board/neo1973/gta01/gta01.c
@@ -375,19 +375,60 @@
#endif
}
+static int pwr_int_pending(void)
+{
+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
+#if defined(CONFIG_ARCH_GTA01B_v4)
+ return !(gpio->GPGDAT & (1 << 1)); /* EINT9/GPG1 */
+#else
+ return !(gpio->GPGDAT & (1 << 8)); /* EINT16/GPG8 */
+#endif /* !CONFIG_ARCH_GTA01B_v4 */
+}
+
+static int have_int1(uint8_t mask)
+{
+ static uint8_t pending = 0;
+
+ if (pwr_int_pending()) {
+ /*
+ * We retrieve all interupts, so that we clear any stray ones
+ * in INT2 and INT3.
+ */
+ uint8_t int1,int2,int3;
+
+ int1 = pcf50606_reg_read(PCF50606_REG_INT1);
+ int2 = pcf50606_reg_read(PCF50606_REG_INT2);
+ int3 = pcf50606_reg_read(PCF50606_REG_INT3);
+ pending |= int1;
+ }
+ if (!(pending & mask))
+ return 0;
+ pending &= ~mask;
+ return 1;
+}
+
int neo1973_new_second(void)
{
- return pcf50606_reg_read(PCF50606_REG_INT1) & PCF50606_INT1_SECOND;
+ return have_int1(PCF50606_INT1_SECOND);
}
int neo1973_on_key_pressed(void)
{
- return !(pcf50606_reg_read(PCF50606_REG_OOCS) & PFC50606_OOCS_ONKEY);
+ static int pressed = -1;
+
+ if (pressed == -1 ||
+ have_int1(PCF50606_INT1_ONKEYF | PCF50606_INT1_ONKEYR)) {
+ pressed = !(pcf50606_reg_read(PCF50606_REG_OOCS) &
+ PFC50606_OOCS_ONKEY);
+}
+ return pressed;
}
int neo1973_aux_key_pressed(void)
{
S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
+
if (gpio->GPFDAT & (1 << 6))
return 0;
return 1;
Index: u-boot/board/neo1973/gta01/pcf50606.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/pcf50606.c
+++ u-boot/board/neo1973/gta01/pcf50606.c
@@ -6,7 +6,7 @@
const u_int8_t pcf50606_initial_regs[__NUM_PCF50606_REGS] = {
[PCF50606_REG_OOCS] = 0x00,
/* gap */
- [PCF50606_REG_INT1M] = PCF50606_INT1_SECOND,
+ [PCF50606_REG_INT1M] = 0x00,
[PCF50606_REG_INT2M] = 0x00,
[PCF50606_REG_INT3M] = PCF50606_INT3_TSCPRES,
[PCF50606_REG_OOCC1] = PCF50606_OOCC1_RTCWAK |

View File

@ -0,0 +1,63 @@
This patch fixes bugs in usbdcore*.c related to the use of devices
with multiple configurations.
The original code made mistakes about the meaning of configuration value and
configuration index, and the resulting off-by-one errors resulted in:
* SET_CONFIGURATION always selected the first configuration, no matter what
wValue is being passed.
* GET_DESCRIPTOR/CONFIGURATION always returned the descriptor for the first
configuration (index 0).
Signed-off-by: Harald Welte <laforge@openmoko.org>
Index: u-boot/drivers/usbdcore_ep0.c
===================================================================
--- u-boot.orig/drivers/usbdcore_ep0.c 2007-03-14 20:29:05.000000000 +0100
+++ u-boot/drivers/usbdcore_ep0.c 2007-03-14 20:29:06.000000000 +0100
@@ -233,8 +233,8 @@
return -1;
}
/*dbg_ep0(2, "%d %d", index, device_descriptor->bNumConfigurations); */
- if (index > device_descriptor->bNumConfigurations) {
- dbg_ep0 (0, "index too large: %d > %d", index,
+ if (index >= device_descriptor->bNumConfigurations) {
+ dbg_ep0 (0, "index too large: %d >= %d", index,
device_descriptor->
bNumConfigurations);
return -1;
@@ -593,13 +593,8 @@
case USB_REQ_SET_CONFIGURATION:
/* c.f. 9.4.7 - the top half of wValue is reserved */
- /* */
- if ((device->configuration =
- le16_to_cpu (request->wValue) & 0x7f) != 0) {
- /* c.f. 9.4.7 - zero is the default or addressed state, in our case this */
- /* is the same is configuration zero */
- device->configuration = 0; /* TBR - ?????? */
- }
+ device->configuration = le16_to_cpu(request->wValue) & 0xff;
+
/* reset interface and alternate settings */
device->interface = device->alternate = 0;
Index: u-boot/drivers/usbdcore.c
===================================================================
--- u-boot.orig/drivers/usbdcore.c 2007-03-14 20:29:05.000000000 +0100
+++ u-boot/drivers/usbdcore.c 2007-03-14 20:37:37.000000000 +0100
@@ -147,12 +147,9 @@
static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
unsigned int port, unsigned int configuration)
{
- /* XXX */
- configuration = configuration ? configuration - 1 : 0;
-
- if (configuration >= device->configurations) {
+ if (configuration >= device->configurations)
return NULL;
- }
+
return device->configuration_instance_array + configuration;
}

View File

@ -0,0 +1,68 @@
This patch should get rid of spurious poweroff after booting from RAM.
Experimental.
cpu/arm920t/start.S: record in global variable "booted_from_nand" whether we
booted from NAND or not
board/neo1973/neo1973.c (board_late_init): if booted from RAM, assume that
wakeup cause was "reset", and skip poweroff check
- Werner Almesberger <werner@openmoko.org>
Index: u-boot/board/neo1973/gta01/gta01.c
===================================================================
--- u-boot.orig/board/neo1973/gta01/gta01.c
+++ u-boot/board/neo1973/gta01/gta01.c
@@ -226,12 +226,16 @@
int board_late_init(void)
{
+ extern unsigned char booted_from_nand;
unsigned char tmp;
char buf[32];
/* Initialize the Power Management Unit with a safe register set */
pcf50606_init();
+ if (!booted_from_nand)
+ goto woken_by_reset;
+
/* obtain wake-up reason, save INT1 in environment */
tmp = pcf50606_reg_read(PCF50606_REG_INT1);
sprintf(buf, "0x%02x", tmp);
@@ -274,6 +278,7 @@
neo1973_poweroff();
}
+woken_by_reset:
/* if there's no other reason, must be regular reset */
neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -77,6 +77,14 @@
*************************************************************************
*/
+#ifdef CONFIG_S3C2410_NAND_BOOT
+.globl booted_from_nand
+booted_from_nand:
+ .word 0
+_booted_from_nand:
+ .word booted_from_nand
+#endif /* CONFIG_S3C2410_NAND_BOOT */
+
_TEXT_BASE:
.word TEXT_BASE
@@ -281,6 +289,9 @@
#endif
1: b 1b
done_nand_read:
+ ldr r0, _booted_from_nand
+ mov r1, #1
+ strb r1, [r0]
#endif /* CONFIG_S3C2410_NAND_BOOT */
done_relocate:
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

View File

@ -0,0 +1,83 @@
require uboot-openmoko_svn.bb
PV = "1.2.0+git9912121f7ed804ea58fd62f3f230b5dcfc357d88svn2238"
SRC_URI = "git://www.denx.de/git/u-boot.git/;protocol=git;tag=9912121f7ed804ea58fd62f3f230b5dcfc357d88 \
file://uboot-machtypes.patch;patch=1 \
file://ext2load_hex.patch;patch=1 \
file://uboot-s3c2410-warnings-fix.patch;patch=1 \
file://uboot-strtoul.patch;patch=1 \
file://uboot-cramfs_but_no_jffs2.patch;patch=1 \
file://nand-read_write_oob.patch;patch=1 \
file://uboot-arm920t-gd_in_irq.patch;patch=1 \
file://uboot-arm920_s3c2410_irq_demux.patch;patch=1 \
file://uboot-s3c2410-nand.patch;patch=1 \
file://uboot-cmd_s3c2410.patch;patch=1 \
file://uboot-s3c2410-mmc.patch;patch=1 \
file://env_nand_oob.patch;patch=1 \
file://dynenv-harden.patch;patch=1 \
file://uboot-s3c2410_fb.patch;patch=1 \
file://uboot-20061030-qt2410.patch;patch=1 \
file://uboot-20061030-neo1973.patch;patch=1 \
file://uboot-s3c2410-misccr-definitions.patch;patch=1 \
file://boot-from-ram-reloc.patch;patch=1 \
file://boot-from-ram-and-nand.patch;patch=1 \
file://wakeup-reason-nand-only.patch;patch=1 \
file://uboot-neo1973-resume.patch;patch=1 \
file://nand-dynamic_partitions.patch;patch=1 \
file://uboot-s3c2410-norelocate_irqvec_cpy.patch;patch=1 \
file://uboot-usbtty-acm.patch;patch=1 \
file://uboot-s3c2410_udc.patch;patch=1 \
file://bbt-create-optional.patch;patch=1 \
file://nand-createbbt.patch;patch=1 \
file://dontask.patch;patch=1 \
file://nand-badisbad.patch;patch=1 \
file://uboot-bbt-quiet.patch;patch=1 \
file://raise-limits.patch;patch=1 \
file://splashimage-command.patch;patch=1 \
file://cmd-unzip.patch;patch=1 \
file://enable-splash-bmp.patch;patch=1 \
file://preboot-override.patch;patch=1 \
file://lowlevel_foo.patch;patch=1 \
file://default-env.patch;patch=1 \
file://console-ansi.patch;patch=1 \
file://boot-menu.patch;patch=1 \
file://uboot-dfu.patch;patch=1 \
file://uboot-neo1973-defaultenv.patch;patch=1 \
file://uboot-nand-markbad-reallybad.patch;patch=1 \
file://usbdcore-multiple_configs.patch;patch=1 \
file://neo1973-chargefast.patch;patch=1 \
file://uboot-s3c2440.patch;patch=1 \
file://uboot-smdk2440.patch;patch=1 \
file://uboot-hxd8.patch;patch=1 \
file://uboot-license.patch;patch=1 \
file://uboot-gta02.patch;patch=1 \
file://uboot-s3c2443.patch;patch=1 \
file://uboot-smdk2443.patch;patch=1 \
file://unbusy-i2c.patch;patch=1 \
file://makefile-no-dirafter.patch;patch=1 \
"
PROVIDES = ""
TARGET_LDFLAGS = ""
do_quilt() {
:
}
do_compile () {
chmod +x board/neo1973/gta01/split_by_variant.sh
oe_runmake gta01bv3_config
oe_runmake clean
oe_runmake tools
}
do_deploy () {
install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
ln -sf ${STAGING_BINDIR_NATIVE}/uboot-mkimage ${STAGING_BINDIR_NATIVE}/mkimage
}
do_deploy[dirs] = "${S}"
addtask deploy before do_package after do_install

View File

@ -1,59 +0,0 @@
DESCRIPTION = "U-boot bootloader w/ Neo1973 (GTA01) support"
AUTHOR = "Harald Welte <laforge@openmoko.org>"
LICENSE = "GPL"
SECTION = "bootloader"
PRIORITY = "optional"
PV = "1.2.0+svn${SRCDATE}"
PR = "r5"
SRCDATE = "20070711"
PROVIDES = "virtual/bootloader"
S = "${WORKDIR}/git"
SRC_URI = "git://www.denx.de/git/u-boot.git/;protocol=git;tag=8993e54b6f397973794f3d6f47d3b3c0c98dd4f6 \
svn://svn.openmoko.org/trunk/src/target/u-boot;module=patches;proto=http \
file://fix-arm920t-eabi.patch;patch=1"
EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}"
TARGET_LDFLAGS = ""
UBOOT_MACHINES = "gta01v3 gta01v4 gta01bv2 gta01bv3"
do_quilt() {
mv ${WORKDIR}/patches ${S}/patches
cd ${S}
quilt push -av
rm -Rf patches .pc
}
do_compile () {
chmod +x board/neo1973/split_by_variant.sh
for type in ram nand
do
for mach in ${UBOOT_MACHINES}
do
oe_runmake ${mach}_config
oe_runmake clean
if [ ${type} == "ram" ]; then
echo 'PLATFORM_RELFLAGS += -DBUILD_FOR_RAM' >> board/neo1973/config.tmp
fi
oe_runmake all
mv u-boot.bin u-boot_${mach}_${type}.bin
done
done
}
do_deploy () {
install -d ${DEPLOY_DIR_IMAGE}
for type in nand ram
do
for mach in ${UBOOT_MACHINES}
do
install ${S}/u-boot_${mach}_${type}.bin ${DEPLOY_DIR_IMAGE}/u-boot_${type}-${mach}-${DATETIME}.bin
done
done
install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
}
do_deploy[dirs] = "${S}"
addtask deploy before do_build after do_compile
addtask quilt before do_patch after do_unpack

View File

@ -0,0 +1,85 @@
DESCRIPTION = "U-boot bootloader w/ Neo1973 (GTA01) support"
AUTHOR = "Harald Welte <laforge@openmoko.org>"
LICENSE = "GPL"
SECTION = "bootloader"
PRIORITY = "optional"
PROVIDES = "virtual/bootloader"
PV = "1.2.0+git${SRCDATE}+svnr${SRCREV}"
PR = "r1"
SRCREV_FORMAT = "patches"
UBOOT_MACHINES = "gta01bv2 gta01bv3 gta01bv4 smdk2440 hxd8 qt2410 gta02v1 gta02v2"
DEFAULT_PREFERENCE = "-1"
SRC_URI = "\
git://www.denx.de/git/u-boot.git/;protocol=git;name=upstream \
svn://svn.openmoko.org/trunk/src/target/u-boot;module=patches;proto=http;name=patches \
file://uboot-eabi-fix-HACK.patch \
file://uboot-20070311-tools_makefile_ln_sf.patch;patch=1 \
"
S = "${WORKDIR}/git"
EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX}"
TARGET_LDFLAGS = ""
do_quilt() {
mv ${WORKDIR}/patches ${S}/patches && cd ${S} && quilt push -av
rm -Rf patches .pc
}
do_svnrev() {
mv -f tools/setlocalversion tools/setlocalversion.old
echo -n "echo " >>tools/setlocalversion
echo ${PV} >>tools/setlocalversion
}
do_configure_prepend() {
find . -name "*.mk" -exec sed -i 's,-mabi=apcs-gnu,,' {} \;
find . -name "Makefile" -exec sed -i 's,-mabi=apcs-gnu,,' {} \;
cat ${WORKDIR}/uboot-eabi-fix-HACK.patch |patch -p1
}
do_compile () {
chmod +x board/neo1973/gta*/split_by_variant.sh
for mach in ${UBOOT_MACHINES}
do
oe_runmake ${mach}_config
oe_runmake clean
find board -name lowlevel_foo.bin -exec rm '{}' \;
oe_runmake all
oe_runmake u-boot.udfu
if [ -f u-boot.udfu ]; then
mv u-boot.udfu u-boot_${mach}.bin
else
mv u-boot.bin u-boot_${mach}.bin
fi
if [ -f board/${mach}/lowlevel_foo.bin ]; then
mv board/${mach}/lowlevel_foo.bin \
lowlevel_foo_${mach}.bin
else
find board -name lowlevel_foo.bin \
-exec mv '{}' lowlevel_foo_${mach}.bin \;
fi
done
}
do_deploy () {
install -d ${DEPLOY_DIR_IMAGE}
for mach in ${UBOOT_MACHINES}
do
install -m 0644 ${S}/u-boot_${mach}.bin ${DEPLOY_DIR_IMAGE}/u-boot-${mach}-${PV}-${PR}.bin
ln -sf ${DEPLOY_DIR_IMAGE}/u-boot-${mach}-${PV}-${PR}.bin ${DEPLOY_DIR_IMAGE}/uboot-${mach}-latest.bin
if [ -f ${S}/lowlevel_foo_${mach}.bin ]; then
install -m 0644 ${S}/lowlevel_foo_${mach}.bin ${DEPLOY_DIR_IMAGE}/lowlevel_foo-${mach}-${PV}-${PR}.bin
ln -sf ${DEPLOY_DIR_IMAGE}/lowlevel_foo-${mach}-${PV}-${PR}.bin ${DEPLOY_DIR_IMAGE}/lowlevel-foo-${mach}-latest.bin
fi
done
install -m 0755 tools/mkimage ${STAGING_BINDIR_NATIVE}/uboot-mkimage
}
do_deploy[dirs] = "${S}"
addtask deploy before do_package after do_install
addtask quilt before do_patch after do_unpack
addtask svnrev before do_patch after do_quilt