diff --git a/arch/arm/src/lc823450/Kconfig b/arch/arm/src/lc823450/Kconfig index 7866de57f69..4040a21a449 100644 --- a/arch/arm/src/lc823450/Kconfig +++ b/arch/arm/src/lc823450/Kconfig @@ -7,6 +7,10 @@ comment "LC823450 Configuration Options" menu "LC823450 Peripheral Support" +config LC823450_IPL2 + bool "IPL2" + default n + config LC823450_UART0 bool "UART0" select UART0_SERIALDRIVER @@ -125,6 +129,14 @@ config MTD_CONFIG_DEVPATH string "Device path for config" default "/dev/mtdblock0p2" +config MTD_RECOVERY_DEVPATH + string "Device path for recovery" + default "/dev/mtdblock0p3" + +config MTD_KERNEL_DEVPATH + string "Device path for kernel" + default "/dev/mtdblock0p4" + config MTD_ETC_DEVPATH string "Device path for etc" default "/dev/mtdblock0p5" @@ -213,7 +225,7 @@ config LC823450_USBDEV_CUSTOM_HSDSEL_10 endchoice config LC823450_LSISTBY - bool "LIS Standby" + bool "LSI Standby" default n config LC823450_MTM0_TICK @@ -229,4 +241,5 @@ config HRT_TIMER bool "High resolution timer" default n + endmenu diff --git a/arch/arm/src/lc823450/Make.defs b/arch/arm/src/lc823450/Make.defs index dca20b04c0a..e15c11db2b7 100644 --- a/arch/arm/src/lc823450/Make.defs +++ b/arch/arm/src/lc823450/Make.defs @@ -137,8 +137,8 @@ ifeq ($(CONFIG_ADC),y) CHIP_CSRCS += lc823450_adc.c endif -ifeq ($(CONFIG_IPL2),y) -ifeq ($(CONFIG_SPIFLASH_BOOT),y) +ifeq ($(CONFIG_LC823450_IPL2),y) +ifeq ($(CONFIG_LC823450_SPIFLASH_BOOT),y) CHIP_CSRCS += lc823450_spif_ipl2.c else CHIP_CSRCS += lc823450_ipl2.c diff --git a/arch/arm/src/lc823450/lc823450_clockconfig.c b/arch/arm/src/lc823450/lc823450_clockconfig.c index 916eac8627c..e2c0d8b6b5f 100644 --- a/arch/arm/src/lc823450/lc823450_clockconfig.c +++ b/arch/arm/src/lc823450/lc823450_clockconfig.c @@ -141,7 +141,7 @@ void lc823450_clockconfig() val |= OSCCNT_SCKSEL_MAIN; putreg32(val, OSCCNT); -#ifdef CONFIG_IPL2 +#ifdef CONFIG_LC823450_IPL2 /* set the common PLL values */ /* XTAL / XT1OSC_CLK = 1MHz */ diff --git a/arch/arm/src/lc823450/lc823450_i2c.c b/arch/arm/src/lc823450/lc823450_i2c.c index 4b9c26451e5..90030c65b85 100644 --- a/arch/arm/src/lc823450/lc823450_i2c.c +++ b/arch/arm/src/lc823450/lc823450_i2c.c @@ -1053,7 +1053,7 @@ static int lc823450_i2c_transfer(FAR struct i2c_master_s *dev, leave_critical_section(irqs); } -#ifndef CONFIG_IPL2 +#ifndef CONFIG_LC823450_IPL2 i2cerr("ERROR: I2C timed out (dev=%xh)\n", msgs->addr); #endif } diff --git a/arch/arm/src/lc823450/lc823450_ipl2.c b/arch/arm/src/lc823450/lc823450_ipl2.c new file mode 100644 index 00000000000..9ede188cffd --- /dev/null +++ b/arch/arm/src/lc823450/lc823450_ipl2.c @@ -0,0 +1,756 @@ +/**************************************************************************** + * arch/arm/src/lc823450/lc823450_ipl2.c + * + * Copyright (C) 2015-2017 Sony Corporation. All rights reserved. + * Author: Masatoshi Tateishi + * Author: Nobutaka Toyoshima + * Author: Yasuhiro Osaki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_FS_EVFAT +# include +#endif + +#include +#include +#include + +#ifdef CONFIG_I2C +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_LASTKMSG +# include +#endif /* CONFIG_LASTKMSG */ + +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" + +#ifdef CONFIG_ADC +# include "lc823450_adc.h" +#endif + +#include "lc823450_syscontrol.h" +#include "lc823450_mtd.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IPL2_DEVPATH "/dev/mtdblock0" +#define IPL2_IMAGE "LC8234xx_17S_start_data.boot_bin" + +#define LASTMSG_LOGPATH "/log/lastkmsg" + +#define R2A20056BM_ADDR 0x1B +#define R2A20056BM_SCL 375000 + +#ifdef CONFIG_CHARGER +# define FORCE_USBBOOT_CHARGER +#endif + +#pragma GCC optimize ("O0") + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +static struct +{ + uint32_t sig; + uint32_t chunknum; + struct + { + char fname[32]; + char csum[32]; + uint32_t size; + uint32_t enc; + uint32_t offset; + } chunk[10]; +} upg_image; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char copybuf[512]; +static void *tmp; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_USBMSC +static void sysreset(void); +static int set_config(int num, char *buf); +#endif + +/**************************************************************************** + * Name: blk_read() + ****************************************************************************/ + +static int blk_read(void *buf, int len, const char *path, int offset) +{ + void *handle; + int ret; + + ret = bchlib_setup(path, true, &handle); + + if (ret) + { + return ret; + } + + ret = bchlib_read(handle, buf, offset, len); + + bchlib_teardown(handle); + + return ret; +} + +/**************************************************************************** + * Name: blk_write() + ****************************************************************************/ + +#ifdef CONFIG_USBMSC +static int blk_write(const void *buf, int len, const char *path, int offset) +{ + void *handle; + int ret; + + ret = bchlib_setup(path, true, &handle); + + if (ret) + { + return ret; + } + + ret = bchlib_write(handle, buf, offset, len); + + bchlib_teardown(handle); + + return ret; +} +#endif + +/**************************************************************************** + * Name: install_recovery() + ****************************************************************************/ + +static int install_recovery(const char *srcpath) +{ + int rfd, i, len, rem; + int ret = 0; + void *handle = NULL; + + if (bchlib_setup(CONFIG_MTD_RECOVERY_DEVPATH, false, &handle)) + { + return -1; + } + + rfd = open(srcpath, O_RDONLY, 0444); + + if (read(rfd, &upg_image, sizeof(upg_image)) != sizeof(upg_image)) + { + _info("read head"); + ret = -EIO; + goto err; + } + +#ifdef IMG_SIGNATURE + if (upg_image.sig != IMG_SIGNATURE) + { + _info("image signature missmatch. IPL2=%u, UPG=%u\n", + IMG_SIGNATURE, upg_image.sig); + _info("go normal boot\n"); + + memset(copybuf, 0, sizeof(copybuf)); + snprintf(copybuf, sizeof(copybuf), "normal"); + set_config(1, copybuf); + sysreset(); + + /* NOT REACHED */ + + } +#endif + + for (i = 0; i < upg_image.chunknum; i++) + { + if (!strcmp(basename(upg_image.chunk[i].fname), "recovery")) + { + break; + } + } + + if (i == upg_image.chunknum) + { + _info("recovery not found\n"); + ret = -ENOENT; + goto err; + } + + lseek(rfd, upg_image.chunk[i].offset + + ((void *)&upg_image.chunk[upg_image.chunknum] - (void *)&upg_image), + SEEK_SET); + + rem = upg_image.chunk[i].size; + + while (rem > 0) + { + len = read(rfd, copybuf, rem > 512 ? 512 : rem); + + if (len < 0) + { + _info("read image"); + ret = -EIO; + goto err; + } + + bchlib_write(handle, copybuf, upg_image.chunk[i].size - rem, len); + rem -= len; + } + +err: + if (handle) + { + bchlib_teardown(handle); + } + + close(rfd); + _info("DONE\n"); + return ret; +} + +/**************************************************************************** + * Name: load_kernel() + ****************************************************************************/ + +static void load_kernel(const char *name, const char *devname) +{ + int i; + + tmp = (void *)0x02040000; + + (void)blk_read(tmp, 512 * 1024, devname, 0); + + /* disable all IRQ */ + for (i = LC823450_IRQ_NMI + 1; i < NR_IRQS; i++) + { + up_disable_irq(i); + } + + /* clear pending IRQ */ + putreg32(0xffffffff, NVIC_IRQ0_31_CLRPEND); + putreg32(0xffffffff, NVIC_IRQ32_63_CLRPEND); + putreg32(0xffffffff, NVIC_IRQ64_95_CLRPEND); + + _info("start %s\n", name); + + __asm__ __volatile__ + ( + "ldr r0, =tmp\n" + "ldr r1, [r0, #0]\n" /* r1 = 0x02040000 */ + "ldr sp, [r1, #0]\n" /* set sp */ + "ldr pc, [r1, #4]" /* set pc, start nuttx */ + ); + +} + +/**************************************************************************** + * Name: check_diskformat() + ****************************************************************************/ + +#ifdef CONFIG_USBMSC +static int check_diskformat(void) +{ + int ret; + +#ifdef CONFIG_FS_EVFAT + struct evfat_format_s fmt = EVFAT_FORMAT_INITIALIZER; + + /* load MBR */ + + ret = blk_read(copybuf, sizeof(copybuf), "/dev/mtdblock0p2", 0); + + if (ret < 0) + { + return 0; + } + + /* If part2 has MBR signature, this eMMC was formated by PC. + * This means the set is just after writing IPL2. + */ + + if (copybuf[510] != 0x55 || copybuf[511] != 0xaa) + { + return 0; + } + + ret = mkevfatfs(CONFIG_MTD_CP_DEVPATH, &fmt); +#endif + + _info("FORMAT content partition : %d\n", ret); + + memset(copybuf, 0, sizeof(copybuf)); + ret = blk_write(copybuf, 512, CONFIG_MTD_ETC_DEVPATH, 0); + _info("clear /etc : %d\n", ret); + ret = blk_write(copybuf, 512, CONFIG_MTD_SYSTEM_DEVPATH, 0); + _info("clear /system : %d\n", ret); + ret = blk_write(copybuf, 512, CONFIG_MTD_CACHE_DEVPATH, 0); + _info("clear /cache : %d\n", ret); + + return 1; +} +#endif + +/**************************************************************************** + * Name: check_forceusbboot() + ****************************************************************************/ + +#ifdef CONFIG_ADC +static int check_forceusbboot(void) +{ + uint32_t val; + uint32_t val1; + + /* enable clock & unreset */ + + modifyreg32(MCLKCNTAPB, 0, MCLKCNTAPB_ADC_CLKEN); + modifyreg32(MRSTCNTAPB, 0, MRSTCNTAPB_ADC_RSTB); + + usleep(10000); + + /* start ADC0,1 */ + + putreg32(rADCCTL_fADCNVCK_DIV32 | rADCCTL_fADACT | rADCCTL_fADCHSCN | + 1 /* 0,1 ch */, rADCCTL); + + putreg32(53, rADCSMPL); + + /* wait for adc done */ + + while ((getreg32(rADCSTS) & rADCSTS_fADCMPL) == 0) + ; + + val = getreg32(rADC0DT); + val1 = getreg32(rADC1DT); + + _info("val = %d, val1 = %d\n", val, val1); + + /* disable clock & reset */ + + modifyreg32(MCLKCNTAPB, MCLKCNTAPB_ADC_CLKEN, 0); + modifyreg32(MRSTCNTAPB, MRSTCNTAPB_ADC_RSTB, 0); + + /* check KEY0_AD_D key pressed */ + + if (val >= (0x3A << 2) && val < (0x57 << 2)) + { + return 1; + } + + /* check KEY0_AD_B key pressed */ + + if (val >= (0x0B << 2) && val < (0x20 << 2)) + { + return 1; + } + + /* check KEY1_AD_B key pressed */ + + if (val1 >= (0x0B << 2) && val1 < (0x20 << 2)) + { + return 1; + } + + return 0; +} +#endif + +#ifdef CONFIG_USBMSC + +/**************************************************************************** + * Name: sysreset() + ****************************************************************************/ + +static void sysreset(void) +{ + /* workaround to flush eMMC cache */ + + usleep(100000); + + up_systemreset(); +} + +/**************************************************************************** + * Name: get_config() + ****************************************************************************/ + +static int get_config(int num, char *buf) +{ + int ret; + ret = blk_read(buf, 512, CONFIG_MTD_CONFIG_DEVPATH, num * 512); + return ret; +} + +/**************************************************************************** + * Name: set_config() + ****************************************************************************/ + +static int set_config(int num, char *buf) +{ + int ret; + ret = blk_write(buf, 512, CONFIG_MTD_CONFIG_DEVPATH, num * 512); + return ret; +} + +#endif /* CONFIG_USBMSC */ + +extern volatile int g_update_flag; + +/**************************************************************************** + * Name: chg_disable() + ****************************************************************************/ + +#ifdef CONFIG_CHARGER +static void chg_disable(void) +{ + FAR struct i2c_dev_s *i2c; + int ret; + uint32_t freq; + + const uint8_t addr = 0x01; + const uint8_t data = 0x83; + + struct i2c_msg_s msg[2] = + { + { + .addr = R2A20056BM_ADDR, + .flags = 0, + .buffer = (uint8_t *)&addr, + .length = 1, + }, + { + .addr = R2A20056BM_ADDR, + .flags = I2C_M_NORESTART, + .buffer = (uint8_t *)&data, + .length = 1, + } + }; + + /* I2C pinmux */ + + modifyreg32(PMDCNT0, 0x0003C000, 0x00014000); + + /* I2C drv : 4mA */ + + modifyreg32(PTDRVCNT0, 0x0003C000, 0x0003C000); + + /* Enable I2C controller */ + + modifyreg32(MCLKCNTAPB, 0, MCLKCNTAPB_I2C0_CLKEN); + modifyreg32(MRSTCNTAPB, 0, MRSTCNTAPB_I2C0_RSTB); + + /* I2C SCL: push pull */ + + modifyreg32(I2CMODE, 0, I2CMODE0); + + /* Disable charge */ + + i2c = up_i2cinitialize(1); + + if (i2c) + { + /* Set slave address */ + + ret = I2C_SETADDRESS(i2c, R2A20056BM_ADDR, 7); + + /* Set frequency */ + + freq = I2C_SETFREQUENCY(i2c, R2A20056BM_SCL); + + /* Charge disable */ + + if (ret == OK && freq == R2A20056BM_SCL) + { + ret = I2C_TRANSFER(i2c, msg, sizeof(msg) / sizeof(msg[0])); + + if (ret != OK) + { + _info("no vbus (%d)\n", ret); + } + else + { + usleep(20); + } + } + + up_i2cuninitialize(i2c); + } + else + { + _info("Failed to i2c initialize\n"); + } +} +#endif + +/**************************************************************************** + * Name: msc_enable() + ****************************************************************************/ + +#ifdef CONFIG_USBMSC +static int msc_enable(int forced) +{ + int ret; + void *handle; + + usbmsc_configure(1, &handle); + usbmsc_bindlun(handle, CONFIG_MTD_CP_DEVPATH, 0, 0, 0, false); + usbmsc_exportluns(handle); + +#ifdef FORCE_USBBOOT_CHARGER + if (!forced && !usbdev_is_usbcharger()) + { + /* If not USBCharger, go normal boot */ + + usbmsc_uninitialize(handle); + return 0; + } + + /* wait for SCSI command */ + + while (g_update_flag == 0) + { + /* If key released, go normal boot */ + + if (!forced && !check_forceusbboot()) + { + usbmsc_uninitialize(handle); + return 0; + } + usleep(10000); + } + +#else + /* wait for SCSI command */ + + while (g_update_flag == 0) + { + usleep(10000); + } +#endif + + usbmsc_uninitialize(handle); + + /* check recovery kernel update */ + + mount(CONFIG_MTD_CP_DEVPATH, "/mnt/sd0", "evfat", 0, NULL); + usleep(10000); + + /* recovery kernel install from UPG.img */ + + ret = install_recovery("/mnt/sd0/UPG.IMG"); + + if (ret == 0) + { + _info("Install recovery\n"); + + /* clear old MBR */ + memset(copybuf, 0, sizeof(copybuf)); + set_config(0, copybuf); + } + + /* set bootmode to recovery */ + + memset(copybuf, 0, sizeof(copybuf)); + snprintf(copybuf, sizeof(copybuf), "recovery"); + set_config(1, copybuf); + + sysreset(); + + /* not reached */ + return 0; +} +#endif + +#ifdef CONFIG_LASTKMSG + +/**************************************************************************** + * Name: check_lastkmsg() + ****************************************************************************/ + +void check_lastkmsg(void) +{ + int ret; + FILE *fp; + + if (g_lastksg_buf.sig != LASTKMSG_SIG) + { + return; + } + + ret = mount(CONFIG_MTD_LOG_DEVPATH, "/log", "vfat", 0, NULL); + + if (ret) + { + _info("mount: ret = %d\n", ret); + return; + } + + /* log rotate */ + + (void)unlink(LASTMSG_LOGPATH ".4"); + (void)rename(LASTMSG_LOGPATH ".3", LASTMSG_LOGPATH ".4"); + (void)rename(LASTMSG_LOGPATH ".2", LASTMSG_LOGPATH ".3"); + (void)rename(LASTMSG_LOGPATH ".1", LASTMSG_LOGPATH ".2"); + (void)rename(LASTMSG_LOGPATH ".0", LASTMSG_LOGPATH ".1"); + + fp = fopen(LASTMSG_LOGPATH ".0", "w"); + + if (fp) + { + lastkmsg_output(fp); + fflush(fp); + fclose(fp); + } + + umount("/log"); + + /* XXX: workaround for logfile size = 0 */ + + usleep(100000); +} +#endif /* CONFIG_LASTKMSG */ + +/**************************************************************************** + * Name: ipl2_main() + ****************************************************************************/ + +int ipl2_main(int argc, char *argv[]) +{ + int ret; + + _info("start: %s\n", CONFIG_CURRENT_REVISION); + _info("imgsig: %u\n", IMG_SIGNATURE); + +#ifdef CONFIG_CHARGER + /* NOTE: + * chg_disable() must be done before CMIC_FWAKE L->H. + * Please refer to PDFW15IS-2494 for more information + */ + + chg_disable(); +#endif + + lc823450_mtd_initialize(0); + +#ifdef CONFIG_ADC + ret = check_forceusbboot(); +#endif + +#ifdef CONFIG_USBMSC + if (ret) + { + msc_enable(0); + } + + ret = check_diskformat(); + + if (ret) + { + msc_enable(1); + } + + memset(copybuf, 0, sizeof(copybuf)); + get_config(1, copybuf); + + /* for "reboot usb" */ + + if (!strncmp("usb", copybuf, 3)) + { + /* remove boot flag for next boot */ + + memset(copybuf, 0, sizeof(copybuf)); + set_config(1, copybuf); + msc_enable(1); + } +#endif + +#ifdef CONFIG_LASTKMSG + check_lastkmsg(); +#endif /* CONFIG_LASTKMSG */ + + if (!strncmp("recovery", copybuf, 8)) + { + /* check recovery kernel update */ + + mount(CONFIG_MTD_CP_DEVPATH, "/mnt/sd0", "evfat", 0, NULL); + usleep(10000); + + /* recovery kernel install from UPG.img */ + + install_recovery("/mnt/sd0/UPG.IMG"); + load_kernel("recovery", CONFIG_MTD_RECOVERY_DEVPATH); + + } + else + { + load_kernel("nuttx", CONFIG_MTD_KERNEL_DEVPATH); + } + + /* not reached */ + + return -1; +} + diff --git a/arch/arm/src/lc823450/lc823450_start.c b/arch/arm/src/lc823450/lc823450_start.c index a52bf2cf1fb..adde59c14a9 100644 --- a/arch/arm/src/lc823450/lc823450_start.c +++ b/arch/arm/src/lc823450/lc823450_start.c @@ -251,13 +251,13 @@ void __start(void) #else /* CONFIG_SPIFLASH_BOOT */ /* vector offset */ -#ifdef CONFIG_IPL2 +#ifdef CONFIG_LC823450_IPL2 putreg32(0x02000e00, 0xe000ed08); putreg32(0x0, 0x40080008); /* XXX: remap disable */ -#else /* CONFIG_IPL2 */ +#else /* CONFIG_LC823450_IPL2 */ putreg32(0x02040000, 0xe000ed08); -#endif /* CONFIG_IPL2 */ -#endif /* CONFIG_SPIFLASH_BOOT */ +#endif /* CONFIG_LC823450_IPL2 */ +#endif /* CONFIG_LC823450_SPIFLASH_BOOT */ /* Mutex enable */ @@ -273,7 +273,7 @@ void __start(void) /* IPL2 don't change mux */ -#ifdef CONFIG_IPL2 +#ifdef CONFIG_LC823450_IPL2 /* GPIO2F out High in IPL2 */ modifyreg32(MCLKCNTAPB, 0, MCLKCNTAPB_PORT2_CLKEN); @@ -286,9 +286,9 @@ void __start(void) modifyreg32(PMDCNT5, 0, 3 << 14); #endif /* CONFIG_DEBUG */ -#else /* CONFIG_IPL2 */ +#else /* CONFIG_LC823450_IPL2 */ up_init_default_mux(); -#endif /* CONFIG_IPL2 */ +#endif /* CONFIG_LC823450_IPL2 */ showprogress('B'); @@ -326,9 +326,9 @@ void __start(void) showprogress('F'); -#ifndef CONFIG_IPL2 +#ifndef CONFIG_LC823450_IPL2 sinfo("icx_boot_reason = 0x%x\n", icx_boot_reason); -#endif /* CONFIG_IPL2 */ +#endif /* CONFIG_LC823450_IPL2 */ #ifdef CONFIG_POWERBUTTON_LDOWN if (icx_boot_reason & ICX_BOOT_REASON_POWERBUTTON) diff --git a/configs/lc823450-xgevk/README.txt b/configs/lc823450-xgevk/README.txt index d79fdb4f191..b91b25a3be5 100644 --- a/configs/lc823450-xgevk/README.txt +++ b/configs/lc823450-xgevk/README.txt @@ -11,6 +11,14 @@ LC823450 related documents are available at http://www.onsemi.com/PowerSolutions/supportDoc.do?type=AppNotes&rpn=LC823450 +OpenOCD for NuttX thread and LC823450 support is available at + + https://github.com/sony/openocd-nuttx/wiki + +MakeIPL2 Tool for eMMC boot is available at + + http://www.onsemi.com/PowerSolutions/supportDoc.do?type=software&rpn=LC823450 + This port is intended to test LC823450 features including SMP. Supported peripherals: UART, TIMER, RTC, GPIO, DMA, I2C, SPI, LCD, eMMC, USB, WDT, ADC. @@ -18,7 +26,7 @@ UART, TIMER, RTC, GPIO, DMA, I2C, SPI, LCD, eMMC, USB, WDT, ADC. Settings ^^^^^^^^ -1. Currently only SRAM boot via ICE is supported. +1. eMMC boot and SRAM boot via openocd are supported. 2. If SWD connection is lost, please specify lower adaptor clock. 3. Both CPUs are running at 160MHz. 4. Internal SRAMs (seg0 to seg5) are used. @@ -35,6 +43,9 @@ output into the console because UART operates in FIFO mode. 1. "nsh> smp" works but the result will be corrupted. 2. "nsh> ostest" works but might cause a deadlock or assertion. + + + Other Status ^^^^^^^^^^^^ @@ -128,9 +139,56 @@ nsh> wdog NO ping elapsed=5500 NO ping elapsed=6000 +9. IPL2 and eMMC boot + +IPL2 is the 2nd boot loader based on NuttX and can be built as follows. + + $ make distclean + $ ./tools/configure.sh lc823450-xgevk/ipl2 + $ make V=1 + $ MakeIPL2 ./nuttx.bin 0 2 0 0 0 + $ cp LC8234xx_17S_start_data.boot_bin /tmp/ + +To write the IPL2 (LC8234xx_17S_start_data.boot_bin), +firstly build USB configuration image. + + $ make distclean + $ ./tools/configure.sh lc823450-xgevk/usb + $ make V=1 + +Load the nuttx.bin with openocd + gdb + + $ cd openocd-nuttx + $ ./bootstrap + $ ./configure + $ make + $ sudo ./src/openocd -s ./tcl -f ./tcl/board/lc823450_xgevk.cfg -c init -c "reset halt" + + $ arm-none-eabi-gdb + (gdb) target extended-remote :3333 + (gdb) load ./nuttx + (gdb) symbol-file ./nuttx + (gdb) c + +Start USB MSC to copy nuttx.bin and the IPL2 to the FAT32 partition (/dev/mtdblock0p10) +then dd the files to the kernel partition (/dev/mtdblock0p4) and the IPL2 partition +(/dev/mtdblock0p1) respectively. + + nsh> mkfatfs -F 32 /dev/mtdblock0p10 + nsh> msconn + + $ sudo cp ./nuttx.bin /media/usb0/ + $ sudo cp /tmp/LC8234xx_17S_start_data.boot_bin /media/usb0/ + $ sudo sync + + nsh> msdis + nsh> mount -t vfat /dev/mtdblock0p10 /mnt/sd0 + nsh> dd if=/mnt/sd0/nuttx.bin of=/dev/mtdblock0p4 + nsh> dd if=/mnt/sd0/LC8234xx_17S_start_data.boot_bin of=/dev/mtdblock0p1 + nsh> reboot TODO ^^^^ The following features will be supported. -IPL2 (eMMC boot), Audio, etc. +Audio, etc. diff --git a/configs/lc823450-xgevk/ipl2/defconfig b/configs/lc823450-xgevk/ipl2/defconfig new file mode 100644 index 00000000000..2279112c485 --- /dev/null +++ b/configs/lc823450-xgevk/ipl2/defconfig @@ -0,0 +1,77 @@ +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="lc823450-xgevk" +CONFIG_ARCH_BOARD_LC823450_XGEVK=y +CONFIG_ARCH_CHIP_LC823450=y +CONFIG_ARCH_FLOAT_H=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STDARG_H=y +CONFIG_BOARD_LOOPSPERMSEC=12061 +CONFIG_BUILTIN=y +CONFIG_C99_BOOL8=y +CONFIG_CODECS_HASH_MD5=y +CONFIG_DEBUG_ASSERTIONS=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_WARN=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_EXPERIMENTAL=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FS_FATTIME=y +CONFIG_FS_FAT=y +CONFIG_FS_PROCFS=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LC823450_IPL2=y +CONFIG_LC823450_MTD=y +CONFIG_LC823450_SDIF_SDC=y +CONFIG_LC823450_UART0=y +CONFIG_LC823450_UART1=y +CONFIG_LIBM=y +CONFIG_MAX_TASKS=64 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_MEMSET_OPTSPEED=y +CONFIG_MTD=y +CONFIG_NAME_MAX=765 +CONFIG_NETUTILS_CODECS=y +CONFIG_NFILE_DESCRIPTORS=45 +CONFIG_NFILE_STREAMS=8 +CONFIG_PIPES=y +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=2048 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PREALLOC_WDOGS=16 +CONFIG_PTHREAD_MUTEX_TYPES=y +CONFIG_PTHREAD_STACK_DEFAULT=3072 +CONFIG_RAM_SIZE=1044480 +CONFIG_RAM_START=0x02001000 +CONFIG_RAW_BINARY=y +CONFIG_RTC_DATETIME=y +CONFIG_RTC=y +CONFIG_SCHED_ATEXIT=y +CONFIG_SCHED_CHILD_STATUS=y +CONFIG_SCHED_HAVE_PARENT=y +CONFIG_SCHED_INSTRUMENTATION_BUFFER=y +CONFIG_SCHED_INSTRUMENTATION=y +CONFIG_SCHED_ONEXIT_MAX=32 +CONFIG_SCHED_ONEXIT=y +CONFIG_SCHED_STARTHOOK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_SENSORS=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_START_DAY=3 +CONFIG_START_MONTH=10 +CONFIG_START_YEAR=2013 +CONFIG_TASK_NAME_SIZE=24 +CONFIG_UART0_RXBUFSIZE=512 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_UART0_TXBUFSIZE=2048 +CONFIG_USBDEV_BUSPOWERED=y +CONFIG_USBDEV_DUALSPEED=y +CONFIG_USBDEV_MAXPOWER=500 +CONFIG_USBDEV=y +CONFIG_USER_ENTRYPOINT="ipl2_main" +CONFIG_USERMAIN_STACKSIZE=3072 diff --git a/configs/lc823450-xgevk/scripts/Make.defs b/configs/lc823450-xgevk/scripts/Make.defs index 49cf8241c03..81f4c86309b 100644 --- a/configs/lc823450-xgevk/scripts/Make.defs +++ b/configs/lc823450-xgevk/scripts/Make.defs @@ -37,6 +37,12 @@ include ${TOPDIR}/.config include ${TOPDIR}/tools/Config.mk include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs +ifeq ($(CONFIG_LC823450_IPL2),y) + LDSCRIPT = ld-ipl2.script +else + LDSCRIPT = ld.script +endif + ifeq ($(WINTOOL),y) # Windows-native toolchains DIRLINK = $(TOPDIR)/tools/copydir.sh @@ -44,13 +50,13 @@ ifeq ($(WINTOOL),y) MKDEP = $(TOPDIR)/tools/mkwindeps.sh ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" - ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/ld.script}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" else # Linux/Cygwin-native toolchain MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) ARCHINCLUDES = -I. -isystem $(TOPDIR)/include ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx - ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/ld.script + ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT) endif CC = $(CROSSDEV)gcc diff --git a/configs/lc823450-xgevk/scripts/ld-ipl2.script b/configs/lc823450-xgevk/scripts/ld-ipl2.script new file mode 100644 index 00000000000..f9408b2f65d --- /dev/null +++ b/configs/lc823450-xgevk/scripts/ld-ipl2.script @@ -0,0 +1,120 @@ +/**************************************************************************** + * configs/lc823450-xgevk/scripts/ld-ipl2.script + * + * Copyright (C) 2017 Sony Corporation. All rights reserved. + * Author: Masayuki Ishikawa + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + +MEMORY +{ + progmem (rx) : ORIGIN = 0x02000e00, LENGTH = 124K + sram (rwx) : ORIGIN = 0x02100000, LENGTH = 256K + ramlog (rwx) : ORIGIN = 0x020fe000, LENGTH = 8K +} + +OUTPUT_ARCH(arm) +ENTRY(_stext) +SECTIONS +{ + + .text : { + _stext = ABSOLUTE(.); + KEEP(*(.vectors)) + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > progmem + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > progmem + + .ARM.extab : { + *(.ARM.extab*) + } > progmem + + __exidx_start = ABSOLUTE(.); + .ARM.exidx : { + *(.ARM.exidx*) + } > progmem + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(LOADADDR(.data)); + + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > progmem + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + .ramlog : { + *(.ramlog) + } > ramlog + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +}