diff --git a/boards/arm/secureiot1702/CMakeLists.txt b/boards/arm/secureiot1702/CMakeLists.txt new file mode 100644 index 0000000000000..042bdd2b79acb --- /dev/null +++ b/boards/arm/secureiot1702/CMakeLists.txt @@ -0,0 +1,8 @@ +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_library() +zephyr_library_sources(pinmux.c) diff --git a/boards/arm/secureiot1702/Kconfig.board b/boards/arm/secureiot1702/Kconfig.board new file mode 100644 index 0000000000000..94bb5a0458fb3 --- /dev/null +++ b/boards/arm/secureiot1702/Kconfig.board @@ -0,0 +1,10 @@ +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# + +config BOARD_SECUREIOT1702 + bool "Microchip SecureIoT1702" + depends on SOC_SERIES_CEC1702 + select HAS_DTS diff --git a/boards/arm/secureiot1702/Kconfig.defconfig b/boards/arm/secureiot1702/Kconfig.defconfig new file mode 100644 index 0000000000000..414120c022543 --- /dev/null +++ b/boards/arm/secureiot1702/Kconfig.defconfig @@ -0,0 +1,12 @@ +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# + +if BOARD_SECUREIOT1702 + +config BOARD + default "secureiot1702" + +endif diff --git a/boards/arm/secureiot1702/doc/index.rst b/boards/arm/secureiot1702/doc/index.rst new file mode 100644 index 0000000000000..eabf92ae1e491 --- /dev/null +++ b/boards/arm/secureiot1702/doc/index.rst @@ -0,0 +1,124 @@ +.. _secureiot1702: + +Microchip SecureIoT1702 +####################### + +Overview +******** + +This demo board features a Microchip CEC1702 cryptographic +embedded controlled based on an ARM Cortex-M4. + +Highlights of the board: + +- CEC1702 32-bit ARM® Cortex®-M4F Controller with Integrated Crypto +- Compact, high-contrast, serial graphic LCD Display Module with back-light +- 2x4 matrix of push buttons inputs +- USB-UART Converter as debug interface +- Potentiometer to ADC channel +- Serial Quad I/O (SQI) flash +- OTP programmable in CEC1702 +- Two expansion headers compatible with MikroElektronika mikroBUS™ Expansion interface + +More information can be found on the `SecureIoT1702 website`_ and +`CEC1702 website`_, and SoC programming information is available +in the `CEC1702 datasheet`_. + +Supported Features +================== + +The following devices are supported: + +- Nested Vectored Interrupt Controller (NVIC) +- System Tick System Clock (SYSTICK) +- Serial Ports (NS16550) + + +Connections and IOs +=================== + +Please refer to the `SecureIoT1702 schematics`_ for the pin routings. +Additional devices can be connected via mikroBUS expansion interface. + +Programming and Debugging +************************* + +This board comes with a 10-pin Cortext Debug port and a separate SPI +flash programming header. + +Applications for the ``secureiot1702`` board configuration can be +built the usual way (see :ref:`build_an_application` for more details) which +is then programmed directly to the external SPI flash chip. + +Flashing +======== + +# Add extra configuration :code:`CONFIG_BOOT_DELAY=4000` in :code:`prj.conf`. + This is needed for the host USB drivers to be ready to see the boot messages. + Build :ref:`hello_world` application. The build will result + in :code:`zephyr_spi_image.bin`. + + .. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: secureiot1702 + :goals: build + +#. Connect your SPI programmer to SecureIoT1702 connector X12 in order to flash. + Then proceed to flash using flashrom v1.1 or a similar tool for flashing + SPI chip with :code:`zephyr_spi_image.bin`. + + .. code-block:: console + + $ flashrom -w zephyr_spi_image.bin + +#. Run your favorite terminal program to listen for output. Under Linux the + terminal should be :code:`/dev/ttyUSB0`. For example: + + .. code-block:: console + + $ minicom -D /dev/ttyUSB0 -o -b 115200 + + The -o option tells minicom not to send the modem initialization + string. Connection should be configured as follows: + + - Speed: 115200 + - Data: 8 bits + - Parity: None + - Stop bits: 1 + +#. Connect the SecureIoT1702 to your host computer using the USB connector. + + You should see "Hello World! secureiot1702" in your terminal. + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: mec15xxevb_assy6853 + :maybe-skip-config: + :goals: debug + + +References +********** + +.. target-notes:: + +.. _CEC1702 website: + http://www.microchip.com/CEC1702 + +.. _CEC1702 datasheet: + http://www.microchip.com/p/207/ + +.. _CEC1702 quick start guide: + http://ww1.microchip.com/downloads/en/DeviceDoc/50002665A.pdf + +.. _SecureIoT1702 website: + http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=DM990012 + +.. _SecureIoT1702 schematics: + http://microchipdeveloper.com/secureiot1702:schematic diff --git a/boards/arm/secureiot1702/dts_fixup.h b/boards/arm/secureiot1702/dts_fixup.h new file mode 100644 index 0000000000000..76480ff5b9109 --- /dev/null +++ b/boards/arm/secureiot1702/dts_fixup.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2017 Crypta Labs Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* This file is a temporary workaround for mapping of the generated information + * to the current driver definitions. This will be removed when the drivers + * are modified to handle the generated information, or the mapping of + * generated data matches the driver definitions. + */ + +#define DT_NUM_IRQ_PRIO_BITS DT_ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS diff --git a/boards/arm/secureiot1702/pinmux.c b/boards/arm/secureiot1702/pinmux.c new file mode 100644 index 0000000000000..90bfef968bb87 --- /dev/null +++ b/boards/arm/secureiot1702/pinmux.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Crypta Labs Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "soc.h" + +static int board_init(struct device *dev) +{ +#ifdef DT_NS16550_400F2400_BASE_ADDRESS + /* Set clock request, muxing and power up UART0 */ + PCR_INST->CLK_REQ_2_b.UART_0_CLK_REQ = 1; + GPIO_100_137_INST->GPIO_104_PIN_CONTROL_b.MUX_CONTROL = 1; + GPIO_100_137_INST->GPIO_105_PIN_CONTROL_b.MUX_CONTROL = 1; + UART0_INST->CONFIG = 0; + UART0_INST->ACTIVATE = 1; +#endif +#ifdef DT_NS16550_400F2800_BASE_ADDRESS + /* Set clock request, muxing, UART1_RX_EN and power up UART1 */ + PCR_INST->CLK_REQ_2_b.UART_1_CLK_REQ = 1; + GPIO_140_176_INST->GPIO_170_PIN_CONTROL_b.MUX_CONTROL = 2; + GPIO_140_176_INST->GPIO_171_PIN_CONTROL_b.MUX_CONTROL = 2; + GPIO_100_137_INST->GPIO_113_PIN_CONTROL_b.GPIO_DIRECTION = 1; + UART1_INST->CONFIG = 0; + UART1_INST->ACTIVATE = 1; +#endif + return 0; +} + +SYS_INIT(board_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/boards/arm/secureiot1702/secureiot1702.dts b/boards/arm/secureiot1702/secureiot1702.dts new file mode 100644 index 0000000000000..fa13716acd502 --- /dev/null +++ b/boards/arm/secureiot1702/secureiot1702.dts @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Crypta Labs Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "microchip/cec1702.dtsi" + +/ { + model = "Microchip SecureIoT1702 board"; + compatible = "microchip,secureiot1702", "microchip,cec1702"; + + chosen { + zephyr,sram = &sram0; + zephyr,console = &uart1; + zephyr,flash = &flash0; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; +}; + +&uart1 { + status = "okay"; + current-speed = <115200>; +}; + diff --git a/boards/arm/secureiot1702/secureiot1702_defconfig b/boards/arm/secureiot1702/secureiot1702_defconfig new file mode 100644 index 0000000000000..bbe9934453cb7 --- /dev/null +++ b/boards/arm/secureiot1702/secureiot1702_defconfig @@ -0,0 +1,13 @@ +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_CEC1702=y +CONFIG_BOARD_SECUREIOT1702=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=48000000 + +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 3cebe5660412c..4df7700b20db7 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -79,6 +79,10 @@ BUILD_ASSERT_MSG(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); #define REG_DLF 0xC0 /* Divisor Latch Fraction */ #define REG_PCP 0x200 /* PRV_CLOCK_PARAMS (Apollo Lake) */ +/* equates for baud rate divisor register */ + +#define BRD_MCHP_XEC_BAUD_CLK_SEL 0x8000 /* microchip uart: use system clock */ + /* equates for interrupt enable register */ #define IER_RXRDY 0x01 /* receiver data ready */ @@ -296,6 +300,11 @@ static void set_baud_rate(struct device *dev, u32_t baud_rate) */ divisor = ((dev_cfg->devconf.sys_clk_freq + (baud_rate << 3)) / baud_rate) >> 4; +#if defined(DT_COMPAT_MICROCHIP_XEC_NS16550) + if (dev_cfg->devconf.sys_clk_freq == CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { + divisor |= BRD_MCHP_XEC_BAUD_CLK_SEL; + } +#endif /* set the DLAB to access the baud rate divisor registers */ lcr_cache = INBYTE(LCR(dev)); diff --git a/dts/arm/microchip/cec1702.dtsi b/dts/arm/microchip/cec1702.dtsi new file mode 100644 index 0000000000000..a34a2f18359f3 --- /dev/null +++ b/dts/arm/microchip/cec1702.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 Crypta Labs Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include "armv7-m.dtsi" + +/ { + compatible = "microchip,cec1702"; + + cpus { + cpu0 { + compatible = "arm,cortex-m4f"; + }; + }; + + flash0: flash@b0000 { + reg = <0x000B0000 0x68000>; + }; + + sram0: memory@118000 { + compatible = "mmio-sram"; + reg = <0x00118000 0x10000>; + }; + + soc { + uart0: uart@400f2400 { + compatible = "ns16550", "microchip,xec-ns16550"; + reg = <0x400f2400 0x400>; + interrupts = <40 0>; + clock-frequency = <1843200>; + label = "UART_0"; + reg-shift = <0>; + }; + uart1: uart@400f2800 { + compatible = "ns16550", "microchip,xec-ns16550"; + reg = <0x400f2800 0x400>; + interrupts = <41 0>; + clock-frequency = <1843200>; + label = "UART_1"; + reg-shift = <0>; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; diff --git a/soc/arm/microchip_mec/Kconfig b/soc/arm/microchip_mec/Kconfig index e7b5d6402dd98..f0256ea0f246e 100644 --- a/soc/arm/microchip_mec/Kconfig +++ b/soc/arm/microchip_mec/Kconfig @@ -1,4 +1,4 @@ -# Microchip MEC MCU line +# Microchip CEC/MEC MCU line # Copyright (c) 2018, Intel Corporation # SPDX-License-Identifier: Apache-2.0 diff --git a/soc/arm/microchip_mec/cec1702/CMakeLists.txt b/soc/arm/microchip_mec/cec1702/CMakeLists.txt new file mode 100644 index 0000000000000..bbf474c9fbf32 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources( + soc_config.c + ) + +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${SOC_DIR}/${ARCH}/${SOC_PATH}/cec1702-image.py + --img0-image ${PROJECT_BINARY_DIR}/zephyr.bin + --image-out ${PROJECT_BINARY_DIR}/zephyr_spi_image.bin +) diff --git a/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.cec1702 b/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.cec1702 new file mode 100644 index 0000000000000..b6fa7a5e7f905 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.cec1702 @@ -0,0 +1,21 @@ +# Microchip CEC1702 + +# Copyright (c) 2019 Crypta Labs Ltd. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_CEC1702 + +config SOC + default "cec1702" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 48000000 + +if SERIAL + +config UART_NS16550 + default y + +endif # SERIAL + +endif # SOC_CEC1702 diff --git a/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.series b/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.series new file mode 100644 index 0000000000000..8ed146a1b20d1 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/Kconfig.defconfig.series @@ -0,0 +1,23 @@ +# Kconfig - Microchip CEC MCU line +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_CEC1702 + +config SOC_SERIES + default "cec1702" + +config NUM_IRQS + int + # must be >= the highest interrupt number used + # - include the UART interrupts + default 42 + +config CORTEX_M_SYSTICK + default y + +source "soc/arm/microchip_mec/cec1702/Kconfig.defconfig.cec1702*" + +endif diff --git a/soc/arm/microchip_mec/cec1702/Kconfig.series b/soc/arm/microchip_mec/cec1702/Kconfig.series new file mode 100644 index 0000000000000..ead8bc31746b1 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/Kconfig.series @@ -0,0 +1,15 @@ +# Kconfig - Microchip CEC MCU line +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_CEC1702 + bool "Microchip CEC1702 Series" + select ARM + select CPU_CORTEX_M4 + select SOC_FAMILY_MEC + select CPU_HAS_FPU + select HAS_MEC_HAL + help + Enable support for Microchip CEC1702 Cortex-M4 MCU series diff --git a/soc/arm/microchip_mec/cec1702/Kconfig.soc b/soc/arm/microchip_mec/cec1702/Kconfig.soc new file mode 100644 index 0000000000000..b8fe075bc497d --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/Kconfig.soc @@ -0,0 +1,14 @@ +# Kconfig - Microchip CEC MCU line +# +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "CEC1702 Selection" + depends on SOC_SERIES_CEC1702 + +config SOC_CEC1702 + bool "CEC1702" + +endchoice diff --git a/soc/arm/microchip_mec/cec1702/cec1702-image.py b/soc/arm/microchip_mec/cec1702/cec1702-image.py new file mode 100644 index 0000000000000..7d9e0036c1dac --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/cec1702-image.py @@ -0,0 +1,167 @@ +#!/usr/bin/python3 + +# cec1702-image.py - CEC1702 SPI flash image creater utility +# Copyright (c) 2019 Crypta Labs Ltd. +# +# SPDX-License-Identifier: Apache-2.0 + +import os, argparse, struct, sys, crcmod +from cryptography import x509 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import ec, utils + +backend = default_backend() + +def int_to_bytes(val, num_bytes): + # big-endian representation (ROM Addendum documentation is incorrect) + return [(val >> (num_bytes-pos-1)*8) & 0xff for pos in range(num_bytes)] + +def digest(hashalg, blob): + d = hashes.Hash(hashalg, backend=backend) + d.update(blob) + return d.finalize() + +def sign(blob, sign_key): + # Sign or add checksum according to ROM Addendum + if sign_key: + # Raw EC-DSA signature using secp256R1 EC-key + rfc = sign_key.sign(blob, ec.ECDSA(hashes.SHA256())) + r, s = utils.decode_dss_signature(rfc) + return bytes(bytearray(int_to_bytes(r, 32) + int_to_bytes(s, 32))) + else: + # Raw SHA256 digest + return digest(hashes.SHA256(), blob) + b'\x00'*32 + +def private_key_to_raw_public_key(p): + # Return RAW Uncompressed format without the leading 0x04 format byte of X962 + pubkey = p.public_key() + if not hasattr(serialization.Encoding, 'X962'): + # Old API, deprecated in cryptography 2.5 + return pubkey.public_numbers().encode_point()[1:] + return pubkey.public_bytes(serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint)[1:] + +def encrypt(blob, peer_public_key): + from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF + from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + + # Encrypt firmware image according to ROM Addendum: + # Ephemeral EC-DH over secp256R1, with ANSI X9.63 KDF to generate AES-256-CBC key and IV + # The uncompressed public ephemeral key is appended to the end + ephemeral_key = ec.generate_private_key(ec.SECP256R1(), backend) + shared_secret = ephemeral_key.exchange(ec.ECDH(), peer_public_key) + derived_key = X963KDF(algorithm=hashes.SHA256(), length=48, sharedinfo=None, backend=backend).derive(shared_secret) + enc = Cipher(algorithms.AES(derived_key[0:32]), modes.CBC(derived_key[32:48]), backend=backend).encryptor() + return enc.update(blob) + enc.finalize() + private_key_to_raw_public_key(ephemeral_key) + +def bootable_image(opts): + # image size needs to be modulo 64 due to block size requirement + # try to workaround bootloader bug in part C2 by increasing padding as needed + img = opts.image.read() + if opts.encrypt: + img_pad = 256 + elif opts.sign: + img_pad = 128 + else: + img_pad = 64 + x = len(img) % img_pad + if x != 0: + img = img + b'\0' * (img_pad - x) + + # header + entry = struct.unpack_from("> 8 + h = crcmod.predefined.Crc('crc-8-itu') + h.update(struct.pack('BBB', offset & 0xff, (offset >> 8) & 0xff, (offset >> 16) & 0xff)) + return offset | (ord(h.digest()) << 24) + +def flashable_image(args, img0, img1): + img = bytearray(b'\xff' * args.flash_size) + struct.pack_into(" diff --git a/soc/arm/microchip_mec/cec1702/soc.h b/soc/arm/microchip_mec/cec1702/soc.h new file mode 100644 index 0000000000000..6ae90a8346db8 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/soc.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2017 Crypta Labs Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CEC_SOC_H +#define CEC_SOC_H + +#define SYSCLK_DEFAULT_IOSC_HZ MHZ(48) + +#ifndef _ASMLANGUAGE + +#include "MCHP_CEC1702_C0.h" + +#endif /* !_ASMLANGUAGE */ + +#endif diff --git a/soc/arm/microchip_mec/cec1702/soc_config.c b/soc/arm/microchip_mec/cec1702/soc_config.c new file mode 100644 index 0000000000000..f50b347c87118 --- /dev/null +++ b/soc/arm/microchip_mec/cec1702/soc_config.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Crypta Labs Ltd + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "soc.h" + +static int soc_init(struct device *dev) +{ + __IO uint32_t *girc_enable; + + /* Enable IRQs as ROM loader does PRIMASK=1 */ + __enable_irq(); + + /* Enable clocks for Interrupts and CPU */ + PCR_INST->CLK_REQ_1_b.INT_CLK_REQ = 1; + PCR_INST->CLK_REQ_1_b.PROCESSOR_CLK_REQ = 1; + + /* Route all interrupts from EC to NVIC */ + EC_REG_BANK_INST->INTERRUPT_CONTROL = 0x1; + for (girc_enable = &INTS_INST->GIRQ08_EN_SET; + girc_enable <= &INTS_INST->GIRQ15_EN_SET; + girc_enable += 5) { + *girc_enable = 0xFFFFFFFF; + } + + return 0; +} + +SYS_INIT(soc_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/west.yml b/west.yml index d281c58fd7b0e..820ee040ece32 100644 --- a/west.yml +++ b/west.yml @@ -53,7 +53,7 @@ manifest: revision: 3b54187649cc9b37161d49918f1ad28ff7c7f830 path: modules/hal/openisa - name: hal_microchip - revision: 03c8819ac3105cc2aee295a8d330de0e665b705f + revision: 558f4bc471cb2ea976468b4c190d52aadf0ff82b path: modules/hal/microchip - name: hal_silabs revision: 9a3fe1af3a14bf88c86b9cda3bf2a0921d5a97a1