[arm64][imx8mmevk] Add support for booting on the imx8mmevk board

TEST: boots into shell on imx8mmevk
Change-Id: Ia893839786a753c6b98dc927a7925fe6c91b693f
diff --git a/kernel/target/arm64/board/imx8mmevk/boot-shim-config.h b/kernel/target/arm64/board/imx8mmevk/boot-shim-config.h
new file mode 100644
index 0000000..e856ef0
--- /dev/null
+++ b/kernel/target/arm64/board/imx8mmevk/boot-shim-config.h
@@ -0,0 +1,82 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#define HAS_DEVICE_TREE 1
+
+static const zbi_cpu_config_t cpu_config = {
+    .cluster_count = 1,
+    .clusters = {
+        {
+            .cpu_count = 4,
+        },
+    },
+};
+
+static const zbi_mem_range_t mem_config[] = {
+    {
+        .type = ZBI_MEM_RANGE_RAM,
+        .paddr = 0x40000000,
+        .length = 0x80000000, // 2GB
+    },
+    {
+        .type = ZBI_MEM_RANGE_PERIPHERAL,
+        .paddr = 0,
+        .length = 0x40000000,
+    },
+};
+
+static const dcfg_simple_t uart_driver = {
+    .mmio_phys = 0x30890000,
+    .irq = 58,
+};
+
+static const dcfg_arm_gicv3_driver_t gicv3_driver = {
+    .mmio_phys = 0x38800000,
+    .gicd_offset = 0x00000,
+    .gicr_offset = 0x80000,
+    .gicr_stride = 0x20000,
+    .ipi_base = 9,
+    // Used for Errata e11171
+    .mx8_gpr_phys = 0x30340000,
+};
+
+static const dcfg_arm_psci_driver_t psci_driver = {
+    .use_hvc = false,
+};
+
+static const dcfg_arm_generic_timer_driver_t timer_driver = {
+    .irq_phys = 30,
+    .irq_virt = 27,
+    .freq_override = 8333333,
+};
+
+static const zbi_platform_id_t platform_id = {
+    .vid = PDEV_VID_NXP,
+    .pid = PDEV_PID_IMX8MMEVK,
+    .board_name = "imx8mmevk",
+};
+
+static void append_board_boot_item(zbi_header_t* bootdata) {
+    // add CPU configuration
+    append_boot_item(bootdata, ZBI_TYPE_CPU_CONFIG, 0, &cpu_config,
+                    sizeof(zbi_cpu_config_t) +
+                    sizeof(zbi_cpu_cluster_t) * cpu_config.cluster_count);
+
+    // add memory configuration
+    append_boot_item(bootdata, ZBI_TYPE_MEM_CONFIG, 0, &mem_config,
+                    sizeof(zbi_mem_range_t) * countof(mem_config));
+
+    // add kernel drivers
+    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_NXP_IMX_UART, &uart_driver,
+                    sizeof(uart_driver));
+    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V3, &gicv3_driver,
+                    sizeof(gicv3_driver));
+    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_PSCI, &psci_driver,
+                    sizeof(psci_driver));
+    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GENERIC_TIMER, &timer_driver,
+                    sizeof(timer_driver));
+
+    // add platform ID
+    append_boot_item(bootdata, ZBI_TYPE_PLATFORM_ID, 0, &platform_id, sizeof(platform_id));
+}
diff --git a/kernel/target/arm64/board/imx8mmevk/rules.mk b/kernel/target/arm64/board/imx8mmevk/rules.mk
new file mode 100644
index 0000000..ad58bc8
--- /dev/null
+++ b/kernel/target/arm64/board/imx8mmevk/rules.mk
@@ -0,0 +1,20 @@
+# Copyright 2018 The Fuchsia Authors
+# Use of this source code is governed by a MIT-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/MIT
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+PLATFORM_BOARD_NAME := imx8mmevk
+PLATFORM_USE_SHIM := true
+PLATFORM_USE_MKBOOTIMG := true
+PLATFORM_DTB := mkbootimg
+PLATFORM_DTB_OFFSET := 0x03000000
+PLATFORM_USE_AVB := true
+
+PLATFORM_KERNEL_OFFSET := 0x00080000
+PLATFORM_MEMBASE := 0x40000000
+PLATFORM_CMDLINE := netsvc.netboot=true
+PLATFORM_BOOT_PARTITION_SIZE := 33554432
+
+include make/board.mk
diff --git a/kernel/target/arm64/boot-shim/boot-shim.S b/kernel/target/arm64/boot-shim/boot-shim.S
index 14839af..fdeb533 100644
--- a/kernel/target/arm64/boot-shim/boot-shim.S
+++ b/kernel/target/arm64/boot-shim/boot-shim.S
@@ -19,6 +19,25 @@
 
 .section .text.boot0,"ax"
 FUNCTION(_start)
+    // magic instruction that gives us UEFI "MZ" signature
+    add x13, x18, #0x16
+    b header_end
+
+    .quad   0             // image offset from start of ram (unused)
+    .quad   0             // image size (unused)
+    .quad   0
+    .quad   0
+    .quad   0
+    .quad   0
+
+    // arm64 magic number
+    .byte   'A'
+    .byte   'R'
+    .byte   'M'
+    .byte   0x64
+    .align 3
+
+header_end:
     // x0 typically points to device tree at entry
 
    // what EL are we running at?
diff --git a/kernel/target/arm64/boot-shim/imx8mmevk-uart.c b/kernel/target/arm64/boot-shim/imx8mmevk-uart.c
new file mode 100644
index 0000000..a0bfe56
--- /dev/null
+++ b/kernel/target/arm64/boot-shim/imx8mmevk-uart.c
@@ -0,0 +1,18 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include "debug.h"
+
+#define MX8_UTXD                    (0x40)
+#define MX8_UTS                     (0xB4)
+#define UTS_TXFULL                  (1 << 4)
+
+#define UARTREG(reg) (*(volatile uint32_t*)(0x30890000 + (reg)))
+
+void uart_pputc(char c) {
+    while (UARTREG(MX8_UTS) & UTS_TXFULL)
+        ;
+    UARTREG(MX8_UTXD) = c;
+}
diff --git a/scripts/flash-imx8mmevk b/scripts/flash-imx8mmevk
new file mode 100755
index 0000000..9f935d7
--- /dev/null
+++ b/scripts/flash-imx8mmevk
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+# Copyright 2018 The Fuchsia Authors
+#
+# Use of this source code is governed by a MIT-style
+# license that can be found in the LICENSE file or at
+# https://opensource.org/licenses/MIT
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+exec $DIR/flash-avb -b imx8mmevk
diff --git a/system/ulib/ddk/include/ddk/platform-defs.h b/system/ulib/ddk/include/ddk/platform-defs.h
index d0046a4..bb26344 100644
--- a/system/ulib/ddk/include/ddk/platform-defs.h
+++ b/system/ulib/ddk/include/ddk/platform-defs.h
@@ -112,6 +112,7 @@
 // NXP
 #define PDEV_VID_NXP                9
 #define PDEV_PID_IMX8MEVK           1
+#define PDEV_PID_IMX8MMEVK          2
 
 #define PDEV_DID_IMX_GPIO           1
 #define PDEV_DID_IMX_DISPLAY        2