From 91259b783fb00422df6157b85317bf5035c72ed4 Mon Sep 17 00:00:00 2001 From: Evert Pap Date: Fri, 16 Sep 2016 15:16:50 +0200 Subject: merge with master diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index bfda47d..ee537f4 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -3200,14 +3200,4 @@ struct ccsr_scfg { u32 res4[60]; u32 sparecr[8]; /* 0x500 Spare Control register(0-7) */ }; - -#if defined(CONFIG_PPC_T1013) || defined(CONFIG_PPC_T1014) ||\ - defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) ||\ - defined(CONFIG_PPC_T1023) || defined(CONFIG_PPC_T1024) ||\ - defined(CONFIG_PPC_T1040) || defined(CONFIG_PPC_T1042) -#define CONFIG_SYS_MPC8XXX_GPIO1_ADDR (CONFIG_SYS_IMMR + 0x130000) -#define CONFIG_SYS_MPC8XXX_GPIO2_ADDR (CONFIG_SYS_IMMR + 0x131000) -#define CONFIG_SYS_MPC8XXX_GPIO3_ADDR (CONFIG_SYS_IMMR + 0x132000) -#define CONFIG_SYS_MPC8XXX_GPIO4_ADDR (CONFIG_SYS_IMMR + 0x133000) -#endif #endif /*__IMMAP_85xx__*/ diff --git a/arch/powerpc/include/asm/mpc8xxx_gpio.h b/arch/powerpc/include/asm/mpc8xxx_gpio.h deleted file mode 100644 index 1069638..0000000 --- a/arch/powerpc/include/asm/mpc8xxx_gpio.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2016 Scalys B.V. - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _POWERPC_ASM_MPC8XXX_GPIO_H -#define _POWERPC_ASM_MPC8XXX_GPIO_H - -#include - -#define MPC8XXX_GPIO_NR(port, pin) ((((port)-1)*32)+((pin)&31)) -#define MPC8XXX_GPIO_TO_PORT(gpio) (gpio/32) -#define MPC8XXX_GPIO_TO_PIN(gpio) (gpio&31) - -static inline void mpc8xxx_gpio_set(uint32_t gpio, int value) -{ - int port, pin; - ccsr_gpio_t *gpio_regs; - uint32_t regval; - - port = MPC8XXX_GPIO_TO_PORT(gpio); - pin = MPC8XXX_GPIO_TO_PIN(gpio); - - switch (port) { -#ifdef CONFIG_SYS_MPC8XXX_GPIO1_ADDR - case 0: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO1_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO2_ADDR - case 1: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO2_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO3_ADDR - case 2: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO3_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO4_ADDR - case 3: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO4_ADDR; - break; -#endif - default: - return; - } - - /* Set output */ - regval = in_be32(&(gpio_regs->gpdat)); - regval |= (0x80000000 >> pin); - out_be32(&(gpio_regs->gpdat), regval); - - /* Set direction to acivate gpio pin */ - regval = in_be32(&(gpio_regs->gpdir)); - regval |= (0x80000000 >> pin); - out_be32(&(gpio_regs->gpdir), regval); -} - -static inline int mpc8xxx_gpio_get(uint32_t gpio, int value) -{ - int port, pin; - ccsr_gpio_t *gpio_regs; - uint32_t regval; - - port = MPC8XXX_GPIO_TO_PORT(gpio); - pin = MPC8XXX_GPIO_TO_PIN(gpio); - - switch (port) { -#ifdef CONFIG_SYS_MPC8XXX_GPIO1_ADDR - case 0: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO1_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO2_ADDR - case 1: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO2_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO3_ADDR - case 2: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO3_ADDR; - break; -#endif -#ifdef CONFIG_SYS_MPC8XXX_GPIO4_ADDR - case 3: - gpio_regs = (ccsr_gpio_t *) CONFIG_SYS_MPC8XXX_GPIO4_ADDR; - break; -#endif - default: - return -ENODEV; - } - - /* Get inputs */ - regval = in_be32(&(gpio_regs->gpdat)); - regval <<= pin; - regval &= 1; - - return regval; -} - -#endif /* _POWERPC_ASM_MPC8XXX_GPIO_H */ diff --git a/board/scalys/common/Makefile b/board/scalys/common/Makefile index dc95801..92c36e7 100644 --- a/board/scalys/common/Makefile +++ b/board/scalys/common/Makefile @@ -5,3 +5,7 @@ # obj-y += board_configuration_data.o + +ifdef CONFIG_SECURE_BOOT + obj-$(CONFIG_CMD_ESBC_VALIDATE) += fsl_validate.o cmd_esbc_validate.o +endif diff --git a/board/scalys/common/cmd_esbc_validate.c b/board/scalys/common/cmd_esbc_validate.c new file mode 100644 index 0000000..cefe3cc --- /dev/null +++ b/board/scalys/common/cmd_esbc_validate.c @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (fsl_check_boot_mode_secure() == 0) { + printf("Boot Mode is Non-Secure. Not entering spin loop.\n"); + return 0; + } + + printf("Core is entering spin loop.\n"); +loop: + goto loop; + + return 0; +} + +static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + char *hash_str = NULL; + uintptr_t haddr; + int ret; + uintptr_t img_addr = 0; + char buf[20]; + + if (argc < 2) + return cmd_usage(cmdtp); + else if (argc > 2) + /* Second arg - Optional - Hash Str*/ + hash_str = argv[2]; + + /* First argument - header address -32/64bit */ + haddr = (uintptr_t)simple_strtoul(argv[1], NULL, 16); + + /* With esbc_validate command, Image address must be + * part of header. So, the function is called + * by passing this argument as 0. + */ + ret = fsl_secboot_validate(haddr, hash_str, &img_addr); + + /* Need to set "img_addr" even if validation failure. + * Required when SB_EN in RCW set and non-fatal error + * to continue U-Boot + */ + sprintf(buf, "%lx", img_addr); + setenv("img_addr", buf); + + if (ret) + return 1; + + printf("esbc_validate command successful\n"); + return 0; +} + +/***************************************************/ +static char esbc_validate_help_text[] = + "esbc_validate hdr_addr - Validates signature using\n" + " RSA verification\n" + " $hdr_addr Address of header of the image\n" + " to be validated.\n" + " $hash_val -Optional\n" + " It provides Hash of public/srk key to be\n" + " used to verify signature.\n"; + +U_BOOT_CMD( + esbc_validate, 3, 0, do_esbc_validate, + "Validates signature on a given image using RSA verification", + esbc_validate_help_text +); + +U_BOOT_CMD( + esbc_halt, 1, 0, do_esbc_halt, + "Put the core in spin loop (Secure Boot Only)", + "" +); diff --git a/board/scalys/common/fsl_validate.c b/board/scalys/common/fsl_validate.c new file mode 100644 index 0000000..8c171b1 --- /dev/null +++ b/board/scalys/common/fsl_validate.c @@ -0,0 +1,927 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_LS102XA +#include +#endif + +#define SHA256_BITS 256 +#define SHA256_BYTES (256/8) +#define SHA256_NIBBLES (256/4) +#define NUM_HEX_CHARS (sizeof(ulong) * 2) + +#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \ + ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \ + ((key_len) == 2 * KEY_SIZE_BYTES)) + +/* This array contains DER value for SHA-256 */ +static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, + 0x04, 0x20 + }; + +static u8 hash_val[SHA256_BYTES]; + +#ifdef CONFIG_ESBC_HDR_LS +/* New Barker Code for LS ESBC Header */ +static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 }; +#else +static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; +#endif + +void branch_to_self(void) __attribute__ ((noreturn)); + +/* + * This function will put core in infinite loop. + * This will be called when the ESBC can not proceed further due + * to some unknown errors. + */ +void branch_to_self(void) +{ + printf("Core is in infinite loop due to errors.\n"); +self: + goto self; +} + +#if defined(CONFIG_FSL_ISBC_KEY_EXT) +static u32 check_ie(struct fsl_secboot_img_priv *img) +{ + if (img->hdr.ie_flag) + return 1; + + return 0; +} + +/* This function returns the CSF Header Address of uboot + * For MPC85xx based platforms, the LAW mapping for NOR + * flash changes in uboot code. Hence the offset needs + * to be calculated and added to the new NOR flash base + * address + */ +#if defined(CONFIG_MPC85xx) +int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); + u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE); + u32 flash_addr, addr; + int found = 0; + int i = 0; + + for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { + flash_addr = flash_info[i].start[0]; + addr = flash_info[i].start[0] + csf_flash_offset; + if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) { + debug("Barker found on addr %x\n", addr); + found = 1; + break; + } + } + + if (!found) + return -1; + + *csf_addr = addr; + *flash_base_addr = flash_addr; + + return 0; +} +#else +/* For platforms like LS1020, correct flash address is present in + * the header. So the function reqturns flash base address as 0 + */ +int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); + + if (memcmp((u8 *)(uintptr_t)csf_hdr_addr, + barker_code, ESBC_BARKER_LEN)) + return -1; + + *csf_addr = csf_hdr_addr; + *flash_base_addr = 0; + return 0; +} +#endif + +static int get_ie_info_addr(u32 *ie_addr) +{ + struct fsl_secboot_img_hdr *hdr; + struct fsl_secboot_sg_table *sg_tbl; + u32 flash_base_addr, csf_addr; + + if (get_csf_base_addr(&csf_addr, &flash_base_addr)) + return -1; + + hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr; + + /* For SoC's with Trust Architecture v1 with corenet bus + * the sg table field in CSF header has absolute address + * for sg table in memory. In other Trust Architecture, + * this field specifies the offset of sg table from the + * base address of CSF Header + */ +#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET) + sg_tbl = (struct fsl_secboot_sg_table *) + (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) + + flash_base_addr); +#else + sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr + + (u32)hdr->psgtable); +#endif + + /* IE Key Table is the first entry in the SG Table */ +#if defined(CONFIG_MPC85xx) + *ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) + + flash_base_addr; +#else + *ie_addr = sg_tbl->src_addr; +#endif + + debug("IE Table address is %x\n", *ie_addr); + return 0; +} + +#endif + +#ifdef CONFIG_KEY_REVOCATION +/* This function checks srk_table_flag in header and set/reset srk_flag.*/ +static u32 check_srk(struct fsl_secboot_img_priv *img) +{ +#ifdef CONFIG_ESBC_HDR_LS + /* In LS, No SRK Flag as SRK is always present*/ + return 1; +#else + if (img->hdr.len_kr.srk_table_flag & SRK_FLAG) + return 1; + + return 0; +#endif +} + +/* This function returns ospr's key_revoc values.*/ +static u32 get_key_revoc(void) +{ + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); + return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >> + OSPR_KEY_REVOC_SHIFT; +} + +/* This function checks if selected key is revoked or not.*/ +static u32 is_key_revoked(u32 keynum, u32 rev_flag) +{ + if (keynum == UNREVOCABLE_KEY) + return 0; + + if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag) + return 1; + + return 0; +} + +/* It read validates srk_table key lengths.*/ +static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img) +{ + int i = 0; + u32 ret, key_num, key_revoc_flag, size; + struct fsl_secboot_img_hdr *hdr = &img->hdr; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; + + if ((hdr->len_kr.num_srk == 0) || + (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) + return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; + + key_num = hdr->len_kr.srk_sel; + if (key_num == 0 || key_num > hdr->len_kr.num_srk) + return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; + + /* Get revoc key from sfp */ + key_revoc_flag = get_key_revoc(); + ret = is_key_revoked(key_num, key_revoc_flag); + if (ret) + return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; + + size = hdr->len_kr.num_srk * sizeof(struct srk_table); + + memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); + + for (i = 0; i < hdr->len_kr.num_srk; i++) { + if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len)) + return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN; + } + + img->key_len = img->srk_tbl[key_num - 1].key_len; + + memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), + img->key_len); + + return 0; +} +#endif + +#ifndef CONFIG_ESBC_HDR_LS +static u32 read_validate_single_key(struct fsl_secboot_img_priv *img) +{ + struct fsl_secboot_img_hdr *hdr = &img->hdr; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; + + /* check key length */ + if (!CHECK_KEY_LEN(hdr->key_len)) + return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; + + memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); + + img->key_len = hdr->key_len; + + return 0; +} +#endif /* CONFIG_ESBC_HDR_LS */ + +#if defined(CONFIG_FSL_ISBC_KEY_EXT) +static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img) +{ + struct fsl_secboot_img_hdr *hdr = &img->hdr; + u32 ie_key_len, ie_revoc_flag, ie_num; + struct ie_key_info *ie_info; + + if (get_ie_info_addr(&img->ie_addr)) + return ERROR_IE_TABLE_NOT_FOUND; + ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; + if (ie_info->num_keys == 0 || ie_info->num_keys > 32) + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; + + ie_num = hdr->ie_key_sel; + if (ie_num == 0 || ie_num > ie_info->num_keys) + return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; + + ie_revoc_flag = ie_info->key_revok; + if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) + return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; + + ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; + + if (!CHECK_KEY_LEN(ie_key_len)) + return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; + + memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), + ie_key_len); + + img->key_len = ie_key_len; + return 0; +} +#endif + + +/* This function return length of public key.*/ +static inline u32 get_key_len(struct fsl_secboot_img_priv *img) +{ + return img->key_len; +} + +/* + * Handles the ESBC uboot client header verification failure. + * This function handles all the errors which might occur in the + * parsing and checking of ESBC uboot client header. It will also + * set the error bits in the SEC_MON. + */ +static void fsl_secboot_header_verification_failure(void) +{ + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) + (CONFIG_SYS_SEC_MON_ADDR); + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); + u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); + + /* 29th bit of OSPR is ITS */ + u32 its = sfp_in32(&sfp_regs->ospr) >> 2; + + /* + * Read the SEC_MON status register + * Read SSM_ST field + */ + sts = sec_mon_in32(&sec_mon_regs->hp_stat); + if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { + if (its == 1) + change_sec_mon_state(HPSR_SSM_ST_TRUST, + HPSR_SSM_ST_SOFT_FAIL); + else + change_sec_mon_state(HPSR_SSM_ST_TRUST, + HPSR_SSM_ST_NON_SECURE); + } + + printf("Generating reset request\n"); + do_reset(NULL, 0, 0, NULL); + /* If reset doesn't coocur, halt execution */ + do_esbc_halt(NULL, 0, 0, NULL); +} + +/* + * Handles the ESBC uboot client image verification failure. + * This function handles all the errors which might occur in the + * public key hash comparison and signature verification of + * ESBC uboot client image. It will also + * set the error bits in the SEC_MON. + */ +static void fsl_secboot_image_verification_failure(void) +{ + struct ccsr_sec_mon_regs *sec_mon_regs = (void *) + (CONFIG_SYS_SEC_MON_ADDR); + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); + u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); + + u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT; + + /* + * Read the SEC_MON status register + * Read SSM_ST field + */ + sts = sec_mon_in32(&sec_mon_regs->hp_stat); + if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { + if (its == 1) { + change_sec_mon_state(HPSR_SSM_ST_TRUST, + HPSR_SSM_ST_SOFT_FAIL); + + printf("Generating reset request\n"); + do_reset(NULL, 0, 0, NULL); + /* If reset doesn't coocur, halt execution */ + do_esbc_halt(NULL, 0, 0, NULL); + + } else { + change_sec_mon_state(HPSR_SSM_ST_TRUST, + HPSR_SSM_ST_NON_SECURE); + } + } +} + +static void fsl_secboot_bootscript_parse_failure(void) +{ + fsl_secboot_header_verification_failure(); +} + +/* + * Handles the errors in esbc boot. + * This function handles all the errors which might occur in the + * esbc boot phase. It will call the appropriate api to log the + * errors and set the error bits in the SEC_MON. + */ +void fsl_secboot_handle_error(int error) +{ + const struct fsl_secboot_errcode *e; + + for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX; + e++) { + if (e->errcode == error) + printf("ERROR :: %x :: %s\n", error, e->name); + } + + /* If Boot Mode is secure, transition the SNVS state and issue + * reset based on type of failure and ITS setting. + * If Boot mode is non-secure, return from this function. + */ + if (fsl_check_boot_mode_secure() == 0) + return; + + switch (error) { + case ERROR_ESBC_CLIENT_HEADER_BARKER: + case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: + case ERROR_ESBC_CLIENT_HEADER_KEY_LEN: + case ERROR_ESBC_CLIENT_HEADER_SIG_LEN: + case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN: + case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1: + case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2: + case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD: + case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP: + case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD: + case ERROR_KEY_TABLE_NOT_FOUND: +#ifdef CONFIG_KEY_REVOCATION + case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED: + case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY: + case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM: + case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN: +#endif +#if defined(CONFIG_FSL_ISBC_KEY_EXT) + /*@fallthrough@*/ + case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED: + case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY: + case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM: + case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN: + case ERROR_IE_TABLE_NOT_FOUND: +#endif + fsl_secboot_header_verification_failure(); + break; + case ERROR_ESBC_SEC_RESET: + case ERROR_ESBC_SEC_DEQ: + case ERROR_ESBC_SEC_ENQ: + case ERROR_ESBC_SEC_DEQ_TO: + case ERROR_ESBC_SEC_JOBQ_STATUS: + case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY: + case ERROR_ESBC_CLIENT_HASH_COMPARE_EM: + fsl_secboot_image_verification_failure(); + break; + case ERROR_ESBC_MISSING_BOOTM: + fsl_secboot_bootscript_parse_failure(); + break; + case ERROR_ESBC_WRONG_CMD: + default: + branch_to_self(); + break; + } +} + +static void fsl_secblk_handle_error(int error) +{ + switch (error) { + case ERROR_ESBC_SEC_ENQ: + fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ); + break; + case ERROR_ESBC_SEC_DEQ: + fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ); + break; + case ERROR_ESBC_SEC_DEQ_TO: + fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO); + break; + default: + printf("Job Queue Output status %x\n", error); + fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS); + break; + } +} + +/* + * Calculate hash of key obtained via offset present in ESBC uboot + * client hdr. This function calculates the hash of key which is obtained + * through offset present in ESBC uboot client header. + */ +static int calc_img_key_hash(struct fsl_secboot_img_priv *img) +{ + struct hash_algo *algo; + void *ctx; + int i, srk = 0; + int ret = 0; + const char *algo_name = "sha256"; + + /* Calculate hash of the esbc key */ + ret = hash_progressive_lookup_algo(algo_name, &algo); + if (ret) + return ret; + + ret = algo->hash_init(algo, &ctx); + if (ret) + return ret; + + /* Update hash for ESBC key */ +#ifdef CONFIG_KEY_REVOCATION + if (check_srk(img)) { + ret = algo->hash_update(algo, ctx, + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); + srk = 1; + } +#endif + if (!srk) + ret = algo->hash_update(algo, ctx, + img->img_key, img->key_len, 1); + if (ret) + return ret; + + /* Copy hash at destination buffer */ + ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); + if (ret) + return ret; + + for (i = 0; i < SHA256_BYTES; i++) + img->img_key_hash[i] = hash_val[i]; + + return 0; +} + +/* + * Calculate hash of ESBC hdr and ESBC. This function calculates the + * single hash of ESBC header and ESBC image. If SG flag is on, all + * SG entries are also hashed alongwith the complete SG table. + */ +static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) +{ + struct hash_algo *algo; + void *ctx; + int ret = 0; + int key_hash = 0; + const char *algo_name = "sha256"; + + /* Calculate the hash of the ESBC */ + ret = hash_progressive_lookup_algo(algo_name, &algo); + if (ret) + return ret; + + ret = algo->hash_init(algo, &ctx); + /* Copy hash at destination buffer */ + if (ret) + return ret; + + /* Update hash for CSF Header */ + ret = algo->hash_update(algo, ctx, + (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0); + if (ret) + return ret; + + /* Update the hash with that of srk table if srk flag is 1 + * If IE Table is selected, key is not added in the hash + * If neither srk table nor IE key table available, add key + * from header in the hash calculation + */ +#ifdef CONFIG_KEY_REVOCATION + if (check_srk(img)) { + ret = algo->hash_update(algo, ctx, + (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), + img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); + key_hash = 1; + } +#endif +#if defined(CONFIG_FSL_ISBC_KEY_EXT) + if (!key_hash && check_ie(img)) + key_hash = 1; +#endif +#ifndef CONFIG_ESBC_HDR_LS +/* No single key support in LS ESBC header */ + if (!key_hash) { + ret = algo->hash_update(algo, ctx, + img->img_key, img->hdr.key_len, 0); + key_hash = 1; + } +#endif + if (ret) + return ret; + if (!key_hash) + return ERROR_KEY_TABLE_NOT_FOUND; + + /* Update hash for actual Image */ + ret = algo->hash_update(algo, ctx, + (u8 *)(*(img->img_addr_ptr)), img->img_size, 1); + if (ret) + return ret; + + /* Copy hash at destination buffer */ + ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); + if (ret) + return ret; + + return 0; +} + +/* + * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the + * pointers for padding, DER value and hash. And finally, constructs EM' + * which includes hash of complete CSF header and ESBC image. If SG flag + * is on, hash of SG table and entries is also included. + */ +static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img) +{ + /* + * RSA PKCSv1.5 encoding format for encoded message is below + * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash + * PS is Padding String + * DER is DER value for SHA-256 + * Hash is SHA-256 hash + * ********************************************************* + * representative points to first byte of EM initially and is + * filled with 0x0 + * representative is incremented by 1 and second byte is filled + * with 0x1 + * padding points to third byte of EM + * digest points to full length of EM - 32 bytes + * hash_id (DER value) points to 19 bytes before pDigest + * separator is one byte which separates padding and DER + */ + + size_t len; + u8 *representative; + u8 *padding, *digest; + u8 *hash_id, *separator; + int i; + + len = (get_key_len(img) / 2) - 1; + representative = img->img_encoded_hash_second; + representative[0] = 0; + representative[1] = 1; /* block type 1 */ + + padding = &representative[2]; + digest = &representative[1] + len - 32; + hash_id = digest - sizeof(hash_identifier); + separator = hash_id - 1; + + /* fill padding area pointed by padding with 0xff */ + memset(padding, 0xff, separator - padding); + + /* fill byte pointed by separator */ + *separator = 0; + + /* fill SHA-256 DER value pointed by HashId */ + memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); + + /* fill hash pointed by Digest */ + for (i = 0; i < SHA256_BYTES; i++) + digest[i] = hash_val[i]; +} + +/* + * Reads and validates the ESBC client header. + * This function reads key and signature from the ESBC client header. + * If Scatter/Gather flag is on, lengths and offsets of images + * present as SG entries are also read. This function also checks + * whether the header is valid or not. + */ +static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) +{ + struct fsl_secboot_img_hdr *hdr = &img->hdr; + void *esbc = (u8 *)(uintptr_t)img->ehdrloc; + u8 *k, *s; + u32 ret = 0; + + int key_found = 0; + + /* check barker code */ + if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) + return ERROR_ESBC_CLIENT_HEADER_BARKER; + + /* If Image Address is not passed as argument to function, + * then Address and Size must be read from the Header. + */ + if (*(img->img_addr_ptr) == 0) { + #ifdef CONFIG_ESBC_ADDR_64BIT + *(img->img_addr_ptr) = hdr->pimg64; + #else + *(img->img_addr_ptr) = hdr->pimg; + #endif + } + + if (!hdr->img_size) + return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; + + img->img_size = hdr->img_size; + + /* Key checking*/ +#ifdef CONFIG_KEY_REVOCATION + if (check_srk(img)) { + ret = read_validate_srk_tbl(img); + if (ret != 0) + return ret; + key_found = 1; + } +#endif + +#if defined(CONFIG_FSL_ISBC_KEY_EXT) + if (!key_found && check_ie(img)) { + ret = read_validate_ie_tbl(img); + if (ret != 0) + return ret; + key_found = 1; + } +#endif +#ifndef CONFIG_ESBC_HDR_LS +/* Single Key Feature not available in LS ESBC Header */ + if (key_found == 0) { + ret = read_validate_single_key(img); + if (ret != 0) + return ret; + key_found = 1; + } +#endif + if (!key_found) + return ERROR_KEY_TABLE_NOT_FOUND; + + /* check signaure */ + if (get_key_len(img) == 2 * hdr->sign_len) { + /* check signature length */ + if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) || + (hdr->sign_len == KEY_SIZE_BYTES / 2) || + (hdr->sign_len == KEY_SIZE_BYTES))) + return ERROR_ESBC_CLIENT_HEADER_SIG_LEN; + } else { + return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN; + } + + memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len); +/* No SG support in LS-CH3 */ +#ifndef CONFIG_ESBC_HDR_LS + /* No SG support */ + if (hdr->sg_flag) + return ERROR_ESBC_CLIENT_HEADER_SG; +#endif + + /* modulus most significant bit should be set */ + k = (u8 *)&img->img_key; + + if ((k[0] & 0x80) == 0) + return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1; + + /* modulus value should be odd */ + if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0) + return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2; + + /* Check signature value < modulus value */ + s = (u8 *)&img->img_sign; + + if (!(memcmp(s, k, hdr->sign_len) < 0)) + return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD; + + return ESBC_VALID_HDR; +} + +static inline int str2longbe(const char *p, ulong *num) +{ + char *endptr; + ulong tmp; + + if (!p) { + return 0; + } else { + tmp = simple_strtoul(p, &endptr, 16); + if (sizeof(ulong) == 4) + *num = cpu_to_be32(tmp); + else + *num = cpu_to_be64(tmp); + } + + return *p != '\0' && *endptr == '\0'; +} +/* Function to calculate the ESBC Image Hash + * and hash from Digital signature. + * The Two hash's are compared to yield the + * result of signature validation. + */ +static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) +{ + int ret; + uint32_t key_len; + struct key_prop prop; +#if !defined(USE_HOSTCC) + struct udevice *mod_exp_dev; +#endif + ret = calc_esbchdr_esbc_hash(img); + if (ret) + return ret; + + /* Construct encoded hash EM' wrt PKCSv1.5 */ + construct_img_encoded_hash_second(img); + + /* Fill prop structure for public key */ + memset(&prop, 0, sizeof(struct key_prop)); + key_len = get_key_len(img) / 2; + prop.modulus = img->img_key; + prop.public_exponent = img->img_key + key_len; + prop.num_bits = key_len * 8; + prop.exp_len = key_len; + + ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); + if (ret) { + printf("RSA: Can't find Modular Exp implementation\n"); + return -EINVAL; + } + + ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, + &prop, img->img_encoded_hash); + if (ret) + return ret; + + /* + * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 + * memcmp returns zero on success + * memcmp returns non-zero on failure + */ + ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, + img->hdr.sign_len); + + if (ret) + return ERROR_ESBC_CLIENT_HASH_COMPARE_EM; + + return 0; +} +/* haddr - Address of the header of image to be validated. + * arg_hash_str - Option hash string. If provided, this + * overrides the key hash in the SFP fuses. + * img_addr_ptr - Optional pointer to address of image to be validated. + * If non zero addr, this overrides the addr of image in header, + * otherwise updated to image addr in header. + * Acts as both input and output of function. + * This pointer shouldn't be NULL. + */ +int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str, + uintptr_t *img_addr_ptr) +{ + struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); + ulong hash[SHA256_BYTES/sizeof(ulong)]; + char hash_str[NUM_HEX_CHARS + 1]; + struct fsl_secboot_img_priv *img; + struct fsl_secboot_img_hdr *hdr; + void *esbc; + int ret, i, hash_cmd = 0; + u32 srk_hash[8]; + + if (arg_hash_str != NULL) { + const char *cp = arg_hash_str; + int i = 0; + + if (*cp == '0' && *(cp + 1) == 'x') + cp += 2; + + /* The input string expected is in hex, where + * each 4 bits would be represented by a hex + * sha256 hash is 256 bits long, which would mean + * num of characters = 256 / 4 + */ + if (strlen(cp) != SHA256_NIBBLES) { + printf("%s is not a 256 bits hex string as expected\n", + arg_hash_str); + return -1; + } + + for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) { + strncpy(hash_str, cp + (i * NUM_HEX_CHARS), + NUM_HEX_CHARS); + hash_str[NUM_HEX_CHARS] = '\0'; + if (!str2longbe(hash_str, &hash[i])) { + printf("%s is not a 256 bits hex string ", + arg_hash_str); + return -1; + } + } + + hash_cmd = 1; + } + + img = malloc(sizeof(struct fsl_secboot_img_priv)); + + if (!img) + return -1; + + memset(img, 0, sizeof(struct fsl_secboot_img_priv)); + + /* Update the information in Private Struct */ + hdr = &img->hdr; + img->ehdrloc = haddr; + img->img_addr_ptr = img_addr_ptr; + esbc = (u8 *)img->ehdrloc; + + memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); + + /* read and validate esbc header */ + ret = read_validate_esbc_client_header(img); + + if (ret != ESBC_VALID_HDR) { + fsl_secboot_handle_error(ret); + goto exit; + } + + /* SRKH present in SFP */ + for (i = 0; i < NUM_SRKH_REGS; i++) + srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]); + + /* + * Calculate hash of key obtained via offset present in + * ESBC uboot client hdr + */ + ret = calc_img_key_hash(img); + if (ret) { + fsl_secblk_handle_error(ret); + goto exit; + } + + /* Compare hash obtained above with SRK hash present in SFP */ + if (hash_cmd) + ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES); + else + ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES); + +#if defined(CONFIG_FSL_ISBC_KEY_EXT) + if (!hash_cmd && check_ie(img)) + ret = 0; +#endif + + if (ret != 0) { + fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY); + goto exit; + } + + ret = calculate_cmp_img_sig(img); + if (ret) { + fsl_secboot_handle_error(ret); + goto exit; + } + +exit: + return ret; +} diff --git a/board/scalys/simc-t10xx/Kconfig b/board/scalys/simc-t10xx/Kconfig index d43dc85..2b18913 100644 --- a/board/scalys/simc-t10xx/Kconfig +++ b/board/scalys/simc-t10xx/Kconfig @@ -57,7 +57,7 @@ config PPC_T1020 config PPC_T1022 bool - prompt "T1040" + prompt "T1022" config PPC_T1040 bool diff --git a/board/scalys/simc-t10xx/ddr.c b/board/scalys/simc-t10xx/ddr.c index ca5407e..f6d04ac 100644 --- a/board/scalys/simc-t10xx/ddr.c +++ b/board/scalys/simc-t10xx/ddr.c @@ -7,7 +7,7 @@ #include #include -#include +//#include #include #include @@ -18,10 +18,7 @@ #include #include #include -#include - -/* DDR_RST_N => IFC_CS3_B => GPIO2_12 */ -#define DDR_RST_N MPC8XXX_GPIO_NR(2, 12) +//#include /* MT41K512M8RH-125 */ dimm_params_t ddr_raw_timing = { @@ -91,8 +88,8 @@ void fsl_ddr_board_options(memctl_options_t *popts, popts->ddr_cdr1 = 0x800c0000; popts->ddr_cdr2 = 0x00000001; - /* Clock is launched 1/4 applied cycle after address/command */ - popts->clk_adjust = 4; + /* Clock is launched 1/2 applied cycle after address/command */ + popts->clk_adjust = 8; } int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, @@ -114,15 +111,29 @@ int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, phys_size_t initdram(int board_type) { phys_size_t dram_size; - + #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) + uint32_t regval; + + /* Remove reset of DDR using GPIO pin. We do this manually since + * we have not yet access to the DM gpio at this time */ + /* DDR_RST_N => IFC_CS3_B => GPIO2_12 */ + +#define CONFIG_SYS_MPC85XX_GPIO2_ADDR (CONFIG_SYS_IMMR + 0x131000) +#define DDR_RST_N (12) +/* DDR_RST_N => IFC_CS3_B => GPIO2_12 */ +/* #define DDR_RST_N MPC85XX_GPIO_NR(2, 12) */ -#ifdef GPIO_IN_SPL_WORKING - gpio_request(DDR_RST_N, "DDR_RST_N"); - gpio_direction_output(DDR_RST_N, 1); -#else - mpc8xxx_gpio_set(DDR_RST_N,1); -#endif + /* Set output */ + regval = in_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR+0x8); + regval |= (0x80000000 >> 12); + out_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR+0x8, regval); + + /* Set direction to acivate gpio pin */ + regval = in_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR); + regval |= (0x80000000 >> 12); + out_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR, regval); + dram_size = fsl_ddr_sdram(); dram_size = setup_ddr_tlbs(dram_size / 0x100000); dram_size *= 0x100000; diff --git a/board/scalys/simc-t10xx/dragonfruit.c b/board/scalys/simc-t10xx/dragonfruit.c index 1656054..0ae849c 100644 --- a/board/scalys/simc-t10xx/dragonfruit.c +++ b/board/scalys/simc-t10xx/dragonfruit.c @@ -7,8 +7,6 @@ #include #include -#include -#include #include "dragonfruit.h" @@ -42,10 +40,10 @@ * SERDES H => Slot 4, lane 3 */ -#define MUX_SER0_1_SEL MPC8XXX_GPIO_NR(2, 25) -#define MUX_SER2_3_SEL MPC8XXX_GPIO_NR(2, 26) -#define MUX_SER5_6_SEL MPC8XXX_GPIO_NR(2, 27) -#define SERDES_CLK_OE MPC8XXX_GPIO_NR(2, 29) +#define MUX_SER0_1_SEL MPC85XX_GPIO_NR(2, 25) +#define MUX_SER2_3_SEL MPC85XX_GPIO_NR(2, 26) +#define MUX_SER5_6_SEL MPC85XX_GPIO_NR(2, 27) +#define SERDES_CLK_OE MPC85XX_GPIO_NR(2, 29) int scalys_carrier_setup_muxing(int serdes_config) { diff --git a/board/scalys/simc-t10xx/simc-t10xx.c b/board/scalys/simc-t10xx/simc-t10xx.c index f5b8a2c..46c5677 100644 --- a/board/scalys/simc-t10xx/simc-t10xx.c +++ b/board/scalys/simc-t10xx/simc-t10xx.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include #include #include "dragonfruit.h" @@ -43,13 +41,15 @@ int misc_init_r(void) int serdes_config; ccsr_gur_t __iomem *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); int ret; + + debug("t10xx: misc_init_r\n"); /* * Initialize and set the LED's on the module to indicate u-boot is alive * IFC_A30 : led green : GPIO2_30 * IFC_A31 : led red : GPIO2_31 */ - #define MODULE_LED_RED MPC8XXX_GPIO_NR(2, 31) - #define MODULE_LED_GREEN MPC8XXX_GPIO_NR(2, 30) + #define MODULE_LED_RED MPC85XX_GPIO_NR(2, 31) + #define MODULE_LED_GREEN MPC85XX_GPIO_NR(2, 30) gpio_request(MODULE_LED_RED, "module_led_red"); gpio_request(MODULE_LED_GREEN, "module_led_green"); @@ -74,22 +74,18 @@ int misc_init_r(void) } /* Platform data for the GPIOs */ -static const struct mpc8xxx_gpio_platdata gpio_platdata[] = { - { .regs = (ccsr_gpio_t*) CONFIG_SYS_MPC8XXX_GPIO1_ADDR, - .bank_name = "GPIO1_" }, - { .regs = (ccsr_gpio_t*) CONFIG_SYS_MPC8XXX_GPIO2_ADDR, - .bank_name = "GPIO2_" }, - { .regs = (ccsr_gpio_t*) CONFIG_SYS_MPC8XXX_GPIO3_ADDR, - .bank_name = "GPIO3_" }, - { .regs = (ccsr_gpio_t*) CONFIG_SYS_MPC8XXX_GPIO4_ADDR, - .bank_name = "GPIO4_" }, +static const struct mpc85xx_gpio_plat gpio_platdata[] = { + { .addr = 0x130000, .ngpios = 32 }, + { .addr = 0x131000, .ngpios = 32 }, + { .addr = 0x132000, .ngpios = 32 }, + { .addr = 0x133000, .ngpios = 32,}, }; -U_BOOT_DEVICES(mpc8xxx_gpios) = { - { "gpio-mpc8xxx", &gpio_platdata[0] }, - { "gpio-mpc8xxx", &gpio_platdata[1] }, - { "gpio-mpc8xxx", &gpio_platdata[2] }, - { "gpio-mpc8xxx", &gpio_platdata[3] }, +U_BOOT_DEVICES(mpc85xx_gpios) = { + { "gpio_mpc85xx", &gpio_platdata[0] }, + { "gpio_mpc85xx", &gpio_platdata[1] }, + { "gpio_mpc85xx", &gpio_platdata[2] }, + { "gpio_mpc85xx", &gpio_platdata[3] }, }; int ft_board_setup(void *blob, bd_t *bd) @@ -97,7 +93,7 @@ int ft_board_setup(void *blob, bd_t *bd) phys_addr_t base; phys_size_t size; - debug( "ft_board_setup\n" ); + debug( "t10xx: ft_board_setup\n" ); ft_cpu_setup(blob, bd); base = getenv_bootm_low(); @@ -144,4 +140,4 @@ void board_detail(void) { do_bcdinfo(); } -#endif \ No newline at end of file +#endif diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 34c4a40..fecb2fc 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -34,6 +34,7 @@ config DWAPB_GPIO help Support for the Designware APB GPIO driver. +<<<<<<< 82a006ca2df310164bb48c36a793d1b733cf4af8 <<<<<<< bc5d0384458466ed5b3608d326eec03cd4f13016 config AT91_GPIO bool "AT91 PIO GPIO driver" @@ -56,6 +57,8 @@ config MPC8XXX_GPIO Support for the NXP (Freescale) MPC/QorIQ GPIO controller >>>>>>> dm: gpio: Add DM GPIO driver for MPC8xxx platforms +======= +>>>>>>> merge with master config ATMEL_PIO4 bool "ATMEL PIO4 driver" depends on DM_GPIO diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c deleted file mode 100644 index c5d72ef..0000000 --- a/drivers/gpio/gpio-mpc8xxx.c +++ /dev/null @@ -1,178 +0,0 @@ - -/* - * GPIOs on MPC512x/8349/8572/8610/T-series and compatible - * - * Driver ported from the linux kernel 4.5 (b562e44f507e863c6792946e4e1b1449fbbac85d) - * and removed the interrupt functionallity. - * - * Copyright (C) 2008 Peter Korsgaard - * Copyright (c) 2016 Scalys B.V. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -#define MPC8XXX_GPIO_PINS 32 - -static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) -{ - return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio); -} - -static int mpc8xxx_dm_gpio_set(struct udevice *dev, unsigned pin, int val) -{ - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - -#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) - - if (val) { - plat->data |= mpc8xxx_gpio2mask(pin); - } else { - plat->data &= ~mpc8xxx_gpio2mask(pin); - } - - out_be32(&(plat->regs->gpdat), plat->data); -#else - if (val) { - setbits_be32(&(plat->regs->gpdat), mpc8xxx_gpio2mask(pin)); - } else { - clrbits_be32(&(plat->regs->gpdat), mpc8xxx_gpio2mask(pin)); - } -#endif - return 0; -} - -static int mpc8xxx_dm_gpio_dir_in(struct udevice *dev, unsigned int gpio) -{ - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - - clrbits_be32(&(plat->regs->gpdir), mpc8xxx_gpio2mask(gpio)); - - return 0; -} - -static int mpc8xxx_dm_gpio_dir_out(struct udevice *dev, unsigned int gpio, - int val) -{ - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - - mpc8xxx_dm_gpio_set(dev, gpio, val); - - setbits_be32(&(plat->regs->gpdir), mpc8xxx_gpio2mask(gpio)); - - return 0; -} - -static int mpc8xxx_dm_gpio_get(struct udevice *dev, unsigned int gpio) -{ - int ret = 0; - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - -#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) - uint32_t data_val, out_mask, out_shadow; - - /* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs - * defined as output cannot be determined by reading GPDAT register, - * so we use shadow data register instead. The status of input pins - * is determined by reading GPDAT register. - */ - out_mask = in_be32(&plat->regs->gpdir); - - data_val = in_be32(&plat->regs->gpdat) & ~out_mask; - out_shadow = plat->data & out_mask; - - ret = ! !((data_val | out_shadow) & mpc8xxx_gpio2mask(gpio)); -#else - if (in_be32(&plat->regs->gpdat) & mpc8xxx_gpio2mask(gpio)) { - ret = 1; - } else { - ret = 0; - } -#endif - return ret; -} - -static int mpc8xxx_dm_gpio_get_function(struct udevice *dev, unsigned gpio) -{ - int ret = GPIOF_UNUSED; - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - - if (in_be32(&plat->regs->gpdir) & mpc8xxx_gpio2mask(gpio)) { - ret = GPIOF_OUTPUT; - } else { - ret = GPIOF_INPUT; - } - return ret; -} - -static const struct udevice_id mpc8xxx_gpio_ids[] = { - {.compatible = "fsl,mpc8349-gpio",}, - {.compatible = "fsl,mpc8572-gpio",}, - {.compatible = "fsl,mpc8610-gpio",}, - {.compatible = "fsl,mpc5121-gpio",}, - {.compatible = "fsl,mpc5125-gpio",}, - {.compatible = "fsl,pq3-gpio",}, - {.compatible = "fsl,qoriq-gpio",}, - {} -}; - -static const struct dm_gpio_ops mpc8xxx_gpio_ops = { - .direction_input = mpc8xxx_dm_gpio_dir_in, - .direction_output = mpc8xxx_dm_gpio_dir_out, - .get_value = mpc8xxx_dm_gpio_get, - .set_value = mpc8xxx_dm_gpio_set, - .get_function = mpc8xxx_dm_gpio_get_function, -}; - -#ifdef SPL_OF_CONTROL -static int mpc8xxx_gpio_ofdata_to_platdata(struct udevice *dev) -{ - int register_address; - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - - register_address = - fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1); - if (register_address == -1) { - debug("%s: Invalid register offset %d\n", __func__, - register_address); - return -EINVAL; - } - plat->regs = map_physmem(register_address, sizeof(ccsr_gpio_t), - MAP_NOCACHE); - plat->gpio_count = MPC8XXX_GPIO_PINS; - plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset, - "bank-name", NULL); - - return 0; -} -#endif - -static int mpc8xxx_gpio_probe(struct udevice *dev) -{ - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - struct mpc8xxx_gpio_platdata *plat = dev_get_platdata(dev); - - uc_priv->gpio_count = MPC8XXX_GPIO_PINS; - uc_priv->bank_name = plat->bank_name; - - return 0; -} - -U_BOOT_DRIVER(gpio_mpc8xxx) = { - .name = "gpio-mpc8xxx",.id = UCLASS_GPIO,.of_match = - mpc8xxx_gpio_ids,.ops = &mpc8xxx_gpio_ops, -#ifdef SPL_OF_CONTROL - .ofdata_to_platdata = mpc8xxx_gpio_ofdata_to_platdata, -#endif -.platdata_auto_alloc_size = - sizeof(struct mpc8xxx_gpio_platdata),.probe = mpc8xxx_gpio_probe,}; diff --git a/include/common.h b/include/common.h index c8fb277..958a40e 100644 --- a/include/common.h +++ b/include/common.h @@ -42,6 +42,7 @@ typedef volatile unsigned char vu_char; #define CONFIG_SYS_SUPPORT_64BIT_DATA #endif +#define DEBUG #ifdef DEBUG #define _DEBUG 1 #else diff --git a/include/configs/simc-t10xx.h b/include/configs/simc-t10xx.h index f53c201..49550b7 100644 --- a/include/configs/simc-t10xx.h +++ b/include/configs/simc-t10xx.h @@ -10,6 +10,9 @@ #include "simc-t10x0.h" #include + +#define MPC85XX_GPIO_NR(port, pin) ((((port)-1)*32)+((pin)&31)) + /* * SIMC-T10xx board configuration file */ @@ -186,9 +189,20 @@ */ #define CONFIG_SYS_INIT_L3_ADDR 0xFFFC0000 #define CONFIG_SYS_L3_SIZE 256 << 10 -#define CONFIG_SPL_GD_ADDR (CONFIG_SYS_INIT_L3_ADDR + 32 * 1024) +/* TODO CLEANUP #define CONFIG_SPL_GD_ADDR (CONFIG_SYS_INIT_L3_ADDR + 32 * 1024) */ #ifdef CONFIG_RAMBOOT_PBL #define CONFIG_ENV_ADDR (CONFIG_SPL_GD_ADDR + 4 * 1024) + + +/* + * For Secure Boot CONFIG_SYS_INIT_L3_ADDR will be redefined and hence + * Physical address (CONFIG_SYS_INIT_L3_ADDR) and virtual address + * (CONFIG_SYS_INIT_L3_VADDR) will be different. + */ +#define CONFIG_SYS_INIT_L3_VADDR 0xFFFC0000 +#define CONFIG_SPL_GD_ADDR (CONFIG_SYS_INIT_L3_VADDR + 32 * 1024) + + #endif /* CONFIG_RAMBOOT_PBL */ #define CONFIG_SPL_RELOC_MALLOC_ADDR (CONFIG_SPL_GD_ADDR + 12 * 1024) #define CONFIG_SPL_RELOC_MALLOC_SIZE (30 << 10) @@ -623,8 +637,6 @@ #define CONFIG_MTD_DEVICE #define CONFIG_MTD_PARTITIONS -#define CONFIG_CMD_BOOTZ - #define CONFIG_SYS_NO_FLASH @@ -666,7 +678,6 @@ /* default location for tftp and bootm */ #define CONFIG_LOADADDR 1000000 -#define CONFIG_BOOTDELAY 3 /*-1 disables auto-boot*/ #define CONFIG_ZERO_BOOTDELAY_CHECK /* Also check for boot interruption, when bootdelay is zero */ #define CONFIG_BAUDRATE 115200 diff --git a/include/dm/platform_data/gpio_mpc8xxx.h b/include/dm/platform_data/gpio_mpc8xxx.h deleted file mode 100644 index 37e5241..0000000 --- a/include/dm/platform_data/gpio_mpc8xxx.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2016 Scalys B.V. - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MPC8XXX_GPIO_H -#define _MPC8XXX_GPIO_H - -struct mpc8xxx_gpio_platdata { - const char *bank_name; - ccsr_gpio_t *regs; - int gpio_count; -#if defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) - /* shadowed data register used to work around errata on - * MPC8572 and MPC8535 where it is not possible to read the - * state of an output pin */ - uint32_t data; -#endif -}; - -#endif -- cgit v0.10.2