From ad6be25c19840811e2e9ecd56620a0a1f5415631 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:11 +0200 Subject: [PATCH 01/32] board/BuR/common: prepare for compiling common into non AM33XX boards Today the BuR common stuff is only used on AM33XX boards. In future we plan to have many other platforms than AM33XX so we have to move arch- specific #include(s) to responsible #ifdef sections. By the way we drop unneeded #include(s). Signed-off-by: Hannes Schmelzer --- board/BuR/common/common.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c index 602c571f9c..513872a7d7 100644 --- a/board/BuR/common/common.c +++ b/board/BuR/common/common.c @@ -10,28 +10,22 @@ */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include #include #include "bur_common.h" -#include "../../../drivers/video/am335x-fb.h" DECLARE_GLOBAL_DATA_PTR; /* --------------------------------------------------------------------------*/ #if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \ !defined(CONFIG_SPL_BUILD) +#include +#include +#include +#include +#include "../../../drivers/video/am335x-fb.h" + void lcdbacklight(int on) { unsigned int driver = env_get_ulong("ds1_bright_drv", 16, 0UL); @@ -272,7 +266,12 @@ int ft_board_setup(void *blob, bd_t *bd) return 0; } -#ifdef CONFIG_SPL_BUILD +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_AM33XX) +#include +#include +#include +#include +#include static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; @@ -359,8 +358,7 @@ void set_mux_conf_regs(void) enable_board_pin_mux(); } -#endif /* CONFIG_SPL_BUILD */ - +#endif /* CONFIG_SPL_BUILD && CONFIG_AM33XX */ int overwrite_console(void) { return 1; From 47656d98bd721ef92f944f2c17938e8605c66698 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:12 +0200 Subject: [PATCH 02/32] board/BuR/common: cosmetic: move 'overwrite_console' up to more related stuff Signed-off-by: Hannes Schmelzer --- board/BuR/common/common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c index 513872a7d7..28ebb84595 100644 --- a/board/BuR/common/common.c +++ b/board/BuR/common/common.c @@ -266,6 +266,11 @@ int ft_board_setup(void *blob, bd_t *bd) return 0; } +int overwrite_console(void) +{ + return 1; +} + #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_AM33XX) #include #include @@ -359,7 +364,3 @@ void set_mux_conf_regs(void) } #endif /* CONFIG_SPL_BUILD && CONFIG_AM33XX */ -int overwrite_console(void) -{ - return 1; -} From 2fac7a82945902c79a14357407e8b63fde1a96e8 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:13 +0200 Subject: [PATCH 03/32] board/BuR/common: add 'brdefaulip_setup' function Many B&R boards are equipped with an I2C-EEPROM where various information can be stored. Today there is only a single byte for 'board_id' used. We write this 'board_id' into environment for later use during boot. If the value != 0xFF, meaning the byte is programmed, we modify the "brdefaultip" environment variable for setting an IP-Address based on board_id. Signed-off-by: Hannes Schmelzer --- board/BuR/common/bur_common.h | 2 ++ board/BuR/common/common.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/board/BuR/common/bur_common.h b/board/BuR/common/bur_common.h index f743194c34..2591bf4bb3 100644 --- a/board/BuR/common/bur_common.h +++ b/board/BuR/common/bur_common.h @@ -21,4 +21,6 @@ void enable_i2c_pin_mux(void); void enable_board_pin_mux(void); int board_eth_init(bd_t *bis); +int brdefaultip_setup(int bus, int chip); + #endif diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c index 28ebb84595..89087d7dba 100644 --- a/board/BuR/common/common.c +++ b/board/BuR/common/common.c @@ -266,6 +266,40 @@ int ft_board_setup(void *blob, bd_t *bd) return 0; } +int brdefaultip_setup(int bus, int chip) +{ + int rc; + struct udevice *i2cdev; + u8 u8buf = 0; + char defip[256] = { 0 }; + + rc = i2c_get_chip_for_busnum(bus, chip, 2, &i2cdev); + if (rc != 0) { + printf("WARN: cannot probe baseboard EEPROM!\n"); + return -1; + } + + rc = dm_i2c_read(i2cdev, 0, &u8buf, 1); + if (rc != 0) { + printf("WARN: cannot read baseboard EEPROM!\n"); + return -1; + } + + if (u8buf != 0xFF) + snprintf(defip, sizeof(defip), + "if test -r ${ipaddr}; then; else setenv ipaddr 192.168.60.%d; setenv serverip 192.168.60.254; setenv gatewayip 192.168.60.254; setenv netmask 255.255.255.0; fi;", + u8buf); + else + strncpy(defip, + "if test -r ${ipaddr}; then; else setenv ipaddr 192.168.60.1; setenv serverip 192.168.60.254; setenv gatewayip 192.168.60.254; setenv netmask 255.255.255.0; fi;", + sizeof(defip)); + + env_set("brdefaultip", defip); + env_set_hex("board_id", u8buf); + + return 0; +} + int overwrite_console(void) { return 1; From f4b9f0bdbacec5da0e54f486e960fdd2da0f5c0b Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:14 +0200 Subject: [PATCH 04/32] board/BuR/common: add br resetcontoller implementation On many B&R boards we have a reset-controller, responsible for very early board-bringup (voltages, clocks, ...) and bootmode selection. To be ready for adding more B&R boards to source tree while avoiding duplicate code, we add the resetcontroller implementation to the common part of B&R boards. Signed-off-by: Hannes Schmelzer --- board/BuR/common/br_resetc.c | 234 +++++++++++++++++++++++++++++++++++ board/BuR/common/br_resetc.h | 26 ++++ 2 files changed, 260 insertions(+) create mode 100644 board/BuR/common/br_resetc.c create mode 100644 board/BuR/common/br_resetc.h diff --git a/board/BuR/common/br_resetc.c b/board/BuR/common/br_resetc.c new file mode 100644 index 0000000000..190f141091 --- /dev/null +++ b/board/BuR/common/br_resetc.c @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * common reset-controller functions for B&R boards + * + * Copyright (C) 2019 Hannes Schmelzer + * B&R Industrial Automation GmbH - http://www.br-automation.com/ * + */ +#include +#include +#include +#include +#include "br_resetc.h" + +/* I2C Address of controller */ +#define RSTCTRL_ADDR_PSOC 0x75 +#define RSTCTRL_ADDR_STM32 0x60 + +#define BMODE_DEFAULTAR 0 +#define BMODE_SERVICE 2 +#define BMODE_RUN 4 +#define BMODE_PME 12 +#define BMODE_DIAG 15 + +#ifdef CONFIG_LCD +#include +#define LCD_SETCURSOR(x, y) lcd_position_cursor(x, y) +#define LCD_PUTS(x) lcd_puts(x) +#else +#define LCD_SETCURSOR(x, y) +#define LCD_PUTS(x) +#endif /* CONFIG_LCD */ + +static const char *bootmodeascii[16] = { + "BOOT", "reserved", "reserved", "reserved", + "RUN", "reserved", "reserved", "reserved", + "reserved", "reserved", "reserved", "reserved", + "PME", "reserved", "reserved", "DIAG", +}; + +struct br_reset_t { + struct udevice *i2cdev; + u8 is_psoc; +}; + +static struct br_reset_t resetc; + +__weak int board_boot_key(void) +{ + return 0; +} + +__weak void board_boot_led(unsigned int on) +{ +} + +static int resetc_init(void) +{ + struct udevice *i2cbus; + int rc; + + rc = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus); + if (rc) { + printf("Cannot find I2C bus #0!\n"); + return -1; + } + + rc = dm_i2c_probe(i2cbus, + RSTCTRL_ADDR_PSOC, 0, &resetc.i2cdev); + if (rc) { + resetc.is_psoc = 0; + rc = dm_i2c_probe(i2cbus, + RSTCTRL_ADDR_STM32, 0, &resetc.i2cdev); + } + + if (rc) + printf("Warning: cannot probe BuR resetcontroller!\n"); + + return rc; +} + +int br_resetc_regget(u8 reg, u8 *dst) +{ + int rc = 0; + + if (!resetc.i2cdev) + rc = resetc_init(); + + if (rc != 0) + return rc; + + return dm_i2c_read(resetc.i2cdev, reg, dst, 1); +} + +int br_resetc_regset(u8 reg, u8 val) +{ + int rc = 0; + u16 regw = (val << 8) | val; + + if (!resetc.i2cdev) + rc = resetc_init(); + + if (rc != 0) + return rc; + + if (resetc.is_psoc) + return dm_i2c_write(resetc.i2cdev, reg, (u8 *)®w, 2); + + return dm_i2c_write(resetc.i2cdev, reg, (u8 *)®w, 1); +} + +int br_resetc_bmode(void) +{ + int rc = 0; + u16 regw; + u8 regb, scr; + int cnt; + unsigned int bmode = 0; + + if (!resetc.i2cdev) + rc = resetc_init(); + + if (rc != 0) + return rc; + + rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_ENHSTATUS, ®b, 1); + if (rc != 0) { + printf("WARN: cannot read ENHSTATUS from resetcontroller!\n"); + return -1; + } + + rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_SCRATCHREG0, &scr, 1); + if (rc != 0) { + printf("WARN: cannot read SCRATCHREG from resetcontroller!\n"); + return -1; + } + + board_boot_led(1); + + /* special bootmode from resetcontroller */ + if (regb & 0x4) { + bmode = BMODE_DIAG; + } else if (regb & 0x8) { + bmode = BMODE_DEFAULTAR; + } else if (board_boot_key() != 0) { + cnt = 4; + do { + LCD_SETCURSOR(1, 8); + switch (cnt) { + case 4: + LCD_PUTS + ("release KEY to enter SERVICE-mode. "); + break; + case 3: + LCD_PUTS + ("release KEY to enter DIAGNOSE-mode. "); + break; + case 2: + LCD_PUTS + ("release KEY to enter BOOT-mode. "); + break; + } + mdelay(1000); + cnt--; + if (board_boot_key() == 0) + break; + } while (cnt); + + switch (cnt) { + case 0: + bmode = BMODE_PME; + break; + case 1: + bmode = BMODE_DEFAULTAR; + break; + case 2: + bmode = BMODE_DIAG; + break; + case 3: + bmode = BMODE_SERVICE; + break; + } + } else if ((regb & 0x1) || scr == 0xCC) { + bmode = BMODE_PME; + } else { + bmode = BMODE_RUN; + } + + LCD_SETCURSOR(1, 8); + + switch (bmode) { + case BMODE_PME: + LCD_PUTS("entering PME-Mode (netscript). "); + regw = 0x0C0C; + break; + case BMODE_DEFAULTAR: + LCD_PUTS("entering BOOT-mode. "); + regw = 0x0000; + break; + case BMODE_DIAG: + LCD_PUTS("entering DIAGNOSE-mode. "); + regw = 0x0F0F; + break; + case BMODE_SERVICE: + LCD_PUTS("entering SERVICE mode. "); + regw = 0xB4B4; + break; + case BMODE_RUN: + LCD_PUTS("loading OS... "); + regw = 0x0404; + break; + } + + board_boot_led(0); + + if (resetc.is_psoc) + rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0, + (u8 *)®w, 2); + else + rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0, + (u8 *)®w, 1); + + if (rc != 0) + printf("WARN: cannot write into resetcontroller!\n"); + + if (resetc.is_psoc) + printf("Reset: PSOC controller\n"); + else + printf("Reset: STM32 controller\n"); + + printf("Mode: %s\n", bootmodeascii[regw & 0x0F]); + env_set_ulong("b_mode", regw & 0x0F); + + return rc; +} diff --git a/board/BuR/common/br_resetc.h b/board/BuR/common/br_resetc.h new file mode 100644 index 0000000000..ba0689bf20 --- /dev/null +++ b/board/BuR/common/br_resetc.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * common reset-controller functions for B&R boards + * + * Copyright (C) 2019 Hannes Schmelzer + * B&R Industrial Automation GmbH - http://www.br-automation.com/ * + */ +#ifndef __CONFIG_BRRESETC_H__ +#define __CONFIG_BRRESETC_H__ +#include + +int br_resetc_regget(u8 reg, u8 *dst); +int br_resetc_regset(u8 reg, u8 val); +int br_resetc_bmode(void); + +/* reset controller register defines */ +#define RSTCTRL_CTRLREG 0x01 +#define RSTCTRL_SCRATCHREG0 0x04 +#define RSTCTRL_ENHSTATUS 0x07 +#define RSTCTRL_SCRATCHREG1 0x08 +#define RSTCTRL_RSTCAUSE 0x00 +#define RSTCTRL_ERSTCAUSE 0x09 +#define RSTCTRL_SPECGPIO_I 0x0A +#define RSTCTRL_SPECGPIO_O 0x0B + +#endif /* __CONFIG_BRRESETC_H__ */ From 2b1e242423cc9097b48ffb5454aad370055e7e93 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:15 +0200 Subject: [PATCH 05/32] board/BuR/brxre1: cosmetic cleanup - fixup coding style - drop unused 'PUSH_KEY' define Signed-off-by: Hannes Schmelzer --- board/BuR/brxre1/board.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/board/BuR/brxre1/board.c b/board/BuR/brxre1/board.c index 2d0ed41dde..6639f22784 100644 --- a/board/BuR/brxre1/board.c +++ b/board/BuR/brxre1/board.c @@ -30,11 +30,9 @@ /* -------------------------------------------------------------------------*/ /* -- defines for used GPIO Hardware -- */ -#define ESC_KEY (0+19) -#define LCD_PWR (0+5) -#define PUSH_KEY (0+31) -/* -------------------------------------------------------------------------*/ /* -- PSOC Resetcontroller Register defines -- */ +#define ESC_KEY (0 + 19) +#define LCD_PWR (0 + 5) /* I2C Address of controller */ #define RSTCTRL_ADDR 0x75 @@ -69,13 +67,13 @@ static int rstctrl_rw(u8 reg, unsigned char rnw, void *pdat, int size) } #if defined(CONFIG_SPL_BUILD) -/* TODO: check ram-timing ! */ static const struct ddr_data ddr3_data = { .datardsratio0 = MT41K256M16HA125E_RD_DQS, .datawdsratio0 = MT41K256M16HA125E_WR_DQS, .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, }; + static const struct cmd_control ddr3_cmd_ctrl_data = { .cmd0csratio = MT41K256M16HA125E_RATIO, .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, @@ -86,6 +84,7 @@ static const struct cmd_control ddr3_cmd_ctrl_data = { .cmd2csratio = MT41K256M16HA125E_RATIO, .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, }; + static struct emif_regs ddr3_emif_reg_data = { .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, @@ -104,8 +103,8 @@ static const struct ctrl_ioregs ddr3_ioregs = { .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, }; -#define OSC (V_OSCK/1000000) -const struct dpll_params dpll_ddr3 = { 400, OSC-1, 1, -1, -1, -1, -1}; +#define OSC (V_OSCK / 1000000) +const struct dpll_params dpll_ddr3 = { 400, OSC - 1, 1, -1, -1, -1, -1}; void am33xx_spl_board_init(void) { @@ -289,8 +288,8 @@ int board_late_init(void) char othbootargs[128]; snprintf(othbootargs, sizeof(othbootargs), "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", - (unsigned int) gd->fb_base-0x20, - (u32)env_get_ulong("vx_memtop", 16, gd->fb_base-0x20), + (u32)gd->fb_base - 0x20, + (u32)env_get_ulong("vx_memtop", 16, gd->fb_base - 0x20), (u32)env_get_ulong("vx_romfsbase", 16, 0), (u32)env_get_ulong("vx_romfssize", 16, 0)); env_set("othbootargs", othbootargs); From 1d260739bdb7ef0e8fc58654e52ecea69eaaf672 Mon Sep 17 00:00:00 2001 From: Hannes Schmelzer Date: Wed, 10 Apr 2019 14:13:16 +0200 Subject: [PATCH 06/32] board/BuR/brxre1: use common resetcontroller implementation The handling of regarding bootmode and early setup has been moved to central location 'common/br_resetc.c', so use this on brxre1 board. Signed-off-by: Hannes Schmelzer --- board/BuR/brxre1/Makefile | 1 + board/BuR/brxre1/board.c | 159 ++++---------------------------------- 2 files changed, 18 insertions(+), 142 deletions(-) diff --git a/board/BuR/brxre1/Makefile b/board/BuR/brxre1/Makefile index 1cf7124dbd..1d224e9e71 100644 --- a/board/BuR/brxre1/Makefile +++ b/board/BuR/brxre1/Makefile @@ -6,5 +6,6 @@ # Bernecker & Rainer Industrielektronik GmbH - http://www.br-automation.com/ obj-$(CONFIG_SPL_BUILD) += mux.o +obj-y += ../common/br_resetc.o obj-y += ../common/common.o obj-y += board.o diff --git a/board/BuR/brxre1/board.c b/board/BuR/brxre1/board.c index 6639f22784..0d1c6c4720 100644 --- a/board/BuR/brxre1/board.c +++ b/board/BuR/brxre1/board.c @@ -23,49 +23,20 @@ #include #include #include -#include #include #include "../common/bur_common.h" -#include +#include "../common/br_resetc.h" /* -------------------------------------------------------------------------*/ /* -- defines for used GPIO Hardware -- */ -/* -- PSOC Resetcontroller Register defines -- */ #define ESC_KEY (0 + 19) #define LCD_PWR (0 + 5) -/* I2C Address of controller */ -#define RSTCTRL_ADDR 0x75 -/* Register for CTRL-word */ -#define RSTCTRL_CTRLREG 0x01 -/* Register for giving some information to VxWorks OS */ -#define RSTCTRL_SCRATCHREG 0x04 - -/* -- defines for RSTCTRL_CTRLREG -- */ -#define RSTCTRL_FORCE_PWR_NEN 0x0404 -#define RSTCTRL_CAN_STB 0x4040 +#define RSTCTRL_FORCE_PWR_NEN 0x04 +#define RSTCTRL_CAN_STB 0x40 DECLARE_GLOBAL_DATA_PTR; -static int rstctrl_rw(u8 reg, unsigned char rnw, void *pdat, int size) -{ - struct udevice *i2cdev; - int rc; - - rc = i2c_get_chip_for_busnum(0, RSTCTRL_ADDR, 1, &i2cdev); - if (rc >= 0) { - if (rnw) - rc = dm_i2c_read(i2cdev, reg, pdat, size); - else - rc = dm_i2c_write(i2cdev, reg, pdat, size); - } else { - printf("%s: cannot get udevice for chip 0x%02x!\n", - __func__, RSTCTRL_ADDR); - } - - return rc; -} - #if defined(CONFIG_SPL_BUILD) static const struct ddr_data ddr3_data = { .datardsratio0 = MT41K256M16HA125E_RD_DQS, @@ -108,7 +79,6 @@ const struct dpll_params dpll_ddr3 = { 400, OSC - 1, 1, -1, -1, -1, -1}; void am33xx_spl_board_init(void) { - unsigned short buf; int rc; struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; @@ -142,10 +112,10 @@ void am33xx_spl_board_init(void) enable_i2c_pin_mux(); /* power-ON 3V3 via Resetcontroller */ - buf = RSTCTRL_FORCE_PWR_NEN | RSTCTRL_CAN_STB; - rc = rstctrl_rw(RSTCTRL_CTRLREG, 0, (uint8_t *)&buf, sizeof(buf)); + rc = br_resetc_regset(RSTCTRL_CTRLREG, + RSTCTRL_FORCE_PWR_NEN | RSTCTRL_CAN_STB); if (rc != 0) - printf("ERROR: cannot write to resetc (turn on PWR_nEN)\n"); + printf("ERROR: cannot write to resetc (turn on PWR_nEN)!\n"); pmicsetup(0, 0); } @@ -168,6 +138,9 @@ void sdram_init(void) */ int board_init(void) { + /* request common used gpios */ + gpio_request(ESC_KEY, "boot-key"); + if (power_tps65217_init(0)) printf("WARN: cannot setup PMIC 0x24 @ bus #0, not found!.\n"); @@ -175,117 +148,19 @@ int board_init(void) } #ifdef CONFIG_BOARD_LATE_INIT + +int board_boot_key(void) +{ + return gpio_get_value(ESC_KEY); +} + int board_late_init(void) { - const unsigned int toff = 1000; - unsigned int cnt = 3; - unsigned short buf = 0xAAAA; - unsigned char scratchreg = 0; - int rc; + char othbootargs[128]; - /* try to read out some boot-instruction from resetcontroller */ - rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 1, &scratchreg, sizeof(scratchreg)); - if (rc != 0) - printf("ERROR: read scratchregister (resetc) failed!\n"); - - if (gpio_request(ESC_KEY, "boot-key") != 0) { - printf("cannot request boot-key!\n"); - } else if (gpio_get_value(ESC_KEY)) { - do { - lcd_position_cursor(1, 8); - switch (cnt) { - case 3: - lcd_puts( - "release ESC-KEY to enter SERVICE-mode."); - break; - case 2: - lcd_puts( - "release ESC-KEY to enter DIAGNOSE-mode."); - break; - case 1: - lcd_puts( - "release ESC-KEY to enter BOOT-mode. "); - break; - } - mdelay(toff); - cnt--; - if (!gpio_get_value(ESC_KEY) && - gpio_get_value(PUSH_KEY) && 2 == cnt) { - lcd_position_cursor(1, 8); - lcd_puts( - "switching to network-console ... "); - env_set("bootcmd", "run netconsole"); - cnt = 4; - break; - } else if (!gpio_get_value(ESC_KEY) && - gpio_get_value(PUSH_KEY) && 1 == cnt) { - lcd_position_cursor(1, 8); - lcd_puts( - "starting u-boot script from USB ... "); - env_set("bootcmd", "run usbscript"); - cnt = 4; - break; - } else if ((!gpio_get_value(ESC_KEY) && - gpio_get_value(PUSH_KEY) && cnt == 0) || - (gpio_get_value(ESC_KEY) && - gpio_get_value(PUSH_KEY) && cnt == 0)) { - lcd_position_cursor(1, 8); - lcd_puts( - "starting script from network ... "); - env_set("bootcmd", "run netscript"); - cnt = 4; - break; - } else if (!gpio_get_value(ESC_KEY)) { - break; - } - } while (cnt); - } else if (scratchreg == 0xCC) { - lcd_position_cursor(1, 8); - lcd_puts( - "starting vxworks from network ... "); - env_set("bootcmd", "run netboot"); - cnt = 4; - } else if (scratchreg == 0xCD) { - lcd_position_cursor(1, 8); - lcd_puts( - "starting script from network ... "); - env_set("bootcmd", "run netscript"); - cnt = 4; - } else if (scratchreg == 0xCE) { - lcd_position_cursor(1, 8); - lcd_puts( - "starting AR from eMMC ... "); - env_set("bootcmd", "run mmcboot"); - cnt = 4; - } - - lcd_position_cursor(1, 8); - switch (cnt) { - case 0: - lcd_puts("entering BOOT-mode. "); - env_set("bootcmd", "run defaultAR"); - buf = 0x0000; - break; - case 1: - lcd_puts("entering DIAGNOSE-mode. "); - buf = 0x0F0F; - break; - case 2: - lcd_puts("entering SERVICE mode. "); - buf = 0xB4B4; - break; - case 3: - lcd_puts("loading OS... "); - buf = 0x0404; - break; - } - /* write bootinfo into scratchregister of resetcontroller */ - rc = rstctrl_rw(RSTCTRL_SCRATCHREG, 0, (uint8_t *)&buf, sizeof(buf)); - if (rc != 0) - printf("ERROR: write scratchregister (resetc) failed!\n"); + br_resetc_bmode(); /* setup othbootargs for bootvx-command (vxWorks bootline) */ - char othbootargs[128]; snprintf(othbootargs, sizeof(othbootargs), "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", (u32)gd->fb_base - 0x20, From 3174cafd9cbc130bfecc5b0097bdd0eb0749b73c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 10 Apr 2019 18:59:26 +0200 Subject: [PATCH 07/32] disk: part: fix typo %g/rathen then/rather than/ Signed-off-by: Heinrich Schuchardt --- disk/part.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk/part.c b/disk/part.c index f30f9e9187..98cc54db20 100644 --- a/disk/part.c +++ b/disk/part.c @@ -468,7 +468,7 @@ int blk_get_device_part_str(const char *ifname, const char *dev_part_str, #ifdef CONFIG_CMD_UBIFS /* - * Special-case ubi, ubi goes through a mtd, rathen then through + * Special-case ubi, ubi goes through a mtd, rather than through * a regular block device. */ if (0 == strcmp(ifname, "ubi")) { From 9bdfe290e9796dcbb87e3a079730391886a0099d Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Thu, 11 Apr 2019 00:58:49 +0200 Subject: [PATCH 08/32] tools/Makefile: get openssl CFLAGS from pkg-config Fixes building mkimage on systems where OpenSSL header files do not live in the standard include path. Signed-off-by: Pierre Bourdon --- tools/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/Makefile b/tools/Makefile index d377d85f74..12a3027e23 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -150,6 +150,8 @@ endif # MXSImage needs LibSSL ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X)$(CONFIG_FIT_SIGNATURE),) +HOSTCFLAGS_kwbimage.o += \ + $(shell pkg-config --cflags libssl libcrypto 2> /dev/null || echo "") HOSTLOADLIBES_mkimage += \ $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto") From ee8a4a3f9de011de306238a124680e9511c7a5f5 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Thu, 11 Apr 2019 11:13:13 +0200 Subject: [PATCH 09/32] cmd: pxe: Display splashscreen from extlinux.conf input The objective is to provide a simple way to retrieve a BMP file, and display it as splashscreen, from extlinux.conf file input. For this, we take example on https://www.syslinux.org/wiki/ index.php?title=Menu#The_advanced_menu_system and more particularly on MENU BACKGROUND chapter. For this, add "menu background" support in pxe command. As example, extlinux.conf content will look like: # Generic Distro Configuration file generated by OpenEmbedded menu title Select the boot mode TIMEOUT 20 menu background ../splash.bmp DEFAULT stm32mp157c-ev1-sdcard LABEL stm32mp157c-ev1-sdcard KERNEL /uImage FDT /stm32mp157c-ev1.dtb APPEND root=/dev/mmcblk0p6 rootwait rw earlyprintk console=ttySTM0,115200 Signed-off-by: Patrice Chotard --- cmd/pxe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cmd/pxe.c b/cmd/pxe.c index 274555319b..e77770237c 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "menu.h" @@ -488,6 +490,7 @@ struct pxe_label { * * title - the name of the menu as given by a 'menu title' line. * default_label - the name of the default label, if any. + * bmp - the bmp file name which is displayed in background * timeout - time in tenths of a second to wait for a user key-press before * booting the default label. * prompt - if 0, don't prompt for a choice unless the timeout period is @@ -498,6 +501,7 @@ struct pxe_label { struct pxe_menu { char *title; char *default_label; + char *bmp; int timeout; int prompt; struct list_head labels; @@ -850,6 +854,7 @@ enum token_type { T_FDTDIR, T_ONTIMEOUT, T_IPAPPEND, + T_BACKGROUND, T_INVALID }; @@ -883,6 +888,7 @@ static const struct token keywords[] = { {"fdtdir", T_FDTDIR}, {"ontimeout", T_ONTIMEOUT,}, {"ipappend", T_IPAPPEND,}, + {"background", T_BACKGROUND,}, {NULL, T_INVALID} }; @@ -1160,6 +1166,10 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, nest_level + 1); break; + case T_BACKGROUND: + err = parse_sliteral(c, &cfg->bmp); + break; + default: printf("Ignoring malformed menu command: %.*s\n", (int)(*c - s), s); @@ -1574,6 +1584,20 @@ static void handle_pxe_menu(cmd_tbl_t *cmdtp, struct pxe_menu *cfg) struct menu *m; int err; +#ifdef CONFIG_CMD_BMP + /* display BMP if available */ + if (cfg->bmp) { + if (get_relfile(cmdtp, cfg->bmp, load_addr)) { + run_command("cls", 0); + bmp_display(load_addr, + BMP_ALIGN_CENTER, BMP_ALIGN_CENTER); + } else { + printf("Skipping background bmp %s for failure\n", + cfg->bmp); + } + } +#endif + m = pxe_menu_to_menu(cfg); if (!m) return; From b07cc48ca16f54f51c28f9fa352a68da58ee5881 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Fri, 12 Apr 2019 12:37:03 +0200 Subject: [PATCH 10/32] main: add new bootstage ID for entering cli loop adding a new bootstage ID: BOOTSTAGE_ID_ENTER_CLI_LOOP Signed-off-by: Heiko Schocher --- common/cli.c | 1 + include/bootstage.h | 1 + 2 files changed, 2 insertions(+) diff --git a/common/cli.c b/common/cli.c index fea8f8004c..f4054fb1fc 100644 --- a/common/cli.c +++ b/common/cli.c @@ -213,6 +213,7 @@ err: void cli_loop(void) { + bootstage_mark(BOOTSTAGE_ID_ENTER_CLI_LOOP); #ifdef CONFIG_HUSH_PARSER parse_file_outer(); /* This point is never reached */ diff --git a/include/bootstage.h b/include/bootstage.h index c9408e7b12..5e7e242b83 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -181,6 +181,7 @@ enum bootstage_id { BOOTSTAGE_ID_BOOTM_START, BOOTSTAGE_ID_BOOTM_HANDOFF, BOOTSTAGE_ID_MAIN_LOOP, + BOOTSTAGE_ID_ENTER_CLI_LOOP, BOOTSTAGE_KERNELREAD_START, BOOTSTAGE_KERNELREAD_STOP, BOOTSTAGE_ID_BOARD_INIT, From 407a219261ecb949ff0048b7854861c0948e3ac5 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:42 -0400 Subject: [PATCH 11/32] arm: K3: Avoid use of MCU_PSRAM0 before SYSFW is loaded On HS devices the 512b region of reset isolated memory called MCU_PSRAM0 is firewalled by default. Until SYSFW is loaded we cannot use this memory. It is only used to store a single value left at the end of SRAM by ROM that will be needed later. Save that value to a global variable stored in the .data section. This section is used as .bss will be cleared between saving this value and using it. Signed-off-by: Andrew F. Davis Reviewed-by: Andreas Dannenberg Reviewed-by: Lokesh Vutla --- arch/arm/mach-k3/am6_init.c | 13 ++++++++----- arch/arm/mach-k3/include/mach/am6_hardware.h | 3 --- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index 77cd15f388..60a580305d 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -49,11 +49,16 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 7); } +/* + * This uninitialized global variable would normal end up in the .bss section, + * but the .bss is cleared between writing and reading this variable, so move + * it to the .data section. + */ +u32 bootindex __attribute__((section(".data"))); + static void store_boot_index_from_rom(void) { - u32 *boot_index = (u32 *)K3_BOOT_PARAM_TABLE_INDEX_VAL; - - *boot_index = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); + bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); } void board_init_f(ulong dummy) @@ -92,7 +97,6 @@ u32 spl_boot_mode(const u32 boot_device) { #if defined(CONFIG_SUPPORT_EMMC_BOOT) u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootindex = readl(K3_BOOT_PARAM_TABLE_INDEX_VAL); u32 bootmode = (devstat & CTRLMMR_MAIN_DEVSTAT_BOOTMODE_MASK) >> CTRLMMR_MAIN_DEVSTAT_BOOTMODE_SHIFT; @@ -168,7 +172,6 @@ static u32 __get_primary_bootmedia(u32 devstat) u32 spl_boot_device(void) { u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT); - u32 bootindex = readl(K3_BOOT_PARAM_TABLE_INDEX_VAL); if (bootindex == K3_PRIMARY_BOOTMODE) return __get_primary_bootmedia(devstat); diff --git a/arch/arm/mach-k3/include/mach/am6_hardware.h b/arch/arm/mach-k3/include/mach/am6_hardware.h index b5244609af..3343233aa3 100644 --- a/arch/arm/mach-k3/include/mach/am6_hardware.h +++ b/arch/arm/mach-k3/include/mach/am6_hardware.h @@ -44,7 +44,4 @@ #define CTRLMMR_LOCK_KICK1 0x0100c #define CTRLMMR_LOCK_KICK1_UNLOCK_VAL 0xd172bc5a -/* MCU SCRATCHPAD usage */ -#define K3_BOOT_PARAM_TABLE_INDEX_VAL CONFIG_SYS_K3_MCU_SCRATCHPAD_BASE - #endif /* __ASM_ARCH_AM6_HARDWARE_H */ From 32ca8ffd5b282da8f4767680ac8b440f73ad41b5 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:43 -0400 Subject: [PATCH 12/32] firmware: ti_sci: Add support for firewall management TI-SCI message protocol provides support for controlling the firewall configurations available in SoC. Introduce support for the set of TI-SCI message protocol APIs that provide us with this capability of controlling firewalls. Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- drivers/firmware/ti_sci.c | 177 +++++++++++++++++++++++++ drivers/firmware/ti_sci.h | 121 +++++++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 64 +++++++++ 3 files changed, 362 insertions(+) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index d47d22fff3..44bbeb66c2 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -2428,6 +2428,178 @@ fail: return ret; } +/** + * ti_sci_cmd_set_fwl_region() - Request for configuring a firewall region + * @handle: pointer to TI SCI handle + * @region: region configuration parameters + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, + const struct ti_sci_msg_fwl_region *region) +{ + struct ti_sci_msg_fwl_set_firewall_region_req req; + struct ti_sci_msg_hdr *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_SET, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + req.fwl_id = region->fwl_id; + req.region = region->region; + req.n_permission_regs = region->n_permission_regs; + req.control = region->control; + req.permissions[0] = region->permissions[0]; + req.permissions[1] = region->permissions[1]; + req.permissions[2] = region->permissions[2]; + req.start_address = region->start_address; + req.end_address = region->end_address; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + return 0; +} + +/** + * ti_sci_cmd_get_fwl_region() - Request for getting a firewall region + * @handle: pointer to TI SCI handle + * @region: region configuration parameters + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, + struct ti_sci_msg_fwl_region *region) +{ + struct ti_sci_msg_fwl_get_firewall_region_req req; + struct ti_sci_msg_fwl_get_firewall_region_resp *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET, + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + req.fwl_id = region->fwl_id; + req.region = region->region; + req.n_permission_regs = region->n_permission_regs; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + region->fwl_id = resp->fwl_id; + region->region = resp->region; + region->n_permission_regs = resp->n_permission_regs; + region->control = resp->control; + region->permissions[0] = resp->permissions[0]; + region->permissions[1] = resp->permissions[1]; + region->permissions[2] = resp->permissions[2]; + region->start_address = resp->start_address; + region->end_address = resp->end_address; + + return 0; +} + +/** + * ti_sci_cmd_change_fwl_owner() - Request for changing a firewall owner + * @handle: pointer to TI SCI handle + * @region: region configuration parameters + * + * Return: 0 if all went well, else returns appropriate error value. + */ +static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, + struct ti_sci_msg_fwl_owner *owner) +{ + struct ti_sci_msg_fwl_change_owner_info_req req; + struct ti_sci_msg_fwl_change_owner_info_resp *resp; + struct ti_sci_info *info; + struct ti_sci_xfer *xfer; + int ret = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + if (!handle) + return -EINVAL; + + info = handle_to_ti_sci_info(handle); + + xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_FWL_GET, + TISCI_MSG_FWL_CHANGE_OWNER, + (u32 *)&req, sizeof(req), sizeof(*resp)); + if (IS_ERR(xfer)) { + ret = PTR_ERR(xfer); + dev_err(info->dev, "Message alloc failed(%d)\n", ret); + return ret; + } + + req.fwl_id = owner->fwl_id; + req.region = owner->region; + req.owner_index = owner->owner_index; + + ret = ti_sci_do_xfer(info, xfer); + if (ret) { + dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; + } + + resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf; + + if (!ti_sci_is_response_ack(resp)) + return -ENODEV; + + owner->fwl_id = resp->fwl_id; + owner->region = resp->region; + owner->owner_index = resp->owner_index; + owner->owner_privid = resp->owner_privid; + owner->owner_permission_bits = resp->owner_permission_bits; + + return ret; +} + /* * ti_sci_setup_ops() - Setup the operations structures * @info: pointer to TISCI pointer @@ -2444,6 +2616,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops; struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops; struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops; + struct ti_sci_fwl_ops *fwl_ops = &ops->fwl_ops; bops->board_config = ti_sci_cmd_set_board_config; bops->board_config_rm = ti_sci_cmd_set_board_config_rm; @@ -2501,6 +2674,10 @@ static void ti_sci_setup_ops(struct ti_sci_info *info) udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg; udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg; udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg; + + fwl_ops->set_fwl_region = ti_sci_cmd_set_fwl_region; + fwl_ops->get_fwl_region = ti_sci_cmd_get_fwl_region; + fwl_ops->change_fwl_owner = ti_sci_cmd_change_fwl_owner; } /** diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 2d87cdd2cf..1b601ff01b 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -79,6 +79,10 @@ #define TISCI_MSG_RM_UDMAP_FLOW_GET_CFG 0x1232 #define TISCI_MSG_RM_UDMAP_FLOW_SIZE_THRESH_GET_CFG 0x1233 +#define TISCI_MSG_FWL_SET 0x9000 +#define TISCI_MSG_FWL_GET 0x9001 +#define TISCI_MSG_FWL_CHANGE_OWNER 0x9002 + /** * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses * @type: Type of messages: One of TI_SCI_MSG* values @@ -1338,4 +1342,121 @@ struct ti_sci_msg_rm_udmap_flow_cfg_resp { struct ti_sci_msg_hdr hdr; } __packed; +#define FWL_MAX_PRIVID_SLOTS 3U + +/** + * struct ti_sci_msg_fwl_set_firewall_region_req - Request for configuring the firewall permissions. + * + * @hdr: Generic Header + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number to set config info + * This field is unused in case of a simple firewall and must be initialized + * to zero. In case of a region based firewall, this field indicates the + * region in question. (index starting from 0) In case of a channel based + * firewall, this field indicates the channel in question (index starting + * from 0) + * @n_permission_regs: Number of permission registers to set + * @control: Contents of the firewall CONTROL register to set + * @permissions: Contents of the firewall PERMISSION register to set + * @start_address: Contents of the firewall START_ADDRESS register to set + * @end_address: Contents of the firewall END_ADDRESS register to set + */ + +struct ti_sci_msg_fwl_set_firewall_region_req { + struct ti_sci_msg_hdr hdr; + u16 fwl_id; + u16 region; + u32 n_permission_regs; + u32 control; + u32 permissions[FWL_MAX_PRIVID_SLOTS]; + u64 start_address; + u64 end_address; +} __packed; + +/** + * struct ti_sci_msg_fwl_get_firewall_region_req - Request for retrieving the firewall permissions + * + * @hdr: Generic Header + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number to get config info + * This field is unused in case of a simple firewall and must be initialized + * to zero. In case of a region based firewall, this field indicates the + * region in question (index starting from 0). In case of a channel based + * firewall, this field indicates the channel in question (index starting + * from 0). + * @n_permission_regs: Number of permission registers to retrieve + */ +struct ti_sci_msg_fwl_get_firewall_region_req { + struct ti_sci_msg_hdr hdr; + u16 fwl_id; + u16 region; + u32 n_permission_regs; +} __packed; + +/** + * struct ti_sci_msg_fwl_get_firewall_region_resp - Response for retrieving the firewall permissions + * + * @hdr: Generic Header + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number to set config info This field is + * unused in case of a simple firewall and must be initialized to zero. In + * case of a region based firewall, this field indicates the region in + * question. (index starting from 0) In case of a channel based firewall, this + * field indicates the channel in question (index starting from 0) + * @n_permission_regs: Number of permission registers retrieved + * @control: Contents of the firewall CONTROL register + * @permissions: Contents of the firewall PERMISSION registers + * @start_address: Contents of the firewall START_ADDRESS register This is not applicable for channelized firewalls. + * @end_address: Contents of the firewall END_ADDRESS register This is not applicable for channelized firewalls. + */ +struct ti_sci_msg_fwl_get_firewall_region_resp { + struct ti_sci_msg_hdr hdr; + u16 fwl_id; + u16 region; + u32 n_permission_regs; + u32 control; + u32 permissions[FWL_MAX_PRIVID_SLOTS]; + u64 start_address; + u64 end_address; +} __packed; + +/** + * struct ti_sci_msg_fwl_change_owner_info_req - Request for a firewall owner change + * + * @hdr: Generic Header + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number if applicable + * @owner_index: New owner index to transfer ownership to + */ +struct ti_sci_msg_fwl_change_owner_info_req { + struct ti_sci_msg_hdr hdr; + u16 fwl_id; + u16 region; + u8 owner_index; +} __packed; + +/** + * struct ti_sci_msg_fwl_change_owner_info_resp - Response for a firewall owner change + * + * @hdr: Generic Header + * + * @fwl_id: Firewall ID specified in request + * @region: Region or channel number specified in request + * @owner_index: Owner index specified in request + * @owner_privid: New owner priv-ID returned by DMSC. + * @owner_permission_bits: New owner permission bits returned by DMSC. + */ +struct ti_sci_msg_fwl_change_owner_info_resp { + struct ti_sci_msg_hdr hdr; + u16 fwl_id; + u16 region; + u8 owner_index; + u8 owner_privid; + u16 owner_permission_bits; +} __packed; + #endif /* __TI_SCI_H */ diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 222cf66546..895cb1b911 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -510,6 +510,68 @@ struct ti_sci_rm_udmap_ops { const struct ti_sci_msg_rm_udmap_flow_cfg *params); }; +/** + * struct ti_sci_msg_fwl_region_cfg - Request and Response for firewalls settings + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number to set config info + * This field is unused in case of a simple firewall and must be initialized + * to zero. In case of a region based firewall, this field indicates the + * region in question. (index starting from 0) In case of a channel based + * firewall, this field indicates the channel in question (index starting + * from 0) + * @n_permission_regs: Number of permission registers to set + * @control: Contents of the firewall CONTROL register to set + * @permissions: Contents of the firewall PERMISSION register to set + * @start_address: Contents of the firewall START_ADDRESS register to set + * @end_address: Contents of the firewall END_ADDRESS register to set + */ +struct ti_sci_msg_fwl_region { + u16 fwl_id; + u16 region; + u32 n_permission_regs; + u32 control; + u32 permissions[3]; + u64 start_address; + u64 end_address; +} __packed; + +/** + * \brief Request and Response for firewall owner change + * + * @fwl_id: Firewall ID in question + * @region: Region or channel number to set config info + * This field is unused in case of a simple firewall and must be initialized + * to zero. In case of a region based firewall, this field indicates the + * region in question. (index starting from 0) In case of a channel based + * firewall, this field indicates the channel in question (index starting + * from 0) + * @n_permission_regs: Number of permission registers <= 3 + * @control: Control register value for this region + * @owner_index: New owner index to change to. Owner indexes are setup in DMSC firmware boot configuration data + * @owner_privid: New owner priv-id, used to lookup owner_index is not known, must be set to zero otherwise + * @owner_permission_bits: New owner permission bits + */ +struct ti_sci_msg_fwl_owner { + u16 fwl_id; + u16 region; + u8 owner_index; + u8 owner_privid; + u16 owner_permission_bits; +} __packed; + +/** + * struct ti_sci_fwl_ops - Firewall specific operations + * @set_fwl_region: Request for configuring the firewall permissions. + * @get_fwl_region: Request for retrieving the firewall permissions. + * @change_fwl_owner: Request for a change of firewall owner. + */ +struct ti_sci_fwl_ops { + int (*set_fwl_region)(const struct ti_sci_handle *handle, const struct ti_sci_msg_fwl_region *region); + int (*get_fwl_region)(const struct ti_sci_handle *handle, struct ti_sci_msg_fwl_region *region); + int (*change_fwl_owner)(const struct ti_sci_handle *handle, struct ti_sci_msg_fwl_owner *owner); +}; + /** * struct ti_sci_ops - Function support for TI SCI * @board_ops: Miscellaneous operations @@ -518,6 +580,7 @@ struct ti_sci_rm_udmap_ops { * @core_ops: Core specific operations * @proc_ops: Processor specific operations * @ring_ops: Ring Accelerator Management operations + * @fw_ops: Firewall specific operations */ struct ti_sci_ops { struct ti_sci_board_ops board_ops; @@ -529,6 +592,7 @@ struct ti_sci_ops { struct ti_sci_rm_ringacc_ops rm_ring_ops; struct ti_sci_rm_psil_ops rm_psil_ops; struct ti_sci_rm_udmap_ops rm_udmap_ops; + struct ti_sci_fwl_ops fwl_ops; }; /** From ff6043a5fd9ada40d5890eb6cf4f624e22c14c80 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:44 -0400 Subject: [PATCH 13/32] firmware: ti_sci: Modify auth_boot TI-SCI API to match new version SYSFW version 2019.01 introduces a slightly modified version of this API, add support for it here. Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- drivers/firmware/ti_sci.c | 25 ++++++++++++++++--------- drivers/firmware/ti_sci.h | 9 +++++++-- include/linux/soc/ti/ti_sci_protocol.h | 4 ++-- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 44bbeb66c2..1196ce0712 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1915,16 +1915,19 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, * ti_sci_cmd_proc_auth_boot_image() - Command to authenticate and load the * image and then set the processor configuration flags. * @handle: Pointer to TI SCI handle - * @proc_id: Processor ID this request is for - * @cert_addr: Memory address at which payload image certificate is located. + * @image_addr: Memory address at which payload image and certificate is + * located in memory, this is updated if the image data is + * moved during authentication. + * @image_size: This is updated with the final size of the image after + * authentication. * * Return: 0 if all went well, else returns appropriate error value. */ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, - u8 proc_id, u64 cert_addr) + u64 *image_addr, u32 *image_size) { struct ti_sci_msg_req_proc_auth_boot_image req; - struct ti_sci_msg_hdr *resp; + struct ti_sci_msg_resp_proc_auth_boot_image *resp; struct ti_sci_info *info; struct ti_sci_xfer *xfer; int ret = 0; @@ -1944,9 +1947,8 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } - req.processor_id = proc_id; - req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; - req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> + req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK; + req.cert_addr_high = (*image_addr & TISCI_ADDR_HIGH_MASK) >> TISCI_ADDR_HIGH_SHIFT; ret = ti_sci_do_xfer(info, xfer); @@ -1955,10 +1957,15 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, return ret; } - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf; if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; + return -ENODEV; + + *image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) | + (((u64)resp->image_addr_high << + TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); + *image_size = resp->image_size; return ret; } diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 1b601ff01b..a484b1fa40 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -708,7 +708,6 @@ struct ti_sci_msg_req_set_proc_boot_ctrl { /** * struct ti_sci_msg_req_proc_auth_start_image - Authenticate and start image * @hdr: Generic Header - * @processor_id: ID of processor * @cert_addr_low: Lower 32bit (Little Endian) of certificate * @cert_addr_high: Higher 32bit (Little Endian) of certificate * @@ -717,11 +716,17 @@ struct ti_sci_msg_req_set_proc_boot_ctrl { */ struct ti_sci_msg_req_proc_auth_boot_image { struct ti_sci_msg_hdr hdr; - u8 processor_id; u32 cert_addr_low; u32 cert_addr_high; } __packed; +struct ti_sci_msg_resp_proc_auth_boot_image { + struct ti_sci_msg_hdr hdr; + u32 image_addr_low; + u32 image_addr_high; + u32 image_size; +} __packed; + /** * struct ti_sci_msg_req_get_proc_boot_status - Get processor boot status * @hdr: Generic Header diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index 895cb1b911..c57802f293 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -279,8 +279,8 @@ struct ti_sci_proc_ops { u64 bv, u32 cfg_set, u32 cfg_clr); int (*set_proc_boot_ctrl)(const struct ti_sci_handle *handle, u8 pid, u32 ctrl_set, u32 ctrl_clr); - int (*proc_auth_boot_image)(const struct ti_sci_handle *handle, u8 pid, - u64 caddr); + int (*proc_auth_boot_image)(const struct ti_sci_handle *handle, + u64 *image_addr, u32 *image_size); int (*get_proc_boot_status)(const struct ti_sci_handle *handle, u8 pid, u64 *bv, u32 *cfg_flags, u32 *ctrl_flags, u32 *sts_flags); From 3a543a8084aabae5b31b9858525cbe507d2c67fb Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:45 -0400 Subject: [PATCH 14/32] arm: mach-k3: Add secure device support K3 devices have High Security (HS) variants along with the non-HS already supported. Like the previous generation devices (OMAP/Keystone2) K3 supports boot chain-of-trust by authenticating and optionally decrypting images as they are unpacked from FIT images. Add support for this here. Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- MAINTAINERS | 1 + arch/arm/Kconfig | 2 +- arch/arm/mach-k3/Makefile | 1 + arch/arm/mach-k3/security.c | 63 +++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-k3/security.c diff --git a/MAINTAINERS b/MAINTAINERS index 8a7f0cc370..dab419e3f3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -733,6 +733,7 @@ S: Supported F: arch/arm/mach-omap2/omap5/sec_entry_cpu1.S F: arch/arm/mach-omap2/sec-common.c F: arch/arm/mach-omap2/config_secure.mk +F: arch/arm/mach-k3/security.c F: configs/am335x_hs_evm_defconfig F: configs/am335x_hs_evm_uart_defconfig F: configs/am43xx_hs_evm_defconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dd5ac69a8e..0a76138a92 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1464,7 +1464,7 @@ endchoice config TI_SECURE_DEVICE bool "HS Device Type Support" - depends on ARCH_KEYSTONE || ARCH_OMAP2PLUS + depends on ARCH_KEYSTONE || ARCH_OMAP2PLUS || ARCH_K3 help If a high secure (HS) device type is being used, this config must be set. This option impacts various aspects of the diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile index bd4ab361b2..0c3a4f7db1 100644 --- a/arch/arm/mach-k3/Makefile +++ b/arch/arm/mach-k3/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_SOC_K3_AM6) += am6_init.o obj-$(CONFIG_ARM64) += arm64-mmu.o obj-$(CONFIG_CPU_V7R) += r5_mpu.o lowlevel_init.o +obj-$(CONFIG_TI_SECURE_DEVICE) += security.o obj-y += common.o diff --git a/arch/arm/mach-k3/security.c b/arch/arm/mach-k3/security.c new file mode 100644 index 0000000000..52f49bf01f --- /dev/null +++ b/arch/arm/mach-k3/security.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * K3: Security functions + * + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + */ + +#include +#include +#include +#include +#include + +void board_fit_image_post_process(void **p_image, size_t *p_size) +{ + struct udevice *dev; + struct ti_sci_handle *ti_sci; + struct ti_sci_proc_ops *proc_ops; + u64 image_addr; + u32 image_size; + int ret; + + /* Get handle to Device Management and Security Controller (SYSFW) */ + ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc", &dev); + if (ret) { + printf("Failed to get handle to SYSFW (%d)\n", ret); + hang(); + } + ti_sci = (struct ti_sci_handle *)(ti_sci_get_handle_from_sysfw(dev)); + proc_ops = &ti_sci->ops.proc_ops; + + image_addr = (uintptr_t)*p_image; + + debug("Authenticating image at address 0x%016llx\n", image_addr); + + /* Authenticate image */ + ret = proc_ops->proc_auth_boot_image(ti_sci, &image_addr, &image_size); + if (ret) { + printf("Authentication failed!\n"); + hang(); + } + + /* + * The image_size returned may be 0 when the authentication process has + * moved the image. When this happens no further processing on the + * image is needed or often even possible as it may have also been + * placed behind a firewall when moved. + */ + *p_size = image_size; + + /* + * Output notification of successful authentication to re-assure the + * user that the secure code is being processed as expected. However + * suppress any such log output in case of building for SPL and booting + * via YMODEM. This is done to avoid disturbing the YMODEM serial + * protocol transactions. + */ + if (!(IS_ENABLED(CONFIG_SPL_BUILD) && + IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) && + spl_boot_device() == BOOT_DEVICE_UART)) + printf("Authentication passed\n"); +} From 508369672ca3bc32806b70b5189f18a257e91baf Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:46 -0400 Subject: [PATCH 15/32] arm: mach-k3: Add secure device build support K3 HS devices require signed binaries for boot, use the SECDEV tools to sign the boot artifacts during build. Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- MAINTAINERS | 1 + arch/arm/mach-k3/config.mk | 25 ++++++++++++++++++ arch/arm/mach-k3/config_secure.mk | 44 +++++++++++++++++++++++++++++++ tools/k3_fit_atf.sh | 8 ++++-- 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-k3/config_secure.mk diff --git a/MAINTAINERS b/MAINTAINERS index dab419e3f3..0e8e3d4c3c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -734,6 +734,7 @@ F: arch/arm/mach-omap2/omap5/sec_entry_cpu1.S F: arch/arm/mach-omap2/sec-common.c F: arch/arm/mach-omap2/config_secure.mk F: arch/arm/mach-k3/security.c +F: arch/arm/mach-k3/config_secure.mk F: configs/am335x_hs_evm_defconfig F: configs/am335x_hs_evm_uart_defconfig F: configs/am43xx_hs_evm_defconfig diff --git a/arch/arm/mach-k3/config.mk b/arch/arm/mach-k3/config.mk index be00d79fb0..2d8f61f9db 100644 --- a/arch/arm/mach-k3/config.mk +++ b/arch/arm/mach-k3/config.mk @@ -36,6 +36,14 @@ cmd_gencert = cat $(srctree)/tools/k3_x509template.txt | sed $(SED_OPTS) > u-boo # If external key is not provided, generate key using openssl. ifeq ($(CONFIG_SYS_K3_KEY), "") KEY=u-boot-spl-eckey.pem +# On HS use real key or warn if not available +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/keys/custMpk.pem),) +KEY=$(TI_SECURE_DEV_PKG)/keys/custMpk.pem +else +$(warning "WARNING: signing key not found. Random key will NOT work on HS hardware!") +endif +endif else KEY=$(patsubst "%",$(srctree)/%,$(CONFIG_SYS_K3_KEY)) endif @@ -65,6 +73,15 @@ ALL-y += tiboot3.bin endif ifdef CONFIG_ARM64 +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +SPL_ITS := u-boot-spl-k3_HS.its +$(SPL_ITS): FORCE + IS_HS=1 \ + $(srctree)/tools/k3_fit_atf.sh \ + $(patsubst %,$(obj)/dts/%.dtb,$(subst ",,$(CONFIG_SPL_OF_LIST))) > $@ + +ALL-y += tispl.bin_HS +else SPL_ITS := u-boot-spl-k3.its $(SPL_ITS): FORCE $(srctree)/tools/k3_fit_atf.sh \ @@ -72,7 +89,15 @@ $(SPL_ITS): FORCE ALL-y += tispl.bin endif +endif +else + +ifeq ($(CONFIG_TI_SECURE_DEVICE),y) +ALL-y += u-boot.img_HS else ALL-y += u-boot.img endif +endif + +include $(srctree)/arch/arm/mach-k3/config_secure.mk diff --git a/arch/arm/mach-k3/config_secure.mk b/arch/arm/mach-k3/config_secure.mk new file mode 100644 index 0000000000..6d63c57665 --- /dev/null +++ b/arch/arm/mach-k3/config_secure.mk @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2018 Texas Instruments, Incorporated - http://www.ti.com/ +# Andrew F. Davis + +quiet_cmd_k3secureimg = SECURE $@ +ifneq ($(TI_SECURE_DEV_PKG),) +ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),) +cmd_k3secureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \ + $< $@ \ + $(if $(KBUILD_VERBOSE:1=), >/dev/null) +else +cmd_k3secureimg = echo "WARNING:" \ + "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \ + "$@ was NOT secured!"; cp $< $@ +endif +else +cmd_k3secureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \ + "variable must be defined for TI secure devices." \ + "$@ was NOT secured!"; cp $< $@ +endif + +%.dtb_HS: %.dtb FORCE + $(call if_changed,k3secureimg) + +$(obj)/u-boot-spl-nodtb.bin_HS: $(obj)/u-boot-spl-nodtb.bin FORCE + $(call if_changed,k3secureimg) + +tispl.bin_HS: $(obj)/u-boot-spl-nodtb.bin_HS $(patsubst %,$(obj)/dts/%.dtb_HS,$(subst ",,$(CONFIG_SPL_OF_LIST))) $(SPL_ITS) FORCE + $(call if_changed,mkfitimage) + +MKIMAGEFLAGS_u-boot.img_HS = -f auto -A $(ARCH) -T firmware -C none -O u-boot \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \ + -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \ + $(patsubst %,-b arch/$(ARCH)/dts/%.dtb_HS,$(subst ",,$(CONFIG_OF_LIST))) + +OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST))) +$(OF_LIST_TARGETS): dtbs + +u-boot-nodtb.bin_HS: u-boot-nodtb.bin FORCE + $(call if_changed,k3secureimg) + +u-boot.img_HS: u-boot-nodtb.bin_HS u-boot.img $(patsubst %.dtb,%.dtb_HS,$(OF_LIST_TARGETS)) FORCE + $(call if_changed,mkimage) diff --git a/tools/k3_fit_atf.sh b/tools/k3_fit_atf.sh index 430b5ca616..4e9f69c087 100755 --- a/tools/k3_fit_atf.sh +++ b/tools/k3_fit_atf.sh @@ -21,6 +21,10 @@ if [ ! -f $TEE ]; then TEE=/dev/null fi +if [ ! -z "$IS_HS" ]; then + HS_APPEND=_HS +fi + cat << __HEADER_EOF /dts-v1/; @@ -51,7 +55,7 @@ cat << __HEADER_EOF }; spl { description = "SPL (64-bit)"; - data = /incbin/("spl/u-boot-spl-nodtb.bin"); + data = /incbin/("spl/u-boot-spl-nodtb.bin$HS_APPEND"); type = "standalone"; os = "U-Boot"; arch = "arm64"; @@ -66,7 +70,7 @@ do cat << __FDT_IMAGE_EOF $(basename $dtname) { description = "$(basename $dtname .dtb)"; - data = /incbin/("$dtname"); + data = /incbin/("$dtname$HS_APPEND"); type = "flat_dt"; arch = "arm"; compression = "none"; From 0a4b11b027793d96ffb04b0144f6107c16ce7c1c Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:47 -0400 Subject: [PATCH 16/32] configs: Add configs for AM65x High Security EVM Add new defconfig files for the AM65x High Security EVM. This defconfigs are the same as for the non-secure part, except for: CONFIG_TI_SECURE_DEVICE option set to 'y' CONFIG_FIT_IMAGE_POST_PROCESS option set to 'y' CONFIG_SPL_FIT_IMAGE_POST_PROCESS option set to 'y' Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- MAINTAINERS | 2 + configs/am65x_hs_evm_a53_defconfig | 77 +++++++++++++++++++++++++ configs/am65x_hs_evm_r5_defconfig | 90 ++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 configs/am65x_hs_evm_a53_defconfig create mode 100644 configs/am65x_hs_evm_r5_defconfig diff --git a/MAINTAINERS b/MAINTAINERS index 0e8e3d4c3c..09f31cd483 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -746,6 +746,8 @@ F: configs/k2hk_hs_evm_defconfig F: configs/k2e_hs_evm_defconfig F: configs/k2g_hs_evm_defconfig F: configs/k2l_hs_evm_defconfig +F: configs/am65x_hs_evm_r5_defconfig +F: configs/am65x_hs_evm_a53_defconfig TQ GROUP #M: Martin Krause diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig new file mode 100644 index 0000000000..dcafa458e0 --- /dev/null +++ b/configs/am65x_hs_evm_a53_defconfig @@ -0,0 +1,77 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SOC_K3_AM6=y +CONFIG_TARGET_AM654_A53_EVM=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=2 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run run_kern" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_REMOTEPROC=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_CMD_ASKENV=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +# CONFIG_ISO_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="k3-am654-base-board" +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_INTERFACE="mmc" +CONFIG_ENV_FAT_DEVICE_AND_PART="1:1" +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_TI_SCI=y +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_K3_ARASAN=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_K3=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_TI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y diff --git a/configs/am65x_hs_evm_r5_defconfig b/configs/am65x_hs_evm_r5_defconfig new file mode 100644 index 0000000000..1b9c138c03 --- /dev/null +++ b/configs/am65x_hs_evm_r5_defconfig @@ -0,0 +1,90 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_SOC_K3_AM6=y +CONFIG_TARGET_AM654_R5_EVM=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_ASKENV=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="k3-am654-r5-base-board" +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_INTERFACE="mmc" +CONFIG_ENV_FAT_DEVICE_AND_PART="1:1" +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_TI_SCI=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DM_GPIO=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_K3_ARASAN=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_SPL_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_K3=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y From 74ee9dc502de45bf44a8d5b94458ef12437085f4 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Fri, 12 Apr 2019 12:54:48 -0400 Subject: [PATCH 17/32] doc: Update info on using K3 secure devices Signed-off-by: Andrew F. Davis Reviewed-by: Tom Rini Reviewed-by: Andreas Dannenberg --- doc/README.ti-secure | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/doc/README.ti-secure b/doc/README.ti-secure index 76950253ac..27c0eaa77f 100644 --- a/doc/README.ti-secure +++ b/doc/README.ti-secure @@ -138,7 +138,7 @@ Booting of U-Boot SPL Invoking the script for Keystone2 Secure Devices - ============================================= + ================================================ create-boot-image.sh \ @@ -157,6 +157,18 @@ Booting of U-Boot SPL boot from all media. Secure boot from SPI NOR flash is not currently supported. + Invoking the script for K3 Secure Devices + ========================================= + + The signing steps required to produce a bootable SPL image on secure + K3 TI devices are the same as those performed on non-secure devices. + The only difference is the key is not checked on non-secure devices so + a dummy key is used when building U-Boot for those devices. For secure + K3 TI devices simply use the real hardware key for your device. This + real key can be set with the Kconfig option "K3_KEY". The environment + variable TI_SECURE_DEV_PKG is also searched for real keys when the + build targets secure devices. + Booting of Primary U-Boot (u-boot.img) ====================================== @@ -181,10 +193,8 @@ Booting of Primary U-Boot (u-boot.img) is enabled through the CONFIG_SPL_FIT_IMAGE_POST_PROCESS option which must be enabled for the secure boot scheme to work. In order to allow verifying proper operation of the secure boot chain in case of successful - authentication messages like "Authentication passed: CERT_U-BOOT-NOD" are - output by the SPL to the console for each blob that got extracted from the - FIT image. Note that the last part of this log message is the (truncated) - name of the signing certificate embedded into the blob that got processed. + authentication messages like "Authentication passed" are output by the + SPL to the console for each blob that got extracted from the FIT image. The exact details of the how the images are secured is handled by the SECDEV package. Within the SECDEV package exists a script to process From 633967f9818cb6a0e87ffa8cba33148a5bcc6edb Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sat, 13 Apr 2019 23:50:49 +0200 Subject: [PATCH 18/32] fs: btrfs: fix false negatives in ROOT_ITEM search ROOT_ITEMs in btrfs are referenced without knowing their actual "offset" value. To perform these searches using only two items from the key, the btrfs driver uses a special "btrfs_search_tree_key_type" function. The algorithm used by that function to transform a 3-tuple search into a 2-tuple search was subtly broken, leading to items not being found if they were the first in their tree node. This commit fixes btrfs_search_tree_key_type to properly behave in these situations. Signed-off-by: Pierre Bourdon Cc: Marek Behun --- fs/btrfs/ctree.h | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 65c152a52f..ca44a2404d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -292,20 +292,52 @@ btrfs_search_tree_key_type(const struct btrfs_root *root, u64 objectid, { struct btrfs_key key, *res; + /* + * In some cases (e.g. tree roots), we need to look for a given + * objectid and type without knowing the offset value (3rd element of a + * btrfs tree node key). We can rely on the fact that btrfs_search_tree + * returns the first element with key >= search_key, and then perform + * our own comparison between the returned element and the search key. + * + * It is tempting to use a search key with offset 0 to perform this + * "fuzzy search". This would return the first item with the (objectid, + * type) we're looking for. However, using offset 0 has the wrong + * behavior when the wanted item is the first in a leaf: since our + * search key will be lower than the wanted item, the recursive search + * will explore the wrong branch of the tree. + * + * Instead, use the largest possible offset (-1). The result of this + * search will either be: + * 1. An element with the (objectid, type) we're looking for, if it + * has offset -1 or if it is the last element in its leaf. + * 2. The first element *after* an element with the (objectid, type) + */ key.objectid = objectid; key.type = type; - key.offset = 0; + key.offset = -1; if (btrfs_search_tree(root, &key, path)) return NULL; - res = btrfs_path_leaf_key(path); - if (btrfs_comp_keys_type(&key, res)) { - btrfs_free_path(path); - return NULL; + /* + * Compare with the previous element first -- this is the likely case + * since the result of the search is only what we want if it had offset + * == -1 or if it was last in its leaf. + */ + if (path->slots[0] > 0) { + path->slots[0]--; + res = btrfs_path_leaf_key(path); + if (!btrfs_comp_keys_type(&key, res)) + return res; + path->slots[0]++; } - return res; + res = btrfs_path_leaf_key(path); + if (!btrfs_comp_keys_type(&key, res)) + return res; + + btrfs_free_path(path); + return NULL; } static inline u32 btrfs_path_item_size(struct btrfs_path *p) From 423eba241d7cb7503bb9c41e02b17e71def86af7 Mon Sep 17 00:00:00 2001 From: Ismael Luceno Cortes Date: Mon, 15 Apr 2019 11:19:15 +0000 Subject: [PATCH 19/32] fs: fat: Build only if CONFIG_FS_FAT=y Signed-off-by: Ismael Luceno --- fs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/Makefile b/fs/Makefile index 10c735ad43..2ed4aeac0e 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_FS_BTRFS) += btrfs/ obj-$(CONFIG_FS_CBFS) += cbfs/ obj-$(CONFIG_CMD_CRAMFS) += cramfs/ obj-$(CONFIG_FS_EXT4) += ext4/ -obj-y += fat/ +obj-$(CONFIG_FS_FAT) += fat/ obj-$(CONFIG_FS_JFFS2) += jffs2/ obj-$(CONFIG_CMD_REISER) += reiserfs/ obj-$(CONFIG_SANDBOX) += sandbox/ From 1627e5e5985d92bebdbfb19ab783eaf69337900e Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Tue, 16 Apr 2019 02:47:14 +0200 Subject: [PATCH 20/32] fs: btrfs: fix btrfs_search_tree invalid results btrfs_search_tree should return the first item in the tree that is greater or equal to the searched item. The search algorithm did not properly handle the edge case where the searched item is higher than the last item of the node but lower than the first item of the next node. Instead of properly returning the first item of the next node, it was returning an invalid path pointer (pointing to a non-existent item after the last item of the node + 1). This fixes two issues in the btrfs driver: - Looking for a ROOT_ITEM could fail if it was the first item of its leaf node. - Iterating through DIR_INDEX entries (for readdir) could fail if the first DIR_INDEX entry was the first item of a leaf node. Signed-off-by: Pierre Bourdon Cc: Marek Behun --- fs/btrfs/ctree.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index d248d79932..7fae383f15 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -185,10 +185,20 @@ int btrfs_search_tree(const struct btrfs_root *root, struct btrfs_key *key, p->slots[lvl] = slot; p->nodes[lvl] = buf; - if (lvl) + if (lvl) { logical = buf->node.ptrs[slot].blockptr; - else + } else { + /* + * The path might be invalid if: + * cur leaf max < searched value < next leaf min + * + * Jump to the next valid element if it exists. + */ + if (slot >= buf->header.nritems) + if (btrfs_next_slot(p) < 0) + goto err; break; + } } return 0; From e9cde87ec1eaba3b5233093aec8f4f6c256b3a54 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 16 Apr 2019 13:31:58 +0200 Subject: [PATCH 21/32] dtb_platdata.py: prevent define generation of alias generate define for an alias only if the struct is not created already. This prevents compilerwarning: PLAT spl/dts/dt-platdata.o spl/dts/dt-platdata.c:11:46: error: missing braces around initializer [-Werror=missing-braces] static const struct dtd_simple_bus dtv_ahb = { ^ spl/dts/dt-platdata.c:20:46: error: missing braces around initializer [-Werror=missing-braces] static const struct dtd_simple_bus dtv_apb = { ^ cc1: all warnings being treated as errors on the at91 based taurus board. Reason is in at91sam9260.dtsi is defined: ahb { compatible = "simple-bus"; ranges; and later: pinctrl: pinctrl@fffff400 { compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff400 0xfffff400 0x600>; without this patch dtoc generates: struct dtd_atmel_at91rm9200_pinctrl { fdt32_t atmel_mux_mask[6]; fdt32_t ranges[3]; fdt32_t reg[6]; }; struct dtd_simple_bus { bool ranges; }; "#define dtd_simple_bus dtd_atmel_at91rm9200_pinctrl" and the line with "define dtd_simple_bus..." introduces the warning. This define is not needed. Signed-off-by: Heiko Schocher --- tools/dtoc/dtb_platdata.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index ca580b45d4..17a3dccb11 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -450,8 +450,9 @@ class DtbPlatdata(object): self.out('};\n') for alias, struct_name in self._aliases.iteritems(): - self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias, - STRUCT_PREFIX, struct_name)) + if alias not in sorted(structs): + self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias, + STRUCT_PREFIX, struct_name)) def output_node(self, node): """Output the C code for a node From 5f626e78491c95dbf3e5036cc0c67aea8b1746fd Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 17 Apr 2019 11:22:05 +0200 Subject: [PATCH 22/32] mtd: nand: raw: Fix CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT behavior The purpose of "mtd: nand: raw: allow to disable unneeded ECC layouts" was to allow disabling the default ECC layouts if a driver is known to provide its own ECC layout. However, this commit did the opposite and disabled the default layout when it was _not_ selected. It breaks all the NAND drivers not providing their own ECC layout this patch fix this situation. It was tested with the lpc32xx_nand_slc driver. Fixes: a38c3af868 ("mtd: nand: raw: allow to disable unneeded ECC layouts") Reviewed-by: Miquel Raynal Signed-off-by: Gregory CLEMENT Tested-by: Eugen Hristev --- drivers/mtd/nand/raw/nand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e07bd6b657..aba8ac019d 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -47,7 +47,7 @@ #include /* Define default oob placement schemes for large and small page devices */ -#ifdef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT +#ifndef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, .eccpos = {0, 1, 2}, @@ -5034,7 +5034,7 @@ int nand_scan_tail(struct mtd_info *mtd) */ if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) { switch (mtd->oobsize) { -#ifdef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT +#ifndef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT case 8: ecc->layout = &nand_oob_8; break; From 32dfc12b703faf9e6ab1e544a05ec5dba7d45449 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 17 Apr 2019 11:41:42 +0200 Subject: [PATCH 23/32] net: lpc32xx: Use IRAM for transmit buffer Since the introduction of the driver, some memory in IRAM is reserved for the TX buffers. However there are not used but instead of it, it is the buffer provided by the net stack which is used. As stated in the comment of the driver, not using the IRAM buffer could cause cache issue and lower the throughput. For the second argument it is less the case for transmitting buffers because the throughput gain in IRAM is mitigated by the time to copy the data from RAM to IRAM, but the first argument is still valid and indeed this patch fixes issue seen with Ethernet on some boards Signed-off-by: Gregory CLEMENT --- drivers/net/lpc32xx_eth.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c index 2d15fc8db2..ec5184edf8 100644 --- a/drivers/net/lpc32xx_eth.c +++ b/drivers/net/lpc32xx_eth.c @@ -373,7 +373,8 @@ static int lpc32xx_eth_send(struct eth_device *dev, void *dataptr, int datasize) tx_index = readl(®s->txproduceindex); /* set up transmit packet */ - writel((u32)dataptr, &bufs->tx_desc[tx_index].packet); + memcpy((void *)&bufs->tx_buf[tx_index * PKTSIZE_ALIGN], + (void *)dataptr, datasize); writel(TX_CTRL_LAST | ((datasize - 1) & TX_CTRL_TXSIZE), &bufs->tx_desc[tx_index].control); writel(0, &bufs->tx_stat[tx_index].statusinfo); @@ -508,6 +509,11 @@ static int lpc32xx_eth_init(struct eth_device *dev) writel((u32)(&bufs->rx_stat), ®s->rxstatus); writel(RX_BUF_COUNT-1, ®s->rxdescriptornumber); + /* set up transmit buffers */ + for (index = 0; index < TX_BUF_COUNT; index++) + bufs->tx_desc[index].packet = + (u32)(bufs->tx_buf + index * PKTSIZE_ALIGN); + /* Enable broadcast and matching address packets */ writel(RXFILTERCTRL_ACCEPTBROADCAST | RXFILTERCTRL_ACCEPTPERFECT, ®s->rxfilterctrl); From c8aac24629dec56334c27d98e993d2b3bb481b25 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 17 Apr 2019 11:48:45 +0200 Subject: [PATCH 24/32] arm: lpc32xx: Fix timer initialization The match controller register is not cleared during initialization. However, some bits of this register may reset the TC if tnMRx match it. As we can't make any assumption about how U-Boot is launched by the first stage bootloader (such as S1L) clearing this register ensure that the timers work as expected. Signed-off-by: Gregory CLEMENT --- arch/arm/cpu/arm926ejs/lpc32xx/timer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/cpu/arm926ejs/lpc32xx/timer.c b/arch/arm/cpu/arm926ejs/lpc32xx/timer.c index 404ccbb716..b3ca686040 100644 --- a/arch/arm/cpu/arm926ejs/lpc32xx/timer.c +++ b/arch/arm/cpu/arm926ejs/lpc32xx/timer.c @@ -33,6 +33,9 @@ static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq) /* Set prescale counter value */ writel((get_periph_clk_rate() / freq) - 1, &timer->pr); + + /* Ensure that the counter is not reset when matching TC */ + writel(0, &timer->mcr); } static void lpc32xx_timer_count(struct timer_regs *timer, int enable) From 2b4ea2b34416b892fdf54d8f334106f9bf4df8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Wed, 17 Apr 2019 16:56:54 +0200 Subject: [PATCH 25/32] fw_env: Fix double free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit addr0 is being freed twice, leading to segmentation fault Signed-off-by: Björn Stenberg --- tools/env/fw_env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index a5d75958e1..1ed0f7e9cb 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1566,7 +1566,7 @@ int fw_env_open(struct env_opts *opts) free(addr0); if (addr1) - free(addr0); + free(addr1); return ret; } From fd3c26f3f921ad7addf95857cdb99a883c6e497a Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Wed, 17 Apr 2019 11:21:56 -0500 Subject: [PATCH 26/32] ARM: da850evm: Fix broken SPI Flash A previous patch converted a bunch of settings for CONFIG_SF_DEFAULT but it broke the SPI Flash which now prevents booting. This patch now correctly sets CONFIG_SF_DEFAULT_SPEED=30000000 to match what it was before the conversion. Fixes: 14453fbfadc2 ("Convert CONFIG_SF_DEFAULT_* to Kconfig") Signed-off-by: Adam Ford --- configs/da850evm_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index 4b09ba10a6..745ae2b4b1 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -55,6 +55,7 @@ CONFIG_DM_MMC=y CONFIG_MTD_DEVICE=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y CONFIG_SPI_FLASH_MTD=y From cd2d8245ac364b15becbf117dec4cfa677f21cee Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Wed, 17 Apr 2019 13:24:33 -0500 Subject: [PATCH 27/32] ARM: da850evm: Fix TI boot scripts for MMC The da850evm include environment/ti/mmc.h and places DEFAULT_MMC_TI_ARGS, defined int that file, in CONFIG_EXTRA_ENV_SETTINGS. This has been broken for some time since neither CMD_PART nor CMD_UUID are available, so manually changing the environmental variables was always required before booting from MMC. With this patch, these scripts should work again, and by default they point to mmc 0, partition 2, and the dtb file exists in a /boot directory on partition 2. Signed-off-by: Adam Ford --- configs/da850evm_defconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index 745ae2b4b1..ee39b0b1bc 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -9,9 +9,9 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SYS_MALLOC_F_LEN=0x800 CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL=y +CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 CONFIG_SYS_EXTRA_OPTIONS="MAC_ADDR_IN_SPIFLASH" CONFIG_BOOTDELAY=3 CONFIG_DEFAULT_FDT_FILE="da850-evm.dtb" @@ -30,11 +30,10 @@ CONFIG_CRC32_VERIFY=y CONFIG_CMD_DM=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_GPT is not set -# CONFIG_CMD_PART is not set # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_TIME is not set # CONFIG_CMD_EXT4 is not set -# CONFIG_CMD_FS_GENERIC is not set +CONFIG_CMD_FS_UUID=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=spi0.0" CONFIG_MTDPARTS_DEFAULT="mtdparts=spi0.0:512k(u-boot.ais),64k(u-boot-env),7552k(kernel-spare),64k(MAC-Address)" From 71d8e1b829e543a3bda632d3b90c645321a72073 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 18 Apr 2019 10:46:58 +0300 Subject: [PATCH 28/32] .gitignore: Ignore .log files The generated flash.log file that mach-imx uses for MKIMAGEOUTPUT is not covered by any other ignore pattern. Ignore all *.log files. Signed-off-by: Baruch Siach Reviewed-by: Fabio Estevam --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3df3139d23..c2afcfbca2 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ fit-dtb.blob /System.map /u-boot* /boards.cfg +/*.log # # git files that we don't want to ignore even it they are dot-files From 9ad996adcc135bc34b185957567c8c46deb90d4f Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 18 Apr 2019 08:00:48 -0400 Subject: [PATCH 29/32] doc: delete long-obsolete README.ARM-memory-map As far back as 2011, "_armboot_start" was being described as "no longer defined": commit 297f18ac0fbeef30ba1c17fe131ca75f09a6e7cf Author: Greg Ungerer Date: Fri Sep 9 22:23:34 2011 +1000 CM4000: fix broken flash base for OpenGear boards Use _bss_start_ofs as the size of the boot loader code+data that we want to protect in the flash. This replaces use of the no longer defined _armboot_start. --- doc/README.ARM-memory-map | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 doc/README.ARM-memory-map diff --git a/doc/README.ARM-memory-map b/doc/README.ARM-memory-map deleted file mode 100644 index 1b120ac3e1..0000000000 --- a/doc/README.ARM-memory-map +++ /dev/null @@ -1,17 +0,0 @@ -Subject: Re: [PATCH][CFT] bring ARM memory layout in line with the documented behaviour -From: "Anders Larsen" -Date: Thu, 18 Sep 2003 14:15:21 +0200 -To: Wolfgang Denk - -... ->I still see references to _armboot_start, _armboot_end_data, and ->_armboot_end - which role do these play now? Can we get rid of them? -> ->How are they (should they be) set in your memory map above? - -_armboot_start contains the value of CONFIG_SYS_TEXT_BASE (0xA07E0000); it seems -CONFIG_SYS_TEXT_BASE and _armboot_start are both used for the same purpose in -different parts of the (ARM) code. -Furthermore, the startup code (cpu//start.S) internally uses -another variable (_TEXT_BASE) with the same content as _armboot_start. -I agree that this mess should be cleaned up. From 50fd31fd7781e979254af49efcbc1fbb4882a751 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 18 Apr 2019 17:16:21 +0200 Subject: [PATCH 30/32] sysreset: syscon: remove POWER reset cause The sysreset of 'POWER' type is a PMIC reset defined as 'remove and restore power'. So normally only COLD/WARN is supported by sysreset_syscon. This modification allows to use the function sysreset_walk(SYSRESET_POWER) when it is supported by PMIC driver (see example in stpmic1). Signed-off-by: Patrick Delaunay --- drivers/sysreset/sysreset_syscon.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c index 3fb39b9952..1028160247 100644 --- a/drivers/sysreset/sysreset_syscon.c +++ b/drivers/sysreset/sysreset_syscon.c @@ -24,6 +24,9 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type) { struct syscon_reboot_priv *priv = dev_get_priv(dev); + if (type == SYSRESET_POWER) + return -EPROTONOSUPPORT; + regmap_write(priv->regmap, priv->offset, priv->mask); return -EINPROGRESS; From b85d155199ff717ee1a2c43784db6d7632761679 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 21 Apr 2019 23:54:37 +0200 Subject: [PATCH 31/32] arm: dts: add missing vexpress device trees Add the device trees for * vexpress_ca5x2_defconfig * vexpress_ca9x4_defconfig * vexpress_ca15_tc2_defconfig as available in Linux 5.1 rc5. We are using the vexpress_ca15_tc2_defconfig and vexpress_ca9x4_defconfig for Travis testing via QEMU. The UEFI base Embedded Base Boot Requirements Specification (EBBR) requires that an embedded board either provides a device tree or an ACPI table. All block devices are meant to be moved to the driver model. On ARM this requires a device tree. Signed-off-by: Heinrich Schuchardt --- arch/arm/dts/Makefile | 4 + arch/arm/dts/vexpress-v2m-rs1.dtsi | 437 +++++++++++++++++ arch/arm/dts/vexpress-v2m.dtsi | 451 +++++++++++++++++ arch/arm/dts/vexpress-v2p-ca15_a7.dts | 682 ++++++++++++++++++++++++++ arch/arm/dts/vexpress-v2p-ca5s.dts | 280 +++++++++++ arch/arm/dts/vexpress-v2p-ca9.dts | 368 ++++++++++++++ 6 files changed, 2222 insertions(+) create mode 100644 arch/arm/dts/vexpress-v2m-rs1.dtsi create mode 100644 arch/arm/dts/vexpress-v2m.dtsi create mode 100644 arch/arm/dts/vexpress-v2p-ca15_a7.dts create mode 100644 arch/arm/dts/vexpress-v2p-ca5s.dts create mode 100644 arch/arm/dts/vexpress-v2p-ca9.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1366ae93e2..b4dc57edbd 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -724,6 +724,10 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ dtb-$(CONFIG_TARGET_GE_BX50V3) += imx6q-bx50v3.dtb dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb +dtb-$(CONFIG_TARGET_VEXPRESS_CA5X2) += vexpress-v2p-ca5s.dtb +dtb-$(CONFIG_TARGET_VEXPRESS_CA9X4) += vexpress-v2p-ca9.dtb +dtb-$(CONFIG_TARGET_VEXPRESS_CA15_TC2) += vexpress-v2p-ca15_a7.dtb + targets += $(dtb-y) # Add any required device tree compiler flags here diff --git a/arch/arm/dts/vexpress-v2m-rs1.dtsi b/arch/arm/dts/vexpress-v2m-rs1.dtsi new file mode 100644 index 0000000000..d3963e9eaf --- /dev/null +++ b/arch/arm/dts/vexpress-v2m-rs1.dtsi @@ -0,0 +1,437 @@ +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * RS1 memory map ("ARM Cortex-A Series memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * original variant (vexpress-v2m.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m.dtsi! + */ + +/ { + smb@8000000 { + motherboard { + model = "V2M-P1"; + arm,hbi = <0x190>; + arm,vexpress,site = <0>; + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@1,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <1 0x00000000 0x02000000>; + bank-width = <4>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vdd33a-supply = <&v2m_fixed_3v3>; + vddvario-supply = <&v2m_fixed_3v3>; + }; + + usb@2,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <2 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@3,00000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@10000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x10000 0x1000>; + + v2m_led_gpios: gpio@8 { + compatible = "arm,vexpress-sysreg,sys_led"; + reg = <0x008 4>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_mmc_gpios: gpio@48 { + compatible = "arm,vexpress-sysreg,sys_mci"; + reg = <0x048 4>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_flash_gpios: gpio@4c { + compatible = "arm,vexpress-sysreg,sys_flash"; + reg = <0x04c 4>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + v2m_sysctl: sysctl@20000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>; + assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@30000 { + compatible = "arm,versatile-i2c"; + reg = <0x030000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@40000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + clocks = <&smbclk>; + clock-names = "apb_pclk"; + }; + + mmci@50000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9>, <10>; + cd-gpios = <&v2m_mmc_gpios 0 0>; + wp-gpios = <&v2m_mmc_gpios 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@60000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@70000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@90000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&smbclk>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@160000 { + compatible = "arm,versatile-i2c"; + reg = <0x160000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dvi_bridge_in: endpoint { + remote-endpoint = <&clcd_pads>; + }; + }; + }; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&smbclk>; + clock-names = "apb_pclk"; + }; + + compact-flash@1a0000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a0000 0x100 + 0x1a0100 0xf00>; + reg-shift = <2>; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupt-names = "combined"; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&smbclk>; + clock-names = "clcdclk", "apb_pclk"; + /* 800x600 16bpp @36MHz works fine */ + max-memory-bandwidth = <54000000>; + memory-region = <&vram>; + + port { + clcd_pads: endpoint { + remote-endpoint = <&dvi_bridge_in>; + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; + }; + }; + }; + }; + + v2m_fixed_3v3: fixed-regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + leds { + compatible = "gpio-leds"; + + user1 { + label = "v2m:green:user1"; + gpios = <&v2m_led_gpios 0 0>; + linux,default-trigger = "heartbeat"; + }; + + user2 { + label = "v2m:green:user2"; + gpios = <&v2m_led_gpios 1 0>; + linux,default-trigger = "mmc0"; + }; + + user3 { + label = "v2m:green:user3"; + gpios = <&v2m_led_gpios 2 0>; + linux,default-trigger = "cpu0"; + }; + + user4 { + label = "v2m:green:user4"; + gpios = <&v2m_led_gpios 3 0>; + linux,default-trigger = "cpu1"; + }; + + user5 { + label = "v2m:green:user5"; + gpios = <&v2m_led_gpios 4 0>; + linux,default-trigger = "cpu2"; + }; + + user6 { + label = "v2m:green:user6"; + gpios = <&v2m_led_gpios 5 0>; + linux,default-trigger = "cpu3"; + }; + + user7 { + label = "v2m:green:user7"; + gpios = <&v2m_led_gpios 6 0>; + linux,default-trigger = "cpu4"; + }; + + user8 { + label = "v2m:green:user8"; + gpios = <&v2m_led_gpios 7 0>; + linux,default-trigger = "cpu5"; + }; + }; + + mcc { + compatible = "arm,vexpress,config-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + oscclk0 { + /* MCC static memory clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 0>; + freq-range = <25000000 60000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk0"; + }; + + v2m_oscclk1: oscclk1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 65000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + v2m_oscclk2: oscclk2 { + /* IO FPGA peripheral clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 2>; + freq-range = <24000000 24000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk2"; + }; + + volt-vio { + /* Logic level voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 0>; + regulator-name = "VIO"; + regulator-always-on; + label = "VIO"; + }; + + temp-mcc { + /* MCC internal operating temperature */ + compatible = "arm,vexpress-temp"; + arm,vexpress-sysreg,func = <4 0>; + label = "MCC"; + }; + + reset { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; + }; +}; diff --git a/arch/arm/dts/vexpress-v2m.dtsi b/arch/arm/dts/vexpress-v2m.dtsi new file mode 100644 index 0000000000..798c97aff7 --- /dev/null +++ b/arch/arm/dts/vexpress-v2m.dtsi @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Ltd. Versatile Express + * + * Motherboard Express uATX + * V2M-P1 + * + * HBI-0190D + * + * Original memory map ("Legacy memory map" in the board's + * Technical Reference Manual) + * + * WARNING! The hardware described in this file is independent from the + * RS1 variant (vexpress-v2m-rs1.dtsi), but there is a strong + * correspondence between the two configurations. + * + * TAKE CARE WHEN MAINTAINING THIS FILE TO PROPAGATE ANY RELEVANT + * CHANGES TO vexpress-v2m-rs1.dtsi! + */ + +/ { + smb@4000000 { + motherboard { + model = "V2M-P1"; + arm,hbi = <0x190>; + arm,vexpress,site = <0>; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <1 0x00000000 0x04000000>; + bank-width = <4>; + }; + + psram@2,00000000 { + compatible = "arm,vexpress-psram", "mtd-ram"; + reg = <2 0x00000000 0x02000000>; + bank-width = <4>; + }; + + ethernet@3,02000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <3 0x02000000 0x10000>; + interrupts = <15>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vdd33a-supply = <&v2m_fixed_3v3>; + vddvario-supply = <&v2m_fixed_3v3>; + }; + + usb@3,03000000 { + compatible = "nxp,usb-isp1761"; + reg = <3 0x03000000 0x20000>; + interrupts = <16>; + port1-otg; + }; + + iofpga@7,00000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 7 0 0x20000>; + + v2m_sysreg: sysreg@0 { + compatible = "arm,vexpress-sysreg"; + reg = <0x00000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x1000>; + + v2m_led_gpios: gpio@8 { + compatible = "arm,vexpress-sysreg,sys_led"; + reg = <0x008 4>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_mmc_gpios: gpio@48 { + compatible = "arm,vexpress-sysreg,sys_mci"; + reg = <0x048 4>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_flash_gpios: gpio@4c { + compatible = "arm,vexpress-sysreg,sys_flash"; + reg = <0x04c 4>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + v2m_sysctl: sysctl@1000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x01000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>; + assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>; + }; + + /* PCI-E I2C bus */ + v2m_i2c_pcie: i2c@2000 { + compatible = "arm,versatile-i2c"; + reg = <0x02000 0x1000>; + + #address-cells = <1>; + #size-cells = <0>; + + pcie-switch@60 { + compatible = "idt,89hpes32h8"; + reg = <0x60>; + }; + }; + + aaci@4000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x04000 0x1000>; + interrupts = <11>; + clocks = <&smbclk>; + clock-names = "apb_pclk"; + }; + + mmci@5000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x05000 0x1000>; + interrupts = <9>, <10>; + cd-gpios = <&v2m_mmc_gpios 0 0>; + wp-gpios = <&v2m_mmc_gpios 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@6000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x06000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@7000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x07000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&smbclk>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@9000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x09000 0x1000>; + interrupts = <5>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@a000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a000 0x1000>; + interrupts = <6>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@b000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b000 0x1000>; + interrupts = <7>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@c000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c000 0x1000>; + interrupts = <8>; + clocks = <&v2m_oscclk2>, <&smbclk>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@f000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&smbclk>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@11000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x11000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&smbclk>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@12000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x12000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&smbclk>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + /* DVI I2C bus */ + v2m_i2c_dvi: i2c@16000 { + compatible = "arm,versatile-i2c"; + reg = <0x16000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + dvi-transmitter@39 { + compatible = "sil,sii9022-tpi", "sil,sii9022"; + reg = <0x39>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* + * Both the core tile and the motherboard routes their output + * pads to this transmitter. The motherboard system controller + * can select one of them as input using a mux register in + * "arm,vexpress-muxfpga". The Vexpress with the CA9 core tile is + * the only platform with this specific set-up. + */ + port@0 { + reg = <0>; + dvi_bridge_in_ct: endpoint { + remote-endpoint = <&clcd_pads_ct>; + }; + }; + port@1 { + reg = <1>; + dvi_bridge_in_mb: endpoint { + remote-endpoint = <&clcd_pads_mb>; + }; + }; + }; + }; + + dvi-transmitter@60 { + compatible = "sil,sii9022-cpi", "sil,sii9022"; + reg = <0x60>; + }; + }; + + rtc@17000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x17000 0x1000>; + interrupts = <4>; + clocks = <&smbclk>; + clock-names = "apb_pclk"; + }; + + compact-flash@1a000 { + compatible = "arm,vexpress-cf", "ata-generic"; + reg = <0x1a000 0x100 + 0x1a100 0xf00>; + reg-shift = <2>; + }; + + + clcd@1f000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f000 0x1000>; + interrupt-names = "combined"; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&smbclk>; + clock-names = "clcdclk", "apb_pclk"; + /* 800x600 16bpp @36MHz works fine */ + max-memory-bandwidth = <54000000>; + memory-region = <&vram>; + + port { + clcd_pads_mb: endpoint { + remote-endpoint = <&dvi_bridge_in_mb>; + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; + }; + }; + }; + }; + + v2m_fixed_3v3: fixed-regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + leds { + compatible = "gpio-leds"; + + user1 { + label = "v2m:green:user1"; + gpios = <&v2m_led_gpios 0 0>; + linux,default-trigger = "heartbeat"; + }; + + user2 { + label = "v2m:green:user2"; + gpios = <&v2m_led_gpios 1 0>; + linux,default-trigger = "mmc0"; + }; + + user3 { + label = "v2m:green:user3"; + gpios = <&v2m_led_gpios 2 0>; + linux,default-trigger = "cpu0"; + }; + + user4 { + label = "v2m:green:user4"; + gpios = <&v2m_led_gpios 3 0>; + linux,default-trigger = "cpu1"; + }; + + user5 { + label = "v2m:green:user5"; + gpios = <&v2m_led_gpios 4 0>; + linux,default-trigger = "cpu2"; + }; + + user6 { + label = "v2m:green:user6"; + gpios = <&v2m_led_gpios 5 0>; + linux,default-trigger = "cpu3"; + }; + + user7 { + label = "v2m:green:user7"; + gpios = <&v2m_led_gpios 6 0>; + linux,default-trigger = "cpu4"; + }; + + user8 { + label = "v2m:green:user8"; + gpios = <&v2m_led_gpios 7 0>; + linux,default-trigger = "cpu5"; + }; + }; + + mcc { + compatible = "arm,vexpress,config-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + oscclk0 { + /* MCC static memory clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 0>; + freq-range = <25000000 60000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk0"; + }; + + v2m_oscclk1: oscclk1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 65000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + v2m_oscclk2: oscclk2 { + /* IO FPGA peripheral clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 2>; + freq-range = <24000000 24000000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk2"; + }; + + volt-vio { + /* Logic level voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 0>; + regulator-name = "VIO"; + regulator-always-on; + label = "VIO"; + }; + + temp-mcc { + /* MCC internal operating temperature */ + compatible = "arm,vexpress-temp"; + arm,vexpress-sysreg,func = <4 0>; + label = "MCC"; + }; + + reset { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/arch/arm/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/dts/vexpress-v2p-ca15_a7.dts new file mode 100644 index 0000000000..00cd9f5bef --- /dev/null +++ b/arch/arm/dts/vexpress-v2p-ca15_a7.dts @@ -0,0 +1,682 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A15x2 A7x3 + * Cortex-A15_A7 MPCore (V2P-CA15_A7) + * + * HBI-0249A + */ + +/dts-v1/; +#include "vexpress-v2m-rs1.dtsi" + +/ { + model = "V2P-CA15_CA7"; + arm,hbi = <0x249>; + arm,vexpress,site = <0xf>; + compatible = "arm,vexpress,v2p-ca15_a7", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + cci-control-port = <&cci_control1>; + cpu-idle-states = <&CLUSTER_SLEEP_BIG>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <990>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + cci-control-port = <&cci_control1>; + cpu-idle-states = <&CLUSTER_SLEEP_BIG>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <990>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + cci-control-port = <&cci_control2>; + cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>; + capacity-dmips-mhz = <516>; + dynamic-power-coefficient = <133>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + cci-control-port = <&cci_control2>; + cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>; + capacity-dmips-mhz = <516>; + dynamic-power-coefficient = <133>; + }; + + cpu4: cpu@4 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + cci-control-port = <&cci_control2>; + cpu-idle-states = <&CLUSTER_SLEEP_LITTLE>; + capacity-dmips-mhz = <516>; + dynamic-power-coefficient = <133>; + }; + + idle-states { + CLUSTER_SLEEP_BIG: cluster-sleep-big { + compatible = "arm,idle-state"; + local-timer-stop; + entry-latency-us = <1000>; + exit-latency-us = <700>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_LITTLE: cluster-sleep-little { + compatible = "arm,idle-state"; + local-timer-stop; + entry-latency-us = <1000>; + exit-latency-us = <500>; + min-residency-us = <2500>; + }; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0x40000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* Chipselect 2 is physically at 0x18000000 */ + vram: vram@18000000 { + /* 8 MB of designated video RAM */ + compatible = "shared-dma-pool"; + reg = <0 0x18000000 0 0x00800000>; + no-map; + }; + }; + + wdt@2a490000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0 0x2a490000 0 0x1000>; + interrupts = <0 98 4>; + clocks = <&oscclk6a>, <&oscclk6a>; + clock-names = "wdogclk", "apb_pclk"; + }; + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0 0x2b000000 0 0x1000>; + interrupts = <0 85 4>; + clocks = <&hdlcd_clk>; + clock-names = "pxlclk"; + }; + + memory-controller@2b0a0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0 0x2b0a0000 0 0x1000>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0x2c001000 0 0x1000>, + <0 0x2c002000 0 0x2000>, + <0 0x2c004000 0 0x2000>, + <0 0x2c006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; + + cci@2c090000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0x2c090000 0 0x1000>; + ranges = <0x0 0x0 0x2c090000 0x10000>; + + cci_control1: slave-if@4000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x4000 0x1000>; + }; + + cci_control2: slave-if@5000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x5000 0x1000>; + }; + + pmu@9000 { + compatible = "arm,cci-400-pmu,r0"; + reg = <0x9000 0x5000>; + interrupts = <0 105 4>, + <0 101 4>, + <0 102 4>, + <0 103 4>, + <0 104 4>; + }; + }; + + memory-controller@7ffd0000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0 0x7ffd0000 0 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + }; + + dma@7ff00000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0 0x7ff00000 0 0x1000>; + interrupts = <0 92 4>, + <0 88 4>, + <0 89 4>, + <0 90 4>, + <0 91 4>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + }; + + scc@7fff0000 { + compatible = "arm,vexpress-scc,v2p-ca15_a7", "arm,vexpress-scc"; + reg = <0 0x7fff0000 0 0x1000>; + interrupts = <0 95 4>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + pmu-a15 { + compatible = "arm,cortex-a15-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + interrupt-affinity = <&cpu0>, + <&cpu1>; + }; + + pmu-a7 { + compatible = "arm,cortex-a7-pmu"; + interrupts = <0 128 4>, + <0 129 4>, + <0 130 4>; + interrupt-affinity = <&cpu2>, + <&cpu3>, + <&cpu4>; + }; + + oscclk6a: oscclk6a { + /* Reference 24MHz clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "oscclk6a"; + }; + + dcc { + compatible = "arm,vexpress,config-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + oscclk0 { + /* A15 PLL 0 reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 0>; + freq-range = <17000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk0"; + }; + + oscclk1 { + /* A15 PLL 1 reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <17000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk1"; + }; + + oscclk2 { + /* A7 PLL 0 reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 2>; + freq-range = <17000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk2"; + }; + + oscclk3 { + /* A7 PLL 1 reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 3>; + freq-range = <17000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk3"; + }; + + oscclk4 { + /* External AXI master clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 4>; + freq-range = <20000000 40000000>; + #clock-cells = <0>; + clock-output-names = "oscclk4"; + }; + + hdlcd_clk: oscclk5 { + /* HDLCD PLL reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 5>; + freq-range = <23750000 165000000>; + #clock-cells = <0>; + clock-output-names = "oscclk5"; + }; + + smbclk: oscclk6 { + /* Static memory controller clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 6>; + freq-range = <20000000 40000000>; + #clock-cells = <0>; + clock-output-names = "oscclk6"; + }; + + oscclk7 { + /* SYS PLL reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 7>; + freq-range = <17000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk7"; + }; + + oscclk8 { + /* DDR2 PLL reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 8>; + freq-range = <20000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk8"; + }; + + volt-a15 { + /* A15 CPU core voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 0>; + regulator-name = "A15 Vcore"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + label = "A15 Vcore"; + }; + + volt-a7 { + /* A7 CPU core voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 1>; + regulator-name = "A7 Vcore"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + label = "A7 Vcore"; + }; + + amp-a15 { + /* Total current for the two A15 cores */ + compatible = "arm,vexpress-amp"; + arm,vexpress-sysreg,func = <3 0>; + label = "A15 Icore"; + }; + + amp-a7 { + /* Total current for the three A7 cores */ + compatible = "arm,vexpress-amp"; + arm,vexpress-sysreg,func = <3 1>; + label = "A7 Icore"; + }; + + temp-dcc { + /* DCC internal temperature */ + compatible = "arm,vexpress-temp"; + arm,vexpress-sysreg,func = <4 0>; + label = "DCC"; + }; + + power-a15 { + /* Total power for the two A15 cores */ + compatible = "arm,vexpress-power"; + arm,vexpress-sysreg,func = <12 0>; + label = "A15 Pcore"; + }; + + power-a7 { + /* Total power for the three A7 cores */ + compatible = "arm,vexpress-power"; + arm,vexpress-sysreg,func = <12 1>; + label = "A7 Pcore"; + }; + + energy-a15 { + /* Total energy for the two A15 cores */ + compatible = "arm,vexpress-energy"; + arm,vexpress-sysreg,func = <13 0>, <13 1>; + label = "A15 Jcore"; + }; + + energy-a7 { + /* Total energy for the three A7 cores */ + compatible = "arm,vexpress-energy"; + arm,vexpress-sysreg,func = <13 2>, <13 3>; + label = "A7 Jcore"; + }; + }; + + etb@20010000 { + compatible = "arm,coresight-etb10", "arm,primecell"; + reg = <0 0x20010000 0 0x1000>; + + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + in-ports { + port { + etb_in_port: endpoint { + remote-endpoint = <&replicator_out_port0>; + }; + }; + }; + }; + + tpiu@20030000 { + compatible = "arm,coresight-tpiu", "arm,primecell"; + reg = <0 0x20030000 0 0x1000>; + + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + in-ports { + port { + tpiu_in_port: endpoint { + remote-endpoint = <&replicator_out_port1>; + }; + }; + }; + }; + + replicator { + /* non-configurable replicators don't show up on the + * AMBA bus. As such no need to add "arm,primecell". + */ + compatible = "arm,coresight-replicator"; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + replicator_out_port0: endpoint { + remote-endpoint = <&etb_in_port>; + }; + }; + + port@1 { + reg = <1>; + replicator_out_port1: endpoint { + remote-endpoint = <&tpiu_in_port>; + }; + }; + }; + + in-ports { + port { + replicator_in_port0: endpoint { + remote-endpoint = <&funnel_out_port0>; + }; + }; + }; + }; + + funnel@20040000 { + compatible = "arm,coresight-funnel", "arm,primecell"; + reg = <0 0x20040000 0 0x1000>; + + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + funnel_out_port0: endpoint { + remote-endpoint = + <&replicator_in_port0>; + }; + }; + }; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + funnel_in_port0: endpoint { + remote-endpoint = <&ptm0_out_port>; + }; + }; + + port@1 { + reg = <1>; + funnel_in_port1: endpoint { + remote-endpoint = <&ptm1_out_port>; + }; + }; + + port@2 { + reg = <2>; + funnel_in_port2: endpoint { + remote-endpoint = <&etm0_out_port>; + }; + }; + + /* Input port #3 is for ITM, not supported here */ + + port@4 { + reg = <4>; + funnel_in_port4: endpoint { + remote-endpoint = <&etm1_out_port>; + }; + }; + + port@5 { + reg = <5>; + funnel_in_port5: endpoint { + remote-endpoint = <&etm2_out_port>; + }; + }; + }; + }; + + ptm@2201c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2201c000 0 0x1000>; + + cpu = <&cpu0>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + ptm0_out_port: endpoint { + remote-endpoint = <&funnel_in_port0>; + }; + }; + }; + }; + + ptm@2201d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2201d000 0 0x1000>; + + cpu = <&cpu1>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + ptm1_out_port: endpoint { + remote-endpoint = <&funnel_in_port1>; + }; + }; + }; + }; + + etm@2203c000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203c000 0 0x1000>; + + cpu = <&cpu2>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + etm0_out_port: endpoint { + remote-endpoint = <&funnel_in_port2>; + }; + }; + }; + }; + + etm@2203d000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203d000 0 0x1000>; + + cpu = <&cpu3>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + etm1_out_port: endpoint { + remote-endpoint = <&funnel_in_port4>; + }; + }; + }; + }; + + etm@2203e000 { + compatible = "arm,coresight-etm3x", "arm,primecell"; + reg = <0 0x2203e000 0 0x1000>; + + cpu = <&cpu4>; + clocks = <&oscclk6a>; + clock-names = "apb_pclk"; + out-ports { + port { + etm2_out_port: endpoint { + remote-endpoint = <&funnel_in_port5>; + }; + }; + }; + }; + + smb: smb@8000000 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; + + site2: hsb@40000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x40000000 0x3fef0000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 3>; + interrupt-map = <0 0 &gic 0 36 4>, + <0 1 &gic 0 37 4>, + <0 2 &gic 0 38 4>, + <0 3 &gic 0 39 4>; + }; +}; diff --git a/arch/arm/dts/vexpress-v2p-ca5s.dts b/arch/arm/dts/vexpress-v2p-ca5s.dts new file mode 100644 index 0000000000..d5b47d526f --- /dev/null +++ b/arch/arm/dts/vexpress-v2p-ca5s.dts @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A5x2 + * Cortex-A5 MPCore (V2P-CA5s) + * + * HBI-0225B + */ + +/dts-v1/; +#include "vexpress-v2m-rs1.dtsi" + +/ { + model = "V2P-CA5s"; + arm,hbi = <0x225>; + arm,vexpress,site = <0xf>; + compatible = "arm,vexpress,v2p-ca5s", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <0>; + next-level-cache = <&L2>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a5"; + reg = <1>; + next-level-cache = <&L2>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Chipselect 2 is physically at 0x18000000 */ + vram: vram@18000000 { + /* 8 MB of designated video RAM */ + compatible = "shared-dma-pool"; + reg = <0x18000000 0x00800000>; + no-map; + }; + }; + + hdlcd@2a110000 { + compatible = "arm,hdlcd"; + reg = <0x2a110000 0x1000>; + interrupts = <0 85 4>; + clocks = <&hdlcd_clk>; + clock-names = "pxlclk"; + }; + + memory-controller@2a150000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x2a150000 0x1000>; + clocks = <&axi_clk>; + clock-names = "apb_pclk"; + }; + + memory-controller@2a190000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x2a190000 0x1000>; + interrupts = <0 86 4>, + <0 87 4>; + clocks = <&axi_clk>; + clock-names = "apb_pclk"; + }; + + scu@2c000000 { + compatible = "arm,cortex-a5-scu"; + reg = <0x2c000000 0x58>; + }; + + timer@2c000600 { + compatible = "arm,cortex-a5-twd-timer"; + reg = <0x2c000600 0x20>; + interrupts = <1 13 0x304>; + }; + + timer@2c000200 { + compatible = "arm,cortex-a5-global-timer", + "arm,cortex-a9-global-timer"; + reg = <0x2c000200 0x20>; + interrupts = <1 11 0x304>; + clocks = <&cpu_clk>; + }; + + watchdog@2c000620 { + compatible = "arm,cortex-a5-twd-wdt"; + reg = <0x2c000620 0x20>; + interrupts = <1 14 0x304>; + }; + + gic: interrupt-controller@2c001000 { + compatible = "arm,cortex-a5-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x2c001000 0x1000>, + <0x2c000100 0x100>; + }; + + L2: cache-controller@2c0f0000 { + compatible = "arm,pl310-cache"; + reg = <0x2c0f0000 0x1000>; + interrupts = <0 84 4>; + cache-level = <2>; + }; + + pmu { + compatible = "arm,cortex-a5-pmu"; + interrupts = <0 68 4>, + <0 69 4>; + }; + + dcc { + compatible = "arm,vexpress,config-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + cpu_clk: oscclk0 { + /* CPU and internal AXI reference clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 0>; + freq-range = <50000000 100000000>; + #clock-cells = <0>; + clock-output-names = "oscclk0"; + }; + + axi_clk: oscclk1 { + /* Multiplexed AXI master clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <5000000 50000000>; + #clock-cells = <0>; + clock-output-names = "oscclk1"; + }; + + oscclk2 { + /* DDR2 */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 2>; + freq-range = <80000000 120000000>; + #clock-cells = <0>; + clock-output-names = "oscclk2"; + }; + + hdlcd_clk: oscclk3 { + /* HDLCD */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 3>; + freq-range = <23750000 165000000>; + #clock-cells = <0>; + clock-output-names = "oscclk3"; + }; + + oscclk4 { + /* Test chip gate configuration */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 4>; + freq-range = <80000000 80000000>; + #clock-cells = <0>; + clock-output-names = "oscclk4"; + }; + + smbclk: oscclk5 { + /* SMB clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 5>; + freq-range = <25000000 60000000>; + #clock-cells = <0>; + clock-output-names = "oscclk5"; + }; + + temp-dcc { + /* DCC internal operating temperature */ + compatible = "arm,vexpress-temp"; + arm,vexpress-sysreg,func = <4 0>; + label = "DCC"; + }; + }; + + smb: smb@8000000 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x08000000 0x04000000>, + <1 0 0x14000000 0x04000000>, + <2 0 0x18000000 0x04000000>, + <3 0 0x1c000000 0x04000000>, + <4 0 0x0c000000 0x04000000>, + <5 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; + + site2: hsb@40000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40000000 0x40000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 3>; + interrupt-map = <0 0 &gic 0 36 4>, + <0 1 &gic 0 37 4>, + <0 2 &gic 0 38 4>, + <0 3 &gic 0 39 4>; + }; +}; diff --git a/arch/arm/dts/vexpress-v2p-ca9.dts b/arch/arm/dts/vexpress-v2p-ca9.dts new file mode 100644 index 0000000000..d796efaadb --- /dev/null +++ b/arch/arm/dts/vexpress-v2p-ca9.dts @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ARM Ltd. Versatile Express + * + * CoreTile Express A9x4 + * Cortex-A9 MPCore (V2P-CA9) + * + * HBI-0191B + */ + +/dts-v1/; +#include "vexpress-v2m.dtsi" + +/ { + model = "V2P-CA9"; + arm,hbi = <0x191>; + arm,vexpress,site = <0xf>; + compatible = "arm,vexpress,v2p-ca9", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + i2c0 = &v2m_i2c_dvi; + i2c1 = &v2m_i2c_pcie; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + A9_0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + next-level-cache = <&L2>; + }; + + A9_1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + next-level-cache = <&L2>; + }; + + A9_2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <2>; + next-level-cache = <&L2>; + }; + + A9_3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <3>; + next-level-cache = <&L2>; + }; + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x60000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* Chipselect 3 is physically at 0x4c000000 */ + vram: vram@4c000000 { + /* 8 MB of designated video RAM */ + compatible = "shared-dma-pool"; + reg = <0x4c000000 0x00800000>; + no-map; + }; + }; + + clcd@10020000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x10020000 0x1000>; + interrupt-names = "combined"; + interrupts = <0 44 4>; + clocks = <&oscclk1>, <&oscclk2>; + clock-names = "clcdclk", "apb_pclk"; + /* 1024x768 16bpp @65MHz */ + max-memory-bandwidth = <95000000>; + + port { + clcd_pads_ct: endpoint { + remote-endpoint = <&dvi_bridge_in_ct>; + arm,pl11x,tft-r0g0b0-pads = <0 8 16>; + }; + }; + }; + + memory-controller@100e0000 { + compatible = "arm,pl341", "arm,primecell"; + reg = <0x100e0000 0x1000>; + clocks = <&oscclk2>; + clock-names = "apb_pclk"; + }; + + memory-controller@100e1000 { + compatible = "arm,pl354", "arm,primecell"; + reg = <0x100e1000 0x1000>; + interrupts = <0 45 4>, + <0 46 4>; + clocks = <&oscclk2>; + clock-names = "apb_pclk"; + }; + + timer@100e4000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x100e4000 0x1000>; + interrupts = <0 48 4>, + <0 49 4>; + clocks = <&oscclk2>, <&oscclk2>; + clock-names = "timclk", "apb_pclk"; + status = "disabled"; + }; + + watchdog@100e5000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x100e5000 0x1000>; + interrupts = <0 51 4>; + clocks = <&oscclk2>, <&oscclk2>; + clock-names = "wdogclk", "apb_pclk"; + }; + + scu@1e000000 { + compatible = "arm,cortex-a9-scu"; + reg = <0x1e000000 0x58>; + }; + + timer@1e000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x1e000600 0x20>; + interrupts = <1 13 0xf04>; + }; + + watchdog@1e000620 { + compatible = "arm,cortex-a9-twd-wdt"; + reg = <0x1e000620 0x20>; + interrupts = <1 14 0xf04>; + }; + + gic: interrupt-controller@1e001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x1e001000 0x1000>, + <0x1e000100 0x100>; + }; + + L2: cache-controller@1e00a000 { + compatible = "arm,pl310-cache"; + reg = <0x1e00a000 0x1000>; + interrupts = <0 43 4>; + cache-unified; + cache-level = <2>; + arm,data-latency = <1 1 1>; + arm,tag-latency = <1 1 1>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>; + + }; + + dcc { + compatible = "arm,vexpress,config-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + oscclk0: extsaxiclk { + /* ACLK clock to the AXI master port on the test chip */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 0>; + freq-range = <30000000 50000000>; + #clock-cells = <0>; + clock-output-names = "extsaxiclk"; + }; + + oscclk1: clcdclk { + /* Reference clock for the CLCD */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <10000000 80000000>; + #clock-cells = <0>; + clock-output-names = "clcdclk"; + }; + + smbclk: oscclk2: tcrefclk { + /* Reference clock for the test chip internal PLLs */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 2>; + freq-range = <33000000 100000000>; + #clock-cells = <0>; + clock-output-names = "tcrefclk"; + }; + + volt-vd10 { + /* Test Chip internal logic voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 0>; + regulator-name = "VD10"; + regulator-always-on; + label = "VD10"; + }; + + volt-vd10-s2 { + /* PL310, L2 cache, RAM cell supply (not PL310 logic) */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 1>; + regulator-name = "VD10_S2"; + regulator-always-on; + label = "VD10_S2"; + }; + + volt-vd10-s3 { + /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 2>; + regulator-name = "VD10_S3"; + regulator-always-on; + label = "VD10_S3"; + }; + + volt-vcc1v8 { + /* DDR2 SDRAM and Test Chip DDR2 I/O supply */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 3>; + regulator-name = "VCC1V8"; + regulator-always-on; + label = "VCC1V8"; + }; + + volt-ddr2vtt { + /* DDR2 SDRAM VTT termination voltage */ + compatible = "arm,vexpress-volt"; + arm,vexpress-sysreg,func = <2 4>; + regulator-name = "DDR2VTT"; + regulator-always-on; + label = "DDR2VTT"; + }; + + volt-vcc3v3 { + /* Local board supply for miscellaneous logic external to the Test Chip */ + arm,vexpress-sysreg,func = <2 5>; + compatible = "arm,vexpress-volt"; + regulator-name = "VCC3V3"; + regulator-always-on; + label = "VCC3V3"; + }; + + amp-vd10-s2 { + /* PL310, L2 cache, RAM cell supply (not PL310 logic) */ + compatible = "arm,vexpress-amp"; + arm,vexpress-sysreg,func = <3 0>; + label = "VD10_S2"; + }; + + amp-vd10-s3 { + /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */ + compatible = "arm,vexpress-amp"; + arm,vexpress-sysreg,func = <3 1>; + label = "VD10_S3"; + }; + + power-vd10-s2 { + /* PL310, L2 cache, RAM cell supply (not PL310 logic) */ + compatible = "arm,vexpress-power"; + arm,vexpress-sysreg,func = <12 0>; + label = "PVD10_S2"; + }; + + power-vd10-s3 { + /* Cortex-A9 system supply, Cores, MPEs, SCU and PL310 logic */ + compatible = "arm,vexpress-power"; + arm,vexpress-sysreg,func = <12 1>; + label = "PVD10_S3"; + }; + }; + + smb: smb@4000000 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x40000000 0x04000000>, + <1 0 0x44000000 0x04000000>, + <2 0 0x48000000 0x04000000>, + <3 0 0x4c000000 0x04000000>, + <7 0 0x10000000 0x00020000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 4>, + <0 0 1 &gic 0 1 4>, + <0 0 2 &gic 0 2 4>, + <0 0 3 &gic 0 3 4>, + <0 0 4 &gic 0 4 4>, + <0 0 5 &gic 0 5 4>, + <0 0 6 &gic 0 6 4>, + <0 0 7 &gic 0 7 4>, + <0 0 8 &gic 0 8 4>, + <0 0 9 &gic 0 9 4>, + <0 0 10 &gic 0 10 4>, + <0 0 11 &gic 0 11 4>, + <0 0 12 &gic 0 12 4>, + <0 0 13 &gic 0 13 4>, + <0 0 14 &gic 0 14 4>, + <0 0 15 &gic 0 15 4>, + <0 0 16 &gic 0 16 4>, + <0 0 17 &gic 0 17 4>, + <0 0 18 &gic 0 18 4>, + <0 0 19 &gic 0 19 4>, + <0 0 20 &gic 0 20 4>, + <0 0 21 &gic 0 21 4>, + <0 0 22 &gic 0 22 4>, + <0 0 23 &gic 0 23 4>, + <0 0 24 &gic 0 24 4>, + <0 0 25 &gic 0 25 4>, + <0 0 26 &gic 0 26 4>, + <0 0 27 &gic 0 27 4>, + <0 0 28 &gic 0 28 4>, + <0 0 29 &gic 0 29 4>, + <0 0 30 &gic 0 30 4>, + <0 0 31 &gic 0 31 4>, + <0 0 32 &gic 0 32 4>, + <0 0 33 &gic 0 33 4>, + <0 0 34 &gic 0 34 4>, + <0 0 35 &gic 0 35 4>, + <0 0 36 &gic 0 36 4>, + <0 0 37 &gic 0 37 4>, + <0 0 38 &gic 0 38 4>, + <0 0 39 &gic 0 39 4>, + <0 0 40 &gic 0 40 4>, + <0 0 41 &gic 0 41 4>, + <0 0 42 &gic 0 42 4>; + }; + + site2: hsb@e0000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xe0000000 0x20000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 3>; + interrupt-map = <0 0 &gic 0 36 4>, + <0 1 &gic 0 37 4>, + <0 2 &gic 0 38 4>, + <0 3 &gic 0 39 4>; + }; +}; From fc1fe01b08cedd77a194bb82fa81af4fe1e39031 Mon Sep 17 00:00:00 2001 From: Igor Opaniuk Date: Tue, 9 Apr 2019 15:38:14 +0200 Subject: [PATCH 32/32] avb: add support for named persistent values AVB 2.0 spec. revision 1.1 introduces support for named persistent values that must be tamper evident and allows AVB to store arbitrary key-value pairs [1]. Introduce implementation of two additional AVB operations read_persistent_value()/write_persistent_value() for retrieving/storing named persistent values. Correspondent pull request in the OP-TEE OS project repo [2]. [1]: https://android.googlesource.com/platform/external/avb/+/android-9.0.0_r22 [2]: https://github.com/OP-TEE/optee_os/pull/2699 Reviewed-by: Simon Glass Reviewed-by: Sam Protsenko Signed-off-by: Igor Opaniuk --- cmd/avb.c | 78 +++++++++++++++++++++++ common/avb_verify.c | 125 +++++++++++++++++++++++++++++++++++++ drivers/tee/sandbox.c | 121 +++++++++++++++++++++++++++++------ include/sandboxtee.h | 15 ++++- include/tee.h | 2 + include/tee/optee_ta_avb.h | 16 +++++ test/py/tests/test_avb.py | 16 +++++ 7 files changed, 351 insertions(+), 22 deletions(-) diff --git a/cmd/avb.c b/cmd/avb.c index ff00be4cee..c5af4a2e46 100644 --- a/cmd/avb.c +++ b/cmd/avb.c @@ -340,6 +340,76 @@ int do_avb_is_unlocked(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } +int do_avb_read_pvalue(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const char *name; + size_t bytes; + size_t bytes_read; + void *buffer; + char *endp; + + if (!avb_ops) { + printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + return CMD_RET_FAILURE; + } + + if (argc != 3) + return CMD_RET_USAGE; + + name = argv[1]; + bytes = simple_strtoul(argv[2], &endp, 10); + if (*endp && *endp != '\n') + return CMD_RET_USAGE; + + buffer = malloc(bytes); + if (!buffer) + return CMD_RET_FAILURE; + + if (avb_ops->read_persistent_value(avb_ops, name, bytes, buffer, + &bytes_read) == AVB_IO_RESULT_OK) { + printf("Read %ld bytes, value = %s\n", bytes_read, + (char *)buffer); + free(buffer); + return CMD_RET_SUCCESS; + } + + printf("Failed to read persistent value\n"); + + free(buffer); + + return CMD_RET_FAILURE; +} + +int do_avb_write_pvalue(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + const char *name; + const char *value; + + if (!avb_ops) { + printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + return CMD_RET_FAILURE; + } + + if (argc != 3) + return CMD_RET_USAGE; + + name = argv[1]; + value = argv[2]; + + if (avb_ops->write_persistent_value(avb_ops, name, strlen(value) + 1, + (const uint8_t *)value) == + AVB_IO_RESULT_OK) { + printf("Wrote %ld bytes\n", strlen(value) + 1); + return CMD_RET_SUCCESS; + } + + printf("Failed to write persistent value\n"); + + return CMD_RET_FAILURE; +} + static cmd_tbl_t cmd_avb[] = { U_BOOT_CMD_MKENT(init, 2, 0, do_avb_init, "", ""), U_BOOT_CMD_MKENT(read_rb, 2, 0, do_avb_read_rb, "", ""), @@ -350,6 +420,10 @@ static cmd_tbl_t cmd_avb[] = { U_BOOT_CMD_MKENT(read_part_hex, 4, 0, do_avb_read_part_hex, "", ""), U_BOOT_CMD_MKENT(write_part, 5, 0, do_avb_write_part, "", ""), U_BOOT_CMD_MKENT(verify, 1, 0, do_avb_verify_part, "", ""), +#ifdef CONFIG_OPTEE_TA_AVB + U_BOOT_CMD_MKENT(read_pvalue, 3, 0, do_avb_read_pvalue, "", ""), + U_BOOT_CMD_MKENT(write_pvalue, 3, 0, do_avb_write_pvalue, "", ""), +#endif }; static int do_avb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) @@ -384,6 +458,10 @@ U_BOOT_CMD( " partition and print to stdout\n" "avb write_part - write bytes to\n" " by using data from \n" +#ifdef CONFIG_OPTEE_TA_AVB + "avb read_pvalue - read a persistent value \n" + "avb write_pvalue - write a persistent value \n" +#endif "avb verify - run verification process using hash data\n" " from vbmeta structure\n" ); diff --git a/common/avb_verify.c b/common/avb_verify.c index a8c5a3e7db..32034d927c 100644 --- a/common/avb_verify.c +++ b/common/avb_verify.c @@ -647,6 +647,10 @@ static AvbIOResult invoke_func(struct AvbOpsData *ops_data, u32 func, return AVB_IO_RESULT_OK; case TEE_ERROR_OUT_OF_MEMORY: return AVB_IO_RESULT_ERROR_OOM; + case TEE_ERROR_STORAGE_NO_SPACE: + return AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE; + case TEE_ERROR_ITEM_NOT_FOUND: + return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; case TEE_ERROR_TARGET_DEAD: /* * The TA has paniced, close the session to reload the TA @@ -847,6 +851,123 @@ static AvbIOResult get_size_of_partition(AvbOps *ops, return AVB_IO_RESULT_OK; } +static AvbIOResult read_persistent_value(AvbOps *ops, + const char *name, + size_t buffer_size, + u8 *out_buffer, + size_t *out_num_bytes_read) +{ + AvbIOResult rc; + struct tee_shm *shm_name; + struct tee_shm *shm_buf; + struct tee_param param[2]; + struct udevice *tee; + size_t name_size = strlen(name) + 1; + + if (get_open_session(ops->user_data)) + return AVB_IO_RESULT_ERROR_IO; + + tee = ((struct AvbOpsData *)ops->user_data)->tee; + + rc = tee_shm_alloc(tee, name_size, + TEE_SHM_ALLOC, &shm_name); + if (rc) + return AVB_IO_RESULT_ERROR_OOM; + + rc = tee_shm_alloc(tee, buffer_size, + TEE_SHM_ALLOC, &shm_buf); + if (rc) { + rc = AVB_IO_RESULT_ERROR_OOM; + goto free_name; + } + + memcpy(shm_name->addr, name, name_size); + + memset(param, 0, sizeof(param)); + param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; + param[0].u.memref.shm = shm_name; + param[0].u.memref.size = name_size; + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT; + param[1].u.memref.shm = shm_buf; + param[1].u.memref.size = buffer_size; + + rc = invoke_func(ops->user_data, TA_AVB_CMD_READ_PERSIST_VALUE, + 2, param); + if (rc) + goto out; + + if (param[1].u.memref.size > buffer_size) { + rc = AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; + goto out; + } + + *out_num_bytes_read = param[1].u.memref.size; + + memcpy(out_buffer, shm_buf->addr, *out_num_bytes_read); + +out: + tee_shm_free(shm_buf); +free_name: + tee_shm_free(shm_name); + + return rc; +} + +static AvbIOResult write_persistent_value(AvbOps *ops, + const char *name, + size_t value_size, + const u8 *value) +{ + AvbIOResult rc; + struct tee_shm *shm_name; + struct tee_shm *shm_buf; + struct tee_param param[2]; + struct udevice *tee; + size_t name_size = strlen(name) + 1; + + if (get_open_session(ops->user_data)) + return AVB_IO_RESULT_ERROR_IO; + + tee = ((struct AvbOpsData *)ops->user_data)->tee; + + if (!value_size) + return AVB_IO_RESULT_ERROR_NO_SUCH_VALUE; + + rc = tee_shm_alloc(tee, name_size, + TEE_SHM_ALLOC, &shm_name); + if (rc) + return AVB_IO_RESULT_ERROR_OOM; + + rc = tee_shm_alloc(tee, value_size, + TEE_SHM_ALLOC, &shm_buf); + if (rc) { + rc = AVB_IO_RESULT_ERROR_OOM; + goto free_name; + } + + memcpy(shm_name->addr, name, name_size); + memcpy(shm_buf->addr, value, value_size); + + memset(param, 0, sizeof(param)); + param[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; + param[0].u.memref.shm = shm_name; + param[0].u.memref.size = name_size; + param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT; + param[1].u.memref.shm = shm_buf; + param[1].u.memref.size = value_size; + + rc = invoke_func(ops->user_data, TA_AVB_CMD_WRITE_PERSIST_VALUE, + 2, param); + if (rc) + goto out; + +out: + tee_shm_free(shm_buf); +free_name: + tee_shm_free(shm_name); + + return rc; +} /** * ============================================================================ * AVB2.0 AvbOps alloc/initialisation/free @@ -870,6 +991,10 @@ AvbOps *avb_ops_alloc(int boot_device) ops_data->ops.read_is_device_unlocked = read_is_device_unlocked; ops_data->ops.get_unique_guid_for_partition = get_unique_guid_for_partition; +#ifdef CONFIG_OPTEE_TA_AVB + ops_data->ops.write_persistent_value = write_persistent_value; + ops_data->ops.read_persistent_value = read_persistent_value; +#endif ops_data->ops.get_size_of_partition = get_size_of_partition; ops_data->mmc_dev = boot_device; diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c index ccddb03e73..a136bc9609 100644 --- a/drivers/tee/sandbox.c +++ b/drivers/tee/sandbox.c @@ -14,6 +14,7 @@ * available. */ +static const u32 pstorage_max = 16; /** * struct ta_entry - TA entries * @uuid: UUID of an emulated TA @@ -24,8 +25,11 @@ */ struct ta_entry { struct tee_optee_ta_uuid uuid; - u32 (*open_session)(uint num_params, struct tee_param *params); - u32 (*invoke_func)(u32 func, uint num_params, struct tee_param *params); + u32 (*open_session)(struct udevice *dev, uint num_params, + struct tee_param *params); + u32 (*invoke_func)(struct udevice *dev, + u32 func, uint num_params, + struct tee_param *params); }; #ifdef CONFIG_OPTEE_TA_AVB @@ -59,10 +63,8 @@ bad_params: return TEE_ERROR_BAD_PARAMETERS; } -static u64 ta_avb_rollback_indexes[TA_AVB_MAX_ROLLBACK_LOCATIONS]; -static u32 ta_avb_lock_state; - -static u32 ta_avb_open_session(uint num_params, struct tee_param *params) +static u32 ta_avb_open_session(struct udevice *dev, uint num_params, + struct tee_param *params) { /* * We don't expect additional parameters when opening a session to @@ -73,12 +75,17 @@ static u32 ta_avb_open_session(uint num_params, struct tee_param *params) num_params, params); } -static u32 ta_avb_invoke_func(u32 func, uint num_params, +static u32 ta_avb_invoke_func(struct udevice *dev, u32 func, uint num_params, struct tee_param *params) { + struct sandbox_tee_state *state = dev_get_priv(dev); + ENTRY e, *ep; + char *name; u32 res; uint slot; u64 val; + char *value; + u32 value_sz; switch (func) { case TA_AVB_CMD_READ_ROLLBACK_INDEX: @@ -91,12 +98,12 @@ static u32 ta_avb_invoke_func(u32 func, uint num_params, return res; slot = params[0].u.value.a; - if (slot >= ARRAY_SIZE(ta_avb_rollback_indexes)) { + if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) { printf("Rollback index slot out of bounds %u\n", slot); return TEE_ERROR_BAD_PARAMETERS; } - val = ta_avb_rollback_indexes[slot]; + val = state->ta_avb_rollback_indexes[slot]; params[1].u.value.a = val >> 32; params[1].u.value.b = val; return TEE_SUCCESS; @@ -111,16 +118,16 @@ static u32 ta_avb_invoke_func(u32 func, uint num_params, return res; slot = params[0].u.value.a; - if (slot >= ARRAY_SIZE(ta_avb_rollback_indexes)) { + if (slot >= ARRAY_SIZE(state->ta_avb_rollback_indexes)) { printf("Rollback index slot out of bounds %u\n", slot); return TEE_ERROR_BAD_PARAMETERS; } val = (u64)params[1].u.value.a << 32 | params[1].u.value.b; - if (val < ta_avb_rollback_indexes[slot]) + if (val < state->ta_avb_rollback_indexes[slot]) return TEE_ERROR_SECURITY; - ta_avb_rollback_indexes[slot] = val; + state->ta_avb_rollback_indexes[slot] = val; return TEE_SUCCESS; case TA_AVB_CMD_READ_LOCK_STATE: @@ -132,7 +139,7 @@ static u32 ta_avb_invoke_func(u32 func, uint num_params, if (res) return res; - params[0].u.value.a = ta_avb_lock_state; + params[0].u.value.a = state->ta_avb_lock_state; return TEE_SUCCESS; case TA_AVB_CMD_WRITE_LOCK_STATE: @@ -144,13 +151,64 @@ static u32 ta_avb_invoke_func(u32 func, uint num_params, if (res) return res; - if (ta_avb_lock_state != params[0].u.value.a) { - ta_avb_lock_state = params[0].u.value.a; - memset(ta_avb_rollback_indexes, 0, - sizeof(ta_avb_rollback_indexes)); + if (state->ta_avb_lock_state != params[0].u.value.a) { + state->ta_avb_lock_state = params[0].u.value.a; + memset(state->ta_avb_rollback_indexes, 0, + sizeof(state->ta_avb_rollback_indexes)); } return TEE_SUCCESS; + case TA_AVB_CMD_READ_PERSIST_VALUE: + res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT, + TEE_PARAM_ATTR_TYPE_MEMREF_INOUT, + TEE_PARAM_ATTR_TYPE_NONE, + TEE_PARAM_ATTR_TYPE_NONE, + num_params, params); + if (res) + return res; + + name = params[0].u.memref.shm->addr; + + value = params[1].u.memref.shm->addr; + value_sz = params[1].u.memref.size; + + e.key = name; + e.data = NULL; + hsearch_r(e, FIND, &ep, &state->pstorage_htab, 0); + if (!ep) + return TEE_ERROR_ITEM_NOT_FOUND; + + value_sz = strlen(ep->data); + memcpy(value, ep->data, value_sz); + + return TEE_SUCCESS; + case TA_AVB_CMD_WRITE_PERSIST_VALUE: + res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT, + TEE_PARAM_ATTR_TYPE_MEMREF_INPUT, + TEE_PARAM_ATTR_TYPE_NONE, + TEE_PARAM_ATTR_TYPE_NONE, + num_params, params); + if (res) + return res; + + name = params[0].u.memref.shm->addr; + + value = params[1].u.memref.shm->addr; + value_sz = params[1].u.memref.size; + + e.key = name; + e.data = NULL; + hsearch_r(e, FIND, &ep, &state->pstorage_htab, 0); + if (ep) + hdelete_r(e.key, &state->pstorage_htab, 0); + + e.key = name; + e.data = value; + hsearch_r(e, ENTER, &ep, &state->pstorage_htab, 0); + if (!ep) + return TEE_ERROR_OUT_OF_MEMORY; + + return TEE_SUCCESS; default: return TEE_ERROR_NOT_SUPPORTED; @@ -225,7 +283,7 @@ static int sandbox_tee_open_session(struct udevice *dev, return 0; } - arg->ret = ta->open_session(num_params, params); + arg->ret = ta->open_session(dev, num_params, params); arg->ret_origin = TEE_ORIGIN_TRUSTED_APP; if (!arg->ret) { @@ -261,7 +319,7 @@ static int sandbox_tee_invoke_func(struct udevice *dev, return -EINVAL; } - arg->ret = ta->invoke_func(arg->func, num_params, params); + arg->ret = ta->invoke_func(dev, arg->func, num_params, params); arg->ret_origin = TEE_ORIGIN_TRUSTED_APP; return 0; @@ -285,6 +343,29 @@ static int sandbox_tee_shm_unregister(struct udevice *dev, struct tee_shm *shm) return 0; } +static int sandbox_tee_remove(struct udevice *dev) +{ + struct sandbox_tee_state *state = dev_get_priv(dev); + + hdestroy_r(&state->pstorage_htab); + + return 0; +} + +static int sandbox_tee_probe(struct udevice *dev) +{ + struct sandbox_tee_state *state = dev_get_priv(dev); + /* + * With this hastable we emulate persistent storage, + * which should contain persistent values + * between different sessions/command invocations. + */ + if (!hcreate_r(pstorage_max, &state->pstorage_htab)) + return TEE_ERROR_OUT_OF_MEMORY; + + return 0; +} + static const struct tee_driver_ops sandbox_tee_ops = { .get_version = sandbox_tee_get_version, .open_session = sandbox_tee_open_session, @@ -305,4 +386,6 @@ U_BOOT_DRIVER(sandbox_tee) = { .of_match = sandbox_tee_match, .ops = &sandbox_tee_ops, .priv_auto_alloc_size = sizeof(struct sandbox_tee_state), + .probe = sandbox_tee_probe, + .remove = sandbox_tee_remove, }; diff --git a/include/sandboxtee.h b/include/sandboxtee.h index 44f653d9cf..419643a024 100644 --- a/include/sandboxtee.h +++ b/include/sandboxtee.h @@ -6,16 +6,25 @@ #ifndef __SANDBOXTEE_H #define __SANDBOXTEE_H +#include +#include + /** * struct sandbox_tee_state - internal state of the sandbox TEE - * @session: current open session - * @num_shms: number of registered shared memory objects - * @ta: Trusted Application of current session + * @session: current open session + * @num_shms: number of registered shared memory objects + * @ta: Trusted Application of current session + * @ta_avb_rollback_indexes TA avb rollback indexes storage + * @ta_avb_lock_state TA avb lock state storage + * @pstorage_htab named persistent values storage */ struct sandbox_tee_state { u32 session; int num_shms; void *ta; + u64 ta_avb_rollback_indexes[TA_AVB_MAX_ROLLBACK_LOCATIONS]; + u32 ta_avb_lock_state; + struct hsearch_data pstorage_htab; }; #endif /*__SANDBOXTEE_H*/ diff --git a/include/tee.h b/include/tee.h index edd9f9b0c9..02bcd9e703 100644 --- a/include/tee.h +++ b/include/tee.h @@ -43,7 +43,9 @@ #define TEE_ERROR_COMMUNICATION 0xffff000e #define TEE_ERROR_SECURITY 0xffff000f #define TEE_ERROR_OUT_OF_MEMORY 0xffff000c +#define TEE_ERROR_OVERFLOW 0xffff300f #define TEE_ERROR_TARGET_DEAD 0xffff3024 +#define TEE_ERROR_STORAGE_NO_SPACE 0xffff3041 #define TEE_ORIGIN_COMMS 0x00000002 #define TEE_ORIGIN_TEE 0x00000003 diff --git a/include/tee/optee_ta_avb.h b/include/tee/optee_ta_avb.h index 074386af19..949875a64c 100644 --- a/include/tee/optee_ta_avb.h +++ b/include/tee/optee_ta_avb.h @@ -45,4 +45,20 @@ */ #define TA_AVB_CMD_WRITE_LOCK_STATE 3 +/* + * Reads a persistent value corresponding to the given name. + * + * in params[0].u.memref: persistent value name + * out params[1].u.memref: read persistent value buffer + */ +#define TA_AVB_CMD_READ_PERSIST_VALUE 4 + +/* + * Writes a persistent value corresponding to the given name. + * + * in params[0].u.memref: persistent value name + * in params[1].u.memref: persistent value buffer to write + */ +#define TA_AVB_CMD_WRITE_PERSIST_VALUE 5 + #endif /* __TA_AVB_H */ diff --git a/test/py/tests/test_avb.py b/test/py/tests/test_avb.py index e70a010c9a..2bb75ed6e2 100644 --- a/test/py/tests/test_avb.py +++ b/test/py/tests/test_avb.py @@ -116,3 +116,19 @@ def test_avb_mmc_read(u_boot_console): response = u_boot_console.run_command('cmp 0x%x 0x%x 40' % (temp_addr, temp_addr2)) assert response.find('64 word') + + +@pytest.mark.buildconfigspec('cmd_avb') +@pytest.mark.buildconfigspec('optee_ta_avb') +def test_avb_persistent_values(u_boot_console): + """Test reading/writing persistent storage to avb + """ + + response = u_boot_console.run_command('avb init %s' % str(mmc_dev)) + assert response == '' + + response = u_boot_console.run_command('avb write_pvalue test value_value') + assert response == 'Wrote 12 bytes' + + response = u_boot_console.run_command('avb read_pvalue test 12') + assert response == 'Read 12 bytes, value = value_value'