meta-nuvoton-npcm8xx: import at 62f317ab
Copy the contents of meta-nuvoton from Nuvoton's fork of OpenBMC[0] into
meta-gbmc-staging as a folder named meta-nuvoton-npcm8xx. This will
allow us to import their code without affecting other users of the
meta-nuvoton layer.
Imported from branch `npcm-master` at revision 62f317ab.
To build with support for npcm8xx (Arbel) in your machine bblayers.conf,
add meta-gbmc-staging/meta-nuvoton-npcm8xx and remove meta-nuvoton.
[0] https://github.com/Nuvoton-Israel/openbmc
Tested:
With internal CL 106631, built and booted on NPCM845 EVB
Google-Bug-Id: 223452756
Signed-off-by: Benjamin Fair <benjaminfair@google.com>
Change-Id: If9622e4ea79f3aaf8f4f09e7c53b78b8d80ef09a
diff --git a/meta-nuvoton-npcm8xx/COPYING.MIT b/meta-nuvoton-npcm8xx/COPYING.MIT
new file mode 100644
index 0000000..89de354
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/COPYING.MIT
@@ -0,0 +1,17 @@
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/meta-nuvoton-npcm8xx/COPYING.apache-2.0 b/meta-nuvoton-npcm8xx/COPYING.apache-2.0
new file mode 100644
index 0000000..67db858
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/COPYING.apache-2.0
@@ -0,0 +1,175 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
diff --git a/meta-nuvoton-npcm8xx/LICENSE b/meta-nuvoton-npcm8xx/LICENSE
new file mode 100644
index 0000000..22a3b52
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/LICENSE
@@ -0,0 +1,12 @@
+Different components of meta-nuvoton are under different licenses (a mix
+of MIT and Apache-2.0). Please see:
+
+COPYING.Apache-2.0
+COPYING.MIT (MIT)
+
+All metadata is MIT licensed unless otherwise stated. Source code
+included in tree for individual recipes is under the LICENSE stated in
+the associated recipe (.bb file) unless otherwise stated.
+
+License information for any other files is either explicitly stated
+or defaults to Apache-2.0.
diff --git a/meta-nuvoton-npcm8xx/OWNERS b/meta-nuvoton-npcm8xx/OWNERS
new file mode 100644
index 0000000..929031c
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/OWNERS
@@ -0,0 +1,2 @@
+owners:
+- benjaminfair@google.com
diff --git a/meta-nuvoton-npcm8xx/README.md b/meta-nuvoton-npcm8xx/README.md
new file mode 100644
index 0000000..a93a03c
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/README.md
@@ -0,0 +1,8 @@
+Nuvoton NPCM7XX
+================
+
+This is the Nuvoton NPCM7XX Board Support Package (BSP) layer.
+The NPCM7XX is an ARM based SoC with external DDR RAM and
+supports a large set of peripherals made by Nuvoton.
+More information about the NPCM7XX can be found
+[here](http://www.nuvoton.com/hq/products/cloud-computing/ibmc/?__locale=en).
diff --git a/meta-nuvoton-npcm8xx/classes/fitimage_nuvoton_npcm8xx.bbclass b/meta-nuvoton-npcm8xx/classes/fitimage_nuvoton_npcm8xx.bbclass
new file mode 100644
index 0000000..1b7c77e
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/classes/fitimage_nuvoton_npcm8xx.bbclass
@@ -0,0 +1,206 @@
+#
+# Assemble fitImage
+#
+# $1 ... .its filename
+# $2 ... fitImage name
+# $3 ... include ramdisk
+fitimage_assemble_npcm8xx() {
+ kernelcount=1
+ dtbcount=""
+ DTBS=""
+ ramdiskcount=${3}
+ setupcount=""
+ bootscr_id=""
+ rm -f ${1} arch/${ARCH}/boot/${2}
+ final_offset=600
+
+ fitimage_emit_fit_header ${1}
+
+ #
+ # Step 1: Prepare a image section.
+ #
+ fitimage_emit_section_maint ${1} imagestart
+
+ #
+ # Step 2: Prepare a DTB image section
+ #
+
+ if [ -n "${KERNEL_DEVICETREE}" ]; then
+ dtbcount=1
+ for DTB in ${KERNEL_DEVICETREE}; do
+ if echo ${DTB} | grep -q '/dts/'; then
+ bbwarn "${DTB} contains the full path to the the dts file, but only the dtb name should be used."
+ DTB=`basename ${DTB} | sed 's,\.dts$,.dtb,g'`
+ fi
+
+ # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
+ if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
+ continue
+ fi
+
+ DTB_PATH="arch/${ARCH}/boot/dts/${DTB}"
+ if [ ! -e "${DTB_PATH}" ]; then
+ DTB_PATH="arch/${ARCH}/boot/${DTB}"
+ fi
+
+ DTB=$(echo "${DTB}" | tr '/' '_')
+ DTBS="${DTBS} ${DTB}"
+ fitimage_emit_section_dtb ${1} ${DTB} ${DTB_PATH}
+ done
+ fi
+
+ if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
+ dtbcount=1
+ for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" \( -name '*.dtb' -o -name '*.dtbo' \) -printf '%P\n' | sort); do
+ DTB=$(echo "${DTB}" | tr '/' '_')
+ DTBS="${DTBS} ${DTB}"
+ fitimage_emit_section_dtb ${1} ${DTB} "${EXTERNAL_KERNEL_DEVICETREE}/${DTB}"
+ done
+ fi
+
+ #
+ # Step 3: Prepare a kernel image section.
+ #
+
+ uboot_prep_kimage
+
+ if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
+ initramfs_bundle_path="arch/"${UBOOT_ARCH}"/boot/"${KERNEL_IMAGETYPE_REPLACEMENT}".initramfs"
+ if [ -e "${initramfs_bundle_path}" ]; then
+
+ #
+ # Include the kernel/rootfs bundle.
+ #
+
+ fitimage_emit_section_kernel ${1} "${kernelcount}" "${initramfs_bundle_path}" "${linux_comp}"
+ else
+ bbwarn "${initramfs_bundle_path} not found."
+ fi
+ else
+ fitimage_emit_section_kernel ${1} "${kernelcount}" linux.bin "${linux_comp}"
+ fi
+
+ #
+ # Step 4: Prepare a u-boot script section
+ #
+
+ if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
+ if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
+ cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
+ bootscr_id="${UBOOT_ENV_BINARY}"
+ fitimage_emit_section_boot_script ${1} "${bootscr_id}" ${UBOOT_ENV_BINARY}
+ else
+ bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
+ fi
+ fi
+ #
+ # Step 5: Prepare a setup section. (For x86)
+ #
+ if [ -e arch/${ARCH}/boot/setup.bin ]; then
+ setupcount=1
+ fitimage_emit_section_setup ${1} "${setupcount}" arch/${ARCH}/boot/setup.bin
+ fi
+
+ #
+ # Step 6: Prepare a ramdisk section.
+ #
+ if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
+ # Find and use the first initramfs image archive type we find
+ for img in cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.gz ext2.gz cpio; do
+ initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.${img}"
+ echo "Using $initramfs_path"
+ if [ -e "${initramfs_path}" ]; then
+ fitimage_emit_section_ramdisk ${1} "${ramdiskcount}" "${initramfs_path}"
+ break
+ fi
+ done
+ fi
+
+ fitimage_emit_section_maint ${1} sectend
+
+ # Force the first Kernel and DTB in the default config
+ kernelcount=1
+ if [ -n "${dtbcount}" ]; then
+ dtbcount=1
+ fi
+
+ #
+ # Step 7: Prepare a configurations section
+ #
+ fitimage_emit_section_maint ${1} confstart
+
+ # kernel-fitimage.bbclass currently only supports a single kernel (no less or
+ # more) to be added to the FIT image along with 0 or more device trees and
+ # 0 or 1 ramdisk.
+ # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
+ # When the initramfs bundle is used ramdisk is disabled.
+ # If a device tree is to be part of the FIT image, then select
+ # the default configuration to be used is based on the dtbcount. If there is
+ # no dtb present than select the default configuation to be based on
+ # the kernelcount.
+ if [ -n "${DTBS}" ]; then
+ i=1
+ for DTB in ${DTBS}; do
+ dtb_ext=${DTB##*.}
+ if [ "${dtb_ext}" = "dtbo" ]; then
+ fitimage_emit_section_config ${1} "" "${DTB}" "" "${bootscr_id}" "" "`expr ${i} = ${dtbcount}`"
+ else
+ fitimage_emit_section_config ${1} "${kernelcount}" "${DTB}" "${ramdiskcount}" "${bootscr_id}" "${setupcount}" "`expr ${i} = ${dtbcount}`"
+ fi
+ i=`expr ${i} + 1`
+ done
+ else
+ defaultconfigcount=1
+ fitimage_emit_section_config ${1} "${kernelcount}" "" "${ramdiskcount}" "${bootscr_id}" "${setupcount}" "${defaultconfigcount}"
+ fi
+
+ fitimage_emit_section_maint ${1} sectend
+
+ fitimage_emit_section_maint ${1} fitend
+
+ #
+ # Step 8: Assemble the image
+ #
+ ${UBOOT_MKIMAGE} -E -p ${final_offset} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -f ${1} \
+ arch/${ARCH}/boot/${2}
+
+ #
+ # Step 9: Sign the image and add public key to U-Boot dtb
+ #
+ if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
+ add_key_to_u_boot=""
+ if [ -n "${UBOOT_DTB_BINARY}" ]; then
+ # The u-boot.dtb is a symlink to UBOOT_DTB_IMAGE, so we need copy
+ # both of them, and don't dereference the symlink.
+ cp -P ${STAGING_DATADIR}/u-boot*.dtb ${B}
+ add_key_to_u_boot="-K ${B}/${UBOOT_DTB_BINARY}"
+ fi
+ ${UBOOT_MKIMAGE_SIGN} -E -p ${final_offset} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -F -k "${UBOOT_SIGN_KEYDIR}" \
+ $add_key_to_u_boot \
+ -r arch/${ARCH}/boot/${2} \
+ ${UBOOT_MKIMAGE_SIGN_ARGS}
+ fi
+}
+
+do_assemble_fitimage:append() {
+ if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
+ cd ${B}
+ fitimage_assemble_npcm8xx fit-image.its fitImage
+ fi
+}
+
+do_assemble_fitimage_initramfs:append() {
+ if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
+ test -n "${INITRAMFS_IMAGE}" ; then
+ cd ${B}
+ if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
+ fitimage_assemble_npcm8xx fit-image-${INITRAMFS_IMAGE}.its fitImage ""
+ else
+ fitimage_assemble_npcm8xx fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
+ fi
+ fi
+}
diff --git a/meta-nuvoton-npcm8xx/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass b/meta-nuvoton-npcm8xx/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass
new file mode 100644
index 0000000..89b8e52
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass
@@ -0,0 +1,245 @@
+UBOOT_BINARY := "u-boot.${UBOOT_SUFFIX}"
+BOOTBLOCK = "BootBlockAndHeader.bin"
+ATF_BINARY := "bl31AndHeader.bin"
+OPTEE_BINARY := "teeAndHeader.bin"
+KMT_BINARY = "KmtAndHeader.bin"
+TIPFWL0_BINARY = "TipFwAndHeader_L0.bin"
+TIPFWL1_BINARY = "TipFwAndHeader_L1.bin"
+KMT_TIPFWL0_BINARY = "Kmt_TipFwL0.bin"
+KMT_TIPFWL0L1_BINARY = "Kmt_TipFwL0L1.bin"
+KMT_TIPFW_BB_BINARY = "Kmt_TipFw_BootBlock.bin"
+KMT_TIPFW_BB_BL31_BINARY = "Kmt_TipFw_BootBlock_BL31.bin"
+KMT_TIPFW_BB_BL31_TEE_BINARY = "Kmt_TipFw_BootBlock_BL31_Tee.bin"
+KMT_TIPFW_BB_BL31_TEE_UBOOT_BINARY = "Kmt_TipFw_BootBlock_BL31_Tee_uboot.bin"
+KMT_TIPFW_BB_UBOOT_BINARY = "u-boot.bin.merged"
+FULL_SUFFIX = "full"
+MERGED_SUFFIX = "merged"
+UBOOT_SUFFIX:append = ".${MERGED_SUFFIX}"
+
+IGPS_DIR = "${STAGING_DIR_NATIVE}/${datadir}/npcm8xx-igps"
+inherit logging
+
+# Prepare the Bootblock and U-Boot images using npcm8xx-bingo
+do_prepare_bootloaders() {
+ local olddir="$(pwd)"
+ cd ${DEPLOY_DIR_IMAGE}
+
+ if [ "${SECURED_TIPFW}" = "False" ]; then
+ bingo ${IGPS_DIR}/KmtAndHeader_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${KMT_BINARY}
+
+ bingo ${IGPS_DIR}/TipFwAndHeader_L0_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${TIPFWL0_BINARY}
+
+ bingo ${IGPS_DIR}/TipFwAndHeader_L1_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${TIPFWL1_BINARY}
+ fi
+
+ if [ "${SECURED_OS}" = "True" ]; then
+ bingo ${IGPS_DIR}/BL31_AndHeader_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${ATF_BINARY}
+
+ bingo ${IGPS_DIR}/OpTeeAndHeader_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${OPTEE_BINARY}
+ fi
+
+ bingo ${IGPS_DIR}/BootBlockAndHeader_${IGPS_MACHINE}.xml \
+ -o ${DEPLOY_DIR_IMAGE}/${BOOTBLOCK}
+
+ bingo ${IGPS_DIR}/UbootHeader_${IGPS_MACHINE}.xml \
+ -o ${UBOOT_BINARY}.${FULL_SUFFIX}
+
+ cd "$olddir"
+}
+
+python do_merge_bootloaders() {
+
+ def crc32_tab_val( c ):
+ crc = c % (1<<32)
+ for x in range(0, 8):
+ if ( crc & 0x00000001 ):
+ crc = ( (crc >> 1) % (1<<32) ) ^ 0xEDB88320
+ else:
+ crc = crc >> 1
+ crc = crc % (1<<32)
+ return crc
+
+ def update_crc( crc, c ):
+ long_c = (0x000000ff & c) % (1<<32)
+ tmp = (crc ^ long_c) % (1<<32)
+ crc = ((crc >> 8) ^ crc32_tab_val( tmp & 0xff )) % (1<<32)
+ crc = crc % (1<<32)
+ return crc;
+
+ def CalcCRC32(bin_filename, begin_offset, embed_ecc, output_filename):
+ try:
+ input_size = os.path.getsize(bin_filename)
+ if (begin_offset >= input_size):
+ print("\nfile too small\n")
+
+ crc = 0
+ with open(bin_filename, "rb") as binary_file:
+ tmp = binary_file.read(begin_offset)
+ while True:
+ va = binary_file.read(1)
+ if va:
+ crc = update_crc(crc, ord(va))
+ else:
+ break
+
+ crc = crc & 0xffffffff
+ with open(bin_filename, "rb") as binary_file:
+ input = binary_file.read()
+ crc_arr = bytearray(4)
+ for ind in range(4):
+ crc_arr[ind] = (crc >> (ind*8) ) & 255
+ output = input[:embed_ecc] + crc_arr + input[(embed_ecc + 4):]
+ output_file = open(output_filename, "w+b")
+ output_file.write(output)
+ output_file.close()
+
+ except:
+ raise
+ finally:
+ return
+
+ def CRC32_binary(binfile, begin_offset, embed_ecc, outputFile):
+ CalcCRC32(binfile, begin_offset, embed_ecc, outputFile)
+
+ def Merge_bin_files_and_pad(inF1, inF2, outF, align, padding_at_end):
+ padding_size = 0
+ padding_size_end = 0
+ F1_size = os.path.getsize(inF1)
+ F2_size = os.path.getsize(inF2)
+
+ if ((F1_size % align) != 0):
+ padding_size = align - (F1_size % align)
+
+ if ((F2_size % align) != 0):
+ padding_size_end = align - (F2_size % align)
+
+ with open(outF, "wb") as file3:
+ with open(inF1, "rb") as file1:
+ data = file1.read()
+ file3.write(data)
+
+ file3.write(b'\xFF' * padding_size)
+
+ with open(inF2, "rb") as file2:
+ data = file2.read()
+ file3.write(data)
+
+ file3.write(b'\xFF' * padding_size_end)
+
+ file1.close()
+ file2.close()
+ file3.close()
+
+ if d.getVar('SECURED_TIPFW', True) == "True":
+ d.setVar('KMT_TIPFW_BINARY', "Kmt_TipFwL0_TipFwL1.bin")
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BOOTBLOCK',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
+ 0x1000, 0x20)
+ else:
+ CRC32_binary(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_BINARY',True)),
+ 112, 12,
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_BINARY',True)))
+
+ CRC32_binary(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL0_BINARY',True)),
+ 112, 12,
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL0_BINARY',True)))
+
+ CRC32_binary(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL1_BINARY',True)),
+ 112, 12,
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL1_BINARY',True)))
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL0_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFWL0_BINARY',True)),
+ 0x1000, 0x20)
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFWL0_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('TIPFWL1_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFWL0L1_BINARY',True)),
+ 0x1000, 0x20)
+
+ os.remove(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFWL0_BINARY',True)))
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFWL0L1_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BOOTBLOCK',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
+ 0x1000, 0x20)
+
+ if d.getVar('SECURED_OS', True) == "True":
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('ATF_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_BINARY',True)),
+ 0x1000, 0x20)
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('OPTEE_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_TEE_BINARY',True)),
+ 0x1000, 0x20)
+
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_TEE_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s.full' % d.getVar('UBOOT_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_UBOOT_BINARY',True)),
+ 0x1000, 0x20)
+ else:
+ Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s.full' % d.getVar('UBOOT_BINARY',True)),
+ os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_UBOOT_BINARY',True)),
+ 0x1000, 0x20)
+}
+
+prepare_secureos = "${@ "arm-trusted-firmware:do_deploy optee-os:do_deploy" if bb.utils.to_boolean(d.getVar('SECURED_OS')) else "" }"
+
+do_prepare_bootloaders[depends] += " \
+ npcm8xx-kmt:do_deploy \
+ npcm8xx-kmt-tipfwl0l1:do_deploy \
+ npcm8xx-tipfw-l0:do_deploy \
+ npcm8xx-tipfw-l1:do_deploy \
+ npcm8xx-bootblock:do_deploy \
+ ${prepare_secureos} \
+ npcm7xx-bingo-native:do_populate_sysroot \
+ npcm8xx-igps-native:do_populate_sysroot \
+ "
+
+# link images for we only need to flash partial image with idea name
+do_generate_ext4_tar:append() {
+ cd ${DEPLOY_DIR_IMAGE}
+ ln -sf ${UBOOT_BINARY} image-u-boot
+ ln -sf ${DEPLOY_DIR_IMAGE}/${FLASH_KERNEL_IMAGE} image-kernel
+ ln -sf ${S}/ext4/${IMAGE_LINK_NAME}.${FLASH_EXT4_BASETYPE}.zst image-rofs
+ ln -sf ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.rwfs.${FLASH_EXT4_OVERLAY_BASETYPE} image-rwfs
+ ln -sf ${IMAGE_NAME}.rootfs.wic.gz image-emmc.gz
+}
+
+addtask do_prepare_bootloaders before do_generate_static after do_generate_rwfs_static
+addtask do_merge_bootloaders before do_generate_static after do_prepare_bootloaders
+addtask do_merge_bootloaders before do_generate_ext4_tar after do_prepare_bootloaders
+
+# Include the full bootblock and u-boot in the final static image
+python do_generate_static:append() {
+ _append_image(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
+ 'u-boot.%s' % d.getVar('UBOOT_SUFFIX',True)),
+ int(d.getVar('FLASH_UBOOT_OFFSET', True)),
+ int(d.getVar('FLASH_KERNEL_OFFSET', True)))
+}
+
+do_make_ubi:append() {
+ # Concatenate the uboot and ubi partitions
+ dd bs=1k conv=notrunc seek=${FLASH_UBOOT_OFFSET} \
+ if=${DEPLOY_DIR_IMAGE}/u-boot.${UBOOT_SUFFIX} \
+ of=${IMGDEPLOYDIR}/${IMAGE_NAME}.ubi.mtd
+}
+
+do_make_ubi[depends] += "${PN}:do_prepare_bootloaders"
+do_generate_ubi_tar[depends] += "${PN}:do_prepare_bootloaders"
+do_generate_ubi_tar[depends] += "${PN}:do_merge_bootloaders"
+do_generate_static_tar[depends] += "${PN}:do_prepare_bootloaders"
+do_generate_static_tar[depends] += "${PN}:do_merge_bootloaders"
+do_generate_ext4_tar[depends] += "${PN}:do_prepare_bootloaders"
+do_generate_ext4_tar[depends] += "${PN}:do_merge_bootloaders"
diff --git a/meta-nuvoton-npcm8xx/conf/layer.conf b/meta-nuvoton-npcm8xx/conf/layer.conf
new file mode 100644
index 0000000..d8f5062
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/layer.conf
@@ -0,0 +1,10 @@
+# We have a conf and classes directory, add to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
+ ${LAYERDIR}/recipes-*/*/*.bbappend"
+
+BBFILE_COLLECTIONS += "nuvoton-layer"
+BBFILE_PATTERN_nuvoton-layer = ""
+LAYERVERSION_nuvoton-layer = "1"
+LAYERSERIES_COMPAT_nuvoton-layer = "honister kirkstone"
diff --git a/meta-nuvoton-npcm8xx/conf/machine/evb-npcm750.conf b/meta-nuvoton-npcm8xx/conf/machine/evb-npcm750.conf
new file mode 100644
index 0000000..f0216ea
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/machine/evb-npcm750.conf
@@ -0,0 +1,13 @@
+KMACHINE = "nuvoton"
+KERNEL_DEVICETREE = "${KMACHINE}-npcm750-evb.dtb"
+
+UBOOT_MACHINE = "PolegSVB_config"
+IGPS_MACHINE = "EB"
+
+FLASH_SIZE = "32768"
+
+require conf/machine/include/npcm7xx.inc
+require conf/machine/include/obmc-bsp-common.inc
+require conf/machine/include/obmc-evb-common.inc
+
+IMAGE_FSTYPES = "cpio.${INITRAMFS_CTYPE}.u-boot mtd-static"
diff --git a/meta-nuvoton-npcm8xx/conf/machine/include/npcm7xx.inc b/meta-nuvoton-npcm8xx/conf/machine/include/npcm7xx.inc
new file mode 100644
index 0000000..0a15467
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/machine/include/npcm7xx.inc
@@ -0,0 +1,33 @@
+#@TYPE: Machine
+#@NAME: Nuvoton NPCM7XX
+#@DESCRIPTION: Common machine configuration for Nuvoton NPCM7XX Chip
+
+require conf/machine/include/nuvoton.inc
+
+KERNEL_IMAGETYPE ?= "uImage"
+KERNEL_EXTRA_ARGS ?= "UIMAGE_LOADADDR=0x00008000"
+
+UBOOT_MACHINE ?= "PolegSVB_config"
+UBOOT_ENTRYPOINT ?= "0x00008000"
+UBOOT_LOADADDRESS ?= "0x00008000"
+
+FLASH_UBOOT_OFFSET = "0"
+FLASH_UBOOT_ENV_OFFSET = "1024"
+FLASH_KERNEL_OFFSET = "2048"
+FLASH_UBI_OFFSET = "${FLASH_KERNEL_OFFSET}"
+FLASH_ROFS_OFFSET = "7680"
+FLASH_RWFS_OFFSET = "30720"
+
+# UBI volume sizes in KB unless otherwise noted.
+FLASH_UBI_RWFS_SIZE = "6144"
+FLASH_UBI_RWFS_TXT_SIZE = "6MiB"
+
+DEFAULTTUNE ?= "arm7a-novfp"
+
+SERIAL_CONSOLES = "115200;ttyS3"
+
+SOC_FAMILY = "npcm7xx"
+include conf/machine/include/soc-family.inc
+MACHINEOVERRIDES .= ":npcm7xx"
+
+require conf/machine/include/tune-arm7a-novfp.inc
diff --git a/meta-nuvoton-npcm8xx/conf/machine/include/npcm8xx.inc b/meta-nuvoton-npcm8xx/conf/machine/include/npcm8xx.inc
new file mode 100644
index 0000000..98974d4
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/machine/include/npcm8xx.inc
@@ -0,0 +1,36 @@
+#@TYPE: Machine
+#@NAME: Nuvoton NPCM8XX
+#@DESCRIPTION: Common machine configuration for Nuvoton NPCM8XX Chip
+
+require conf/machine/include/nuvoton.inc
+
+KERNEL_IMAGETYPE ?= "Image"
+KERNEL_EXTRA_ARGS ?= "UIMAGE_LOADADDR=0x00008000"
+
+UBOOT_MACHINE ?= "ArbelEVB_defconfig"
+UBOOT_ENTRYPOINT ?= "0"
+UBOOT_LOADADDRESS ?= "0"
+
+FLASH_SIZE = "32768"
+FLASH_UBOOT_OFFSET = "0"
+FLASH_KERNEL_OFFSET = "2048"
+FLASH_ROFS_OFFSET = "8192"
+FLASH_RWFS_OFFSET = "31744"
+
+# UBI volume sizes in KB unless otherwise noted.
+FLASH_UBI_RWFS_SIZE = "6144"
+FLASH_UBI_RWFS_TXT_SIZE = "6MiB"
+
+SERIAL_CONSOLES = "115200;ttyS0"
+
+SECURED_TIPFW = "True"
+SECURED_OS = "True"
+
+SOC_FAMILY = "npcm8xx"
+include conf/machine/include/soc-family.inc
+MACHINEOVERRIDES .= ":npcm8xx"
+
+require conf/machine/include/arm/armv8a/tune-cortexa35.inc
+
+IMAGE_CLASSES:append:npcm8xx = " image_types_phosphor_nuvoton_npcm8xx"
+KERNEL_CLASSES:append:npcm8xx = " fitimage_nuvoton_npcm8xx"
diff --git a/meta-nuvoton-npcm8xx/conf/machine/include/nuvoton.inc b/meta-nuvoton-npcm8xx/conf/machine/include/nuvoton.inc
new file mode 100644
index 0000000..068fe35
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/machine/include/nuvoton.inc
@@ -0,0 +1,6 @@
+PREFERRED_PROVIDER_virtual/kernel ?= "linux-nuvoton"
+PREFERRED_PROVIDER_virtual/bootloader ?= "u-boot-nuvoton"
+PREFERRED_PROVIDER_u-boot ?= "u-boot-nuvoton"
+PREFERRED_PROVIDER_u-boot-fw-utils ?= "u-boot-fw-utils-nuvoton"
+
+MACHINEOVERRIDES .= ":nuvoton"
diff --git a/meta-nuvoton-npcm8xx/conf/machine/include/tune-arm7a-novfp.inc b/meta-nuvoton-npcm8xx/conf/machine/include/tune-arm7a-novfp.inc
new file mode 100644
index 0000000..b8c6d8c
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/conf/machine/include/tune-arm7a-novfp.inc
@@ -0,0 +1,11 @@
+DEFAULTTUNE ?= "arm7a-novfp"
+
+require conf/machine/include/arm/arch-armv7a.inc
+
+TUNEVALID[arm7a-novfp] = "Enable arm7a-novfp specific processor optimizations"
+
+AVAILTUNES += "arm7a-novfp"
+ARMPKGARCH:tune-arm7a-novfp = "armv7a"
+TUNE_FEATURES:tune-armv7a = "arm armv7a"
+TUNE_FEATURES:tune-arm7a-novfp = "${TUNE_FEATURES:tune-armv7a} arm7a-novfp"
+PACKAGE_EXTRA_ARCHS:tune-arm7a-novfp = "${PACKAGE_EXTRA_ARCHS:tune-armv7a}"
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.bb b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.bb
new file mode 100644
index 0000000..70fa39e
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.bb
@@ -0,0 +1,11 @@
+ATF_VERSION = "1.3"
+SRCREV = "469101d48a1b0cb6c93ea5fe3bd3b32b46bd047e"
+BRANCH = "nuvoton"
+LIC_FILES_CHKSUM = "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031"
+
+include arm-trusted-firmware.inc
+
+FILESEXTRAPATHS:prepend:npcm8xx = "${THISDIR}/${PN}:"
+SRC_URI:append:npcm8xx= " file://0001-plat-nuvoton-npcm845x-fix-build-warning.patch \
+ file://0002-plat-nuvoton-npcm845x-fix-reboot-hang.patch \
+ "
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.inc b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.inc
new file mode 100644
index 0000000..bf56357
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware.inc
@@ -0,0 +1,59 @@
+DESCRIPTION = "ARM Trusted Firmware"
+
+LICENSE = "BSD"
+LIC_FILES_CHKSUM ?= "file://license.rst;md5=1dd070c98a281d18d9eefd938729b031"
+
+PV="1.3.0+git${SRCPV}"
+
+inherit deploy
+
+S = "${WORKDIR}/git"
+
+BRANCH ?= ""
+REPO ?= "git://github.com/Nuvoton-Israel/arm-trusted-firmware.git;protocol=https"
+BRANCHARG = "${@['nobranch=1', 'branch=${BRANCH}'][d.getVar('BRANCH', True) != '']}"
+SRC_URI = "${REPO};${BRANCHARG}"
+
+inherit image-artifact-names
+
+MACHINE_SOC ?= "npcm8xx"
+PLATFORM = "npcm845x"
+
+# requires CROSS_COMPILE set by hand as there is no configure script
+# Some versions of u-boot use .bin and others use .img. By default use .bin
+# but enable individual recipes to change this value.
+ATF_SUFFIX ?= "bin"
+ATF_IMAGE ?= "bl31-${MACHINE_SOC}-${PV}-${PR}.${ATF_SUFFIX}"
+ATF_SYMLINK ?= "bl31-${MACHINE_SOC}.${ATF_SUFFIX}"
+
+export CROSS_COMPILE="${TARGET_PREFIX}"
+
+# Let the Makefile handle setting up the CFLAGS and LDFLAGS as it is a standalone application
+CFLAGS[unexport] = "1"
+LDFLAGS[unexport] = "1"
+AS[unexport] = "1"
+LD[unexport] = "1"
+
+do_configure() {
+ oe_runmake clean -C ${S} PLAT=${PLATFORM}
+}
+
+do_compile() {
+ oe_runmake -C ${S} PLAT=${PLATFORM} SPD=opteed all
+}
+
+# do_install() nothing
+do_install[noexec] = "1"
+
+do_deploy() {
+ # Create deploy folder
+ install -d ${DEPLOYDIR}
+
+ # Copy IPL to deploy folder
+ install -m 0644 ${S}/build/${PLATFORM}/release/bl31.bin ${DEPLOYDIR}/bl31.bin
+ cd ${DEPLOYDIR}
+ ln -sf bl31.bin ${ATF_SYMLINK}
+ ln -sf bl31.bin ${ATF_IMAGE}
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0001-plat-nuvoton-npcm845x-fix-build-warning.patch b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0001-plat-nuvoton-npcm845x-fix-build-warning.patch
new file mode 100644
index 0000000..f68cd6d
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0001-plat-nuvoton-npcm845x-fix-build-warning.patch
@@ -0,0 +1,39 @@
+From 50067a3307193c39ed559e49b0cff3f56cbc9cee Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Thu, 14 Apr 2022 15:45:43 +0800
+Subject: [PATCH] plat: nuvoton: npcm845x: fix build warning
+
+Signed-off-by: Joseph Liu <kwliu@nuvoton.com>
+---
+ plat/nuvoton/npcm845x/npcm845x_psci.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/plat/nuvoton/npcm845x/npcm845x_psci.c b/plat/nuvoton/npcm845x/npcm845x_psci.c
+index f4ac3ac22..f6db31132 100644
+--- a/plat/nuvoton/npcm845x/npcm845x_psci.c
++++ b/plat/nuvoton/npcm845x/npcm845x_psci.c
+@@ -219,8 +219,8 @@ void npcm845x_pwr_domain_on_finish(const psci_power_state_t *target_state)
+ INFO("%s: target_state->pwr_domain_state[%lu]=%x\n",
+ __func__, i, target_state->pwr_domain_state[i]);
+
+- assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+- PLAT_LOCAL_STATE_OFF);
++ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
++ PLAT_LOCAL_STATE_OFF);
+
+
+ gicv2_pcpu_distif_init();
+@@ -244,8 +244,8 @@ void npcm845x_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
+ __func__, i, target_state->pwr_domain_state[i]);
+
+
+- assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+- PLAT_LOCAL_STATE_OFF);
++ assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
++ PLAT_LOCAL_STATE_OFF);
+
+
+ gicv2_pcpu_distif_init();
+--
+2.25.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0002-plat-nuvoton-npcm845x-fix-reboot-hang.patch b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0002-plat-nuvoton-npcm845x-fix-reboot-hang.patch
new file mode 100644
index 0000000..bba8d90
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/arm-trusted-firmware/arm-trusted-firmware/0002-plat-nuvoton-npcm845x-fix-reboot-hang.patch
@@ -0,0 +1,27 @@
+From a62ae26bdc74acca92acfcd129e8c84dabc15941 Mon Sep 17 00:00:00 2001
+From: Stanley Chu <yschu@nuvoton.com>
+Date: Mon, 18 Apr 2022 14:27:51 +0800
+Subject: [PATCH] plat: nuvoton: npcm845x: fix reboot hang
+
+Signed-off-by: Stanley Chu <yschu@nuvoton.com>
+---
+ plat/nuvoton/npcm845x/npcm845x_psci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/plat/nuvoton/npcm845x/npcm845x_psci.c b/plat/nuvoton/npcm845x/npcm845x_psci.c
+index f6db31132..a8b919d85 100644
+--- a/plat/nuvoton/npcm845x/npcm845x_psci.c
++++ b/plat/nuvoton/npcm845x/npcm845x_psci.c
+@@ -266,7 +266,8 @@ void __dead2 npcm845x_system_reset(void)
+ * In future - support all reset types. For now, SW1 reset
+ * Enable software reset 1 to reboot the BMC
+ */
+- mmio_write_32(SWRSTR, SWRSTR_SWRST1);
++ //mmio_write_32(SWRSTR, SWRSTR_SWRST1);
++ mmio_write_32(0xf000801c, 0x83);
+ while (1);
+ }
+
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bingo-native_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bingo-native_git.bb
new file mode 100644
index 0000000..5ec9420
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bingo-native_git.bb
@@ -0,0 +1,20 @@
+SUMMARY = "XML-based binary image generator"
+DESCRIPTION = "XML-based binary image generator"
+HOMEPAGE = "https://github.com/Nuvoton-Israel/bingo"
+PR = "r1"
+PV = "0.1+git${SRCPV}"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI += "git://github.com/Nuvoton-Israel/bingo;branch=master;protocol=https"
+SRCREV = "4f102ff7851da9fd11965857edd1b3046c187b7a"
+
+S = "${WORKDIR}/git"
+
+do_install () {
+
+ install -d "${D}${bindir}"
+ install deliverables/linux/Release/bingo ${D}${bindir}
+}
+
+inherit native
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bootblock_10.10.17.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bootblock_10.10.17.bb
new file mode 100644
index 0000000..21ae615
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-bootblock_10.10.17.bb
@@ -0,0 +1,26 @@
+SUMMARY = "Primary bootloader for NPCM7XX (Poleg) devices"
+DESCRIPTION = "Primary bootloader for NPCM7XX (Poleg) devices"
+HOMEPAGE = "https://github.com/Nuvoton-Israel/npcm7xx-bootblock"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+FILENAME = "Poleg_bootblock_${PV}.bin"
+
+S = "${WORKDIR}"
+
+SRCREV = "7bfef99f7a0354395519c4975f96d66cdda1fb67"
+SRC_URI = " \
+ https://raw.githubusercontent.com/Nuvoton-Israel/bootblock/${SRCREV}/LICENSE;name=lic \
+ https://github.com/Nuvoton-Israel/bootblock/releases/download/BootBlock_${PV}/Poleg_bootblock_basic.bin;downloadfilename=${FILENAME};name=bin \
+"
+
+SRC_URI[lic.md5sum] = "b234ee4d69f5fce4486a80fdaf4a4263"
+SRC_URI[bin.sha256sum] = "3e92e3f6c4624139d000f91541792a54f52205637bb88abd14310c854694cb39"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${WORKDIR}/${FILENAME} ${DEPLOYDIR}/Poleg_bootblock.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps-native_02.01.12.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps-native_02.01.12.bb
new file mode 100644
index 0000000..5ef884c
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps-native_02.01.12.bb
@@ -0,0 +1,25 @@
+SUMMARY = "Image Generation and Programming Scripts for NPCM7XX (Poleg) devices"
+DESCRIPTION = "Image Generation and Programming Scripts for NPCM7XX (Poleg) devices"
+HOMEPAGE = "https://github.com/Nuvoton-Israel/igps"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI = " \
+ git://github.com/Nuvoton-Israel/igps;branch=master;protocol=https \
+ file://0001-Adjust-paths-for-use-with-Bitbake.patch \
+"
+# tag IGPS_02.01.12
+SRCREV = "2fb1a3b0d61164ed1157e27889a4ec2292cbc760"
+
+S = "${WORKDIR}/git"
+
+DEST = "${D}${datadir}/${BPN}"
+
+do_install() {
+ install -d ${DEST}
+ install ImageGeneration/references/BootBlockAndHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ImageGeneration/references/UbootHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ImageGeneration/inputs/mergedBootBlockAndUboot.xml ${DEST}
+}
+
+inherit native
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps/0001-Adjust-paths-for-use-with-Bitbake.patch b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps/0001-Adjust-paths-for-use-with-Bitbake.patch
new file mode 100644
index 0000000..118f199
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm7xx-igps/0001-Adjust-paths-for-use-with-Bitbake.patch
@@ -0,0 +1,145 @@
+From 215a2d9660a929beae8bc420239467fc9e135b4f Mon Sep 17 00:00:00 2001
+From: Benjamin Fair <benjaminfair@google.com>
+Date: Wed, 23 Oct 2019 14:23:08 -0700
+Subject: [PATCH] Adjust paths for use with Bitbake
+
+Signed-off-by: Benjamin Fair <benjaminfair@google.com>
+---
+ ImageGeneration/inputs/mergedBootBlockAndUboot.xml | 10 +++++-----
+ ImageGeneration/references/BootBlockAndHeader_EB.xml | 6 +++---
+ .../references/BootBlockAndHeader_RunBMC.xml | 6 +++---
+ ImageGeneration/references/UbootHeader_EB.xml | 6 +++---
+ ImageGeneration/references/UbootHeader_RunBMC.xml | 6 +++---
+ 5 files changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/ImageGeneration/inputs/mergedBootBlockAndUboot.xml b/ImageGeneration/inputs/mergedBootBlockAndUboot.xml
+index d832f96..f4c7756 100644
+--- a/ImageGeneration/inputs/mergedBootBlockAndUboot.xml
++++ b/ImageGeneration/inputs/mergedBootBlockAndUboot.xml
+@@ -18,18 +18,18 @@
+ <name>BootBlock</name> <!-- name of field -->
+ <config>
+ <offset>0</offset> <!-- offset in the header -->
+- <size format='FileSize'>output_binaries/BootBlockAndHeader.bin</size> <!-- size in the header -->
++ <size format='FileSize'>Poleg_bootblock.bin.full</size> <!-- size in the header -->
+ </config>
+- <content format='FileContent'>output_binaries/BootBlockAndHeader.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>Poleg_bootblock.bin.full</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>u-boot</name> <!-- name of field -->
+ <config>
+- <offset format='FileSize' align='0x1000'>output_binaries/BootBlockAndHeader.bin</offset> <!-- offset in the header -->
+- <size format='FileSize'>output_binaries/UbootAndHeader.bin</size> <!-- size in the header -->
++ <offset format='FileSize' align='0x1000'>Poleg_bootblock.bin.full</offset> <!-- offset in the header -->
++ <size format='FileSize'>u-boot.bin.full</size> <!-- size in the header -->
+ </config>
+- <content format='FileContent'>output_binaries/UbootAndHeader.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>u-boot.bin.full</content> <!-- content the user should fill -->
+ </BinField>
+
+ </Bin_Ecc_Map>
+diff --git a/ImageGeneration/references/BootBlockAndHeader_EB.xml b/ImageGeneration/references/BootBlockAndHeader_EB.xml
+index 775534f..157535d 100644
+--- a/ImageGeneration/references/BootBlockAndHeader_EB.xml
++++ b/ImageGeneration/references/BootBlockAndHeader_EB.xml
+@@ -42,7 +42,7 @@
+ <offset>0x144</offset>
+ <size>0x4</size>
+ </config>
+- <content format='FileSize'>inputs/Poleg_bootblock.bin</content> <!-- content the user should fill -->
++ <content format='FileSize'>Poleg_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+@@ -50,9 +50,9 @@
+ <name>Code</name> <!-- name of field -->
+ <config>
+ <offset>0x200</offset>
+- <size format='FileSize'>inputs/Poleg_bootblock.bin</size> <!-- size in the header calculated by tool-->
++ <size format='FileSize'>Poleg_bootblock.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+- <content format='FileContent'>inputs/Poleg_bootblock.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>Poleg_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+diff --git a/ImageGeneration/references/BootBlockAndHeader_RunBMC.xml b/ImageGeneration/references/BootBlockAndHeader_RunBMC.xml
+index cc719e9..4d1e972 100644
+--- a/ImageGeneration/references/BootBlockAndHeader_RunBMC.xml
++++ b/ImageGeneration/references/BootBlockAndHeader_RunBMC.xml
+@@ -42,7 +42,7 @@
+ <offset>0x144</offset>
+ <size>0x4</size>
+ </config>
+- <content format='FileSize'>inputs/Poleg_bootblock.bin</content> <!-- content the user should fill -->
++ <content format='FileSize'>Poleg_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+@@ -50,9 +50,9 @@
+ <name>Code</name>
+ <config>
+ <offset>0x200</offset>
+- <size format='FileSize'>inputs/Poleg_bootblock.bin</size> <!-- size in the header calculated by tool-->
++ <size format='FileSize'>Poleg_bootblock.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+- <content format='FileContent'>inputs/Poleg_bootblock.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>Poleg_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+diff --git a/ImageGeneration/references/UbootHeader_EB.xml b/ImageGeneration/references/UbootHeader_EB.xml
+index 1e72e22..475ec45 100644
+--- a/ImageGeneration/references/UbootHeader_EB.xml
++++ b/ImageGeneration/references/UbootHeader_EB.xml
+@@ -42,7 +42,7 @@
+ <offset>0x144</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+- <content format='FileSize'>inputs/u-boot.bin</content> <!-- content the user should fill -->
++ <content format='FileSize'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+@@ -50,9 +50,9 @@
+ <name>Code</name> <!-- name of field -->
+ <config>
+ <offset>0x200</offset> <!-- offset in the header -->
+- <size format='FileSize'>inputs/u-boot.bin</size> <!-- size in the header calculated by tool-->
++ <size format='FileSize'>u-boot.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+- <content format='FileContent'>inputs/u-boot.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+diff --git a/ImageGeneration/references/UbootHeader_RunBMC.xml b/ImageGeneration/references/UbootHeader_RunBMC.xml
+index 7eb3076..481ed2f 100644
+--- a/ImageGeneration/references/UbootHeader_RunBMC.xml
++++ b/ImageGeneration/references/UbootHeader_RunBMC.xml
+@@ -42,7 +42,7 @@
+ <offset>0x144</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+- <content format='FileSize'>inputs/u-boot.bin</content> <!-- content the user should fill -->
++ <content format='FileSize'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+@@ -50,9 +50,9 @@
+ <name>Code</name> <!-- name of field -->
+ <config>
+ <offset>0x200</offset> <!-- offset in the header -->
+- <size format='FileSize'>inputs/u-boot.bin</size> <!-- size in the header calculated by tool-->
++ <size format='FileSize'>u-boot.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+- <content format='FileContent'>inputs/u-boot.bin</content> <!-- content the user should fill -->
++ <content format='FileContent'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+--
+2.24.0.rc0.303.g954a862665-goog
+
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock/arbel_a35_bootblock.0.1.9.bin b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock/arbel_a35_bootblock.0.1.9.bin
new file mode 100644
index 0000000..b23fb33
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock/arbel_a35_bootblock.0.1.9.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock_0.1.9.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock_0.1.9.bb
new file mode 100644
index 0000000..43bb244
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-bootblock_0.1.9.bb
@@ -0,0 +1,15 @@
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://arbel_a35_bootblock.${PV}.bin\
+"
+
+S = "${WORKDIR}"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${S}/arbel_a35_bootblock.${PV}.bin ${DEPLOYDIR}/arbel_a35_bootblock.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps-native_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps-native_git.bb
new file mode 100644
index 0000000..e3b2a1a
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps-native_git.bb
@@ -0,0 +1,36 @@
+SUMMARY = "Image Generation and Programming Scripts for NPCM8XX (Arbel) devices"
+DESCRIPTION = "Image Generation and Programming Scripts for NPCM8XX (Arbel) devices"
+HOMEPAGE = "https://github.com/Nuvoton-Israel/igps"
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI = " \
+ git://github.com/Nuvoton-Israel/igps;branch=master;protocol=https \
+ file://KmtAndHeader_${IGPS_MACHINE}.xml \
+ file://TipFwAndHeader_L0_${IGPS_MACHINE}.xml \
+ file://TipFwAndHeader_L1_${IGPS_MACHINE}.xml \
+ file://BootBlockAndHeader_${IGPS_MACHINE}.xml \
+ file://BL31_AndHeader_${IGPS_MACHINE}.xml \
+ file://OpTeeAndHeader_${IGPS_MACHINE}.xml \
+ file://UbootHeader_${IGPS_MACHINE}.xml \
+"
+
+# tag IGPS_02.01.12
+SRCREV = "2fb1a3b0d61164ed1157e27889a4ec2292cbc760"
+
+S = "${WORKDIR}/git"
+
+DEST = "${D}${datadir}/${BPN}"
+
+do_install() {
+ install -d ${DEST}
+ install ${WORKDIR}/KmtAndHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/TipFwAndHeader_L0_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/TipFwAndHeader_L1_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/BootBlockAndHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/BL31_AndHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/OpTeeAndHeader_${IGPS_MACHINE}.xml ${DEST}
+ install ${WORKDIR}/UbootHeader_${IGPS_MACHINE}.xml ${DEST}
+}
+
+inherit native
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BL31_AndHeader_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BL31_AndHeader_EB.xml
new file mode 100644
index 0000000..69220bf
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BL31_AndHeader_EB.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <!-- BootBlock tag (0x50 0x08 0x55 0xAA 0x54 0x4F 0x4F 0x42) or
+ uboot tag (0x55 0x42 0x4F 0x4F 0x54 0x42 0x4C 0x4B) -->
+ <name>StartTag</name>
+ <config>
+ <offset>0</offset>
+ <size>0x8</size>
+ </config>
+ <content format='bytes'>0x0A 0x42 0x4C 0x33 0x31 0x4E 0x50 0x43</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Version (Major.Minor) -->
+ <name>version</name>
+ <config>
+ <offset>0x100</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>DestAddr</name>
+ <config>
+ <offset>0x1F8</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0xFFFB0E00</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>CodeSize</name>
+ <config>
+ <offset>0x1FC</offset>
+ <size>0x4</size>
+ </config>
+ <content format='FileSize'>bl31.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- The BootBlock or u-boot binary file -->
+ <name>Code</name>
+ <config>
+ <offset>0x200</offset>
+ <size format='FileSize'>bl31.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>bl31.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BootBlockAndHeader_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BootBlockAndHeader_EB.xml
new file mode 100644
index 0000000..730e694
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/BootBlockAndHeader_EB.xml
@@ -0,0 +1,515 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <!-- BootBlock tag (0x0A 0x50 0x08 0x55 0xAA 0x54 0x4F 0x4F) -->
+ <name>StartTag</name>
+ <config>
+ <offset>0</offset>
+ <size>0x8</size>
+ </config>
+ <content format='bytes'>0x0A 0x50 0x08 0x55 0xAA 0x54 0x4F 0x4F</content>
+ </BinField>
+
+ <BinField>
+ <!-- Version (Major.Minor) -->
+ <name>version</name>
+ <config>
+ <offset>0x100</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Board manufaturer ( Dell = 0, Nuvoton = 100, Google = 1, MS = 2) -->
+ <name>vendor</name>
+ <config>
+ <offset>0x104</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>100</content> <!--Board_manufacturer: Nuvoton-->
+ </BinField>
+ <BinField>
+ <!-- Board type ( DRB = 0, SVB = 1, EB = 2 RunBMC = 10) -->
+ <!-- WARNING: Currently this value is only printed to serial. -->
+ <name>board_type</name>
+ <config>
+ <offset>0x108</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0x02</content> <!--Board_type: SVB-->
+ </BinField>
+
+ <BinField>
+ <!-- supported values: 300, 500, 666, 700, 720, 750, 775, 787.5 800, 850, 900, 950, 975, 1000, 1037, 1050, 1062.5 1066, 1100, 1150, 1200.
+ Recommended: 1066 or 800. Note: not all values are tested -->
+ <name>MC_FREQ_IN_MHZ</name>
+ <config>
+ <offset>0x10C</offset>
+ <size>0x2</size>
+ </config>
+ <content format='32bit'>1066</content>
+ </BinField>
+ <BinField>
+ <!-- supporeted values: 333,500,600,666,700,720,750,800,825,850,900,950,1000.
+ Recommended: 1000. Note: not all values are tested -->
+ <name>CPU_FREQ_IN_MHZ</name>
+ <config>
+ <offset>0x10E</offset>
+ <size>0x2</size>
+ </config>
+ <content format='32bit'>1000</content>
+ </BinField>
+
+ <BinField>
+ <!-- DDR: SOC (BMC) drive -->
+ <name>ddr_soc_drive</name>
+ <config>
+ <offset>0x110</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>48</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- DDR: SOC (BMC) termination in ohm-->
+ <name>ddr_soc_odt</name>
+ <config>
+ <offset>0x114</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>48</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- DDR: DRAM drive -->
+ <name>ddr_dram_drive</name>
+ <config>
+ <offset>0x118</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>48</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- DDR: DRAM termination in ohm -->
+ <name>ddr_dram_odt</name>
+ <config>
+ <offset>0x11C</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>48</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- -->
+ <name>NoECC_Region_0_Start</name>
+ <config>
+ <offset>0x120</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+
+ <BinField>
+ <!-- -->
+ <name>NoECC_Region_0_End</name>
+ <config>
+ <offset>0x124</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+
+ <BinField>
+ <!-- -->
+ <name>NoECC_Region_1_Start</name>
+ <config>
+ <offset>0x128</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+
+ <BinField>
+ <!-- -->
+ <name>NoECC_Region_1_End</name>
+ <config>
+ <offset>0x12C</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- -->
+ <name>dram_max_size</name>
+ <config>
+ <offset>0x130</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0x40000000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- MC_CONFIG.
+ Bit 0: MC_CAPABILITY_ECC_EN (0x01)
+ Bit 2: Select DRAM type.
+ 0: 1600 DRAM type clk.
+ 1: 2133 DRAM type clk.
+ Bit 3: enable 3 seconds delay.
+ Bit 4: enable debug sweeps (in addition to sweep_debug)
+ -->
+ <name>MC_CONFIG</name>
+ <config>
+ <offset>0x134</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0x04</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- HOST_IF.
+ 0xFF: LPC backward compatible
+ 0x00: LPC.
+ 0x01: eSPI
+ 0x02: GPIOs TRIS. -->
+ <name>HOST_IF</name>
+ <config>
+ <offset>0x135</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0x00</content>
+ </BinField>
+
+
+
+
+ <BinField>
+ <!-- bit 7 : pos\neg
+ bits [6:0] DQS0 in value -->
+ <name>MC_DQS_IN_LANE0</name>
+ <config>
+ <offset>0x136</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- bit 7 : pos\neg
+ bits [6:0] DQS1 in value -->
+ <name>MC_DQS_IN_LANE1</name>
+ <config>
+ <offset>0x137</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- bit 7 : pos\neg
+ bits [6:0] DQS0 out value -->
+ <name>MC_DQS_OUT_LANE0</name>
+ <config>
+ <offset>0x138</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- bit 7 : pos\neg
+ bits [6:0] DQS1 out value -->
+ <name>MC_DQS_OUT_LANE1</name>
+ <config>
+ <offset>0x139</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- bit 6 : incr\dec
+ bits [5:0] TRIM value -->
+ <name>MC_DLLS_TRIM_ADRCTL</name>
+ <config>
+ <offset>0x13A</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- bit 6 : incr\dec
+ bits [5:0] TRIM value -->
+ <name>MC_DLLS_TRIM_ADRCTRL_MA</name>
+ <config>
+ <offset>0x13B</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- bit 6 : incr\dec
+ bits [5:0] TRIM value -->
+ <name>MC_DLLS_TRIM_CLK</name>
+ <config>
+ <offset>0x13C</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+
+ <BinField>
+ <!-- mc_dlls_trim_clk_sqew: not implemented -->
+ <name>mc_dlls_trim_clk_sqew</name>
+ <config>
+ <offset>0x13D</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- PHASE1 lane 0 -->
+ <name>PHASE1_LANE0</name>
+ <config>
+ <offset>0x13E</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- PHASE1 lane 1 -->
+ <name>PHASE1_LANE1</name>
+ <config>
+ <offset>0x13F</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- PHASE2 lane 0 -->
+ <name>PHASE2_LANE0</name>
+ <config>
+ <offset>0x140</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- PHASE2 lane 1 -->
+ <name>PHASE2_LANE1</name>
+ <config>
+ <offset>0x141</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+
+ <BinField>
+ <!-- DLLS_TRIM_1 lane 0 -->
+ <name>DLLS_TRIM_1_LANE0</name>
+ <config>
+ <offset>0x142</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- DLLS_TRIM_1 lane 1 -->
+ <name>DLLS_TRIM_1_LANE1</name>
+ <config>
+ <offset>0x143</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+
+ <BinField>
+ <!-- DLLS_TRIM_2 lane 0 -->
+ <name>DLLS_TRIM_2_LANE0</name>
+ <config>
+ <offset>0x144</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- DLLS_TRIM_2 lane 1 -->
+ <name>DLLS_TRIM_2_LANE1</name>
+ <config>
+ <offset>0x145</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- DLLS_TRIM_3 lane 0 -->
+ <name>DLLS_TRIM_3_LANE0</name>
+ <config>
+ <offset>0x146</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- DLLS_TRIM_3 lane 1 -->
+ <name>DLLS_TRIM_3_LANE1</name>
+ <config>
+ <offset>0x147</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+
+ <BinField>
+ <!-- DLLS_TRIM_2 OFFSET lane 0
+ msb: 1 incr, 0 decr
+ [1:7] offset value added\decremented to trim2 after SCL.
+ -->
+ <name>DLLS_TRIM_2_OFFSET_LANE0</name>
+ <config>
+ <offset>0x148</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- DLLS_TRIM_2 OFFSET lane 1
+ msb: 1 incr, 0 decr
+ [1:7] offset value added\decremented to trim2 after SCL.
+ -->
+ <name>DLLS_TRIM_2_OFFSET_LANE1</name>
+ <config>
+ <offset>0x149</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- VREF_SOC lane 0 -->
+ <name>VREF_SOC_LANE0</name>
+ <config>
+ <offset>0x14A</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+ <BinField>
+ <!-- VREF_SOC lane 1 -->
+ <name>VREF_SOC_LANE1</name>
+ <config>
+ <offset>0x14B</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+
+ <BinField>
+ <!-- VREF_DRAM -->
+ <name>VREF_DRAM</name>
+ <config>
+ <offset>0x14C</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0xFF</content>
+ </BinField>
+
+
+ <BinField>
+ <!-- SWEEP_DEBUG: enable running charectarization sweeps. bitwise:
+ ADRCTL_MA_SWEEP BIT(0)
+ ADRCTL_SWEEP BIT(1)
+ TRIM_2_LANE0_SWEEP BIT(2)
+ TRIM_2_LANE1_SWEEP BIT(3)
+ VREF_SWEEP BIT(4)
+ DRAM_SWEEP BIT(5)
+ OP_DQS_SWEEP BIT(6)
+ IP_DQS_SWEEP BIT(7)
+ -->
+ <name>SWEEP_DEBUG</name>
+ <config>
+ <offset>0x14D</offset>
+ <size>0x1</size>
+ </config>
+ <content format='32bit'>0x00</content>
+ </BinField>
+
+
+
+
+ <BinField>
+ <!-- Code destination address, 32-bit aligned: for BootBlock should be 0xFFFD0000 so code will run in 0xFFFB0200 as linked for -->
+ <name>DestAddr</name>
+ <config>
+ <offset>0x1F8</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0xFFFD0000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>CodeSize</name>
+ <config>
+ <offset>0x1FC</offset>
+ <size>0x4</size>
+ </config>
+ <content format='FileSize'>arbel_a35_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- The BootBlock or u-boot binary file -->
+ <name>Code</name>
+ <config>
+ <offset>0x200</offset>
+ <size format='FileSize'>arbel_a35_bootblock.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>arbel_a35_bootblock.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/KmtAndHeader_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/KmtAndHeader_EB.xml
new file mode 100644
index 0000000..aed8e61
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/KmtAndHeader_EB.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <name>Anchor</name> <!-- name of field -->
+ <config>
+ <offset>0</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0x5E 0x4D 0x3B 0x2A</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- CRC Enabled (0x1E 0xAB 0xF2 0x57) or
+ CRC Disabled (0xE1 0x54 0xF2 0x57) -->
+ <name>ExendedAnchor_CrcEn</name> <!-- name of field -->
+ <config>
+ <offset>4</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0xE1 0x54 0xF2 0x57</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>FWCrc</name> <!-- name of field -->
+ <config>
+ <offset>12</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0x00 0x00 0x00 0x00</content> <!-- will be calculated by IGPS -->
+ </BinField>
+
+ <BinField>
+ <name>SPI0_FlashClock</name> <!-- name of field -->
+ <config>
+ <offset>112</offset>
+ <size>1</size>
+ </config>
+ <content format='bytes'>0x0F</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>SPI1_FlashClock</name> <!-- name of field -->
+ <config>
+ <offset>113</offset>
+ <size>1</size>
+ </config>
+ <content format='bytes'>0x0F</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>SPI3_FlashClock</name> <!-- name of field -->
+ <config>
+ <offset>114</offset>
+ <size>1</size>
+ </config>
+ <content format='bytes'>0x0F</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>SpiFlashReadMode</name> <!-- name of field -->
+ <config>
+ <offset>118</offset>
+ <size>2</size>
+ </config>
+ <content format='bytes'>0x0B 0x10</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Code destination address, 32-bit aligned -->
+ <name>FwStartAddr</name> <!-- name of field -->
+ <config>
+ <offset>120</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x0005F000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Code size -->
+ <name>FwLength</name> <!-- name of field -->
+ <config>
+ <offset>132</offset>
+ <size>4</size>
+ </config>
+ <content format='FileSize'>kmt_map.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>KeyIndex</name> <!-- name of field -->
+ <config>
+ <offset>140</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x1</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>KeyInvalid</name> <!-- name of field -->
+ <config>
+ <offset>144</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>TipFwEncryptionControl</name> <!-- name of field -->
+ <config>
+ <offset>148</offset>
+ <size>1</size>
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>OtpFwVersion</name> <!-- name of field -->
+ <config>
+ <offset>152</offset>
+ <size>2</size>
+ </config>
+ <content format='bytes'>0x00 0x00</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>fwTableOffset</name> <!-- name of field -->
+ <config>
+ <offset>168</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x80001000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>kmt_map</name> <!-- name of field -->
+ <config>
+ <offset>256</offset>
+ <size format='FileSize'>kmt_map.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>kmt_map.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/OpTeeAndHeader_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/OpTeeAndHeader_EB.xml
new file mode 100644
index 0000000..88b36da
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/OpTeeAndHeader_EB.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <!-- BootBlock tag (0x50 0x08 0x55 0xAA 0x54 0x4F 0x4F 0x42) or
+ uboot tag (0x55 0x42 0x4F 0x4F 0x54 0x42 0x4C 0x4B) -->
+ <name>StartTag</name>
+ <config>
+ <offset>0</offset>
+ <size>0x8</size>
+ </config>
+ <content format='bytes'>0x0A 0x54 0x45 0x45 0x5F 0x4E 0x50 0x43</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Version (Major.Minor) -->
+ <name>version</name>
+ <config>
+ <offset>0x100</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>DestAddr</name>
+ <config>
+ <offset>0x1F8</offset>
+ <size>0x4</size>
+ </config>
+ <content format='32bit'>0x35FFFDE4</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>CodeSize</name>
+ <config>
+ <offset>0x1FC</offset>
+ <size>0x4</size>
+ </config>
+ <content format='FileSize'>tee.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- The BootBlock or u-boot binary file -->
+ <name>Code</name>
+ <config>
+ <offset>0x200</offset>
+ <size format='FileSize'>tee.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>tee.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L0_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L0_EB.xml
new file mode 100644
index 0000000..e0edf3f
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L0_EB.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <name>Anchor</name> <!-- name of field -->
+ <config>
+ <offset>0</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0x5E 0x4D 0x7A 0x9B</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- CRC Enabled (0x1E 0xAB 0xF2 0x57) or
+ CRC Disabled (0xE1 0x54 0xF2 0x57) -->
+ <name>ExendedAnchor_CrcEn</name> <!-- name of field -->
+ <config>
+ <offset>4</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0xE1 0x54 0xF2 0x57</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>FWCrc</name> <!-- name of field -->
+ <config>
+ <offset>12</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0x00 0x00 0x00 0x00</content> <!-- will be calculated by IGPS -->
+ </BinField>
+
+ <BinField>
+ <!-- Code destination address, 32-bit aligned -->
+ <name>FwStartAddr</name> <!-- name of field -->
+ <config>
+ <offset>120</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x00020000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Code size -->
+ <name>FwLength</name> <!-- name of field -->
+ <config>
+ <offset>132</offset>
+ <size>4</size>
+ </config>
+ <content format='FileSize'>arbel_tip_fw_L0.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>KeyIndex</name> <!-- name of field -->
+ <config>
+ <offset>140</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>OtpFwVersion</name> <!-- name of field -->
+ <config>
+ <offset>152</offset>
+ <size>2</size>
+ </config>
+ <content format='bytes'>0x00 0x00</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>AesCbcIV</name> <!-- name of field -->
+ <config>
+ <offset>172</offset>
+ <size>16</size>
+ </config>
+ <content format='bytes'>0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>TipFW</name> <!-- name of field -->
+ <config>
+ <offset>256</offset>
+ <size format='FileSize'>arbel_tip_fw_L0.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>arbel_tip_fw_L0.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L1_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L1_EB.xml
new file mode 100644
index 0000000..0db4431
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/TipFwAndHeader_L1_EB.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <!-- tip_fw_L1 tag (0x0A 0x54 0x49 0x50 0x5F 0x4C 0x31 0x0A) -->
+ <name>StartTag</name> <!-- name of field -->
+ <config>
+ <offset>0</offset> <!-- offset in the header -->
+ <size>0x8</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0A 0x54 0x49 0x50 0x5F 0x4C 0x31 0x0A</content>
+ </BinField>
+
+
+
+
+
+ <BinField>
+ <name>FWCrc</name> <!-- name of field -->
+ <config>
+ <offset>12</offset>
+ <size>4</size>
+ </config>
+ <content format='bytes'>0x00 0x00 0x00 0x00</content> <!-- will be calculated by IGPS -->
+ </BinField>
+
+
+ <BinField>
+ <name>KeyIndex</name> <!-- name of field -->
+ <config>
+ <offset>140</offset>
+ <size>4</size>
+ </config>
+ <content format='32bit'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>OtpFwVersion</name> <!-- name of field -->
+ <config>
+ <offset>152</offset>
+ <size>2</size>
+ </config>
+ <content format='bytes'>0x00 0x00</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Code destination address, 32-bit aligned -->
+ <name>DestAddr_L1</name> <!-- name of field -->
+ <config>
+ <offset>0x1F8</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x40000</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>CodeSize_L1</name> <!-- name of field -->
+ <config>
+ <offset>0x1FC</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='FileSize'>arbel_tip_fw_L1.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <name>TipFW_L1</name> <!-- name of field -->
+ <config>
+ <offset>0x200</offset>
+ <size format='FileSize'>arbel_tip_fw_L1.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>arbel_tip_fw_L1.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/UbootHeader_EB.xml b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/UbootHeader_EB.xml
new file mode 100644
index 0000000..9ab23c7
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-igps/UbootHeader_EB.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- SPDX-License-Identifier: GPL-2.0
+#
+# Nuvoton IGPS: Image Generation And Programming Scripts For Arbel BMC
+#
+# Copyright (C) 2022 Nuvoton Technologies, All Rights Reserved
+#======================================== -->
+
+<Bin_Ecc_Map>
+ <!-- BMC mandatory fields -->
+ <ImageProperties>
+ <BinSize>0</BinSize> <!-- If 0 the binary size will be calculated by the tool -->
+ <PadValue>0xFF</PadValue> <!-- Byte value to pad the empty areas, default is 0 -->
+ </ImageProperties>
+
+ <BinField>
+ <!-- uboot tag (0x0A 0x55 0x42 0x4F 0x4F 0x54 0x42 0x4C) -->
+ <name>StartTag</name> <!-- name of field -->
+ <config>
+ <offset>0</offset> <!-- offset in the header -->
+ <size>0x8</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0A 0x55 0x42 0x4F 0x4F 0x54 0x42 0x4C</content>
+ </BinField>
+
+ <!-- BMC optional fields -->
+ <BinField>
+ <!-- Word contents copied by ROM code to FIU0 FIU_DRD_CFG register -->
+ <name>FIU0_DRD_CFG_Set</name> <!-- name of field -->
+ <config>
+ <offset>0x108</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x030111BC</content> <!-- content the user should fill 0x030032EB -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines the clock divide ratio from AHB to FIU0 clock -->
+ <name>FIU0_Clk_Divider</name> <!-- name of field -->
+ <config>
+ <offset>0x10C</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines if FIU0 CS1 is enabled -->
+ <name>fiu0_cs1_en</name> <!-- name of field -->
+ <config>
+ <offset>0x10D</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines if FIU0 CS2 is enabled -->
+ <name>fiu0_cs2_en</name> <!-- name of field -->
+ <config>
+ <offset>0x10E</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines if FIU0 CS3 is enabled -->
+ <name>fiu0_cs3_en</name> <!-- name of field -->
+ <config>
+ <offset>0x10F</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+ <BinField>
+ <!-- Word contents copied by ROM code to FIU3 FIU_DRD_CFG register -->
+ <name>FIU3_DRD_CFG_Set</name> <!-- name of field -->
+ <config>
+ <offset>0x110</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x030011BB</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+ <BinField>
+ <!-- Word contents copied by ROM code to FIU3 FIU_DRD_CFG register -->
+ <name>FIU3_DWR_CFG_Set</name> <!-- name of field -->
+ <config>
+ <offset>0x114</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines the clock divide ratio from AHB to FIU3 clock -->
+ <name>FIU3_Clk_Divider</name> <!-- name of field -->
+ <config>
+ <offset>0x118</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+
+ <BinField>
+ <!-- Defines if FIU3 CS1 is enabled -->
+ <name>fiu3_cs1_en</name> <!-- name of field -->
+ <config>
+ <offset>0x119</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines if FIU3 CS2 is enabled -->
+ <name>fiu3_cs2_en</name> <!-- name of field -->
+ <config>
+ <offset>0x11A</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Defines if FIU3 CS3 is enabled -->
+ <name>fiu3_cs3_en</name> <!-- name of field -->
+ <config>
+ <offset>0x11B</offset> <!-- offset in the header -->
+ <size>0x1</size> <!-- size in the header -->
+ </config>
+ <content format='bytes'>0x0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Version (Major.Minor) -->
+ <name>Version</name> <!-- name of field -->
+ <config>
+ <offset>0x148</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0</content> <!-- content the user should fill -->
+ </BinField>
+
+ <!-- BMC optional fields -->
+ <BinField>
+ <!-- Word contents copied by BB code to FIU0 FIU_DWR_CFG register -->
+ <name>FIU0_DWR_CFG_Set</name> <!-- name of field -->
+ <config>
+ <offset>0x14C</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x03001102</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- Code destination address, 32-bit aligned -->
+ <name>DestAddr</name> <!-- name of field -->
+ <config>
+ <offset>0x1F8</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='32bit'>0x7E00</content> <!-- including uboot header. uboot image starts at 0x8000 -->
+ </BinField>
+
+ <BinField>
+ <!-- BootBlock or u-boot Code size -->
+ <name>CodeSize</name> <!-- name of field -->
+ <config>
+ <offset>0x1FC</offset> <!-- offset in the header -->
+ <size>0x4</size> <!-- size in the header -->
+ </config>
+ <content format='FileSize'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+ <BinField>
+ <!-- The BootBlock or u-boot binary file -->
+ <name>Code</name> <!-- name of field -->
+ <config>
+ <offset>0x200</offset> <!-- offset in the header -->
+ <size format='FileSize'>u-boot.bin</size> <!-- size in the header calculated by tool-->
+ </config>
+ <content format='FileContent'>u-boot.bin</content> <!-- content the user should fill -->
+ </BinField>
+
+
+
+</Bin_Ecc_Map>
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1/Kmt_TipFwL0_TipFwL1.bin b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1/Kmt_TipFwL0_TipFwL1.bin
new file mode 100644
index 0000000..f64834c
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1/Kmt_TipFwL0_TipFwL1.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1_git.bb
new file mode 100644
index 0000000..0c2099a
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt-tipfwl0l1_git.bb
@@ -0,0 +1,15 @@
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://Kmt_TipFwL0_TipFwL1.bin \
+"
+
+S = "${WORKDIR}"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${S}/Kmt_TipFwL0_TipFwL1.bin ${DEPLOYDIR}/Kmt_TipFwL0_TipFwL1.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt/kmt_map.bin b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt/kmt_map.bin
new file mode 100644
index 0000000..d3351de
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt/kmt_map.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt_git.bb
new file mode 100644
index 0000000..dbe86a5
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-kmt_git.bb
@@ -0,0 +1,15 @@
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://kmt_map.bin \
+"
+
+S = "${WORKDIR}"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${S}/kmt_map.bin ${DEPLOYDIR}/kmt_map.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0/arbel_tip_fw_l0.0.2.2.bin b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0/arbel_tip_fw_l0.0.2.2.bin
new file mode 100644
index 0000000..fe74d3d
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0/arbel_tip_fw_l0.0.2.2.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0_0.2.2.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0_0.2.2.bb
new file mode 100644
index 0000000..fcd3a33
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l0_0.2.2.bb
@@ -0,0 +1,15 @@
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://arbel_tip_fw_l0.${PV}.bin \
+"
+
+S = "${WORKDIR}"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${S}/arbel_tip_fw_l0.${PV}.bin ${DEPLOYDIR}/arbel_tip_fw_L0.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1/arbel_tip_fw_l1.0.0.7.bin b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1/arbel_tip_fw_l1.0.0.7.bin
new file mode 100644
index 0000000..8781b6e
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1/arbel_tip_fw_l1.0.0.7.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1_0.0.7.bb b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1_0.0.7.bb
new file mode 100644
index 0000000..a850701
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/images/npcm8xx-tipfw-l1_0.0.7.bb
@@ -0,0 +1,15 @@
+LICENSE = "CLOSED"
+
+SRC_URI = " \
+ file://arbel_tip_fw_l1.${PV}.bin \
+"
+
+S = "${WORKDIR}"
+
+inherit deploy
+
+do_deploy () {
+ install -D -m 644 ${S}/arbel_tip_fw_l1.${PV}.bin ${DEPLOYDIR}/arbel_tip_fw_L1.bin
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-emmc.cfg b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-emmc.cfg
new file mode 100644
index 0000000..4bc6522
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-emmc.cfg
@@ -0,0 +1,5 @@
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_UNZIP=y
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-env-emmc.txt b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-env-emmc.txt
new file mode 100644
index 0000000..8668db5
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/files/u-boot-env-emmc.txt
@@ -0,0 +1,12 @@
+autoload=no
+autostart=no
+bootargs=earlycon=uart8250,mmio32,0xf0001000 console=ttyS0,115200n8 mem=464M
+bootcmd=setenv origbootargs ${bootargs}; run mmc_bootargs; run bootsidecmd
+setmmcargs=setenv bootargs ${bootargs} rootwait root=PARTLABEL=${rootfs}
+mmc_bootargs=setenv bootargs earlycon=${earlycon} console=${console} mem=${mem}
+boota=setenv bootpart 2; setenv rootfs rofs-a; run bootmmc
+bootb=setenv bootpart 3; setenv rootfs rofs-b; run bootmmc
+bootmmc=run setmmcargs; ext4load mmc 1:${bootpart} ${loadaddr} fitImage && bootm; echo Error loading kernel FIT image
+bootsidecmd=if test ${bootside} = b; then run bootb; run boota; else run boota; run bootb; fi
+bootside=a
+loadaddr=0x1200000
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-common-nuvoton.inc b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-common-nuvoton.inc
new file mode 100644
index 0000000..087c87f
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-common-nuvoton.inc
@@ -0,0 +1,14 @@
+HOMEPAGE = "https://github.com/Nuvoton-Israel/u-boot"
+SECTION = "bootloaders"
+DEPENDS += "flex-native bison-native"
+
+LICENSE = "GPL-2.0-or-later"
+LIC_FILES_CHKSUM = "file://Licenses/README;md5=5a7450c57ffe5ae63fd732446b988025"
+
+UBRANCH = "npcm-v2021.04"
+SRC_URI = "git://github.com/Nuvoton-Israel/u-boot.git;branch=${UBRANCH};protocol=https"
+SRCREV = "c07f3f27389626f366f06bea467ad7b6c3c0060d"
+
+S = "${WORKDIR}/git"
+
+PV .= "+${UBRANCH}+"
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-emmc.inc b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-emmc.inc
new file mode 100644
index 0000000..1001ee8
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-emmc.inc
@@ -0,0 +1,16 @@
+# SPI uboot image should support eMMC
+SRC_URI:append = " file://u-boot-emmc.cfg"
+SRC_URI:append:df-phosphor-mmc = " file://u-boot-env-emmc.txt"
+
+UBOOT_ENV_SIZE:df-phosphor-mmc = "0x40000"
+UBOOT_ENV:df-phosphor-mmc = "u-boot-env"
+UBOOT_ENV_SUFFIX:df-phosphor-mmc = "bin"
+UBOOT_ENV_TXT:df-phosphor-mmc = "u-boot-env-emmc.txt"
+
+do_compile:append() {
+ if [ -n "${UBOOT_ENV}" ]
+ then
+ # Generate redundant environment image
+ ${B}/tools/mkenvimage -s ${UBOOT_ENV_SIZE} -p 0 -o ${WORKDIR}/${UBOOT_ENV_BINARY} ${WORKDIR}/${UBOOT_ENV_TXT}
+ fi
+}
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-fw-utils-nuvoton_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-fw-utils-nuvoton_git.bb
new file mode 100644
index 0000000..4ccfdd1
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-fw-utils-nuvoton_git.bb
@@ -0,0 +1,40 @@
+require u-boot-common-nuvoton.inc
+
+SUMMARY = "U-Boot bootloader fw_printenv/setenv utilities"
+DEPENDS = "mtd-utils bison-native"
+
+PROVIDES += "u-boot-fw-utils"
+
+INSANE_SKIP:${PN} = "already-stripped"
+
+EXTRA_OEMAKE:class-target = 'CROSS_COMPILE="${TARGET_PREFIX}" HOSTCC="${BUILD_CC} ${BUILD_FLAGS} ${BUILD_LDFLAGS}" CC="${CC} ${CFLAGS} ${LDFLAGS}" STRIP=true V=1'
+EXTRA_OEMAKE:class-cross = 'ARCH=${TARGET_ARCH} CC="${CC} ${CFLAGS} ${LDFLAGS}" V=1'
+
+inherit uboot-config
+
+do_compile () {
+ oe_runmake ${UBOOT_MACHINE}
+ oe_runmake envtools
+}
+
+do_install () {
+ install -d ${D}${base_sbindir}
+ install -d ${D}${sysconfdir}
+ install -m 755 ${S}/tools/env/fw_printenv ${D}${base_sbindir}/fw_printenv
+ install -m 755 ${S}/tools/env/fw_printenv ${D}${base_sbindir}/fw_setenv
+ install -m 0644 ${S}/tools/env/fw_env.config ${D}${sysconfdir}/fw_env.config
+}
+
+do_install:class-cross () {
+ install -d ${D}${bindir_cross}
+ install -m 755 ${S}/tools/env/fw_printenv ${D}${bindir_cross}/fw_printenv
+ install -m 755 ${S}/tools/env/fw_printenv ${D}${bindir_cross}/fw_setenv
+}
+
+SYSROOT_PREPROCESS_FUNCS:class-cross = "uboot_fw_utils_cross"
+uboot_fw_utils_cross() {
+ sysroot_stage_dir ${D}${bindir_cross} ${SYSROOT_DESTDIR}${bindir_cross}
+}
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+BBCLASSEXTEND = "cross"
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton.inc b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton.inc
new file mode 100644
index 0000000..40fb5ad
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton.inc
@@ -0,0 +1,337 @@
+SUMMARY = "Universal Boot Loader for embedded devices"
+PROVIDES = "virtual/bootloader"
+
+B = "${WORKDIR}/build"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+DEPENDS += "kern-tools-native"
+
+inherit uboot-config uboot-extlinux-config uboot-sign deploy cml1 python3native
+
+DEPENDS += "swig-native"
+
+EXTRA_OEMAKE = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${TARGET_PREFIX}gcc ${TOOLCHAIN_OPTIONS}" V=1'
+EXTRA_OEMAKE += 'HOSTCC="${BUILD_CC} ${BUILD_CFLAGS} ${BUILD_LDFLAGS}"'
+EXTRA_OEMAKE += 'STAGING_INCDIR=${STAGING_INCDIR_NATIVE} STAGING_LIBDIR=${STAGING_LIBDIR_NATIVE}'
+
+PACKAGECONFIG ??= "openssl"
+# u-boot will compile its own tools during the build, with specific
+# configurations (aka when CONFIG_FIT_SIGNATURE is enabled) openssl is needed as
+# a host build dependency.
+PACKAGECONFIG[openssl] = ",,openssl-native"
+
+# Allow setting an additional version string that will be picked up by the
+# u-boot build system and appended to the u-boot version. If the .scmversion
+# file already exists it will not be overwritten.
+UBOOT_LOCALVERSION ?= ""
+
+# Some versions of u-boot use .bin and others use .img. By default use .bin
+# but enable individual recipes to change this value.
+UBOOT_SUFFIX ??= "bin"
+UBOOT_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.${UBOOT_SUFFIX}"
+UBOOT_SYMLINK ?= "u-boot-${MACHINE}.${UBOOT_SUFFIX}"
+UBOOT_MAKE_TARGET ?= "all"
+
+# Output the ELF generated. Some platforms can use the ELF file and directly
+# load it (JTAG booting, QEMU) additionally the ELF can be used for debugging
+# purposes.
+UBOOT_ELF ?= ""
+UBOOT_ELF_SUFFIX ?= "elf"
+UBOOT_ELF_IMAGE ?= "u-boot-${MACHINE}-${PV}-${PR}.${UBOOT_ELF_SUFFIX}"
+UBOOT_ELF_BINARY ?= "u-boot.${UBOOT_ELF_SUFFIX}"
+UBOOT_ELF_SYMLINK ?= "u-boot-${MACHINE}.${UBOOT_ELF_SUFFIX}"
+
+# Some versions of u-boot build an SPL (Second Program Loader) image that
+# should be packaged along with the u-boot binary as well as placed in the
+# deploy directory. For those versions they can set the following variables
+# to allow packaging the SPL.
+SPL_BINARY ?= ""
+SPL_BINARYNAME ?= "${@os.path.basename(d.getVar("SPL_BINARY"))}"
+SPL_IMAGE ?= "${SPL_BINARYNAME}-${MACHINE}-${PV}-${PR}"
+SPL_SYMLINK ?= "${SPL_BINARYNAME}-${MACHINE}"
+
+# Additional environment variables or a script can be installed alongside
+# u-boot to be used automatically on boot. This file, typically 'uEnv.txt'
+# or 'boot.scr', should be packaged along with u-boot as well as placed in the
+# deploy directory. Machine configurations needing one of these files should
+# include it in the SRC_URI and set the UBOOT_ENV parameter.
+UBOOT_ENV_SUFFIX ?= "txt"
+UBOOT_ENV ?= ""
+UBOOT_ENV_BINARY ?= "${UBOOT_ENV}.${UBOOT_ENV_SUFFIX}"
+UBOOT_ENV_IMAGE ?= "${UBOOT_ENV}-${MACHINE}-${PV}-${PR}.${UBOOT_ENV_SUFFIX}"
+UBOOT_ENV_SYMLINK ?= "${UBOOT_ENV}-${MACHINE}.${UBOOT_ENV_SUFFIX}"
+
+# U-Boot EXTLINUX variables. U-Boot searches for /boot/extlinux/extlinux.conf
+# to find EXTLINUX conf file.
+UBOOT_EXTLINUX_INSTALL_DIR ?= "/boot/extlinux"
+UBOOT_EXTLINUX_CONF_NAME ?= "extlinux.conf"
+UBOOT_EXTLINUX_SYMLINK ?= "${UBOOT_EXTLINUX_CONF_NAME}-${MACHINE}-${PR}"
+
+# Set Device tree from the machine config automatically
+UBOOT_MAKE_TARGET += '${@"" if d.getVar("UBOOT_DEVICETREE") is None \
+ else " DEVICE_TREE=" + d.getVar("UBOOT_DEVICETREE")}'
+
+# returns all the elements from the src uri that are .cfg files
+def find_cfgs(d):
+ sources=src_patches(d, True)
+ sources_list=[]
+ for s in sources:
+ if s.endswith('.cfg'):
+ sources_list.append(s)
+
+ return sources_list
+
+do_configure () {
+ if [ -z "${UBOOT_CONFIG}" ]; then
+ if [ -n "${UBOOT_MACHINE}" ]; then
+ oe_runmake -C ${S} O=${B} ${UBOOT_MACHINE}
+ else
+ oe_runmake -C ${S} O=${B} oldconfig
+ fi
+ merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
+ cml1_do_configure
+ fi
+}
+
+do_compile () {
+ if [ "${@bb.utils.filter('DISTRO_FEATURES', 'ld-is-gold', d)}" ]; then
+ sed -i 's/$(CROSS_COMPILE)ld$/$(CROSS_COMPILE)ld.bfd/g' ${S}/config.mk
+ fi
+
+ unset LDFLAGS
+ unset CFLAGS
+ unset CPPFLAGS
+
+ if [ ! -e ${B}/.scmversion -a ! -e ${S}/.scmversion ]
+ then
+ echo ${UBOOT_LOCALVERSION} > ${B}/.scmversion
+ echo ${UBOOT_LOCALVERSION} > ${S}/.scmversion
+ fi
+
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ unset i j k
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ oe_runmake -C ${S} O=${B}/${config} ${config}
+ oe_runmake -C ${S} O=${B}/${config} ${UBOOT_MAKE_TARGET}
+ for binary in ${UBOOT_BINARIES}; do
+ k=$(expr $k + 1);
+ if [ $k -eq $i ]; then
+ cp ${B}/${config}/${binary} ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX}
+ fi
+ done
+ unset k
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ oe_runmake -C ${S} O=${B} ${UBOOT_MAKE_TARGET}
+ fi
+
+}
+
+do_install () {
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -d ${D}/boot
+ install -m 644 ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX} ${D}/boot/u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${D}/boot/${UBOOT_BINARY}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${D}/boot/${UBOOT_BINARY}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -d ${D}/boot
+ install -m 644 ${B}/${UBOOT_BINARY} ${D}/boot/${UBOOT_IMAGE}
+ ln -sf ${UBOOT_IMAGE} ${D}/boot/${UBOOT_BINARY}
+ fi
+
+ if [ -n "${UBOOT_ELF}" ]
+ then
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -m 644 ${B}/${config}/${UBOOT_ELF} ${D}/boot/u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${D}/boot/${UBOOT_BINARY}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${D}/boot/${UBOOT_BINARY}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -m 644 ${B}/${UBOOT_ELF} ${D}/boot/${UBOOT_ELF_IMAGE}
+ ln -sf ${UBOOT_ELF_IMAGE} ${D}/boot/${UBOOT_ELF_BINARY}
+ fi
+ fi
+
+ if [ -e ${WORKDIR}/fw_env.config ] ; then
+ install -d ${D}${sysconfdir}
+ install -m 644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}/fw_env.config
+ fi
+
+ if [ -n "${SPL_BINARY}" ]
+ then
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -m 644 ${B}/${config}/${SPL_BINARY} ${D}/boot/${SPL_IMAGE}-${type}-${PV}-${PR}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${D}/boot/${SPL_BINARYNAME}-${type}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${D}/boot/${SPL_BINARYNAME}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -m 644 ${B}/${SPL_BINARY} ${D}/boot/${SPL_IMAGE}
+ ln -sf ${SPL_IMAGE} ${D}/boot/${SPL_BINARYNAME}
+ fi
+ fi
+
+ if [ -n "${UBOOT_ENV}" ]
+ then
+ install -m 644 ${WORKDIR}/${UBOOT_ENV_BINARY} ${D}/boot/${UBOOT_ENV_IMAGE}
+ ln -sf ${UBOOT_ENV_IMAGE} ${D}/boot/${UBOOT_ENV_BINARY}
+ fi
+
+ if [ "${UBOOT_EXTLINUX}" = "1" ]
+ then
+ install -Dm 0644 ${UBOOT_EXTLINUX_CONFIG} ${D}/${UBOOT_EXTLINUX_INSTALL_DIR}/${UBOOT_EXTLINUX_CONF_NAME}
+ fi
+
+}
+
+FILES:${PN} = "/boot ${sysconfdir} ${datadir}"
+
+do_deploy () {
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -d ${DEPLOYDIR}
+ install -m 644 ${B}/${config}/u-boot-${type}.${UBOOT_SUFFIX} ${DEPLOYDIR}/u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX}
+ cd ${DEPLOYDIR}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${UBOOT_SYMLINK}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${UBOOT_SYMLINK}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${UBOOT_BINARY}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_SUFFIX} ${UBOOT_BINARY}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -d ${DEPLOYDIR}
+ install -m 644 ${B}/${UBOOT_BINARY} ${DEPLOYDIR}/${UBOOT_IMAGE}
+ cd ${DEPLOYDIR}
+ rm -f ${UBOOT_BINARY} ${UBOOT_SYMLINK}
+ ln -sf ${UBOOT_IMAGE} ${UBOOT_SYMLINK}
+ ln -sf ${UBOOT_IMAGE} ${UBOOT_BINARY}
+ fi
+
+ if [ -n "${UBOOT_ELF}" ]
+ then
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -m 644 ${B}/${config}/${UBOOT_ELF} ${DEPLOYDIR}/u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${DEPLOYDIR}/${UBOOT_ELF_BINARY}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${DEPLOYDIR}/${UBOOT_ELF_BINARY}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${DEPLOYDIR}/${UBOOT_ELF_SYMLINK}-${type}
+ ln -sf u-boot-${type}-${PV}-${PR}.${UBOOT_ELF_SUFFIX} ${DEPLOYDIR}/${UBOOT_ELF_SYMLINK}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -m 644 ${B}/${UBOOT_ELF} ${DEPLOYDIR}/${UBOOT_ELF_IMAGE}
+ ln -sf ${UBOOT_ELF_IMAGE} ${DEPLOYDIR}/${UBOOT_ELF_BINARY}
+ ln -sf ${UBOOT_ELF_IMAGE} ${DEPLOYDIR}/${UBOOT_ELF_SYMLINK}
+ fi
+ fi
+
+
+ if [ -n "${SPL_BINARY}" ]
+ then
+ if [ -n "${UBOOT_CONFIG}" ]
+ then
+ for config in ${UBOOT_MACHINE}; do
+ i=$(expr $i + 1);
+ for type in ${UBOOT_CONFIG}; do
+ j=$(expr $j + 1);
+ if [ $j -eq $i ]
+ then
+ install -m 644 ${B}/${config}/${SPL_BINARY} ${DEPLOYDIR}/${SPL_IMAGE}-${type}-${PV}-${PR}
+ rm -f ${DEPLOYDIR}/${SPL_BINARYNAME} ${DEPLOYDIR}/${SPL_SYMLINK}-${type}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${DEPLOYDIR}/${SPL_BINARYNAME}-${type}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${DEPLOYDIR}/${SPL_BINARYNAME}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${DEPLOYDIR}/${SPL_SYMLINK}-${type}
+ ln -sf ${SPL_IMAGE}-${type}-${PV}-${PR} ${DEPLOYDIR}/${SPL_SYMLINK}
+ fi
+ done
+ unset j
+ done
+ unset i
+ else
+ install -m 644 ${B}/${SPL_BINARY} ${DEPLOYDIR}/${SPL_IMAGE}
+ rm -f ${DEPLOYDIR}/${SPL_BINARYNAME} ${DEPLOYDIR}/${SPL_SYMLINK}
+ ln -sf ${SPL_IMAGE} ${DEPLOYDIR}/${SPL_BINARYNAME}
+ ln -sf ${SPL_IMAGE} ${DEPLOYDIR}/${SPL_SYMLINK}
+ fi
+ fi
+
+
+ if [ -n "${UBOOT_ENV}" ]
+ then
+ install -m 644 ${WORKDIR}/${UBOOT_ENV_BINARY} ${DEPLOYDIR}/${UBOOT_ENV_IMAGE}
+ rm -f ${DEPLOYDIR}/${UBOOT_ENV_BINARY} ${DEPLOYDIR}/${UBOOT_ENV_SYMLINK}
+ ln -sf ${UBOOT_ENV_IMAGE} ${DEPLOYDIR}/${UBOOT_ENV_BINARY}
+ ln -sf ${UBOOT_ENV_IMAGE} ${DEPLOYDIR}/${UBOOT_ENV_SYMLINK}
+ fi
+
+ if [ "${UBOOT_EXTLINUX}" = "1" ]
+ then
+ install -m 644 ${UBOOT_EXTLINUX_CONFIG} ${DEPLOYDIR}/${UBOOT_EXTLINUX_SYMLINK}
+ ln -sf ${UBOOT_EXTLINUX_SYMLINK} ${DEPLOYDIR}/${UBOOT_EXTLINUX_CONF_NAME}-${MACHINE}
+ ln -sf ${UBOOT_EXTLINUX_SYMLINK} ${DEPLOYDIR}/${UBOOT_EXTLINUX_CONF_NAME}
+ fi
+}
+
+addtask deploy before do_build after do_compile
diff --git a/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton_git.bb b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton_git.bb
new file mode 100644
index 0000000..3ecb4a4
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-bsp/u-boot/u-boot-nuvoton_git.bb
@@ -0,0 +1,8 @@
+DESCRIPTION = "U-boot for Nuvoton NPCM7xx Baseboard Management Controller"
+
+require u-boot-common-nuvoton.inc
+require u-boot-nuvoton.inc
+
+PROVIDES += "u-boot"
+
+DEPENDS += "dtc-native"
diff --git a/meta-nuvoton-npcm8xx/recipes-connectivity/openssl/openssl_%.bbappend b/meta-nuvoton-npcm8xx/recipes-connectivity/openssl/openssl_%.bbappend
new file mode 100644
index 0000000..2557052
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-connectivity/openssl/openssl_%.bbappend
@@ -0,0 +1 @@
+EXTRA_OECONF:class-native:append = " no-module"
diff --git a/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions.bb b/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions.bb
new file mode 100644
index 0000000..21991b7
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions.bb
@@ -0,0 +1,15 @@
+SUMMARY = "udev rules for MTD partitions"
+DESCRIPTION = "udev rules for MTD partitions"
+PR = "r1"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+S = "${WORKDIR}"
+SRC_URI += "file://76-nuvoton-mtd-partitions.rules"
+
+RDEPENDS:${PN} += "udev"
+
+do_install() {
+ install -d ${D}/${base_libdir}/udev/rules.d
+ install -m 0644 ${WORKDIR}/76-nuvoton-mtd-partitions.rules ${D}/${base_libdir}/udev/rules.d
+}
diff --git a/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions/76-nuvoton-mtd-partitions.rules b/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions/76-nuvoton-mtd-partitions.rules
new file mode 100644
index 0000000..28e4586
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-core/udev/udev-nuvoton-mtd-partitions/76-nuvoton-mtd-partitions.rules
@@ -0,0 +1 @@
+ENV{DEVTYPE}=="mtd", SYMLINK+="mtd/%s{name}"
diff --git a/meta-nuvoton-npcm8xx/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend b/meta-nuvoton-npcm8xx/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend
new file mode 100644
index 0000000..bba4429
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend
@@ -0,0 +1,7 @@
+LIC_FILES_CHKSUM = "file://LICENSE;md5=d32239bcb673463ab874e80d47fae504"
+SRC_URI:nuvoton := "git://github.com/Nuvoton-Israel/obmc-ikvm.git;branch=master;protocol=https"
+SRCREV:nuvoton := "40f879557d7fe612a6dac6dbc0d1dbdca1eacfc5"
+
+#LIC_FILES_CHKSUM = "file://LICENSE;md5=75859989545e37968a99b631ef42722e"
+#SRC_URI:nuvoton := "git://github.com/Nuvoton-Israel/obmc-ikvm.git;branch=upstream;protocol=https"
+#SRCREV:nuvoton := "e7ae01193609dd86ef982a4641fefa2cc8af8f12"
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton.inc b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton.inc
new file mode 100644
index 0000000..0ea2761
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton.inc
@@ -0,0 +1,22 @@
+DESCRIPTION = "Linux kernel for Nuvoton NPCM7xx"
+SECTION = "kernel"
+LICENSE = "GPL-2.0-only"
+
+PROVIDES += "virtual/kernel"
+
+KCONFIG_MODE="--alldefconfig"
+
+KSRC ?= "git://github.com/Nuvoton-Israel/linux;protocol=https;branch=${KBRANCH}"
+SRC_URI = "${KSRC}"
+SRC_URI:append:npcm7xx = " file://defconfig"
+SRC_URI:append:npcm8xx = " file://npcm8xx_defconfig"
+
+LINUX_VERSION_EXTENSION ?= "-${SRCREV}"
+
+PV = "${LINUX_VERSION}+git${SRCPV}"
+
+inherit kernel
+require recipes-kernel/linux/linux-yocto.inc
+
+# From 4.16+ the COPYING file changed
+LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0003-i2c-nuvoton-npcm750-runbmc-integrate-the-slave-mqueu.patch b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0003-i2c-nuvoton-npcm750-runbmc-integrate-the-slave-mqueu.patch
new file mode 100644
index 0000000..352b554
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0003-i2c-nuvoton-npcm750-runbmc-integrate-the-slave-mqueu.patch
@@ -0,0 +1,479 @@
+From 4ccb3076c71c9aa3355cc849f991d4d8e5301654 Mon Sep 17 00:00:00 2001
+From: kfting <kfting@nuvoton.com>
+Date: Mon, 15 Jul 2019 09:22:29 +0800
+Subject: [PATCH] i2c: nuvoton-npcm750-runbmc: integrate the slave mqueue
+
+1. Add support for the runbmc IPMB functionality
+2. The slave mqueue node is required on the i2c bus 5 for runbmc.
+
+Signed-off-by: kfting <kfting@nuvoton.com>
+---
+ .../sysfs-bus-i2c-devices-slave-mqueue | 10 +
+ .../bindings/i2c/i2c-slave-mqueue.txt | 34 +++
+ Documentation/i2c/slave-mqueue-backend.rst | 124 ++++++++++
+ drivers/i2c/Kconfig | 25 ++
+ drivers/i2c/Makefile | 1 +
+ drivers/i2c/i2c-slave-mqueue.c | 215 ++++++++++++++++++
+ 6 files changed, 409 insertions(+)
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-slave-mqueue
+ create mode 100644 Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt
+ create mode 100644 Documentation/i2c/slave-mqueue-backend.rst
+ create mode 100644 drivers/i2c/i2c-slave-mqueue.c
+
+diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-slave-mqueue b/Documentation/ABI/testing/sysfs-bus-i2c-devices-slave-mqueue
+new file mode 100644
+index 000000000000..28318108ce85
+--- /dev/null
++++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-slave-mqueue
+@@ -0,0 +1,10 @@
++What: /sys/bus/i2c/devices/*/slave-mqueue
++Date: May 2019
++KernelVersion: 5.2
++Contact: Eduardo Valentin <eduval@amazon.com>
++Description:
++ Reading to this file will return exactly one message,
++ when available, of the i2c-slave-mqueue device attached
++ to that bus. Userspace can also poll on this file to
++ get notified when new messages are available.
++Users: i2c-slave-mqueue driver
+diff --git a/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt b/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt
+new file mode 100644
+index 000000000000..eb1881a4fc0e
+--- /dev/null
++++ b/Documentation/devicetree/bindings/i2c/i2c-slave-mqueue.txt
+@@ -0,0 +1,34 @@
++===============================================
++Device Tree for I2C slave message queue backend
++===============================================
++
++Some protocols over I2C/SMBus are designed for bi-directional transferring
++messages by using I2C Master Write protocol. This requires that both sides
++of the communication have slave addresses.
++
++This I2C slave mqueue (message queue) is used to receive and queue
++messages from the remote i2c intelligent device; and it will add the target
++slave address (with R/W# bit is always 0) into the message at the first byte.
++
++Links
++----
++`Intelligent Platform Management Bus
++Communications Protocol Specification
++<https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmp-spec-v1.0.pdf>`_
++
++`Management Component Transport Protocol (MCTP)
++SMBus/I2C Transport Binding Specification
++<https://www.dmtf.org/sites/default/files/standards/documents/DSP0237_1.1.0.pdf>`_
++
++Required Properties:
++- compatible : should be "i2c-slave-mqueue"
++- reg : slave address
++
++Example:
++
++i2c {
++ slave_mqueue: i2c-slave-mqueue {
++ compatible = "i2c-slave-mqueue";
++ reg = <0x10>;
++ };
++};
+diff --git a/Documentation/i2c/slave-mqueue-backend.rst b/Documentation/i2c/slave-mqueue-backend.rst
+new file mode 100644
+index 000000000000..376dff998fa3
+--- /dev/null
++++ b/Documentation/i2c/slave-mqueue-backend.rst
+@@ -0,0 +1,124 @@
++.. SPDX-License-Identifier: GPL-2.0
++
++=====================================
++Linux I2C slave message queue backend
++=====================================
++
++:Author: Haiyue Wang <haiyue.wang@linux.intel.com>
++
++Some protocols over I2C/SMBus are designed for bi-directional transferring
++messages by using I2C Master Write protocol. This requires that both sides
++of the communication have slave addresses.
++
++Like MCTP (Management Component Transport Protocol) and IPMB (Intelligent
++Platform Management Bus), they both require that the userspace can receive
++messages from i2c drivers under slave mode.
++
++This I2C slave mqueue (message queue) backend is used to receive and queue
++messages from the remote i2c intelligent device; and it will add the target
++slave address (with R/W# bit is always 0) into the message at the first byte,
++so that userspace can use this byte to dispatch the messages into different
++handling modules. Also, like IPMB, the address byte is in its message format,
++it needs it to do checksum.
++
++For messages are time related, so this backend will flush the oldest message
++to queue the newest one.
++
++Link
++----
++`Intelligent Platform Management Bus
++Communications Protocol Specification
++<https://www.intel.com/content/dam/www/public/us/en/documents/product-briefs/ipmp-spec-v1.0.pdf>`_
++
++`Management Component Transport Protocol (MCTP)
++SMBus/I2C Transport Binding Specification
++<https://www.dmtf.org/sites/default/files/standards/documents/DSP0237_1.1.0.pdf>`_
++
++How to use
++----------
++For example, the I2C5 bus has slave address 0x10, the below command will create
++the related message queue interface:
++
++ echo slave-mqueue 0x1010 > /sys/bus/i2c/devices/i2c-5/new_device
++
++Then you can dump the messages like this:
++
++ hexdump -C /sys/bus/i2c/devices/5-1010/slave-mqueue
++
++Code Example
++------------
++*Note: call 'lseek' before 'read', this is a requirement from kernfs' design.*
++
++::
++
++ #include <sys/types.h>
++ #include <sys/stat.h>
++ #include <unistd.h>
++ #include <poll.h>
++ #include <time.h>
++ #include <fcntl.h>
++ #include <stdio.h>
++
++ int main(int argc, char *argv[])
++ {
++ int i, r;
++ struct pollfd pfd;
++ struct timespec ts;
++ unsigned char data[256];
++
++ pfd.fd = open(argv[1], O_RDONLY | O_NONBLOCK);
++ if (pfd.fd < 0)
++ return -1;
++
++ pfd.events = POLLPRI;
++
++ while (1) {
++ r = poll(&pfd, 1, 5000);
++
++ if (r < 0)
++ break;
++
++ if (r == 0 || !(pfd.revents & POLLPRI))
++ continue;
++
++ lseek(pfd.fd, 0, SEEK_SET);
++ r = read(pfd.fd, data, sizeof(data));
++ if (r <= 0)
++ continue;
++
++ clock_gettime(CLOCK_MONOTONIC, &ts);
++ printf("[%ld.%.9ld] :", ts.tv_sec, ts.tv_nsec);
++ for (i = 0; i < r; i++)
++ printf(" %02x", data[i]);
++ printf("\n");
++ }
++
++ close(pfd.fd);
++
++ return 0;
++ }
++
++Result
++------
++*./a.out "/sys/bus/i2c/devices/5-1010/slave-mqueue"*
++
++::
++
++ [10183.232500449] : 20 18 c8 2c 78 01 5b
++ [10183.479358348] : 20 18 c8 2c 78 01 5b
++ [10183.726556812] : 20 18 c8 2c 78 01 5b
++ [10183.972605863] : 20 18 c8 2c 78 01 5b
++ [10184.220124772] : 20 18 c8 2c 78 01 5b
++ [10184.467764166] : 20 18 c8 2c 78 01 5b
++ [10193.233421784] : 20 18 c8 2c 7c 01 57
++ [10193.480273460] : 20 18 c8 2c 7c 01 57
++ [10193.726788733] : 20 18 c8 2c 7c 01 57
++ [10193.972781945] : 20 18 c8 2c 7c 01 57
++ [10194.220487360] : 20 18 c8 2c 7c 01 57
++ [10194.468089259] : 20 18 c8 2c 7c 01 57
++ [10203.233433099] : 20 18 c8 2c 80 01 53
++ [10203.481058715] : 20 18 c8 2c 80 01 53
++ [10203.727610472] : 20 18 c8 2c 80 01 53
++ [10203.974044856] : 20 18 c8 2c 80 01 53
++ [10204.220734634] : 20 18 c8 2c 80 01 53
++ [10204.468461664] : 20 18 c8 2c 80 01 53
+diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
+index 438905e2a1d0..5ffe13438b6f 100644
+--- a/drivers/i2c/Kconfig
++++ b/drivers/i2c/Kconfig
+@@ -133,6 +133,31 @@ config I2C_SLAVE_TESTUNIT
+ multi-master, SMBus Host Notify, etc. Please read
+ Documentation/i2c/slave-testunit-backend.rst for further details.
+
++config I2C_SLAVE_MQUEUE
++ tristate "I2C mqueue (message queue) slave driver"
++ help
++ Some protocols over I2C are designed for bi-directional transferring
++ messages by using I2C Master Write protocol. This driver is used to
++ receive and queue messages from the remote I2C device.
++
++ Userspace can get the messages by reading sysfs file that this driver
++ exposes.
++
++ This support is also available as a module. If so, the module will be
++ called i2c-slave-mqueue.
++
++config I2C_SLAVE_MQUEUE_MESSAGE_SIZE
++ int "The message size of I2C mqueue slave"
++ depends on I2C_SLAVE_MQUEUE
++ default 120
++
++config I2C_SLAVE_MQUEUE_QUEUE_SIZE
++ int "The queue size of I2C mqueue slave"
++ depends on I2C_SLAVE_MQUEUE
++ default 32
++ help
++ This number MUST be power of 2.
++
+ endif
+
+ config I2C_DEBUG_CORE
+diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
+index c1d493dc9bac..0442e5cf8587 100644
+--- a/drivers/i2c/Makefile
++++ b/drivers/i2c/Makefile
+@@ -17,5 +17,6 @@ obj-y += algos/ busses/ muxes/
+ obj-$(CONFIG_I2C_STUB) += i2c-stub.o
+ obj-$(CONFIG_I2C_SLAVE_EEPROM) += i2c-slave-eeprom.o
+ obj-$(CONFIG_I2C_SLAVE_TESTUNIT) += i2c-slave-testunit.o
++obj-$(CONFIG_I2C_SLAVE_MQUEUE) += i2c-slave-mqueue.o
+
+ ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG
+diff --git a/drivers/i2c/i2c-slave-mqueue.c b/drivers/i2c/i2c-slave-mqueue.c
+new file mode 100644
+index 000000000000..c17c4911928f
+--- /dev/null
++++ b/drivers/i2c/i2c-slave-mqueue.c
+@@ -0,0 +1,215 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2017 - 2018, Intel Corporation.
++
++#include <linux/i2c.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <linux/of.h>
++#include <linux/slab.h>
++#include <linux/spinlock.h>
++#include <linux/sysfs.h>
++
++#define MQ_MSGBUF_SIZE CONFIG_I2C_SLAVE_MQUEUE_MESSAGE_SIZE
++#define MQ_QUEUE_SIZE CONFIG_I2C_SLAVE_MQUEUE_QUEUE_SIZE
++#define MQ_QUEUE_NEXT(x) (((x) + 1) & (MQ_QUEUE_SIZE - 1))
++
++struct mq_msg {
++ int len;
++ u8 *buf;
++};
++
++struct mq_queue {
++ struct bin_attribute bin;
++ struct kernfs_node *kn;
++
++ spinlock_t lock; /* spinlock for queue index handling */
++ int in;
++ int out;
++
++ struct mq_msg *curr;
++ int truncated; /* drop current if truncated */
++ struct mq_msg queue[MQ_QUEUE_SIZE];
++};
++
++static int i2c_slave_mqueue_callback(struct i2c_client *client,
++ enum i2c_slave_event event, u8 *val)
++{
++ struct mq_queue *mq = i2c_get_clientdata(client);
++ struct mq_msg *msg = mq->curr;
++ int ret = 0;
++
++ switch (event) {
++ case I2C_SLAVE_WRITE_REQUESTED:
++ mq->truncated = 0;
++
++ msg->len = 1;
++ msg->buf[0] = client->addr << 1;
++ break;
++
++ case I2C_SLAVE_WRITE_RECEIVED:
++ if (msg->len < MQ_MSGBUF_SIZE) {
++ msg->buf[msg->len++] = *val;
++ } else {
++ dev_err(&client->dev, "message is truncated!\n");
++ mq->truncated = 1;
++ ret = -EINVAL;
++ }
++ break;
++
++ case I2C_SLAVE_STOP:
++ if (unlikely(mq->truncated || msg->len < 2))
++ break;
++
++ spin_lock(&mq->lock);
++ mq->in = MQ_QUEUE_NEXT(mq->in);
++ mq->curr = &mq->queue[mq->in];
++ mq->curr->len = 0;
++
++ /* Flush the oldest message */
++ if (mq->out == mq->in)
++ mq->out = MQ_QUEUE_NEXT(mq->out);
++ spin_unlock(&mq->lock);
++
++ kernfs_notify(mq->kn);
++ break;
++
++ default:
++ *val = 0xFF;
++ break;
++ }
++
++ return ret;
++}
++
++static ssize_t i2c_slave_mqueue_bin_read(struct file *filp,
++ struct kobject *kobj,
++ struct bin_attribute *attr,
++ char *buf, loff_t pos, size_t count)
++{
++ struct mq_queue *mq;
++ struct mq_msg *msg;
++ unsigned long flags;
++ bool more = false;
++ ssize_t ret = 0;
++
++ mq = dev_get_drvdata(kobj_to_dev(kobj));
++
++ spin_lock_irqsave(&mq->lock, flags);
++ if (mq->out != mq->in) {
++ msg = &mq->queue[mq->out];
++
++ if (msg->len <= count) {
++ ret = msg->len;
++ memcpy(buf, msg->buf, ret);
++ } else {
++ ret = -EOVERFLOW; /* Drop this HUGE one. */
++ }
++
++ mq->out = MQ_QUEUE_NEXT(mq->out);
++ if (mq->out != mq->in)
++ more = true;
++ }
++ spin_unlock_irqrestore(&mq->lock, flags);
++
++ if (more)
++ kernfs_notify(mq->kn);
++
++ return ret;
++}
++
++static int i2c_slave_mqueue_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct device *dev = &client->dev;
++ struct mq_queue *mq;
++ int ret, i;
++ void *buf;
++
++ BUILD_BUG_ON(!is_power_of_2(MQ_QUEUE_SIZE));
++
++ mq = devm_kzalloc(dev, sizeof(*mq), GFP_KERNEL);
++ if (!mq)
++ return -ENOMEM;
++
++ buf = devm_kmalloc_array(dev, MQ_QUEUE_SIZE, MQ_MSGBUF_SIZE,
++ GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ for (i = 0; i < MQ_QUEUE_SIZE; i++)
++ mq->queue[i].buf = buf + i * MQ_MSGBUF_SIZE;
++
++ i2c_set_clientdata(client, mq);
++
++ spin_lock_init(&mq->lock);
++ mq->curr = &mq->queue[0];
++
++ sysfs_bin_attr_init(&mq->bin);
++ mq->bin.attr.name = "slave-mqueue";
++ mq->bin.attr.mode = 0400;
++ mq->bin.read = i2c_slave_mqueue_bin_read;
++ mq->bin.size = MQ_MSGBUF_SIZE * MQ_QUEUE_SIZE;
++
++ ret = sysfs_create_bin_file(&dev->kobj, &mq->bin);
++ if (ret)
++ return ret;
++
++ mq->kn = kernfs_find_and_get(dev->kobj.sd, mq->bin.attr.name);
++ if (!mq->kn) {
++ sysfs_remove_bin_file(&dev->kobj, &mq->bin);
++ return -EFAULT;
++ }
++
++ ret = i2c_slave_register(client, i2c_slave_mqueue_callback);
++ if (ret) {
++ kernfs_put(mq->kn);
++ sysfs_remove_bin_file(&dev->kobj, &mq->bin);
++ return ret;
++ }
++
++ return 0;
++}
++
++static int i2c_slave_mqueue_remove(struct i2c_client *client)
++{
++ struct mq_queue *mq = i2c_get_clientdata(client);
++
++ i2c_slave_unregister(client);
++
++ kernfs_put(mq->kn);
++ sysfs_remove_bin_file(&client->dev.kobj, &mq->bin);
++
++ return 0;
++}
++
++static const struct i2c_device_id i2c_slave_mqueue_id[] = {
++ { "slave-mqueue", 0 },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(i2c, i2c_slave_mqueue_id);
++
++#ifdef CONFIG_OF
++static const struct of_device_id i2c_slave_mqueue_of_match[] = {
++ {
++ .compatible = "i2c-slave-mqueue",
++ },
++ { /* sentinel */ }
++};
++MODULE_DEVICE_TABLE(of, i2c_slave_mqueue_of_match);
++#endif
++
++static struct i2c_driver i2c_slave_mqueue_driver = {
++ .driver = {
++ .name = "i2c-slave-mqueue",
++ .of_match_table = of_match_ptr(i2c_slave_mqueue_of_match),
++ },
++ .probe = i2c_slave_mqueue_probe,
++ .remove = i2c_slave_mqueue_remove,
++ .id_table = i2c_slave_mqueue_id,
++};
++module_i2c_driver(i2c_slave_mqueue_driver);
++
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
++MODULE_DESCRIPTION("I2C slave mode for receiving and queuing messages");
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0004-driver-ncsi-replace-del-timer-sync.patch b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0004-driver-ncsi-replace-del-timer-sync.patch
new file mode 100644
index 0000000..9d5a093
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0004-driver-ncsi-replace-del-timer-sync.patch
@@ -0,0 +1,25 @@
+From 65545ab80b03473b661696dc296fd9f238ba5e16 Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Thu, 9 Jan 2020 11:21:30 +0800
+Subject: [PATCH 24/34] driver: ncsi: replace del_timer_sync() with del_timer()
+
+---
+ net/ncsi/ncsi-manage.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
+index 70fe02697544..87484beee5fd 100644
+--- a/net/ncsi/ncsi-manage.c
++++ b/net/ncsi/ncsi-manage.c
+@@ -181,7 +181,7 @@ void ncsi_stop_channel_monitor(struct ncsi_channel *nc)
+ nc->monitor.enabled = false;
+ spin_unlock_irqrestore(&nc->lock, flags);
+
+- del_timer_sync(&nc->monitor.timer);
++ del_timer(&nc->monitor.timer);
+ }
+
+ struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0015-driver-misc-nuvoton-vdm-support-openbmc-libmctp.patch b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0015-driver-misc-nuvoton-vdm-support-openbmc-libmctp.patch
new file mode 100644
index 0000000..e2a34fa
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0015-driver-misc-nuvoton-vdm-support-openbmc-libmctp.patch
@@ -0,0 +1,214 @@
+From fcae4930d0f6a24eca27509e0acbc9da533ed64c Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Mon, 30 Nov 2020 14:33:04 +0800
+Subject: [PATCH] driver: misc: nuvoton: vdm: support openbmc libmctp
+
+---
+ drivers/misc/npcm-vdm/vdm_common.c | 87 +++---------------------------
+ drivers/misc/npcm-vdm/vdm_module.c | 26 +++++++--
+ 2 files changed, 31 insertions(+), 82 deletions(-)
+
+diff --git a/drivers/misc/npcm-vdm/vdm_common.c b/drivers/misc/npcm-vdm/vdm_common.c
+index b622da52dda7..cbf536301fb4 100644
+--- a/drivers/misc/npcm-vdm/vdm_common.c
++++ b/drivers/misc/npcm-vdm/vdm_common.c
+@@ -262,95 +262,24 @@ int vdm_SendMessage(uint8_t route_type, uint16_t aBDF,uint8_t *apData,uint32_t
+ uint8_t idx;
+ uint8_t tag,paddingBytesNum;
+ uint8_t currLength;
+- uint32_t pci_message_header[4]={0};
+
+ ready_for_transmit=0;
+
+- pci_message_header[0]=
+- // ( ( ((1) << 5)+ ( (0x13/*1 0011 (broadcasting) */) << 0)) << 0) + // fmt + type . filled dynamically
+- ( ( ( PCIe_TC0 << 4)+ (PCIe_NO_IDO << 2) + // TC + atr[2]
+- (PCIe_NO_TH << 0) ) << 8 ) + // TH
+- ( ( (PCIe_NO_TD << 7) + (PCIe_NO_EP << 6) + // TD + EP
+- (PCIe_NO_RLX_ORDER_NO_SNOOP << 4) + // atr[1,0]
+- (PCIe_NO_AT << 2) ) << 16); // AT
+- //+ ( (0) << 24) ;// length . filled dynamically
+-
+- pci_message_header[1]=
+- ( (0) << 0) + // request ID filled automatically by HW
+- ( ( PCIe_TAG ) << 8) + // defult tag
+- ( (PCIe_MSG_VDM_TYPE1) << 24 ) ;//message code (vd type1)
+-
+-
+- pci_message_header[2]=
+- // ( (0) << 0) + // bus_num (reserved in broadcasting) . filled dynamically
+- // ( ( (0 << 3) + (0 << 0) ) << 8) + // dev_num + func_num (reserved in broadcasting) . filled dynamically
+- ( ( (VDM_VENDOR_ID >> 8) & 0xff) << 16) +// vendor id msb
+- ( ( VDM_VENDOR_ID & 0xff ) << 24 ) ;// vendor id lsb
+-
+-// PRINTF("<1>vdm:vdm_SendMessage \n" );
+-
+ // data will be split by PCIe_MAX_PAYLOAD_SIZE_BYTES
+ while(aLength)
+ {
+- if(aLength>PCIe_MAX_PAYLOAD_SIZE_BYTES)
+- {
+- currLength=PCIe_MAX_PAYLOAD_SIZE_BYTES;
+- }
++ if (aLength > PCIe_MAX_PAYLOAD_SIZE_BYTES)
++ currLength = PCIe_MAX_PAYLOAD_SIZE_BYTES;
+ else
+- {
+- currLength=aLength;
+- }
++ currLength = aLength;
++
+ aLength-=currLength;
+
+- paddingBytesNum = ( currLength % 4);
+- if ( 0 != paddingBytesNum )
+- {
++ paddingBytesNum = (currLength % 4);
++ if (0 != paddingBytesNum )
+ paddingBytesNum = 4 - paddingBytesNum;
+- }
+-
+- /*********** fill first U32 of TLP : ***************/
+- pci_message_header[0] &= (~PCIe_HEADER_FMT_FIELD_MASK);
+- pci_message_header[0] &= (~PCIe_HEADER_LENGTH_FIELD_MASK);
+- if(currLength > 4)
+- {
+- pci_message_header[0] |= PCIe_HEADER_FMT_MSG_WITH_PAYLOAD;
+- pci_message_header[0] |= (( ((currLength-1)/4) & 0xff) << 24);
+- pci_message_header[0] |= ( (( ((currLength-1)/4) >> 8) & 0x3) << 16);
+- }
+- else
+- {
+- pci_message_header[0] |= PCIe_HEADER_FMT_MSG_NO_PAYLOAD;
+- }
+-
+- /* route_type icludes tlp type and route mechanism*/
+- pci_message_header[0] &= (~PCIe_HEADER_ROUTE_FIELD_MASK);
+- pci_message_header[0] |= route_type;
+-
+- pci_message_header[0] &= (~PCIe_HEADER_ATTR_MASK);
+- pci_message_header[0] |= PCIe_HEADER_ATTR_TEST;
+-
+-
+- /*********** fill second U32 of TLP : ***************/
+- pci_message_header[1] &= (~PCIe_HEADER_TAG_FIELD_MASK);
+- tag = (paddingBytesNum & 3 ) << 4 ;
+- pci_message_header[1] |= (tag << 16);
+-
+-
+- /*********** fill third U32 of TLP : ***************/
+- pci_message_header[2] &= (~PCIe_HEADER_DEST_BDF_FIELD_MASK);
+-
+- if(PCIe_HEADER_ROUTE_BY_ID == route_type)
+- {
+- pci_message_header[2] |=
+- ( ( (aBDF >> 8) & 0xff) ) +
+- ( ( aBDF & 0xff ) << 8 ) ;
+- }
+-
+- iowrite32(pci_message_header[0], vdm_virt_addr + VDM_TXF_REG);
+- iowrite32(pci_message_header[1], vdm_virt_addr + VDM_TXF_REG);
+- iowrite32(pci_message_header[2], vdm_virt_addr + VDM_TXF_REG);
+
+- while(currLength >3 )
++ while (currLength >3 )
+ {
+ txData=(apData[3]<<24) + (apData[2]<<16) + (apData[1]<<8) + (apData[0]) ;
+ iowrite32(txData, vdm_virt_addr + VDM_TXF_REG);
+@@ -401,7 +330,7 @@ int vdm_SendMessage(uint8_t route_type, uint16_t aBDF,uint8_t *apData,uint32_t
+ // test VDM_CNT_REG_VDM_ENABLE_BIT_POS to see that PCIe bus was not reset
+ for (i=0 ; i< SEND_TIMEOUT; i++)
+ {
+- if((read_reg_bit(VDM_TX_DONE_BIT_POS, vdm_virt_addr + VDM_STAT_REG) == 1) || vdm_is_in_reset())
++ if((read_reg_bit(VDM_CNT_REG_START_TX_BIT, vdm_virt_addr + VDM_CNT_REG) == 0) || vdm_is_in_reset())
+ break;
+ else
+ nano_delay(100);
+diff --git a/drivers/misc/npcm-vdm/vdm_module.c b/drivers/misc/npcm-vdm/vdm_module.c
+index 1cdcab95e8ae..b9f319fbe8d6 100644
+--- a/drivers/misc/npcm-vdm/vdm_module.c
++++ b/drivers/misc/npcm-vdm/vdm_module.c
+@@ -279,13 +279,14 @@ static ssize_t vdm_read(struct file *filp, char *buf, size_t count, loff_t *f_po
+ while(1)
+ {
+ spin_lock_irqsave(&lock, flags);
++#if 0
+ if(0 == pVDM_Instance->BDF_is_set)
+ {
+ ret = -ENOENT ;
+ VDM_DEBUG_LOG(tBDF,"BDF was not set for given pVDM Instance\n");
+ goto unlock_and_exit;
+ }
+-
++#endif
+ if (vdm_is_in_reset())
+ {
+ pVDM_Instance->last_errors |= PCIE_VDM_ERR_BUS_RESET_OCCURED;
+@@ -380,13 +381,21 @@ static ssize_t vdm_write( struct file *filp, const char *buf, size_t count, loff
+ goto failed;
+ }
+ //pr_debug("<1> vdm module write start \n");
+-
++#if 0
+ if((count-1) > pVDM_Instance->mptxBufferLength)
+ {
+ VDM_DEBUG_LOG(tBDF,"vdm module data length is too big\n");
+ ret = -EINVAL;
+ goto failed;
+ }
++#endif
++ if(count > pVDM_Instance->mptxBufferLength)
++ {
++ VDM_DEBUG_LOG(tBDF,"vdm module data length is too big\n");
++ ret = -EINVAL;
++ goto failed;
++ }
++
+ if(count < 2)
+ {
+ VDM_DEBUG_LOG(tBDF,"vdm module : wrong buffer\n");
+@@ -394,6 +403,14 @@ static ssize_t vdm_write( struct file *filp, const char *buf, size_t count, loff
+ goto failed;
+ }
+
++ if(copy_from_user( pVDM_Instance->mptxBuffer , &buf[0] , count))
++ {
++ ret = -EFAULT;
++ VDM_DEBUG_LOG(tBDF,"Failed for copying data from user\n");
++ goto failed;
++ }
++
++#if 0
+ if(copy_from_user( pVDM_Instance->mptxBuffer , &buf[1] , count-1))
+ {
+ ret = -EFAULT;
+@@ -407,6 +424,7 @@ static ssize_t vdm_write( struct file *filp, const char *buf, size_t count, loff
+ VDM_DEBUG_LOG(tBDF,"BDF was not set\n");
+ goto failed;
+ }
++
+ if (copy_from_user(&route_type, &buf[0], sizeof(route_type)))
+ {
+ ret = -EFAULT;
+@@ -420,8 +438,9 @@ static ssize_t vdm_write( struct file *filp, const char *buf, size_t count, loff
+ {
+ route_type=PCIe_HEADER_ROUTE_FROM_RC;
+ }
++#endif
+
+- VDM_DEBUG_LOG(tBDF,"Before writing data route_type %d BDF 0x%X and count %d\n",route_type,pVDM_Instance->mBDF,count );
++ VDM_DEBUG_LOG(tBDF,"Before writing data route_type %d BDF 0x%X and count %d\n",route_type,pVDM_Instance->mBDF,count );
+
+ if (0 == vdm_SendMessage(route_type , pVDM_Instance->mBDF , pVDM_Instance->mptxBuffer,count-1))
+ ret = count;
+@@ -608,6 +627,7 @@ static int vdm_open(struct inode *inode, struct file *filp)
+ }
+
+ memset(pVDM_Instance,0,sizeof(vdm_instance_t));
++ pVDM_Instance_Default = pVDM_Instance;
+ pVDM_Instance->BDF_is_set = 0;
+ pVDM_Instance->last_errors = 0;
+ pVDM_Instance->dbg_counter = 0;
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0017-drivers-i2c-workaround-for-i2c-slave-behavior.patch b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0017-drivers-i2c-workaround-for-i2c-slave-behavior.patch
new file mode 100644
index 0000000..c9cfb86
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/0017-drivers-i2c-workaround-for-i2c-slave-behavior.patch
@@ -0,0 +1,44 @@
+From 12744251cc8ceeb3f4bb16fccb70ff0200b13dbf Mon Sep 17 00:00:00 2001
+From: kfting <kfting@nuvoton.com>
+Date: Thu, 1 Jul 2021 15:29:45 +0800
+Subject: [PATCH] drivers: i2c: workaround for i2c slave behavior
+
+1. Not verified yet.
+
+Signed-off-by: kfting <kfting@nuvoton.com>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c
+index 78dc9eeb83a2..0753cf4c41aa 100644
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -1166,13 +1166,13 @@ static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus)
+ bus->stop_ind = I2C_SLAVE_RESTART_IND;
+ bus->master_or_slave = I2C_SLAVE;
+ if (bus->operation == I2C_READ_OPER)
+- npcm_i2c_read_fifo_slave(bus, npcm_i2c_fifo_usage(bus));
++ npcm_i2c_slave_rd_wr(bus);
+ bus->operation = I2C_WRITE_OPER;
+ iowrite8(0, bus->reg + NPCM_I2CRXF_CTL);
+ val = NPCM_I2CFIF_CTS_CLR_FIFO | NPCM_I2CFIF_CTS_SLVRSTR |
+ NPCM_I2CFIF_CTS_RXF_TXE;
+ iowrite8(val, bus->reg + NPCM_I2CFIF_CTS);
+- npcm_i2c_slave_rd_wr(bus);
++ //npcm_i2c_slave_rd_wr(bus);
+ ret = IRQ_HANDLED;
+ }
+
+@@ -1511,7 +1511,7 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus)
+ npcm_i2c_master_stop(bus);
+
+ /* Clear SDA Status bit (by reading dummy byte) */
+- npcm_i2c_rd_byte(bus);
++ //npcm_i2c_rd_byte(bus);
+
+ /*
+ * The bus is released from stall only after the SW clears
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/2222-driver-misc-add-nuvoton-vdmx-vdma-driver.patch b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/2222-driver-misc-add-nuvoton-vdmx-vdma-driver.patch
new file mode 100644
index 0000000..502e6d2
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/2222-driver-misc-add-nuvoton-vdmx-vdma-driver.patch
@@ -0,0 +1,847 @@
+From eee53b269f70fbf2e016b60f911043e5a35a3a17 Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Tue, 8 Jun 2021 12:12:30 +0800
+Subject: [PATCH] driver: misc: add nuvoton vdmx/vdma driver
+
+Signed-off-by: Joseph Liu <kwliu@nuvoton.com>
+---
+ .../dts/nuvoton-npcm750-runbmc-olympus.dts | 5 +
+ drivers/misc/Kconfig | 7 +
+ drivers/misc/Makefile | 1 +
+ drivers/misc/npcm-vdm/Kconfig | 2 +-
+ drivers/misc/npcm7xx-pci-vdm.c | 760 ++++++++++++++++++
+ 5 files changed, 774 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/misc/npcm7xx-pci-vdm.c
+
+diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+index e08f8fb13792..693e6d311995 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+@@ -31,6 +31,7 @@
+ udc8 = &udc8;
+ udc9 = &udc9;
+ emmc0 = &sdhci0;
++ vdma = &vdma;
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
+ i2c2 = &i2c2;
+@@ -976,6 +977,10 @@
+ status = "okay";
+ };
+
++&vdma {
++ status = "okay";
++};
++
+ &vcd {
+ status = "okay";
+ memory-region = <&vcd_memory>;
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 82f10fd5c0ab..4a6b6fe9c11e 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -506,6 +506,13 @@ config NPCM8XX_JTAG_MASTER
+ help
+ NPCM8xx JTAG Master Interfaces.
+
++config NPCM7XX_PCI_VDM
++ tristate "NPCM7xx PCI VDM/VDMA Controller"
++ depends on (ARCH_NPCM || COMPILE_TEST) && REGMAP && MFD_SYSCON
++ help
++ Expose the NPCM8xx/7xx PCI VDM/VDMA registers found on
++ Nuvoton SOCs to userspace.
++
+ source "drivers/misc/c2port/Kconfig"
+ source "drivers/misc/eeprom/Kconfig"
+ source "drivers/misc/cb710/Kconfig"
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 1079cd2f62d4..8ce25e00d01f 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -64,3 +64,4 @@ obj-$(CONFIG_NPCM7XX_JTAG_MASTER) += npcm7xx-jtag-master.o
+ obj-$(CONFIG_NPCM8XX_JTAG_MASTER) += npcm8xx-jtag-master.o
+ obj-$(CONFIG_MCTP_LPC) += mctp-lpc.o
+ obj-$(CONFIG_NPCM7XX_MCU_FLASH) += npcm7xx-mcu-flash.o
++obj-$(CONFIG_NPCM7XX_PCI_VDM) += npcm7xx-pci-vdm.o
+diff --git a/drivers/misc/npcm-vdm/Kconfig b/drivers/misc/npcm-vdm/Kconfig
+index 3cb4b173f835..e53c4be3bd58 100644
+--- a/drivers/misc/npcm-vdm/Kconfig
++++ b/drivers/misc/npcm-vdm/Kconfig
+@@ -6,7 +6,7 @@ menu "Nuvoton Miscellaneous optional drivers"
+ config NPCM_VDM
+ tristate "support npcmx50 VDM on PCIe"
+ depends on ARCH_NPCM
+- default y
++ default n
+ help
+ Say Y here if you want ioctl npcmx50 VDM on PCIe.
+
+diff --git a/drivers/misc/npcm7xx-pci-vdm.c b/drivers/misc/npcm7xx-pci-vdm.c
+new file mode 100644
+index 000000000000..c27f2b695a94
+--- /dev/null
++++ b/drivers/misc/npcm7xx-pci-vdm.c
+@@ -0,0 +1,760 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2014-2018 Nuvoton Technology corporation.
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include <linux/of_address.h>
++#include <linux/clk.h>
++#include <linux/uaccess.h>
++#include <linux/regmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/cdev.h>
++#include <linux/miscdevice.h>
++#include <linux/interrupt.h>
++#include <linux/dma-mapping.h>
++#include <linux/kfifo.h>
++#include <linux/poll.h>
++#include <linux/ptr_ring.h>
++
++#define ENABLE_VDMA 1
++
++#define DEVICE_NAME "vdm"
++#define TX_TIMEOUT 100
++
++#ifdef CONFIG_ARCH_NPCM7XX
++/* GCR Register */
++#define MFSEL3 0x64
++#define MFSEL3_PCIE_PUSE BIT(17)
++#define INTCR3 0x9C
++#define INTCR3_PCIRREL BIT(30)
++#endif
++
++/* VDM Register */
++#define VDMX_BA 0xE0800000
++#define VDMX_STATR 0x0000
++
++#ifdef CONFIG_ARCH_NPCM7XX
++#define VDMX_IEN 0x0004
++#define VDMX_RXF 0x0008
++#define VDMX_TXF 0x000C
++#define VDMX_CNT 0x0010
++#define VDMX_RXFILT 0x0014
++#else
++#define VDMX_IEN 0x0100
++#define VDMX_RXF 0x0200
++#define VDMX_TXF 0x0300
++#define VDMX_CNT 0x0400
++#define VDMX_RXFILT 0x0500
++#endif
++
++/* VDMX_STATR */
++#define VDMX_STATR_RXNDW GENMASK(23, 16)
++#define VDMX_STATR_RXNDW_OFFSET 16
++#define VDMX_STATR_RXDR BIT(2)
++#define VDMX_STATR_RXF BIT(1)
++#define VDMX_STATR_TXS BIT(0)
++
++/* VDMX_IEN */
++#define VDMX_IEN_RXDREN BIT(2)
++#define VDMX_IEN_RXFEN BIT(1)
++#define VDMX_IEN_TXSEN BIT(0)
++
++/* VDMX_CNT */
++#define VDMX_CNT_RXTO_05US BIT(4)
++#define VDMX_CNT_RXTO_1US BIT(5)
++#define VDMX_CNT_RXTO_2US (BIT(5) | BIT(4))
++#define VDMX_CNT_RXTO_4US BIT(6)
++#define VDMX_CNT_RXTO_8US (BIT(6) | BIT(4))
++#define VDMX_CNT_VDMXEN BIT(1)
++#define VDMX_CNT_TXP BIT(0)
++
++/* VDMX_RXFILT */
++#define VDMX_RXFILT_FEN BIT(31)
++
++#define VDMX_VENDOR_ID 0xb4a1
++#define VDMX_RX_LEN 1024
++#define VDMX_TX_LEN 4
++#define VDMA_BUFFER_SIZE SZ_16K
++
++/* VDMA Register */
++#define VDMA_CTL 0x0000
++#define VDMA_CTL_BLOCK_BIT_POS BIT(17)
++#define VDMA_CTL_BME BIT(9)
++#define VDMA_CTL_VDMAEN BIT(0)
++
++#define VDMA_SRCB 0x0004
++#define VDMA_DSTB 0x0008
++#define VDMA_CDST 0x0014
++#define VDMA_CTCNT 0x0018
++#define VDMA_ECTL 0x0040
++#define VDMA_ECTL_DRDYEN BIT(29)
++#define VDMA_ECTL_DRDY BIT(28)
++#define VDMA_ECTL_NRTGIEN BIT(27)
++#define VDMA_ECTL_NORTG BIT(26)
++#define VDMA_ECTL_HALTINTEN BIT(25)
++#define VDMA_ECTL_DMAHALT BIT(24)
++#define VDMA_ECTL_BUFFSIZE_POS 16
++#define VDMA_ECTL_RTRGREQ BIT(12)
++#define VDMA_ECTL_RTRGSZ BIT(11)
++#define VDMA_ECTL_ENSTSUP1 BIT(10)
++#define VDMA_ECTL_ENSTSUP0 BIT(9)
++#define VDMA_ECTL_SZOFS_POS 7
++#define VDMA_ECTL_SZMOD_BIT23_16 (BIT(5) | BIT(4))
++#define VDMA_ECTL_STAMPP BIT(2)
++#define VDMA_ECTL_CYCBUF BIT(1)
++
++#define VDMA_ESRCSZ 0x0044
++#define VDMA_ERDPNT 0x0048
++#define VDMA_EST0AD 0x0050
++#define VDMA_EST0MK 0x0054
++#define VDMA_EST0DT 0x0058
++#define VDMA_EST1AD 0x0060
++#define VDMA_EST1MK 0x0064
++#define VDMA_EST1DT 0x0068
++
++#define VDMA_TX_DONE BIT(0)
++#define VDMA_RX_DONE BIT(1)
++#define VDMA_RX_FULL BIT(2)
++
++typedef void *(*copy_func_t)(void *dest, const void *src, size_t n);
++
++struct mctp_pcie_packet {
++ struct {
++ u32 hdr[4];
++ u32 payload[16];
++ } data;
++ u32 size;
++};
++
++struct npcm7xx_vdm {
++ struct device *dev;
++ struct miscdevice miscdev;
++ spinlock_t lock;
++ int is_open;
++ int irq;
++ struct regmap *vdmx_base;
++ struct regmap *vdma_base;
++ dma_addr_t dma;
++ void *virt;
++ struct regmap *gcr_base;
++ wait_queue_head_t wait_queue;
++ struct tasklet_struct tasklet;
++ struct ptr_ring rx_queue;
++ u32 wrap;
++};
++
++static atomic_t npcm7xx_vdm_open_count = ATOMIC_INIT(0);
++
++struct kmem_cache *packet_cache;
++
++static void *packet_alloc(gfp_t flags)
++{
++ return kmem_cache_alloc(packet_cache, flags);
++}
++
++static void packet_free(void *packet)
++{
++ kmem_cache_free(packet_cache, packet);
++}
++
++static void npcm7xx_vdm_rx_tasklet(unsigned long data)
++{
++ struct npcm7xx_vdm *priv = (struct npcm7xx_vdm *)data;
++ struct mctp_pcie_packet *rx_packet;
++ int ret;
++ u32 rdpnt = 0;
++ u32 curdst = 0;
++ u32 size = 0;
++
++ regmap_read(priv->vdma_base, VDMA_CDST, &curdst);
++ regmap_read(priv->vdma_base, VDMA_ERDPNT, &rdpnt);
++
++ dev_dbg(priv->dev, "curdst 0x%x\n", curdst);
++ dev_dbg(priv->dev, "rdpnt 0x%x\n", rdpnt);
++
++ // handle wrapped around
++ while (rdpnt > curdst) {
++ priv->wrap++;
++
++ rx_packet = packet_alloc(GFP_ATOMIC);
++ if (!rx_packet) {
++ dev_err(priv->dev, "Failed to allocate RX packet\n");
++ goto out_skip;
++ }
++
++ size = (priv->dma + VDMA_BUFFER_SIZE) - rdpnt;
++
++ if (size > sizeof(rx_packet->data))
++ size = sizeof(rx_packet->data);
++
++ memcpy(&rx_packet->data,
++ (void *)(priv->virt + (rdpnt - priv->dma)),
++ size);
++
++ rx_packet->size = size;
++
++ ret = ptr_ring_produce(&priv->rx_queue, rx_packet);
++ if (ret) {
++ dev_warn(priv->dev, "Failed to produce RX packet: %d\n",
++ ret);
++ packet_free(rx_packet);
++ continue;
++ }
++
++ rdpnt += size;
++
++ if (rdpnt == (priv->dma + VDMA_BUFFER_SIZE)) {
++ int left = curdst - priv->dma;
++ int free = sizeof(rx_packet->data) - size;
++
++ if (left <= free) {
++ memcpy(((void *)&rx_packet->data) + size, (void *)(priv->virt), left);
++ rx_packet->size += left;
++ rdpnt = priv->dma + left;
++ } else {
++ rdpnt = priv->dma;
++ }
++ break;
++ }
++ }
++
++ while (rdpnt < curdst) {
++ rx_packet = packet_alloc(GFP_ATOMIC);
++ if (!rx_packet) {
++ dev_err(priv->dev, "Failed to allocate RX packet\n");
++ goto out_skip;
++ }
++
++ size = curdst - rdpnt;
++ if (size > sizeof(rx_packet->data))
++ size = sizeof(rx_packet->data);
++
++ memcpy(&rx_packet->data,
++ (void *)(priv->virt + (rdpnt - priv->dma)),
++ size);
++
++ rx_packet->size = size;
++
++ ret = ptr_ring_produce(&priv->rx_queue, rx_packet);
++ if (ret) {
++ dev_warn(priv->dev, "Failed to produce RX packet: %d\n",
++ ret);
++ packet_free(rx_packet);
++ continue;
++ }
++
++ rdpnt += size;
++ }
++
++out_skip:
++ dev_dbg(priv->dev, "wrap count %d\n", priv->wrap);
++ dev_dbg(priv->dev, "update rdpnt to 0x%x\n", rdpnt);
++ regmap_write(priv->vdma_base, VDMA_ERDPNT, rdpnt);
++
++ wake_up_all(&priv->wait_queue);
++}
++
++static irqreturn_t npcm7xx_vdm_irq(int irq, void *arg)
++{
++ struct npcm7xx_vdm *priv = arg;
++ u32 status = 0;
++
++ regmap_read(priv->vdma_base, VDMA_ECTL, &status);
++ dev_dbg(priv->dev, "status 0x%x\n", status);
++
++ if (status & VDMA_ECTL_DRDY) {
++ dev_dbg(priv->dev, "VDMA_ECTL_DRDY\n");
++ tasklet_hi_schedule(&priv->tasklet);
++ }
++
++ if (status & VDMA_ECTL_DMAHALT) {
++ /*to do: we should reinit dam buffer if dma halt*/
++ dev_dbg(priv->dev, "VDMA_ECTL_DMAHALT\n");
++ }
++
++ if (status & VDMA_ECTL_NORTG) {
++ dev_dbg(priv->dev, "VDMA_ECTL_NORTG\n");
++ }
++
++ regmap_write(priv->vdma_base, VDMA_ECTL, status);
++
++ return IRQ_HANDLED;
++}
++
++static void npcm7xx_vdm_hw_finit(struct npcm7xx_vdm *priv)
++{
++ /* VDM RESET */
++ regmap_write(priv->vdmx_base, VDMX_CNT, 0);
++
++ /* Disable Interrupt */
++ regmap_write(priv->vdmx_base, VDMX_IEN, 0);
++
++ /* Clear VDM STAT */
++ regmap_write(priv->vdmx_base, VDMX_STATR,
++ VDMX_STATR_RXDR | VDMX_STATR_RXF | VDMX_STATR_TXS);
++
++ /* VDMA Disable */
++ regmap_write(priv->vdma_base, VDMA_CTL, 0);
++
++ /* VDMA Disable Interrupt */
++ regmap_update_bits(priv->vdma_base, VDMA_ECTL, VDMA_ECTL_DRDYEN, ~VDMA_ECTL_DRDYEN);
++ regmap_update_bits(priv->vdma_base, VDMA_ECTL, VDMA_ECTL_HALTINTEN, ~VDMA_ECTL_HALTINTEN);
++ regmap_update_bits(priv->vdma_base, VDMA_ECTL, VDMA_ECTL_NRTGIEN, ~VDMA_ECTL_NRTGIEN);
++
++ /* Clear VDMA State*/
++ regmap_write(priv->vdma_base, VDMA_ECTL,
++ VDMA_ECTL_DRDY | VDMA_ECTL_NORTG | VDMA_ECTL_DMAHALT);
++}
++
++static int npcm7xx_vdm_hw_init(struct npcm7xx_vdm *priv)
++{
++ int ret = 0;
++ u32 reg_val = 0;
++#ifdef CONFIG_ARCH_NPCM7XX
++ struct regmap *gcr = priv->gcr_base;
++
++ /* Configure PCIE phy selection for bridge */
++ regmap_update_bits(gcr, MFSEL3, MFSEL3_PCIE_PUSE, ~MFSEL3_PCIE_PUSE);
++#endif
++ /* Clear VDM STAT */
++ regmap_write(priv->vdmx_base, VDMX_STATR,
++ VDMX_STATR_RXDR | VDMX_STATR_RXF | VDMX_STATR_TXS);
++
++ /* VDM RESET */
++ regmap_write(priv->vdmx_base, VDMX_CNT, 0);
++ reg_val = VDMX_CNT_RXTO_8US | VDMX_CNT_VDMXEN;
++ regmap_write(priv->vdmx_base, VDMX_CNT, reg_val);
++
++ /* VDM Filter */
++ reg_val = 0;//VDMX_RXFILT_FEN | VDMX_VENDOR_ID;
++ regmap_write(priv->vdmx_base, VDMX_RXFILT, reg_val);
++
++ /* Enable RX int */
++ regmap_write(priv->vdmx_base, VDMX_IEN, VDMX_IEN_RXFEN);
++
++ /* VDMA Disable */
++ regmap_write(priv->vdma_base, VDMA_CTL, 0);
++
++ regmap_write(priv->vdma_base, VDMA_SRCB, VDMX_BA | VDMX_RXF); // src_addr
++ regmap_write(priv->vdma_base, VDMA_DSTB, priv->dma); // dst_addr
++
++ regmap_write(priv->vdma_base, VDMA_ESRCSZ, VDMX_BA | VDMX_STATR); // size_addr
++ regmap_write(priv->vdma_base, VDMA_ERDPNT, priv->dma); // read pointer
++
++ regmap_write(priv->vdma_base, VDMA_EST0AD, VDMX_BA | VDMX_STATR); // address of clear bit
++ regmap_write(priv->vdma_base, VDMA_EST0MK, 0xffffffff);
++ regmap_write(priv->vdma_base, VDMA_EST0DT, VDMX_IEN_RXFEN);
++
++ reg_val = VDMA_ECTL_DRDYEN | VDMA_ECTL_DRDY | VDMA_ECTL_HALTINTEN | VDMA_ECTL_DMAHALT |
++ VDMA_ECTL_RTRGSZ | VDMA_ECTL_ENSTSUP0 | VDMA_ECTL_CYCBUF | VDMA_ECTL_SZMOD_BIT23_16 |
++ ((VDMA_BUFFER_SIZE / SZ_16K) << VDMA_ECTL_BUFFSIZE_POS);
++ regmap_write(priv->vdma_base, VDMA_ECTL, reg_val);
++
++ reg_val = VDMA_CTL_BLOCK_BIT_POS | VDMA_CTL_VDMAEN;
++ regmap_write(priv->vdma_base, VDMA_CTL, reg_val);
++
++ return ret;
++}
++
++static ssize_t npcm7xx_vdm_read(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++ struct mctp_pcie_packet *rx_packet;
++
++ if (buf && count > 0) {
++ rx_packet = ptr_ring_consume_bh(&priv->rx_queue);
++ if (!rx_packet)
++ return -EAGAIN;
++
++ if (count > rx_packet->size)
++ count = rx_packet->size;
++
++ if (copy_to_user(buf, &rx_packet->data, count)) {
++ dev_err(priv->dev, "copy to user failed\n");
++ packet_free(rx_packet);
++ return -EFAULT;
++ }
++
++ packet_free(rx_packet);
++ }
++
++ return count;
++}
++
++static int
++npcm7xx_vdm_send(struct npcm7xx_vdm *priv, u8 *txbuf, int size)
++{
++ u32 timeout, stat;
++ int i, ret = -EIO;
++
++ regmap_read(priv->vdmx_base, VDMX_CNT, &stat);
++ if (stat & VDMX_CNT_VDMXEN) {
++ ret = size;
++
++ for (i = 0; i < size; i += VDMX_TX_LEN)
++ regmap_write(priv->vdmx_base, VDMX_TXF, readl(txbuf + i));
++
++ regmap_update_bits(priv->vdmx_base, VDMX_CNT, VDMX_CNT_TXP, VDMX_CNT_TXP);
++
++ timeout = wait_event_interruptible_timeout(priv->wait_queue,
++ !regmap_read(priv->vdmx_base, VDMX_CNT, &stat) &
++ !(stat & VDMX_CNT_TXP),
++ msecs_to_jiffies(TX_TIMEOUT));
++ if (!timeout) {
++ dev_err(priv->dev, "vdm send timeout 0x%x\n", stat);
++ ret = -EIO;
++ }
++
++ regmap_update_bits(priv->vdmx_base, VDMX_STATR, VDMX_STATR_TXS, VDMX_STATR_TXS);
++ }
++
++ return ret;
++}
++
++static ssize_t npcm7xx_vdm_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++ struct mctp_pcie_packet *tx_packet;
++ int ret;
++
++ if (!access_ok(buf, count)) {
++ ret = -EFAULT;
++ goto out;
++ }
++
++ tx_packet = packet_alloc(GFP_KERNEL);
++ if (!tx_packet) {
++ ret = -ENOMEM;
++ goto out;
++ }
++
++ if (buf && count > 0) {
++ if (count > sizeof(tx_packet->data)) {
++ ret = -ENOSPC;
++ goto out_packet;
++ }
++
++ if (copy_from_user(&tx_packet->data, buf, count)) {
++ dev_err(priv->dev, "copy from user failed\n");
++ ret = -EFAULT;
++ goto out_packet;
++ }
++ tx_packet->size = count;
++
++ ret = npcm7xx_vdm_send(priv, (u8 *)&tx_packet->data, tx_packet->size);
++ }
++
++out_packet:
++ packet_free(tx_packet);
++out:
++ return ret;
++}
++
++static int npcm7xx_vdm_open(struct inode *inode, struct file *file)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++
++ if (atomic_inc_return(&npcm7xx_vdm_open_count) == 1) {
++ if (npcm7xx_vdm_hw_init(priv)) {
++ dev_err(priv->dev, "Failed to init VDM\n");
++ return -EBUSY;
++ }
++
++ local_bh_disable();
++ tasklet_hi_schedule(&priv->tasklet);
++ local_bh_enable();
++
++ return 0;
++ }
++
++ atomic_dec(&npcm7xx_vdm_open_count);
++ return -EBUSY;
++}
++
++static int npcm7xx_vdm_release(struct inode *inode, struct file *file)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++
++ if (atomic_dec_return(&npcm7xx_vdm_open_count) == 0)
++ npcm7xx_vdm_hw_finit(priv);
++
++ return 0;
++}
++
++static __poll_t npcm7xx_vdm_poll(struct file *file,
++ struct poll_table_struct *pt)
++{
++ struct miscdevice *misc = file->private_data;
++ struct platform_device *pdev = to_platform_device(misc->parent);
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++
++ __poll_t ret = 0;
++
++ poll_wait(file, &priv->wait_queue, pt);
++
++ if (__ptr_ring_peek(&priv->rx_queue))
++ ret |= EPOLLIN;
++
++ return ret;
++}
++
++const struct file_operations npcm7xx_vdm_fops = {
++ .llseek = noop_llseek,
++ .open = npcm7xx_vdm_open,
++ .read = npcm7xx_vdm_read,
++ .write = npcm7xx_vdm_write,
++ .release = npcm7xx_vdm_release,
++ .poll = npcm7xx_vdm_poll,
++};
++
++static int npcm7xx_vdm_config_irq(struct npcm7xx_vdm *priv)
++{
++ struct platform_device *pdev = to_platform_device(priv->dev);
++ int irq, ret;
++
++ irq = platform_get_irq(pdev, 0);
++ if (!irq)
++ return -ENODEV;
++
++ ret = devm_request_irq(priv->dev, irq, npcm7xx_vdm_irq, IRQF_SHARED, DEVICE_NAME, priv);
++ if (ret < 0) {
++ dev_err(priv->dev, "Unable to request IRQ %d\n", irq);
++ return ret;
++ }
++
++ return 0;
++}
++
++static void npcm7xx_vdm_tsk_init(struct npcm7xx_vdm *priv)
++{
++ spin_lock_init(&priv->lock);
++ init_waitqueue_head(&priv->wait_queue);
++
++ ptr_ring_init(&priv->rx_queue, VDMX_RX_LEN, GFP_ATOMIC);
++
++ tasklet_init(&priv->tasklet, npcm7xx_vdm_rx_tasklet,
++ (unsigned long)priv);
++}
++
++static void npcm7xx_vdm_tsk_fini(struct npcm7xx_vdm *priv)
++{
++ tasklet_disable(&priv->tasklet);
++ tasklet_kill(&priv->tasklet);
++}
++
++static const struct regmap_config npcm7xx_vdmx_regmap_cfg = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .max_register = VDMX_RXFILT,
++};
++
++static const struct regmap_config npcm7xx_vdma_regmap_cfg = {
++ .reg_bits = 32,
++ .reg_stride = 4,
++ .val_bits = 32,
++ .max_register = VDMA_EST1DT,
++};
++
++static int npcm7xx_vdm_resources_init(struct npcm7xx_vdm *priv)
++{
++ struct platform_device *pdev = to_platform_device(priv->dev);
++
++ void __iomem *regs;
++
++ regs = devm_platform_ioremap_resource(pdev, 0);
++ if (IS_ERR(regs)) {
++ dev_err(priv->dev, "Failed to get regmap!\n");
++ return PTR_ERR(regs);
++ }
++
++ priv->vdmx_base = devm_regmap_init_mmio(priv->dev, regs,
++ &npcm7xx_vdmx_regmap_cfg);
++ if (IS_ERR(priv->vdmx_base))
++ return PTR_ERR(priv->vdmx_base);
++
++ regs = devm_platform_ioremap_resource(pdev, 1);
++ if (IS_ERR(regs)) {
++ dev_err(priv->dev, "Failed to get regmap!\n");
++ return PTR_ERR(regs);
++ }
++
++ priv->vdma_base = devm_regmap_init_mmio(priv->dev, regs,
++ &npcm7xx_vdma_regmap_cfg);
++ if (IS_ERR(priv->vdma_base))
++ return PTR_ERR(priv->vdma_base);
++
++#ifdef CONFIG_ARCH_NPCM7XX
++ priv->gcr_base =
++ syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
++ if (IS_ERR(priv->gcr_base)) {
++ dev_err(priv->dev, "failed to find nuvoton,npcm750-gcr\n");
++ return PTR_ERR(priv->gcr_base);
++ }
++#endif
++ platform_set_drvdata(pdev, priv);
++
++ return 0;
++}
++
++static int npcm7xx_vdm_dma_init(struct npcm7xx_vdm *priv)
++{
++ priv->virt = dma_alloc_coherent(priv->dev, VDMA_BUFFER_SIZE,
++ &priv->dma, GFP_KERNEL);
++ if (!priv->virt)
++ return -ENOMEM;
++
++ return 0;
++}
++
++static void npcm7xx_vdm_dma_fini(struct npcm7xx_vdm *priv)
++{
++ dma_free_coherent(priv->dev, VDMA_BUFFER_SIZE,
++ priv->virt, priv->dma);
++}
++
++struct device_type npcm7xx_vdm_type = {
++ .name = DEVICE_NAME,
++};
++
++static struct miscdevice npcm7xx_vdm_miscdev = {
++ .minor = MISC_DYNAMIC_MINOR,
++ .name = DEVICE_NAME,
++ .fops = &npcm7xx_vdm_fops,
++};
++
++static int npcm_vdm_probe(struct platform_device *pdev)
++{
++ struct npcm7xx_vdm *priv;
++ int ret;
++
++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++ if (!priv) {
++ ret = -ENOMEM;
++ goto out;
++ }
++ priv->dev = &pdev->dev;
++ dev_set_drvdata(&pdev->dev, priv);
++
++ ret = npcm7xx_vdm_resources_init(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to init resources\n");
++ goto out_drv;
++ }
++
++ ret = npcm7xx_vdm_dma_init(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to init DMA\n");
++ goto out_drv;
++ }
++
++ /* register miscdev */
++ npcm7xx_vdm_miscdev.parent = priv->dev;
++ ret = misc_register(&npcm7xx_vdm_miscdev);
++ if (ret) {
++ dev_err(priv->dev, "Failed to register miscdev\n");
++ goto out_dma;
++ }
++ npcm7xx_vdm_miscdev.this_device->type = &npcm7xx_vdm_type;
++
++ npcm7xx_vdm_hw_finit(priv);
++
++ npcm7xx_vdm_tsk_init(priv);
++
++ ret = npcm7xx_vdm_config_irq(priv);
++ if (ret) {
++ dev_err(priv->dev, "Failed to configure IRQ\n");
++ goto out_dma;
++ }
++
++ pr_info("NPCM7XX VDM Driver probed\n");
++
++ return 0;
++
++out_dma:
++ npcm7xx_vdm_dma_fini(priv);
++out_drv:
++ npcm7xx_vdm_tsk_fini(priv);
++out:
++ dev_err(priv->dev, "Failed to probe Nuvoton VDM: %d\n", ret);
++ return ret;
++}
++
++static int npcm_vdm_remove(struct platform_device *pdev)
++{
++ struct npcm7xx_vdm *priv = platform_get_drvdata(pdev);
++
++ if (!priv)
++ return 0;
++
++ misc_deregister(&npcm7xx_vdm_miscdev);
++
++ ptr_ring_cleanup(&priv->rx_queue, &packet_free);
++
++ npcm7xx_vdm_hw_finit(priv);
++
++ npcm7xx_vdm_dma_fini(priv);
++
++ npcm7xx_vdm_tsk_fini(priv);
++
++ kfree(priv);
++
++ return 0;
++}
++
++static const struct of_device_id npcm7xx_vdm_match[] = {
++ { .compatible = "nuvoton,npcm750-vdm", },
++ { .compatible = "nuvoton,npcm845-vdm", },
++ {},
++};
++
++static struct platform_driver npcm_vdm_driver = {
++ .probe = npcm_vdm_probe,
++ .remove = npcm_vdm_remove,
++ .driver = {
++ .name = DEVICE_NAME,
++ .owner = THIS_MODULE,
++ .of_match_table = npcm7xx_vdm_match,
++ },
++};
++
++static int __init npcm_vdm_init(void)
++{
++ packet_cache =
++ kmem_cache_create_usercopy("mctp-packet",
++ sizeof(struct mctp_pcie_packet),
++ 0, 0, 0,
++ sizeof(struct mctp_pcie_packet),
++ NULL);
++ if (!packet_cache)
++ return -ENOMEM;
++
++ return platform_driver_register(&npcm_vdm_driver);
++}
++
++static void __exit npcm_vdm_exit(void)
++{
++ platform_driver_unregister(&npcm_vdm_driver);
++ kmem_cache_destroy(packet_cache);
++}
++
++module_init(npcm_vdm_init)
++module_exit(npcm_vdm_exit)
++
++MODULE_DEVICE_TABLE(of, npcm7xx_vdm_match);
++MODULE_AUTHOR("Nuvoton Technology Corp.");
++MODULE_DESCRIPTION("VDM Master Driver");
++MODULE_LICENSE("GPL");
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/defconfig b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/defconfig
new file mode 100644
index 0000000..cbc3fd2
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/defconfig
@@ -0,0 +1,130 @@
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=21
+CONFIG_CGROUPS=y
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_ARCH_NPCM=y
+CONFIG_ARCH_NPCM7XX=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_3G_OPT=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_SHA512=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_DEVTMPFS=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_PARTITIONED_MASTER=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_OF_OVERLAY=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NPCM7XX_LPC_BPC=y
+CONFIG_NPCM7XX_PCI_MBOX=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_NPCM7XX_EMC_ETH=y
+CONFIG_STMMAC_ETH=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_NPCM7XX_KCS_IPMI_BMC=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_NPCM7XX=y
+CONFIG_SPI=y
+CONFIG_SPI_NPCM_FIU=y
+CONFIG_SPI_NPCM_PSPI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_NPCM7XX=y
+CONFIG_SENSORS_TMP102=y
+CONFIG_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_EDAC=y
+# CONFIG_EDAC_LEGACY_SYSFS is not set
+CONFIG_EDAC_NPCM7XX=y
+CONFIG_IIO=y
+CONFIG_NPCM_ADC=y
+CONFIG_IIO_MUX=y
+CONFIG_RAS=y
+CONFIG_MUX_MMIO=y
+CONFIG_OVERLAY_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=y
+CONFIG_CIFS_XATTR=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_READABLE_ASM=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_FUNCTION_TRACER=y
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/npcm8xx_defconfig b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/npcm8xx_defconfig
new file mode 100644
index 0000000..fb6009d
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/npcm8xx_defconfig
@@ -0,0 +1,188 @@
+CONFIG_SYSVIPC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_NPCM=y
+CONFIG_ARCH_NPCM8XX=y
+CONFIG_SMP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_OF_OVERLAY=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NPCM7XX_LPC_BPC=y
+CONFIG_NPCM7XX_PCI_MBOX=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_STMMAC_ETH=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_PINCTRL_NPCM8XX=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I2C_NPCM7XX=y
+CONFIG_I3C=y
+CONFIG_I3CDEV=y
+CONFIG_SVC_I3C_MASTER=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_NPCM7XX_KCS_IPMI_BMC=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_NPCM=y
+CONFIG_SPI=y
+CONFIG_SPI_NPCM_PSPI=y
+CONFIG_SPI_NPCM_FIU=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SENSORS_NPCM8XX=y
+CONFIG_SENSORS_TMP102=y
+CONFIG_WATCHDOG=y
+CONFIG_NPCM7XX_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_NPCM_UDC=y
+CONFIG_USB_GADGET_NPCM_USB2=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_NPCM750=y
+CONFIG_ROMFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_DEV_NPCM=y
+CONFIG_CRYPTO_DEV_NPCM_AES=y
+CONFIG_CRYPTO_DEV_NPCM_SHA=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_NPCM750_OTP=y
+CONFIG_ARM_CRYPTO=y
+CONFIG_PCI=y
+CONFIG_PCIE_NPCM=y
+CONFIG_PECI=y
+CONFIG_PECI_NPCM=y
+CONFIG_MFD_INTEL_PECI_CLIENT=y
+CONFIG_SENSORS_PECI_CPUTEMP=y
+CONFIG_SENSORS_PECI_DIMMTEMP=y
+CONFIG_RESET_NPCM=y
+CONFIG_SENSORS_NPCM7XX=y
+
+CONFIG_IPMI_KCS_BMC=y
+CONFIG_NPCM7XX_KCS_IPMI_BMC=y
+CONFIG_NPCM_VDM=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_NPCM_THERMAL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_TMPFS=y
+CONFIG_EXPERT=y
+
+# Enable KVM Support
+CONFIG_NPCM750_VCD=y
+CONFIG_NPCM750_ECE=y
+
+# Enable JTAG Master Support
+CONFIG_NPCM8XX_JTAG_MASTER=y
+
+# Enable OpenBMC FS support
+CONFIG_OVERLAY_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_DEBUG_FS=y
+
+# Enable EDAC support
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EDAC=y
+CONFIG_EDAC_NPCM8XX=y
+CONFIG_RAS=y
+
+# Enable RemotePorc driver support
+CONFIG_REMOTEPROC=y
+CONFIG_NPCM8XX_REMOTEPROC=y
+
+# Enable SGPIO Driver support
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_NUVOTON_SGPIO=y
+
+# Enable ADC
+CONFIG_NPCM_ADC=y
+CONFIG_IIO=y
+CONFIG_SENSORS_IIO_HWMON=y
+
+# CONFIG_VGA_ARB is not set
+# CONFIG_VGA_ARB_MAX_GPUS is not set
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/v4l2.cfg b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/v4l2.cfg
new file mode 100644
index 0000000..50f53a2
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton/v4l2.cfg
@@ -0,0 +1,13 @@
+CONFIG_CMA=y
+CONFIG_CMA_AREAS=7
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_NUVOTON=y
diff --git a/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton_git.bb b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton_git.bb
new file mode 100644
index 0000000..224898e
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-kernel/linux/linux-nuvoton_git.bb
@@ -0,0 +1,21 @@
+
+#KBRANCH ?= "dev-5.14"
+#LINUX_VERSION ?= "5.14"
+#SRCREV="e2413239f9a751a2a7491569d27dce76773f2777"
+
+KBRANCH ?= "NPCM-5.10-OpenBMC"
+LINUX_VERSION ?= "5.10.67"
+SRCREV = "12abb777ddcade8549704016eb1c233244892355"
+
+require linux-nuvoton.inc
+
+SRC_URI:append:nuvoton = " file://0003-i2c-nuvoton-npcm750-runbmc-integrate-the-slave-mqueu.patch"
+SRC_URI:append:nuvoton = " file://0004-driver-ncsi-replace-del-timer-sync.patch"
+SRC_URI:append:nuvoton = " file://0015-driver-misc-nuvoton-vdm-support-openbmc-libmctp.patch"
+SRC_URI:append:nuvoton = " file://0017-drivers-i2c-workaround-for-i2c-slave-behavior.patch"
+
+# V4L2 VCD driver
+# SRC_URI:append:nuvoton = " file://v4l2.cfg"
+
+# New Arch VDMX/VDMA driver
+# SRC_URI:append:nuvoton = " file://2222-driver-misc-add-nuvoton-vdmx-vdma-driver.patch"
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-update.service b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-update.service
new file mode 100644
index 0000000..95ba4bd
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-update.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=NPCM7xx MCU F/W update service
+
+[Service]
+ExecStart=/usr/bin/loadmcu -d /dev/mcu0 -s /tmp/image-mcu
+Type=oneshot
+ExecStopPost=/bin/systemctl start mcu-version@* --all
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version.sh b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version.sh
new file mode 100644
index 0000000..b855aa7
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+sleep 1
+
+i2c_bus=$(echo $1)
+
+# get mcu firmware version
+version=$(i2ctransfer -f -y $i2c_bus w2@0x70 0x01 0x30 r2)
+
+# parse mcu firmware major revision
+major=`echo $version | awk '{print$2}'`
+
+# parse mcu firmware minor revision
+minor=`echo $version | awk '{print$1}'`
+
+version="V`echo $((major))`.`echo $((minor))`"
+
+if [ $version != "V0.0" ]; then
+ echo "VERSION_ID=$version" > /var/lib/phosphor-bmc-code-mgmt/mcu-release
+else
+ echo "VERSION_ID=N/A" > /var/lib/phosphor-bmc-code-mgmt/mcu-release
+fi
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version@.service b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version@.service
new file mode 100644
index 0000000..6e622ef
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/files/mcu-version@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=NPCM7xx MCU F/W version service
+Requires=xyz.openbmc_project.Software.BMC.Updater.service
+Before=xyz.openbmc_project.Software.BMC.Updater.service
+
+[Service]
+Restart=no
+Type=oneshot
+ExecStart=/usr/bin/mcu-version.sh %i
+SyslogIdentifier=mcu-version.sh
+
+[Install]
+WantedBy={SYSTEMD_DEFAULT_TARGET}
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/loadmcu.bb b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/loadmcu.bb
new file mode 100644
index 0000000..cbd08ee
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadmcu/loadmcu.bb
@@ -0,0 +1,31 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}:"
+DESCRIPTION = "MCU F/W Programmer"
+PR = "r1"
+
+LICENSE = "GPL-2.0-or-later"
+LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+inherit systemd
+inherit obmc-phosphor-systemd
+inherit autotools pkgconfig
+
+DEPENDS += "systemd"
+DEPENDS += "autoconf-archive-native"
+RDEPENDS:${PN} += "bash"
+
+SRC_URI = "git://github.com/Nuvoton-Israel/loadmcu.git;branch=master;protocol=https \
+ file://mcu-update.service \
+ file://mcu-version.sh \
+ file://mcu-version@.service \
+ "
+SRCREV = "12fed94b53f6fa0fe1c96bee264c7e363f2ed7d8"
+S = "${WORKDIR}/git"
+
+SYSTEMD_PACKAGES = "${PN}"
+SYSTEMD_SERVICE:${PN} = "mcu-update.service mcu-version@.service"
+SYSTEMD_SERVICE:${PN} += "mcu-version@13.service"
+
+do_install:append() {
+ install -d ${D}${bindir}
+ install -m 0755 ${WORKDIR}/mcu-version.sh ${D}${bindir}/
+}
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/loadsvf/loadsvf_git.bb b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadsvf/loadsvf_git.bb
new file mode 100644
index 0000000..956ffa8
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/loadsvf/loadsvf_git.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "CPLD/FPGA Programmer"
+PR = "r1"
+
+LICENSE = "GPL-2.0-or-later"
+LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+SRC_URI = "git://github.com/Nuvoton-Israel/loadsvf.git;branch=master;protocol=https"
+SRCREV = "f2296005cbba13b49e5163340cac80efbec9cdf4"
+S = "${WORKDIR}/git"
+
+inherit autotools pkgconfig
+
+DEPENDS += "autoconf-archive-native"
+
diff --git a/meta-nuvoton-npcm8xx/recipes-nuvoton/nuvoton-ipmi/nuvoton-ipmi-oem_git.bb b/meta-nuvoton-npcm8xx/recipes-nuvoton/nuvoton-ipmi/nuvoton-ipmi-oem_git.bb
new file mode 100644
index 0000000..d0c7314
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-nuvoton/nuvoton-ipmi/nuvoton-ipmi-oem_git.bb
@@ -0,0 +1,28 @@
+SUMMARY = "Nuvoton IPMI OEM command library"
+DESCRIPTION = "Nuvoton IPMI OEM command library"
+HOMEPAGE = "https://github.com/nuvoton-ipmi-oem"
+PR = "r1"
+PV = "0.1+git${SRCPV}"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=ce3556061e8d4b01638d497053a82dfd"
+
+inherit autotools pkgconfig
+inherit obmc-phosphor-ipmiprovider-symlink
+
+DEPENDS += "autoconf-archive-native"
+DEPENDS += "sdbusplus"
+DEPENDS += "phosphor-logging"
+DEPENDS += "phosphor-ipmi-host"
+DEPENDS += "nlohmann-json"
+
+S = "${WORKDIR}/git"
+SRCBRANCH = "master"
+SRC_URI = "git://github.com/Nuvoton-Israel/nuvoton-ipmi-oem;protocol=https;branch=${SRCBRANCH}"
+SRCREV = "50d80e64a01d933c10484da63b447d6a27b8b702"
+
+FILES:${PN}:append = " ${libdir}/ipmid-providers/lib*${SOLIBS}"
+FILES:${PN}:append = " ${libdir}/host-ipmid/lib*${SOLIBS}"
+FILES:${PN}:append = " ${libdir}/net-ipmid/lib*${SOLIBS}"
+FILES:${PN}-dev:append = " ${libdir}/ipmid-providers/lib*${SOLIBSDEV} ${libdir}/ipmid-providers/*.la"
+
+HOSTIPMI_PROVIDER_LIBRARY += "libnuvoemcmds.so"
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Use-numeric-limit-is-intergral-replace-std-is-intergral.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Use-numeric-limit-is-intergral-replace-std-is-intergral.patch
new file mode 100644
index 0000000..c3a521d
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Use-numeric-limit-is-intergral-replace-std-is-intergral.patch
@@ -0,0 +1,34 @@
+diff --git a/include/ipmid/message/pack.hpp b/include/ipmid/message/pack.hpp
+index 00750007..9c45d514 100644
+--- a/include/ipmid/message/pack.hpp
++++ b/include/ipmid/message/pack.hpp
+@@ -77,7 +77,7 @@ struct PackSingle
+ */
+ static int op(Payload& p, const T& t)
+ {
+- static_assert(std::is_integral_v<T>,
++ static_assert(std::numeric_limits<T>::is_integer,
+ "Attempt to pack a type that has no IPMI pack operation");
+ // if not on a byte boundary, must pack values LSbit/LSByte first
+ if (p.bitCount)
+diff --git a/include/ipmid/message/unpack.hpp b/include/ipmid/message/unpack.hpp
+index 4ac49165..3f9c6832 100644
+--- a/include/ipmid/message/unpack.hpp
++++ b/include/ipmid/message/unpack.hpp
+@@ -16,6 +16,7 @@
+ #pragma once
+
+ #include <array>
++#include <boost/type_traits/is_fundamental.hpp>
+ #include <ipmid/message/types.hpp>
+ #include <optional>
+ #include <string>
+@@ -74,7 +75,7 @@ struct UnpackSingle
+ */
+ static int op(Payload& p, T& t)
+ {
+- if constexpr (std::is_fundamental<T>::value)
++ if constexpr (std::numeric_limits<T>::is_integer)
+ {
+ t = 0;
+ if (p.bitCount)
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
new file mode 100644
index 0000000..eba096e
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
@@ -0,0 +1,4 @@
+FILESEXTRAPATHS:append:nuvoton := "${THISDIR}/${PN}:"
+
+# Fix static assert build break
+SRC_URI:append:nuvoton = " file://0001-Use-numeric-limit-is-intergral-replace-std-is-intergral.patch"
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch
new file mode 100644
index 0000000..00b739b
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch
@@ -0,0 +1,42 @@
+From 1c23639acdbc68b36b30ed0ef9d3922142985975 Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Tue, 12 May 2020 17:01:29 +0800
+Subject: [PATCH] novnc: add 16-bit hextile support for nuvoton ece engine
+
+Signed-off-by: Joseph Liu <kwliu@nuvoton.com>
+---
+ package-lock.json | 4 ++--
+ package.json | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/package-lock.json b/package-lock.json
+index 47b22a2e..054ca32f 100644
+--- a/package-lock.json
++++ b/package-lock.json
+@@ -935,8 +935,8 @@
+ }
+ },
+ "@novnc/novnc": {
+- "version": "git+https://github.com/novnc/noVNC.git#25b3d49d322b0a7c9ee1e071d93042d70f5176b7",
+- "from": "@novnc/novnc@git+https://github.com/novnc/noVNC.git#25b3d49d322b0a7c9ee1e071d93042d70f5176b7"
++ "version": "Nuvoton-Israel/noVNC.git#openbmc-v1.2.0",
++ "from": "@novnc/novnc@Nuvoton-Israel/noVNC.git#openbmc-v1.2.0"
+ },
+ "@types/anymatch": {
+ "version": "1.3.1",
+diff --git a/package.json b/package.json
+index 7e808df4..517f86e0 100644
+--- a/package.json
++++ b/package.json
+@@ -35,7 +35,7 @@
+ "node"
+ ],
+ "dependencies": {
+- "@novnc/novnc": "git+https://github.com/novnc/noVNC.git#25b3d49d322b0a7c9ee1e071d93042d70f5176b7",
++ "@novnc/novnc": "Nuvoton-Israel/noVNC.git#openbmc-v1.1.0",
+ "angular": "1.7.9",
+ "angular-animate": "1.7.9",
+ "angular-clipboard": "1.7.0",
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0002-support-pldm-sensors-effecters.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0002-support-pldm-sensors-effecters.patch
new file mode 100644
index 0000000..e2c49a3
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0002-support-pldm-sensors-effecters.patch
@@ -0,0 +1,888 @@
+commit 61623e4129178233eeaf5a0f0e7013271f5a88d2
+Author: Medad CChien <ctcchien@nuvoton.com>
+Date: Mon Mar 15 09:38:57 2021 +0800
+
+ support pldm sensors and effecters
+
+ Signed-off-by: Medad CChien <ctcchien@nuvoton.com>
+
+diff --git a/app/common/directives/app-navigation.html b/app/common/directives/app-navigation.html
+index 41441e27..04fa60eb 100644
+--- a/app/common/directives/app-navigation.html
++++ b/app/common/directives/app-navigation.html
+@@ -27,6 +27,11 @@
+ <span>Sensors</span>
+ </a>
+ </li>
++ <li ng-class="{'active': (path == '/server-health/pldm-overview' || path == '/server-health/pldm')}">
++ <a href="#/server-health/pldm-overview" tabindex="{{(showHealthMenu) ? 0 : -1}}">
++ <span>PLDM</span>
++ </a>
++ </li>
+ </ul>
+ </li>
+ <li ng-class="{opened: showControlMenu}">
+@@ -116,4 +121,4 @@
+ </ul>
+ </li>
+ </ul>
+-</nav>
+\ No newline at end of file
++</nav>
+diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
+index f10476d8..2a1fd1f8 100644
+--- a/app/common/services/api-utils.js
++++ b/app/common/services/api-utils.js
+@@ -1051,6 +1051,359 @@ window.angular && (function(angular) {
+ console.log(error);
+ });
+ },
++ getAllNumericSensorStatus: function(callback) {
++ $http({
++ method: 'GET',
++ url: DataService.getHost() +
++ '/xyz/openbmc_project/numericsensors/enumerate',
++ withCredentials: true
++ })
++ .then(
++ function(response) {
++ var json = JSON.stringify(response.data);
++ var content = JSON.parse(json);
++ var dataClone = JSON.parse(JSON.stringify(content.data));
++ var sensorData = [];
++ var severity = {};
++ var title = '';
++ var tempKeyParts = [];
++ var order = 0;
++ var customOrder = 0;
++
++ function getSensorStatus(reading) {
++ var severityFlags = {
++ critical: false,
++ warning: false,
++ normal: false
++ },
++ severityText = '', order = 0;
++
++ if (reading.hasOwnProperty('CriticalLow') &&
++ reading.Value < reading.CriticalLow) {
++ severityFlags.critical = true;
++ severityText = 'critical';
++ order = 2;
++ } else if (
++ reading.hasOwnProperty('CriticalHigh') &&
++ reading.Value > reading.CriticalHigh) {
++ severityFlags.critical = true;
++ severityText = 'critical';
++ order = 2;
++ } else if (
++ reading.hasOwnProperty('CriticalLow') &&
++ reading.hasOwnProperty('WarningLow') &&
++ reading.Value >= reading.CriticalLow &&
++ reading.Value <= reading.WarningLow) {
++ severityFlags.warning = true;
++ severityText = 'warning';
++ order = 1;
++ } else if (
++ reading.hasOwnProperty('WarningHigh') &&
++ reading.hasOwnProperty('CriticalHigh') &&
++ reading.Value >= reading.WarningHigh &&
++ reading.Value <= reading.CriticalHigh) {
++ severityFlags.warning = true;
++ severityText = 'warning';
++ order = 1;
++ } else {
++ severityFlags.normal = true;
++ severityText = 'normal';
++ }
++ return {
++ flags: severityFlags,
++ severityText: severityText,
++ order: order
++ };
++ }
++
++ for (var key in content.data) {
++ if (content.data.hasOwnProperty(key) &&
++ content.data[key].hasOwnProperty('Unit')) {
++ severity = getSensorStatus(content.data[key]);
++
++ if (!content.data[key].hasOwnProperty('CriticalLow')) {
++ content.data[key].CriticalLow = '--';
++ content.data[key].CriticalHigh = '--';
++ }
++
++ if (!content.data[key].hasOwnProperty('WarningLow')) {
++ content.data[key].WarningLow = '--';
++ content.data[key].WarningHigh = '--';
++ }
++
++ tempKeyParts = key.split('/');
++ title = tempKeyParts.pop();
++ title = tempKeyParts.pop() + '_' + title;
++ title = title.split('_')
++ .map(function(item) {
++ return item.toLowerCase()
++ .charAt(0)
++ .toUpperCase() +
++ item.slice(1);
++ })
++ .reduce(function(prev, el) {
++ return prev + ' ' + el;
++ });
++
++ if (Constants.SENSOR_SORT_ORDER.indexOf(
++ content.data[key].Unit) > -1) {
++ customOrder = Constants.SENSOR_SORT_ORDER.indexOf(
++ content.data[key].Unit);
++ } else {
++ customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
++ }
++
++ sensorData.push(Object.assign(
++ {
++ path: key,
++ selected: false,
++ confirm: false,
++ copied: false,
++ title: title,
++ unit:
++ Constants
++ .SENSOR_UNIT_MAP[content.data[key].Unit],
++ severity_flags: severity.flags,
++ status: severity.severityText,
++ order: severity.order,
++ custom_order: customOrder,
++ search_text:
++ (title + ' ' + content.data[key].Value + ' ' +
++ Constants.SENSOR_UNIT_MAP[content.data[key]
++ .Unit] +
++ ' ' + severity.severityText + ' ' +
++ content.data[key].CriticalLow + ' ' +
++ content.data[key].CriticalHigh + ' ' +
++ content.data[key].WarningLow + ' ' +
++ content.data[key].WarningHigh + ' ')
++ .toLowerCase(),
++ original_data:
++ {key: key, value: content.data[key]}
++ },
++ content.data[key]));
++ }
++ }
++
++ sensorData.sort(function(a, b) {
++ return a.title.localeCompare(
++ b.title, 'en', {numeric: true});
++ });
++
++ callback(sensorData, dataClone);
++ },
++ function(error) {
++ console.log(error);
++ });
++ },
++ toggleEffecterState: function(path, state) {
++ return $http({
++ method: 'PUT',
++ url: DataService.getHost() + path + '/attr/setDeviceState',
++ //url: DataService.getHost() + '/xyz/openbmc_project/effecters/GPIO/PLDM_GPIO91' + '/attr/setDeviceState',
++ //url: DataService.getHost() + '/xyz/openbmc_project/numericeffecters/FAN_PWM/PLDM_FAN_PWM1' + '/attr/setNumericValue',
++ withCredentials: true,
++ data: JSON.stringify({'data': state})
++ })
++ .then(function(response) {
++ return response.data;
++ });
++ },
++ setEffecterValue: function(path, value) {
++ return $http({
++ method: 'PUT',
++ url: DataService.getHost() + path + '/attr/setNumericValue',
++ //url: DataService.getHost() + '/xyz/openbmc_project/numericeffecters/FAN_PWM/PLDM_FAN_PWM1' + '/attr/setNumericValue',
++ //url: DataService.getHost() + '/xyz/openbmc_project/numericeffecters/FAN_PWM/PLDM_FAN_PWM1' + '/attr/setDeviceState',
++ withCredentials: true,
++ data: JSON.stringify({'data': value})
++ })
++ .then(function(response) {
++ return response.data;
++ });
++ },
++ getAllEffecterStatus: function(callback) {
++ $http({
++ method: 'GET',
++ url: DataService.getHost() +
++ '/xyz/openbmc_project/stateeffecters/enumerate',
++ withCredentials: true
++ })
++ .then(
++ function(response) {
++ var json = JSON.stringify(response.data);
++ var content = JSON.parse(json);
++ var dataClone = JSON.parse(JSON.stringify(content.data));
++ var effecterData = [];
++ var title = '';
++ var tempKeyParts = [];
++
++ for (var key in content.data) {
++ if (content.data.hasOwnProperty(key)) {
++
++ tempKeyParts = key.split('/');
++ title = tempKeyParts.pop();
++ title = tempKeyParts.pop() + '_' + title;
++ title = title.split('_')
++ .map(function(item) {
++ return item.toLowerCase()
++ .charAt(0)
++ .toUpperCase() +
++ item.slice(1);
++ })
++ .reduce(function(prev, el) {
++ return prev + ' ' + el;
++ });
++
++ effecterData.push(Object.assign(
++ {
++ path: key,
++ selected: false,
++ confirm: false,
++ copied: false,
++ title: title,
++ search_text:
++ (title + ' ' + content.data[key].Value + ' ')
++ .toLowerCase(),
++ original_data:
++ {key: key, value: content.data[key]}
++ },
++ content.data[key]));
++ }
++ }
++
++ effecterData.sort(function(a, b) {
++ return a.title.localeCompare(
++ b.title, 'en', {numeric: true});
++ });
++
++ callback(effecterData, dataClone);
++ },
++ function(error) {
++ console.log(error);
++ });
++ },
++ getAllNumericEffecterStatus: function(callback) {
++ $http({
++ method: 'GET',
++ url: DataService.getHost() +
++ '/xyz/openbmc_project/numericeffecters/enumerate',
++ withCredentials: true
++ })
++ .then(
++ function(response) {
++ var json = JSON.stringify(response.data);
++ var content = JSON.parse(json);
++ var dataClone = JSON.parse(JSON.stringify(content.data));
++ var statesensorData = [];
++ var title = '';
++ var tempKeyParts = [];
++
++ for (var key in content.data) {
++ if (content.data.hasOwnProperty(key)) {
++
++ tempKeyParts = key.split('/');
++ title = tempKeyParts.pop();
++ title = tempKeyParts.pop() + '_' + title;
++ title = title.split('_')
++ .map(function(item) {
++ return item.toLowerCase()
++ .charAt(0)
++ .toUpperCase() +
++ item.slice(1);
++ })
++ .reduce(function(prev, el) {
++ return prev + ' ' + el;
++ });
++
++ statesensorData.push(Object.assign(
++ {
++ path: key,
++ selected: false,
++ confirm: false,
++ copied: false,
++ title: title,
++ search_text:
++ (title + ' ' + content.data[key].Value + ' ')
++ .toLowerCase(),
++ original_data:
++ {key: key, value: content.data[key]}
++ },
++ content.data[key]));
++ }
++ }
++
++ statesensorData.sort(function(a, b) {
++ return a.title.localeCompare(
++ b.title, 'en', {numeric: true});
++ });
++
++ callback(statesensorData, dataClone);
++ },
++ function(error) {
++ console.log(error);
++ });
++ },
++ getAllStateSensorStatus: function(callback) {
++ $http({
++ method: 'GET',
++ url: DataService.getHost() +
++ '/xyz/openbmc_project/statesensors/enumerate',
++ withCredentials: true
++ })
++ .then(
++ function(response) {
++ var json = JSON.stringify(response.data);
++ var content = JSON.parse(json);
++ var dataClone = JSON.parse(JSON.stringify(content.data));
++ var statesensorData = [];
++ var title = '';
++ var tempKeyParts = [];
++
++ for (var key in content.data) {
++ if (content.data.hasOwnProperty(key)) {
++
++ tempKeyParts = key.split('/');
++ title = tempKeyParts.pop();
++ title = tempKeyParts.pop() + '_' + title;
++ title = title.split('_')
++ .map(function(item) {
++ return item.toLowerCase()
++ .charAt(0)
++ .toUpperCase() +
++ item.slice(1);
++ })
++ .reduce(function(prev, el) {
++ return prev + ' ' + el;
++ });
++
++ statesensorData.push(Object.assign(
++ {
++ path: key,
++ selected: false,
++ confirm: false,
++ copied: false,
++ title: title,
++ search_text:
++ (title + ' ' + content.data[key].Value + ' ')
++ .toLowerCase(),
++ original_data:
++ {key: key, value: content.data[key]}
++ },
++ content.data[key]));
++ }
++ }
++
++ statesensorData.sort(function(a, b) {
++ return a.title.localeCompare(
++ b.title, 'en', {numeric: true});
++ });
++
++ callback(statesensorData, dataClone);
++ },
++ function(error) {
++ console.log(error);
++ });
++ },
+ getActivation: function(imageId) {
+ return $http({
+ method: 'GET',
+diff --git a/app/index.js b/app/index.js
+index 156fab6b..fa0d9e6f 100644
+--- a/app/index.js
++++ b/app/index.js
+@@ -98,6 +98,7 @@ import server_health_index from './server-health/index.js';
+ import inventory_overview_controller from './server-health/controllers/inventory-overview-controller.js';
+ import log_controller from './server-health/controllers/log-controller.js';
+ import sensors_overview_controller from './server-health/controllers/sensors-overview-controller.js';
++import pldm_overview_controller from './server-health/controllers/pldm-overview-controller.js';
+ import syslog_controller from './server-health/controllers/syslog-controller.js';
+ import syslog_filter from './common/directives/syslog-filter.js';
+ import remote_logging_server from './server-health/directives/remote-logging-server.js';
+diff --git a/app/server-health/controllers/pldm-overview-controller.html b/app/server-health/controllers/pldm-overview-controller.html
+new file mode 100644
+index 00000000..1c55677b
+--- /dev/null
++++ b/app/server-health/controllers/pldm-overview-controller.html
+@@ -0,0 +1,274 @@
++<loader loading="loading"></loader>
++<div id="stateeffecters" class="sensors">
++ <h1>State Effecters</h1>
++ <div class="page-header">
++ <h2 class="inline">All state effecters present in the system</h2>
++ <a ng-href="data_state_effecter:text/json;charset=utf-8,{{export_data_state_effecter}}" class="btn btn-tertiary float-right" download="{{export_name_state_effecter}}"><icon file="icon-export.svg"></icon>Export</a>
++ </div>
++ <table id="sensor-categories" class="sensors__table" cellpadding="0" cellspacing="0" ng-show="filteredStateEffecterData.length">
++ <thead class="sensors__thead fixed-table-header">
++ <tr class="sensors__thead-row">
++ <th class="sensors__thead-cell">State Effecters ({{filteredStateEffecterData.length}})<th>
++ <th class="sensors__thead-cell">Previous State<th>
++ <th class="sensors__thead-cell sensor__heading-current">Present State<th>
++ <th class="sensors__thead-cell">Operational State<th>
++ <th class="sensors__thead-cell">Event State<th>
++ <th class="sensors__thead-cell">Toggle State<th>
++ </tr>
++ </thead>
++ <tbody class="sensors__tbody">
++ <tr class="sensors__tbody-row" ng-repeat="state_effecter in data_state_effecter as filteredStateEffecterData">
++ <th class="sensors__tbody-header">
++ <span>{{state_effecter.title}}</span>
++ </th>
++
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Previous State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_effecter.previous_state}}</span>
++ </span>
++ </td>
++
++ <td class="sensors__tbody-cell sensors__tbody-current" ng-class="{'sensors__tbody-current--normal': state_effecter.status == 'normal'}">
++ <span class="sensors__tbody-cell__title">Present State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_effecter.present_state}}</span>
++ </span>
++ </td>
++
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Operational State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_effecter.effecterOperationalState}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Event State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_effecter.event_state}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Toggle State</span>
++ <span class="sensors__tbody-cell__content">
++ <button class="btn" ng-class="state_effecter.present_state == state_effecter.effecterOperationalState ? 'btn-primary' : 'btn-secondary'" ng-click="toggleEffecterState(state_effecter)">Toggle
++ </button>
++ </span>
++ </td>
++ </tr>
++ </tbody>
++ </table>
++</div>
++<div id="numericeffecters" class="sensors">
++ <h1>Numeric Effecters</h1>
++ <div class="page-header">
++ <h2 class="inline">All Numeric effecters present in the system</h2>
++ <a ng-href="data_numeric_effecter:text/json;charset=utf-8,{{export_data_numeric_effecter}}" class="btn btn-tertiary float-right" download="{{export_name_numeric_effecter}}"><icon file="icon-export.svg"></icon>Export</a>
++ </div>
++ <table id="sensor-categories" class="sensors__table" cellpadding="0" cellspacing="0" ng-show="filteredNumericStateData.length">
++ <thead class="sensors__thead fixed-table-header">
++ <tr class="sensors__thead-row">
++ <th class="sensors__thead-cell">Numeric Effecters ({{filteredNumericStateData.length}})<th>
++ <th class="sensors__thead-cell sensor__heading-current">Present Value<th>
++ <th class="sensors__thead-cell">Operational State<th>
++ <th class="sensors__thead-cell">Pending value<th>
++ <th class="sensors__thead-cell">Set Value<th>
++ </tr>
++ </thead>
++ <tbody class="sensors__tbody">
++ <tr class="sensors__tbody-row" ng-repeat="numeric_effecter in data_numeric_effecter as filteredNumericStateData">
++ <th class="sensors__tbody-header">
++ <span>{{numeric_effecter.title}}</span>
++ </th>
++
++ <td class="sensors__tbody-cell sensors__tbody-current" ng-class="{'sensors__tbody-current--normal': numeric_effecter.status == 'normal'}">
++ <span class="sensors__tbody-cell__title">Present Value</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{numeric_effecter.presentValue}}</span>
++ </span>
++ </td>
++
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Operational State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{numeric_effecter.effecterOperationalState}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Pending Value</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{numeric_effecter.presentValue}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <input id="net-config__mac" type="text" ng-model="setvalue" />
++ <span class="sensors__tbody-cell__title">Set Value</span>
++ <span class="sensors__tbody-cell__content">
++ <button class="btn btn-primary" ng-click="setEffecterValue(numeric_effecter,setvalue)">Set
++ </button>
++ </span>
++ </td>
++ </tr>
++ </tbody>
++ </table>
++</div>
++<div id="statesensors" class="sensors">
++ <h1>State Sensors</h1>
++ <div class="page-header">
++ <h2 class="inline">All state sensors present in the system</h2>
++ <a ng-href="data_state_sensor:text/json;charset=utf-8,{{export_data_state_sensor}}" class="btn btn-tertiary float-right" download="{{export_name_state_sensor}}"><icon file="icon-export.svg"></icon>Export</a>
++ </div>
++ <table id="sensor-categories" class="sensors__table" cellpadding="0" cellspacing="0" ng-show="filteredStateSensorData.length">
++ <thead class="sensors__thead fixed-table-header">
++ <tr class="sensors__thead-row">
++ <th class="sensors__thead-cell">Sensors ({{filteredStateSensorData.length}})<th>
++ <th class="sensors__thead-cell">Previous State<th>
++ <th class="sensors__thead-cell sensor__heading-current">Present State<th>
++ <th class="sensors__thead-cell">Operational State<th>
++ <th class="sensors__thead-cell">Event State<th>
++ </tr>
++ </thead>
++ <tbody class="sensors__tbody">
++ <tr class="sensors__tbody-row" ng-repeat="state_sensor in data_state_sensor as filteredStateSensorData">
++ <th class="sensors__tbody-header">
++ <span>{{state_sensor.title}}</span>
++ </th>
++
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Previous State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_sensor.previous_state}}</span>
++ </span>
++ </td>
++
++ <td class="sensors__tbody-cell sensors__tbody-current" ng-class="{'sensors__tbody-current--normal': state_sensor.status == 'normal'}">
++ <span class="sensors__tbody-cell__title">Present State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_sensor.present_state}}</span>
++ </span>
++ </td>
++
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Operational State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_sensor.sensorOperationalState}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Event State</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{state_sensor.event_state}}</span>
++ </span>
++ </td>
++ </tr>
++ </tbody>
++ </table>
++</div>
++<div id="numericsensors" class="sensors">
++ <h1>Numeric Sensors</h1>
++ <div class="page-header">
++ <h2 class="inline">All numeric sensors present in the system</h2>
++ <a ng-href="data_numeric_sensor:text/json;charset=utf-8,{{export_data_numeric_sensor}}" class="btn btn-tertiary float-right" download="{{export_name_numeric_sensor}}"><icon file="icon-export.svg"></icon>Export</a>
++ </div>
++
++ <div>
++ <p class="content-label" aria-label="sensors filter">Filter sensors</p>
++ <div class="content__search">
++ <label for="content__search-input">Sensors Search</label>
++ <input id="content__search-input" type="text" ng-model="customSearch" ng-keydown="doSearchOnEnter($event)"/>
++ <div class="search-submit__wrapper">
++ <button class="btn" type="button" aria-label="clear filter" ng-click="clear()">
++ <icon file="icon-close.svg" aria-hidden="true"></icon>
++ </button>
++ <input id="content__search-submit" type="submit" class="btn btn-primary content__search-submit" value="Filter" ng-click="doSearchOnClick()"/>
++ </div>
++ </div>
++
++ <div class="toggle-filter">
++ <p class="content-label">FILTER BY SEVERITY</p>
++ <button class="btn" ng-click="toggleSeverityAll()"
++ ng-class="selectedSeverity.all ? 'btn-primary' : 'btn-secondary'">All
++ </button>
++ <button class="btn" ng-click="toggleSeverity('critical')"
++ ng-class="selectedSeverity.critical ? 'btn-primary' : 'btn-secondary'">Critical
++ </button>
++ <button class="btn" ng-click="toggleSeverity('warning')"
++ ng-class="selectedSeverity.warning ? 'btn-primary' : 'btn-secondary'">Warning
++ </button>
++ <button class="btn" ng-click="toggleSeverity('normal')"
++ ng-class="selectedSeverity.normal ? 'btn-primary' : 'btn-secondary'">Normal
++ </button>
++ </div>
++ </div>
++
++ <div ng-show="filteredSensorData.length == 0">
++ <span ng-if="selectedSeverity.all">{{messages.NO_SENSOR_DATA}}</span>
++ <span ng-if="selectedSeverity.critical">{{messages.CRITICAL_NO_SENSOR_DATA}}</span>
++ <span ng-if="selectedSeverity.warning">{{messages.WARNING_NO_SENSOR_DATA}}</span>
++ <span ng-if="selectedSeverity.normal">{{messages.NORMAL_NO_SENSOR_DATA}}</span>
++ </div>
++
++ <table id="sensor-categories" class="sensors__table" cellpadding="0" cellspacing="0" ng-show="filteredSensorData.length">
++ <thead class="sensors__thead fixed-table-header">
++ <tr class="sensors__thead-row">
++ <th class="sensors__thead-cell">Sensors ({{filteredSensorData.length}})<th>
++ <th class="sensors__thead-cell">Low critical<th>
++ <th class="sensors__thead-cell">Low warning<th>
++ <th class="sensors__thead-cell sensor__heading-current">Current<th>
++ <th class="sensors__thead-cell">High warning<th>
++ <th class="sensors__thead-cell">High critical<th>
++ </tr>
++ </thead>
++ <tbody class="sensors__tbody">
++ <tr class="sensors__tbody-row" ng-repeat="sensor in data_numeric_sensor|filter:filterBySeverity|filter:filterBySearchTerms|orderBy:'+custom_order' as filteredSensorData">
++ <th class="sensors__tbody-header">
++ <status-icon status="{{ sensor.status == 'critical' ? 'error' :
++ sensor.status == 'warning' ? 'warn' : null }}"
++ aria-label="Sensor status: {{sensor.status}}">
++ </status-icon>
++ <span>{{sensor.title}}</span>
++ </th>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Low critical</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{sensor.CriticalLow}}</span>
++ <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span>
++ <span class="sensors__tbody-unit">{{sensor.unit}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">Low warning</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{sensor.WarningLow}}</span>
++ <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span>
++ <span class="sensors__tbody-unit">{{sensor.unit}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell sensors__tbody-current" ng-class="{'sensors__tbody-current--critical': sensor.status == 'critical', 'sensors__tbody-current--warn': sensor.status == 'warning', 'sensors__tbody-current--normal': sensor.status == 'normal'}">
++ <span class="sensors__tbody-cell__title">Current</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{sensor.Value}}</span>
++ <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span>
++ <span class="sensors__tbody-unit">{{sensor.unit}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">High warning</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{sensor.WarningHigh}}</span>
++ <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span>
++ <span class="sensors__tbody-unit">{{sensor.unit}}</span>
++ </span>
++ </td>
++ <td class="sensors__tbody-cell">
++ <span class="sensors__tbody-cell__title">High critical</span>
++ <span class="sensors__tbody-cell__content">
++ <span class="sensors__tbody-info">{{sensor.CriticalHigh}}</span>
++ <span class="sensors__tbody-degree" ng-if="sensor.unit == 'C'">°</span>
++ <span class="sensors__tbody-unit">{{sensor.unit}}</span>
++ </span>
++ </td>
++ </tr>
++ </tbody>
++ </table>
++</div>
+\ No newline at end of file
+diff --git a/app/server-health/controllers/pldm-overview-controller.js b/app/server-health/controllers/pldm-overview-controller.js
+new file mode 100644
+index 00000000..134a6cac
+--- /dev/null
++++ b/app/server-health/controllers/pldm-overview-controller.js
+@@ -0,0 +1,177 @@
++/**
++ * Controller for sensors-overview
++ *
++ * @module app/serverHealth
++ * @exports sensorsOverviewController
++ * @name sensorsOverviewController
++ */
++
++window.angular && (function(angular) {
++ 'use strict';
++ angular.module('app.overview').controller('pldmOverviewController', [
++ '$scope', '$log', '$window', 'APIUtils', 'dataService', 'Constants',
++ function($scope, $log, $window, APIUtils, dataService, Constants) {
++ $scope.dataService = dataService;
++
++ $scope.dropdown_selected = false;
++
++ $scope.$log = $log;
++ $scope.customSearch = '';
++ $scope.searchTerms = [];
++ $scope.messages = Constants.MESSAGES.SENSOR;
++ $scope.selectedSeverity =
++ {all: true, normal: false, warning: false, critical: false};
++ $scope.export_name_state_effecter = 'state_effecters.json';
++ $scope.export_name_numeric_effecter = 'numeric_effecters.json';
++ $scope.export_name_state_sensor = 'state_sensors.json';
++ $scope.export_name_numeric_sensor = 'numeric_sensors.json';
++ $scope.loading = false;
++
++ $scope.jsonData = function(data) {
++ var dt = {};
++ data.data.forEach(function(item) {
++ dt[item.original_data.key] = item.original_data.value;
++ });
++ return JSON.stringify(dt);
++ };
++
++ $scope.clear = function() {
++ $scope.customSearch = '';
++ $scope.searchTerms = [];
++ };
++
++ $scope.doSearchOnEnter = function(event) {
++ var search =
++ $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
++ if (event.keyCode === 13 && search.length >= 2) {
++ $scope.searchTerms = $scope.customSearch.split(' ');
++ } else {
++ if (search.length == 0) {
++ $scope.searchTerms = [];
++ }
++ }
++ };
++
++ $scope.doSearchOnClick = function() {
++ var search =
++ $scope.customSearch.replace(/^\s+/g, '').replace(/\s+$/g, '');
++ if (search.length >= 2) {
++ $scope.searchTerms = $scope.customSearch.split(' ');
++ } else {
++ if (search.length == 0) {
++ $scope.searchTerms = [];
++ }
++ }
++ };
++
++ $scope.toggleSeverityAll = function() {
++ $scope.selectedSeverity.all = !$scope.selectedSeverity.all;
++
++ if ($scope.selectedSeverity.all) {
++ $scope.selectedSeverity.normal = false;
++ $scope.selectedSeverity.warning = false;
++ $scope.selectedSeverity.critical = false;
++ }
++ };
++
++ $scope.toggleSeverity = function(severity) {
++ $scope.selectedSeverity[severity] = !$scope.selectedSeverity[severity];
++
++ if (['normal', 'warning', 'critical'].indexOf(severity) > -1) {
++ if ($scope.selectedSeverity[severity] == false &&
++ (!$scope.selectedSeverity.normal &&
++ !$scope.selectedSeverity.warning &&
++ !$scope.selectedSeverity.critical)) {
++ $scope.selectedSeverity.all = true;
++ return;
++ }
++ }
++
++ if ($scope.selectedSeverity.normal && $scope.selectedSeverity.warning &&
++ $scope.selectedSeverity.critical) {
++ $scope.selectedSeverity.all = true;
++ $scope.selectedSeverity.normal = false;
++ $scope.selectedSeverity.warning = false;
++ $scope.selectedSeverity.critical = false;
++ } else {
++ $scope.selectedSeverity.all = false;
++ }
++ };
++
++ $scope.filterBySeverity = function(sensor) {
++ if ($scope.selectedSeverity.all) return true;
++
++ return (
++ (sensor.severity_flags.normal && $scope.selectedSeverity.normal) ||
++ (sensor.severity_flags.warning &&
++ $scope.selectedSeverity.warning) ||
++ (sensor.severity_flags.critical &&
++ $scope.selectedSeverity.critical));
++ };
++ $scope.filterBySearchTerms = function(sensor) {
++ if (!$scope.searchTerms.length) return true;
++
++ for (var i = 0, length = $scope.searchTerms.length; i < length; i++) {
++ if (sensor.search_text.indexOf($scope.searchTerms[i].toLowerCase()) ==
++ -1)
++ return false;
++ }
++ return true;
++ };
++
++ $scope.toggleEffecterState = function(sensor) {
++ if(sensor.effecterOperationalState != sensor.present_state) {
++ APIUtils.toggleEffecterState(sensor.path, '1');
++ sensor.present_state = '1';
++ sensor.previous_state = '2';
++ //$scope.loadEffecterData();
++ return;
++ }
++ else {
++ APIUtils.toggleEffecterState(sensor.path, '2');
++ sensor.present_state = '2';
++ sensor.previous_state = '1';
++ //$scope.loadEffecterData();
++ return;
++ }
++ };
++
++ $scope.setEffecterValue = function(sensor, setvalue) {
++ APIUtils.setEffecterValue(sensor.path, setvalue);
++ $scope.loadEffecterData();
++ };
++
++ $scope.loadEffecterData = function() {
++ $scope.loading = true;
++ APIUtils.getAllEffecterStatus(function(data, originalData) {
++ $scope.data_state_effecter = data;
++ $scope.originalData_state_effecter = originalData;
++ $scope.export_data_state_effecter = JSON.stringify(originalData);
++ $scope.loading = false;
++ });
++ $scope.loading = true;
++ APIUtils.getAllNumericEffecterStatus(function(data, originalData) {
++ $scope.data_numeric_effecter = data;
++ $scope.originalData_numeric_effecter = originalData;
++ $scope.export_data_numeric_effecter = JSON.stringify(originalData);
++ $scope.loading = false;
++ });
++ $scope.loading = true;
++ APIUtils.getAllStateSensorStatus(function(data, originalData) {
++ $scope.data_state_sensor = data;
++ $scope.originalData_state_sensor = originalData;
++ $scope.export_data_state_sensor = JSON.stringify(originalData);
++ $scope.loading = false;
++ });
++ $scope.loading = true;
++ APIUtils.getAllNumericSensorStatus(function(data, originalData) {
++ $scope.data_numeric_sensor = data;
++ $scope.originalData_numeric_sensor = originalData;
++ $scope.export_data_numeric_sensor = JSON.stringify(originalData);
++ $scope.loading = false;
++ });
++ };
++ $scope.loadEffecterData();
++ }
++ ]);
++})(angular);
+diff --git a/app/server-health/index.js b/app/server-health/index.js
+index 96172d86..173eb9cb 100644
+--- a/app/server-health/index.js
++++ b/app/server-health/index.js
+@@ -42,6 +42,12 @@ window.angular && (function(angular) {
+ 'controller': 'sensorsOverviewController',
+ authenticated: true
+ })
++ .when('/server-health/pldm-overview', {
++ 'template':
++ require('./controllers/pldm-overview-controller.html'),
++ 'controller': 'pldmOverviewController',
++ authenticated: true
++ })
+ .when('/server-health/sys-log', {
+ 'template': require('./controllers/syslog-controller.html'),
+ 'controller': 'sysLogController',
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0003-add-mcu-firmware-update-functionality.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0003-add-mcu-firmware-update-functionality.patch
new file mode 100644
index 0000000..df11052
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui/0003-add-mcu-firmware-update-functionality.patch
@@ -0,0 +1,138 @@
+From 4a3aedb671ad65c56e0e638453f7a8f713b4a653 Mon Sep 17 00:00:00 2001
+From: Tim Lee <timlee660101@gmail.com>
+Date: Wed, 23 Sep 2020 15:55:33 +0800
+Subject: [PATCH 5/5] add mcu firmware update functionality
+
+Signed-off-by: Tim Lee <timlee660101@gmail.com>
+---
+ app/common/services/api-utils.js | 9 ++++++++-
+ .../controllers/firmware-controller.html | 19 ++++++++++++++++++-
+ .../controllers/firmware-controller.js | 15 ++++++++++++++-
+ 3 files changed, 40 insertions(+), 3 deletions(-)
+
+diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
+index cc1122f3..fd1c5dac 100644
+--- a/app/common/services/api-utils.js
++++ b/app/common/services/api-utils.js
+@@ -1111,6 +1111,7 @@ window.angular && (function(angular) {
+ var isExtended = false;
+ var bmcActiveVersion = '';
+ var hostActiveVersion = '';
++ var mcuActiveVersion = '';
+ var imageType = '';
+ var extendedVersions = [];
+ var functionalImages = [];
+@@ -1197,13 +1198,19 @@ window.angular && (function(angular) {
+ imageType == 'Host') {
+ hostActiveVersion = content.data[key].Version;
+ }
++
++ if (activationStatus == 'Functional' &&
++ imageType == 'MCU') {
++ mcuActiveVersion = content.data[key].Version;
++ }
+ }
+ }
+
+ deferred.resolve({
+ data: data,
+ bmcActiveVersion: bmcActiveVersion,
+- hostActiveVersion: hostActiveVersion
++ hostActiveVersion: hostActiveVersion,
++ mcuActiveVersion: mcuActiveVersion
+ });
+ },
+ function(error) {
+diff --git a/app/configuration/controllers/firmware-controller.html b/app/configuration/controllers/firmware-controller.html
+index d2ff89dc..3c6c11a0 100644
+--- a/app/configuration/controllers/firmware-controller.html
++++ b/app/configuration/controllers/firmware-controller.html
+@@ -2,7 +2,7 @@
+ <div class="row column">
+ <h1>Firmware</h1>
+ <div class="column small-12 page-header">
+- <h2 class="inline">Manage BMC and server firmware</h2>
++ <h2 class="inline">Manage BMC, server and MCU firmware</h2>
+ </div>
+ </div>
+ <div class="row column">
+@@ -11,6 +11,7 @@
+ </div>
+ <firmware-list title="BMC images" version="bmcActiveVersion" firmwares="firmwares" filter-by="filters.bmc"></firmware-list>
+ <firmware-list title="Server images" version="hostActiveVersion" firmwares="firmwares" filter-by="filters.host"></firmware-list>
++<firmware-list title="MCU images" version="mcuActiveVersion" firmwares="firmwares" filter-by="filters.mcu"></firmware-list>
+ <div class="row column" id="upload">
+ <div class="column small-12 page-header">
+ <h2 class="inline bold">Specify image file location</h2>
+@@ -134,6 +135,22 @@
+ </div>
+ </fieldset>
+ </form>
++ <form ng-if="activate_image_type == 'MCU'">
++ <fieldset>
++ <div class="row column">
++ <label class="control-radio bold" for="activate-without-reboot">Activate MCU file without rebooting BMC
++ <input type="radio" name="activate-without-reboot" id="activate-without-reboot" ng-model="activate.reboot" ng-value="false"/>
++ <span class="control__indicator control__indicator-on"></span>
++ </label>
++ </div>
++ <div class="row column">
++ <label class="control-radio bold" for="activate-with-reboot">Activate MCU file and automatically reboot BMC
++ <input type="radio" name="activate-with-reboot" id="activate-with-reboot" ng-model="activate.reboot" ng-value="true"/>
++ <span class="control__indicator control__indicator-on"></span>
++ </label>
++ </div>
++ </fieldset>
++ </form>
+ </div>
+ <div class="modal__button-wrapper">
+ <button class="btn btn-secondary" ng-click="activate_confirm=false;">Cancel</button>
+diff --git a/app/configuration/controllers/firmware-controller.js b/app/configuration/controllers/firmware-controller.js
+index 451c16ce..b208ab74 100644
+--- a/app/configuration/controllers/firmware-controller.js
++++ b/app/configuration/controllers/firmware-controller.js
+@@ -26,6 +26,7 @@ window.angular && (function(angular) {
+ $scope.firmwares = [];
+ $scope.bmcActiveVersion = '';
+ $scope.hostActiveVersion = '';
++ $scope.mcuActiveVersion = '';
+ $scope.activate_confirm = false;
+ $scope.delete_image_id = '';
+ $scope.delete_image_version = '';
+@@ -136,6 +137,17 @@ window.angular && (function(angular) {
+ warmReboot();
+ }
+ }
++ if ($scope.activate.reboot &&
++ ($scope.activate_image_type == 'MCU')) {
++ APIUtils.bmcReboot().then(
++ function(response) {
++ toastService.success('BMC is rebooting.')
++ },
++ function(error) {
++ console.log(JSON.stringify(error));
++ toastService.error('Unable to reboot BMC.');
++ });
++ }
+ });
+ });
+ $scope.activate_confirm = false;
+@@ -308,13 +320,14 @@ window.angular && (function(angular) {
+ $scope.confirm_delete = false;
+ };
+
+- $scope.filters = {bmc: {imageType: 'BMC'}, host: {imageType: 'Host'}};
++ $scope.filters = {bmc: {imageType: 'BMC'}, host: {imageType: 'Host'}, mcu: {imageType: 'MCU'}};
+
+ $scope.loadFirmwares = function() {
+ APIUtils.getFirmwares().then(function(result) {
+ $scope.firmwares = result.data;
+ $scope.bmcActiveVersion = result.bmcActiveVersion;
+ $scope.hostActiveVersion = result.hostActiveVersion;
++ $scope.mcuActiveVersion = result.mcuActiveVersion;
+ });
+ };
+
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui_%.bbappend b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui_%.bbappend
new file mode 100644
index 0000000..8bff7fb
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/phosphor-webui_%.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS:append:nuvoton := ":${THISDIR}/${PN}"
+
+SRC_URI:append:nuvoton = " file://0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch"
+#SRC_URI:append:nuvoton = " file://0002-support-pldm-sensors-effecters.patch"
+SRC_URI:append:nuvoton = " file://0003-add-mcu-firmware-update-functionality.patch"
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch
new file mode 100644
index 0000000..2b96345
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch
@@ -0,0 +1,43 @@
+From c33f0a97a15c99ca3144c9f8e67a67abe8fcee0a Mon Sep 17 00:00:00 2001
+From: Joseph Liu <kwliu@nuvoton.com>
+Date: Thu, 11 Nov 2021 16:10:26 +0800
+Subject: [PATCH] novnc: add 16-bit hextile support for nuvoton ece engine
+
+Signed-off-by: Joseph Liu <kwliu@nuvoton.com>
+---
+ package-lock.json | 5 ++---
+ package.json | 2 +-
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/package-lock.json b/package-lock.json
+index 413dd624..759fe1ba 100644
+--- a/package-lock.json
++++ b/package-lock.json
+@@ -3281,9 +3281,8 @@
+ "dev": true
+ },
+ "@novnc/novnc": {
+- "version": "1.2.0",
+- "resolved": "https://registry.npmjs.org/@novnc/novnc/-/novnc-1.2.0.tgz",
+- "integrity": "sha512-FaUckOedGhSbwQBXk/KGyxKt9ngskg4wPw6ghbHWXOUEmQscAZr3467lTU5DSfppwHJt5k+lQiHoeYUuY90l2Q=="
++ "version": "Nuvoton-Israel/noVNC.git#openbmc-v1.2.0",
++ "from": "@novnc/novnc@Nuvoton-Israel/noVNC.git#openbmc-v1.2.0"
+ },
+ "@npmcli/move-file": {
+ "version": "1.0.1",
+diff --git a/package.json b/package.json
+index 91d45434..9cb3e226 100644
+--- a/package.json
++++ b/package.json
+@@ -16,7 +16,7 @@
+ },
+ "dependencies": {
+ "@carbon/icons-vue": "10.28.0",
+- "@novnc/novnc": "1.2.0",
++ "@novnc/novnc": "Nuvoton-Israel/noVNC.git#openbmc-v1.2.0",
+ "axios": "0.21.4",
+ "bootstrap": "4.6.0",
+ "bootstrap-vue": "2.21.2",
+--
+2.25.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0002-Add-Nuvoton-MCU-firmware-support.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0002-Add-Nuvoton-MCU-firmware-support.patch
new file mode 100644
index 0000000..cce40ea
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0002-Add-Nuvoton-MCU-firmware-support.patch
@@ -0,0 +1,143 @@
+From 155799c9bd45e80fee3c260dcbba36fa84dabefd Mon Sep 17 00:00:00 2001
+From: Brian Ma <chma0@nuvoton.com>
+Date: Tue, 29 Jun 2021 10:34:23 +0800
+Subject: [PATCH 1/2] Add Nuvoton MCU firmware support
+
+Signed-off-by: Brian Ma <chma0@nuvoton.com>
+---
+ src/locales/en-US.json | 1 +
+ .../modules/Configuration/FirmwareStore.js | 9 +++++
+ src/views/Configuration/Firmware/Firmware.vue | 5 +++
+ .../Firmware/FirmwareCardsMcu.vue | 37 +++++++++++++++++++
+ 4 files changed, 52 insertions(+)
+ create mode 100644 src/views/Configuration/Firmware/FirmwareCardsMcu.vue
+
+diff --git a/src/locales/en-US.json b/src/locales/en-US.json
+index 437ce03..c087f82 100644
+--- a/src/locales/en-US.json
++++ b/src/locales/en-US.json
+@@ -310,6 +310,7 @@
+ "sectionTitleBmcCards": "BMC",
+ "sectionTitleBmcCardsCombined": "BMC and server",
+ "sectionTitleHostCards": "Host",
++ "sectionTitleMcuCards": "MCU",
+ "sectionTitleUpdateFirmware": "Update firmware",
+ "alert": {
+ "operationInProgress": "Server power operation in progress.",
+diff --git a/src/store/modules/Configuration/FirmwareStore.js b/src/store/modules/Configuration/FirmwareStore.js
+index c6639ff..79f8638 100644
+--- a/src/store/modules/Configuration/FirmwareStore.js
++++ b/src/store/modules/Configuration/FirmwareStore.js
+@@ -6,6 +6,7 @@ const FirmwareStore = {
+ state: {
+ bmcFirmware: [],
+ hostFirmware: [],
++ mcuFirmware: null,
+ bmcActiveFirmwareId: null,
+ hostActiveFirmwareId: null,
+ applyTime: null,
+@@ -24,6 +25,7 @@ const FirmwareStore = {
+ (firmware) => firmware.id === state.hostActiveFirmwareId
+ );
+ },
++ mcuFirmware: (state) => state.mcuFirmware,
+ backupBmcFirmware: (state) => {
+ return state.bmcFirmware.find(
+ (firmware) => firmware.id !== state.bmcActiveFirmwareId
+@@ -40,6 +42,7 @@ const FirmwareStore = {
+ setActiveHostFirmwareId: (state, id) => (state.hostActiveFirmwareId = id),
+ setBmcFirmware: (state, firmware) => (state.bmcFirmware = firmware),
+ setHostFirmware: (state, firmware) => (state.hostFirmware = firmware),
++ setMcuFirmware: (state, firmware) => (state.mcuFirmware = firmware),
+ setApplyTime: (state, applyTime) => (state.applyTime = applyTime),
+ setTftpUploadAvailable: (state, tftpAvailable) =>
+ (state.tftpAvailable = tftpAvailable),
+@@ -81,6 +84,12 @@ const FirmwareStore = {
+ const bmcFirmware = [];
+ const hostFirmware = [];
+ response.forEach(({ data }) => {
++ const Description = data?.Description;
++ if (Description === 'MCU image') {
++ // there is only one MCU firmware, and we just care version
++ const mcuFirmware = data?.Version;
++ commit('setMcuFirmware', mcuFirmware);
++ }
+ const firmwareType = data?.RelatedItem?.[0]?.['@odata.id']
+ .split('/')
+ .pop();
+diff --git a/src/views/Configuration/Firmware/Firmware.vue b/src/views/Configuration/Firmware/Firmware.vue
+index a2acb9b..bfb9b78 100644
+--- a/src/views/Configuration/Firmware/Firmware.vue
++++ b/src/views/Configuration/Firmware/Firmware.vue
+@@ -14,6 +14,9 @@
+
+ <!-- Host Firmware -->
+ <host-cards v-if="!isSingleFileUploadEnabled" />
++
++ <!-- MCU Firmware -->
++ <mcu-cards />
+ </b-col>
+ </b-row>
+
+@@ -39,6 +42,7 @@ import AlertsServerPower from './FirmwareAlertServerPower';
+ import BmcCards from './FirmwareCardsBmc';
+ import FormUpdate from './FirmwareFormUpdate';
+ import HostCards from './FirmwareCardsHost';
++import McuCards from './FirmwareCardsMcu';
+ import PageSection from '@/components/Global/PageSection';
+ import PageTitle from '@/components/Global/PageTitle';
+
+@@ -51,6 +55,7 @@ export default {
+ BmcCards,
+ FormUpdate,
+ HostCards,
++ McuCards,
+ PageSection,
+ PageTitle,
+ },
+diff --git a/src/views/Configuration/Firmware/FirmwareCardsMcu.vue b/src/views/Configuration/Firmware/FirmwareCardsMcu.vue
+new file mode 100644
+index 0000000..3d5641e
+--- /dev/null
++++ b/src/views/Configuration/Firmware/FirmwareCardsMcu.vue
+@@ -0,0 +1,37 @@
++<template>
++ <page-section :section-title="$t('pageFirmware.sectionTitleMcuCards')">
++ <b-card-group deck>
++ <!-- Running image -->
++ <b-card>
++ <template #header>
++ <p class="font-weight-bold m-0">
++ {{ $t('pageFirmware.cardTitleRunning') }}
++ </p>
++ </template>
++ <dl class="mb-0">
++ <dt>{{ $t('pageFirmware.cardBodyVersion') }}</dt>
++ <dd class="mb-0">{{ runningVersion }}</dd>
++ </dl>
++ </b-card>
++ </b-card-group>
++ </page-section>
++</template>
++
++<script>
++import PageSection from '@/components/Global/PageSection';
++
++export default {
++ components: { PageSection },
++ computed: {
++ runningVersion() {
++ return this.$store.getters['firmware/mcuFirmware'] || '--';
++ },
++ },
++};
++</script>
++
++<style lang="scss" scoped>
++.page-section {
++ margin-top: -$spacer * 1.5;
++}
++</style>
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0003-DEMO-Add-reboot-cause-support.patch b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0003-DEMO-Add-reboot-cause-support.patch
new file mode 100644
index 0000000..95e28ae
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue/0003-DEMO-Add-reboot-cause-support.patch
@@ -0,0 +1,105 @@
+From a9a54e019f0423d583794b71e47ff4248febe7c8 Mon Sep 17 00:00:00 2001
+From: Brian Ma <chma0@nuvoton.com>
+Date: Tue, 29 Jun 2021 10:42:42 +0800
+Subject: [PATCH 2/2] [DEMO]Add reboot cause support
+
+---
+ src/locales/en-US.json | 1 +
+ src/store/modules/Control/ControlStore.js | 24 +++++++++++++++++++++++
+ src/views/Control/RebootBmc/RebootBmc.vue | 7 +++++++
+ 3 files changed, 32 insertions(+)
+
+diff --git a/src/locales/en-US.json b/src/locales/en-US.json
+index c087f82..1bc7704 100644
+--- a/src/locales/en-US.json
++++ b/src/locales/en-US.json
+@@ -635,6 +635,7 @@
+ "pageRebootBmc": {
+ "lastReboot": "Last BMC reboot",
+ "rebootBmc": "Reboot BMC",
++ "rebootCause": "Reboot cause:",
+ "rebootInformation": "When you reboot the BMC, your web browser loses contact with the BMC for several minutes. When the BMC is back online, you may need to log in again.",
+ "modal": {
+ "confirmMessage": "Are you sure you want to reboot the BMC?",
+diff --git a/src/store/modules/Control/ControlStore.js b/src/store/modules/Control/ControlStore.js
+index 9b8bf73..09e8b95 100644
+--- a/src/store/modules/Control/ControlStore.js
++++ b/src/store/modules/Control/ControlStore.js
+@@ -34,11 +34,13 @@ const ControlStore = {
+ isOperationInProgress: false,
+ lastPowerOperationTime: null,
+ lastBmcRebootTime: null,
++ lastBmcRebootCause: null,
+ },
+ getters: {
+ isOperationInProgress: (state) => state.isOperationInProgress,
+ lastPowerOperationTime: (state) => state.lastPowerOperationTime,
+ lastBmcRebootTime: (state) => state.lastBmcRebootTime,
++ lastBmcRebootCause: (state) => state.lastBmcRebootCause,
+ },
+ mutations: {
+ setOperationInProgress: (state, inProgress) =>
+@@ -47,6 +49,8 @@ const ControlStore = {
+ (state.lastPowerOperationTime = lastPowerOperationTime),
+ setLastBmcRebootTime: (state, lastBmcRebootTime) =>
+ (state.lastBmcRebootTime = lastBmcRebootTime),
++ setLastBmcRebootCause: (state, lastBmcRebootCause) =>
++ (state.lastBmcRebootCause = lastBmcRebootCause),
+ },
+ actions: {
+ async getLastPowerOperationTime({ commit }) {
+@@ -62,6 +66,26 @@ const ControlStore = {
+ .catch((error) => console.log(error));
+ },
+ getLastBmcRebootTime({ commit }) {
++ // get reboot cause first
++ api
++ .get('/xyz/openbmc_project/state/bmc0/attr/LastRebootCause')
++ .then((response) => {
++ const lastRebootCause = response.data.data;
++ console.log(lastRebootCause);
++ if (
++ lastRebootCause === 'xyz.openbmc_project.State.BMC.RebootCause.POR'
++ ) {
++ commit('setLastBmcRebootCause', 'Power-On-Reset');
++ } else if (
++ lastRebootCause ===
++ 'xyz.openbmc_project.State.BMC.RebootCause.Watchdog'
++ ) {
++ commit('setLastBmcRebootCause', 'Watchdog');
++ } else {
++ commit('setLastBmcRebootCause', 'Unknown');
++ }
++ })
++ .catch((error) => console.log(error));
+ return api
+ .get('/redfish/v1/Managers/bmc')
+ .then((response) => {
+diff --git a/src/views/Control/RebootBmc/RebootBmc.vue b/src/views/Control/RebootBmc/RebootBmc.vue
+index 900619c..910188e 100644
+--- a/src/views/Control/RebootBmc/RebootBmc.vue
++++ b/src/views/Control/RebootBmc/RebootBmc.vue
+@@ -15,6 +15,10 @@
+ {{ lastBmcRebootTime | formatTime }}
+ </dd>
+ <dd v-else>--</dd>
++ <dd>
++ {{ $t('pageRebootBmc.rebootCause') }}
++ {{ lastBmcRebootCause }}
++ </dd>
+ </dl>
+ </b-col>
+ </b-row>
+@@ -51,6 +55,9 @@ export default {
+ lastBmcRebootTime() {
+ return this.$store.getters['controls/lastBmcRebootTime'];
+ },
++ lastBmcRebootCause() {
++ return this.$store.getters['controls/lastBmcRebootCause'] || '--';
++ },
+ },
+ created() {
+ this.startLoader();
+--
+2.17.1
+
diff --git a/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue_%.bbappend b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue_%.bbappend
new file mode 100644
index 0000000..cd08975
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-phosphor/webui/webui-vue_%.bbappend
@@ -0,0 +1,3 @@
+FILESEXTRAPATHS:append:nuvoton := ":${THISDIR}/${PN}"
+
+SRC_URI:append:nuvoton = " file://0001-novnc-add-16-bit-hextile-support-for-nuvoton-ece-eng.patch"
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client.bb b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client.bb
new file mode 100644
index 0000000..269fdb9
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client.bb
@@ -0,0 +1,40 @@
+SUMMARY = "OPTEE Client"
+HOMEPAGE = "https://github.com/OP-TEE/optee_client"
+
+LICENSE = "BSD-2-Clause"
+LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=69663ab153298557a59c67a60a743e5b"
+
+PV = "3.16.0+git${SRCPV}"
+
+inherit python3native systemd
+
+SRC_URI = "git://github.com/OP-TEE/optee_client.git;branch=master;protocol=https \
+ file://tee-supplicant.service \
+ "
+SRCREV = "06db73b3f3fdb8d23eceaedbc46c49c0b45fd1e2"
+
+S = "${WORKDIR}/git"
+
+EXTRA_OEMAKE = "CFG_TEE_FS_PARENT_PATH=/var/tee \
+ "
+
+do_install() {
+ oe_runmake install
+
+ install -D -p -m0755 ${S}/out/export/usr/sbin/tee-supplicant ${D}${bindir}/tee-supplicant
+
+ install -D -p -m0644 ${S}/out/export/usr/lib/libteec.so.1.0.0 ${D}${libdir}/libteec.so.1.0.0
+ ln -sf libteec.so.1.0.0 ${D}${libdir}/libteec.so
+ ln -sf libteec.so.1.0.0 ${D}${libdir}/libteec.so.1
+ ln -sf libteec.so.1.0.0 ${D}${libdir}/libteec.so.1.0
+
+ cp -a ${S}/out/export/usr/include ${D}/usr/
+
+ install -d ${D}${systemd_system_unitdir}/
+ install -m 0644 ${WORKDIR}/tee-supplicant.service ${D}${systemd_system_unitdir}/
+ sed -i -e s:/etc:${sysconfdir}:g -e s:/usr/bin:${bindir}:g ${D}${systemd_system_unitdir}/tee-supplicant.service
+}
+
+SYSTEMD_SERVICE:${PN} = "tee-supplicant.service"
+
+FILES:${PN} += "${libdir}/* ${includedir}/* ${systemd_system_unitdir}/*"
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client/tee-supplicant.service b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client/tee-supplicant.service
new file mode 100644
index 0000000..04e0409
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-client/tee-supplicant.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=TEE Supplicant
+
+[Service]
+User=root
+EnvironmentFile=-/etc/default/tee-supplicant
+ExecStart=/usr/bin/tee-supplicant $OPTARGS /dev/teepriv0
+
+[Install]
+WantedBy=basic.target
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os.bb b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os.bb
new file mode 100644
index 0000000..6fa6441
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os.bb
@@ -0,0 +1,71 @@
+SUMMARY = "OP-TEE Trusted OS"
+DESCRIPTION = "OPTEE OS"
+
+LICENSE = "BSD-2-Clause"
+LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=c1f21c4f72f372ef38a5a4aee55ec173"
+
+PV="1.0.0+git${SRCPV}"
+
+inherit deploy python3native
+DEPENDS = "python3-pycryptodome-native python3-pyelftools-native python3-pycryptodomex-native python3-cryptography-native"
+
+S = "${WORKDIR}/git"
+BRANCH ?= "nuvoton"
+REPO ?= "git://github.com/Nuvoton-Israel/optee_os.git;branch=nuvoton;protocol=https"
+BRANCHARG = "${@['nobranch=1', 'branch=${BRANCH}'][d.getVar('BRANCH', True) != '']}"
+SRC_URI = "${REPO};${BRANCHARG} \
+ file://0001-allow-sysroot-for-libgcc-lookup.patch \
+ "
+SRCREV = "6d2cdcf8e9c660751fc656b45ee631ade8d956e4"
+
+OPTEEMACHINE ?= "nuvoton"
+MACHINE_SOC ?= "npcm8xx"
+
+# Some versions of u-boot use .bin and others use .img. By default use .bin
+# but enable individual recipes to change this value.
+OPTEE_SUFFIX ?= "bin"
+OPTEE_IMAGE ?= "tee-${MACHINE_SOC}-${PV}-${PR}.${OPTEE_SUFFIX}"
+OPTEE_SYMLINK ?= "tee-${MACHINE_SOC}.${OPTEE_SUFFIX}"
+CFG_TEE_TA_LOG_LEVEL ?= "1"
+CFG_TEE_CORE_LOG_LEVEL ?= "1"
+
+EXTRA_OEMAKE = "PLATFORM=${OPTEEMACHINE} CFG_ARM64_core=y \
+ CROSS_COMPILE_core=${HOST_PREFIX} \
+ CROSS_COMPILE_ta_arm64=${HOST_PREFIX} \
+ NOWERROR=1 \
+ ta-targets=ta_arm64 \
+ LDFLAGS= \
+ LIBGCC_LOCATE_CFLAGS=--sysroot=${STAGING_DIR_HOST} \
+ "
+
+OPTEE_ARCH_aarch64 = "arm64"
+
+do_compile() {
+ unset LDFLAGS
+ oe_runmake CFG_TEE_LOGLEVEL=0 CFG_TEE_CORE_LOG_LEVEL=0
+}
+
+do_install () {
+ # Install the TA devkit
+ install -d ${D}/usr/include/optee/export-user_ta/
+
+ for f in ${B}/out/arm-plat-nuvoton/export-ta_arm64/*; do
+ cp -aR $f ${D}/usr/include/optee/export-user_ta/
+ done
+}
+
+do_deploy() {
+ install -d ${DEPLOYDIR}
+ install -m 0644 ${S}/out/arm-plat-${OPTEEMACHINE}/core/tee.bin ${DEPLOYDIR}/tee.bin
+ cd ${DEPLOYDIR}
+ ln -sf tee.bin ${OPTEE_SYMLINK}
+ ln -sf tee.bin ${OPTEE_IMAGE}
+}
+
+addtask deploy before do_build after do_compile
+
+FILES:${PN} = "${nonarch_base_libdir}/firmware/ ${nonarch_base_libdir}/optee_armtz/"
+FILES:${PN}-staticdev = "/usr/include/optee/"
+RDEPENDS:${PN}-dev += "${PN}-staticdev"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
\ No newline at end of file
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/0001-allow-sysroot-for-libgcc-lookup.patch b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/0001-allow-sysroot-for-libgcc-lookup.patch
new file mode 100644
index 0000000..e6d8d22
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/0001-allow-sysroot-for-libgcc-lookup.patch
@@ -0,0 +1,12 @@
+diff -Nur a/mk/gcc.mk b/mk/gcc.mk
+--- a/mk/gcc.mk 2022-03-06 10:30:27.518860700 +0200
++++ b/mk/gcc.mk 2022-03-07 10:42:04.764306171 +0200
+@@ -13,7 +13,7 @@
+ -print-file-name=include 2> /dev/null)
+
+ # Get location of libgcc from gcc
+-libgcc$(sm) := $(shell $(CC$(sm)) $(CFLAGS$(arch-bits-$(sm))) \
++libgcc$(sm) := $(shell $(CC$(sm)) $(LIBGCC_LOCATE_CFLAGS) $(CFLAGS$(arch-bits-$(sm))) $(comp-cflags$(sm)) \
+ -print-libgcc-file-name 2> /dev/null)
+ libstdc++$(sm) := $(shell $(CXX$(sm)) $(CXXFLAGS$(arch-bits-$(sm))) $(comp-cxxflags$(sm)) \
+ -print-file-name=libstdc++.a 2> /dev/null)
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/tee.bin b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/tee.bin
new file mode 100644
index 0000000..1061ad2
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-os/tee.bin
Binary files differ
diff --git a/meta-nuvoton-npcm8xx/recipes-security/optee/optee-test.bb b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-test.bb
new file mode 100644
index 0000000..39fe6f8
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes-security/optee/optee-test.bb
@@ -0,0 +1,53 @@
+SUMMARY = "OP-TEE sanity testsuite"
+HOMEPAGE = "https://github.com/OP-TEE/optee_test"
+
+LICENSE = "BSD-2-Clause & GPLv2"
+LIC_FILES_CHKSUM = "file://${S}/LICENSE.md;md5=daa2bcccc666345ab8940aab1315a4fa"
+
+SRC_URI = "git://github.com/OP-TEE/optee_test.git;branch=master;protocol=https"
+SRCREV = "1cf0e6d2bdd1145370033d4e182634458528579d"
+
+PV = "3.16.0+git${SRCPV}"
+
+S = "${WORKDIR}/git"
+
+# Imports machine specific configs from staging to build
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+DEPENDS = "optee-client optee-os python3-pycryptodome-native python3-pycryptodomex-native python3-cryptography-native"
+
+inherit python3native
+
+OPTEE_CLIENT_EXPORT = "${STAGING_DIR_HOST}${prefix}"
+TEEC_EXPORT = "${STAGING_DIR_HOST}${prefix}"
+TA_DEV_KIT_DIR = "${STAGING_INCDIR}/optee/export-user_ta"
+
+EXTRA_OEMAKE = " TA_DEV_KIT_DIR=${TA_DEV_KIT_DIR} \
+ OPTEE_CLIENT_EXPORT=${OPTEE_CLIENT_EXPORT} \
+ TEEC_EXPORT=${TEEC_EXPORT} \
+ CROSS_COMPILE_HOST=${TARGET_PREFIX} \
+ CROSS_COMPILE_TA=${TARGET_PREFIX} \
+ V=1 \
+ CFG_TEE_CLIENT_LOAD_PATH=${libdir} \
+ LIBGCC_LOCATE_CFLAGS='--sysroot=${STAGING_DIR_HOST}' \
+ "
+
+do_compile() {
+ # Top level makefile doesn't seem to handle parallel make gracefully
+ oe_runmake xtest
+ oe_runmake ta
+}
+
+do_install () {
+ install -D -p -m0755 ${S}/out/xtest/xtest ${D}${bindir}/xtest
+
+ # install path should match the value set in optee-client/tee-supplicant
+ # default TEEC_LOAD_PATH is /lib
+ mkdir -p ${D}${nonarch_base_libdir}/optee_armtz/
+ install -D -p -m0444 ${S}/out/ta/*/*.ta ${D}${nonarch_base_libdir}/optee_armtz/
+}
+
+FILES:${PN} += "${nonarch_base_libdir} ${libdir}/tee-supplicant/plugins/"
+
+DEBUG_OPTIMIZATION:append = " -Wno-error=maybe-uninitialized -Wno-deprecated-declarations"
+FULL_OPTIMIZATION:append = " -Wno-error=maybe-uninitialized -Wno-deprecated-declarations"
diff --git a/meta-nuvoton-npcm8xx/recipes.txt b/meta-nuvoton-npcm8xx/recipes.txt
new file mode 100644
index 0000000..149509f
--- /dev/null
+++ b/meta-nuvoton-npcm8xx/recipes.txt
@@ -0,0 +1,2 @@
+recipes-bsp - Anything with links to specific hardware or hardware configuration information
+recipes-kernel - The kernel and generic applications/libraries with strong kernel dependencies