Index: ecos/packages/hal/arm/mx35/fab4/current/cdl/hal_arm_board.cdl =================================================================== --- ecos.orig/packages/hal/arm/mx35/fab4/current/cdl/hal_arm_board.cdl 2009-02-13 10:51:49.000000000 +0000 +++ ecos/packages/hal/arm/mx35/fab4/current/cdl/hal_arm_board.cdl 2009-02-13 14:22:05.000000000 +0000 @@ -54,6 +54,8 @@ #implements CYGHWR_HAL_ARM_DUART_UARTB implements CYGHWR_HAL_ARM_SOC_UART1 + define SQUEEZEOS_REDBOOT + define_proc { puts $::cdl_system_header "#define CYGBLD_HAL_TARGET_H " puts $::cdl_system_header "#define CYGBLD_HAL_VARIANT_H " @@ -61,7 +63,7 @@ puts $::cdl_header "#define HAL_PLATFORM_CPU \"i.MX35 \"" puts $::cdl_header "#define HAL_PLATFORM_BOARD \"Logitech Fab4\"" puts $::cdl_header "#define HAL_PLATFORM_MACHINE_TYPE 1804" - puts $::cdl_header "#define HAL_PLATFORM_MACHINE_REVISION 3" + puts $::cdl_header "#define HAL_PLATFORM_MACHINE_REVISION 2" puts $::cdl_header "#define HAL_ARCH_PROGRAM_NEW_STACK board_program_new_stack" } Index: ecos/packages/hal/arm/mx35/fab4/current/misc/redboot_fab4.ecm =================================================================== --- ecos.orig/packages/hal/arm/mx35/fab4/current/misc/redboot_fab4.ecm 2009-02-13 10:51:53.000000000 +0000 +++ ecos/packages/hal/arm/mx35/fab4/current/misc/redboot_fab4.ecm 2009-02-13 10:51:57.000000000 +0000 @@ -14,3 +14,19 @@ cdl_option CYGDAT_DEVS_ETH_FEC_FCONFIG_ESA_DATA { user_value 1 \"\\x00\\x04\\x20\\xFF\\xFF\\x01\" }; + +cdl_option CYGDAT_REDBOOT_FCONFIG_BOOT_SCRIPT_DATA { + user_value 1 "\"ubi attach -f 0x80000 -l 0x07EC0000 -w 0x800 -e 0x20000 -s 0x200\\nubi load -b 0x100000 kernel%{os_backup}\\nexec -c %{os_cmdline}\\0\"" +}; + +cdl_option CYGDAT_SQUEEZEOS_FCONFIG_OS_CMDLINE { + user_value 1 "\"\\\"console=ttymxc0,115200 noinitrd init=/linuxrc ubi.mtd=1 root=/dev/mtdblock:cramfs%{os_backup} %{os_cmdargs}\\\"\"" +}; + +cdl_option CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION { + user_value 1 +}; + +cdl_option CYGDAT_REDBOOT_FCONFIG_BOOT_SCRIPT_TIMEOUT { + user_value 100 +}; Index: ecos/packages/hal/arm/mx35/fab4/current/src/board_misc.c =================================================================== --- ecos.orig/packages/hal/arm/mx35/fab4/current/src/board_misc.c 2009-02-13 10:51:49.000000000 +0000 +++ ecos/packages/hal/arm/mx35/fab4/current/src/board_misc.c 2009-02-13 10:51:57.000000000 +0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include CYGBLD_HAL_PLATFORM_H #include // base types @@ -58,6 +59,8 @@ #include // diag_printf +#include + // All the MM table layout is here: #include @@ -111,8 +114,13 @@ void plf_hardware_init(void) { - unsigned long val = readl(CCM_BASE_ADDR + CLKCTL_CCMR); - g_clock_src = FREQ_24MHZ; + writel(0x05, IOMUXC_BASE_ADDR + 0x2d0); + writel(0xC0, IOMUXC_BASE_ADDR + 0x734); + writel(readl(GPIO3_BASE_ADDR + 0x004) | 0x04, GPIO3_BASE_ADDR + 0x004); + writel(readl(GPIO3_BASE_ADDR) | 0x04, GPIO3_BASE_ADDR); + hal_delay_us(100000); + writel(readl(GPIO3_BASE_ADDR) & 0xfffffffb, GPIO3_BASE_ADDR); + mxc_serial_setup(); @@ -292,34 +300,159 @@ } RedBoot_init(display_clock_src, RedBoot_INIT_LAST); + +static void set_alias(char *key, char *value) { + struct config_option opt; + + opt.type = CONFIG_STRING; + opt.enable = (char *)0; + opt.enable_sense = 1; + opt.key = key; + opt.dflt = (void *)value; + flash_add_config(&opt, false); +} + + static void do_halt_boot(void) { + int button_pressed; int button_timeout_ms; + int ir_timeout_ms; + struct mxc_i2c_request rq; + unsigned int script_timeout = CYGDAT_REDBOOT_FCONFIG_BOOT_SCRIPT_TIMEOUT; + unsigned char val[6]; + char *hold_script, *tmp; + +#define IR_TIMEOUT 200 +#define BUTTON_HALT_TIMEOUT 2000 +#define BUTTON_RESET_TIMEOUT 5000 +#define BOOTSCRIPT_TIMEOUT_INTERVAL 100 + +#define IRMCU_I2C_PORT 0x0 +#define IRMCU_I2C_ADDR 0x47 + +#define IR_CODE_ADD 0x7689609f +#define IR_CODE_SLEEP 0x7689B847 +#define IR_CODE_VOLUME_UP 0x7689807f +#define IR_CODE_FACTORY_TEST 0x768930cf + + /* upgrade fconfig settings if required */ + if (!flash_get_config("alias/os_cmdline", &tmp, CONFIG_STRING)) { + diag_printf("Upgrading fconfig\n"); + + set_alias("alias/os_cmdline", CYGDAT_SQUEEZEOS_FCONFIG_OS_CMDLINE); + set_alias("alias/os_cmdargs", ""); + set_alias("alias/os_backup", ""); + flash_set_config("boot_script_timeout", &script_timeout, CONFIG_INT); + flash_set_config("boot_script_data", CYGDAT_REDBOOT_FCONFIG_BOOT_SCRIPT_DATA, CONFIG_SCRIPT); + } if (!IS_BOOTING_FROM_NAND()) { - diag_printf("Halt boot - booting from RAM\n"); - squeezeos_halt_boot = true; - return; + diag_printf("Halt boot - booting from RAM\n"); + squeezeos_halt_boot = true; + return; } -#define BOOTSCRIPT_TIMEOUT 2000 -#define BOOTSCRIPT_TIMEOUT_INTERVAL 100 + /* ir and button timeouts */ + ir_timeout_ms = IR_TIMEOUT; + button_timeout_ms = BUTTON_RESET_TIMEOUT; + + /* check if button is pressed */ + button_pressed = !((readl(GPIO1_BASE_ADDR + 0x000) >> 8) & 1); + + /* read from ir mcu */ + rq.dev_addr = IRMCU_I2C_ADDR; + rq.reg_addr = 0; + rq.reg_addr_sz = 1; + rq.buffer = val; + rq.buffer_sz = 6; + + /* init and clear status */ + i2c_init(i2c_base_addr[IRMCU_I2C_PORT], 100000); + i2c_xfer(IRMCU_I2C_PORT, &rq, I2C_READ); + + while (ir_timeout_ms >= 0) { + unsigned int status; + unsigned int code; + + ir_timeout_ms -= BOOTSCRIPT_TIMEOUT_INTERVAL; + button_timeout_ms -= BOOTSCRIPT_TIMEOUT_INTERVAL; + hal_delay_us(BOOTSCRIPT_TIMEOUT_INTERVAL * 1000); + + if (i2c_xfer(IRMCU_I2C_PORT, &rq, I2C_READ) != 0) { + diag_printf("Error I2C transfer\n\n"); + } + else { + status = val[0]; + code = (val[1] << 24) | (val[2] << 16) | (val[3] << 8) | (val[4] << 0); + + if (status == 1) { + diag_printf("IR code %08x\n", code); + + if (code == IR_CODE_ADD) { + diag_printf("== factory reset\n"); + set_alias("alias/os_cmdargs", "factoryreset=true"); + return; + } + + if (code == IR_CODE_VOLUME_UP) { + diag_printf("== boot backup image\n"); + set_alias("alias/os_backup", "_bak"); + return; + } + + if (code == IR_CODE_FACTORY_TEST) { + diag_printf("== factory test\n"); + set_alias("alias/os_cmdargs", "factorytest=true"); + return; + } + + if (code == IR_CODE_SLEEP) { + diag_printf("== boot aborted\n"); + squeezeos_halt_boot = true; + return; + } + } + } + } + + /* Factory reset if button is pressed for five seconds */ + diag_printf("== enter ^C to abort\n"); + + hold_script = script; + script = NULL; - /* Stop boot if reset button is pressed for two seconds */ - button_timeout_ms = BOOTSCRIPT_TIMEOUT; while (button_timeout_ms >= 0) { - squeezeos_halt_boot = !((readl(GPIO1_BASE_ADDR + 0x000) >> 8) & 1); - if (!squeezeos_halt_boot) { - /* Button not pressed */ - return; + if (!button_pressed) { + /* Halt if button is pressed for > 2 seconds */ + if (BUTTON_RESET_TIMEOUT - button_timeout_ms > BUTTON_HALT_TIMEOUT) { + diag_printf("== boot aborted\n"); + squeezeos_halt_boot = true; + return; } - button_timeout_ms -= BOOTSCRIPT_TIMEOUT_INTERVAL; - hal_delay_us(BOOTSCRIPT_TIMEOUT_INTERVAL * 1000); + /* Button not pressed */ + script = hold_script; + return; + } + + /* check serial console when button is released */ + if (_rb_gets(val, sizeof(val), BOOTSCRIPT_TIMEOUT_INTERVAL) == _GETS_CTRLC) { + diag_printf("== aborted\n"); + squeezeos_halt_boot = true; + return; + } + + button_timeout_ms -= BOOTSCRIPT_TIMEOUT_INTERVAL; + button_pressed = !((readl(GPIO1_BASE_ADDR + 0x000) >> 8) & 1); } - diag_printf("Halt boot - reset button is pressed\n"); + script = hold_script; + + /* Reset if button is pressed for > 5 seconds */ + diag_printf("== factory reset\n"); + set_alias("alias/os_cmdargs", "factoryreset=true"); } -RedBoot_init(do_halt_boot, RedBoot_INIT_SECOND); +RedBoot_init(do_halt_boot, RedBoot_INIT_BEFORE_NET); // ------------------------------------------------------------------------