499 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			499 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import pyfdt
 | 
						|
import json
 | 
						|
import argparse
 | 
						|
# some oaalnx has no colorama
 | 
						|
#import colorama
 | 
						|
from pyfdt import FdtBlobParse
 | 
						|
 | 
						|
 | 
						|
def dbg_err(msg):
 | 
						|
    #print(colorama.Fore.RED+colorama.Style.BRIGHT+msg+colorama.Style.RESET_ALL, file=sys.stderr)
 | 
						|
    print(msg, file=sys.stderr)
 | 
						|
 | 
						|
 | 
						|
def dbg_wrn(msg):
 | 
						|
    #print(colorama.Fore.YELLOW+colorama.Style.BRIGHT+msg+colorama.Style.RESET_ALL, file=sys.stderr)
 | 
						|
    print(msg, file=sys.stderr)
 | 
						|
 | 
						|
 | 
						|
def parse_nvt_info(fdt):
 | 
						|
    nvt_info = dict()
 | 
						|
    fdt_nvt_info = fdt.to_fdt().resolve_path(r'/nvt_info')
 | 
						|
    iter = fdt_nvt_info.walk()
 | 
						|
    for item in iter:
 | 
						|
        if isinstance(item[1], pyfdt.FdtPropertyStrings):
 | 
						|
            nvt_info[item[1].name] = item[1].strings[0]
 | 
						|
        else:
 | 
						|
            nvt_info[item[1].name] = ""
 | 
						|
    return nvt_info
 | 
						|
 | 
						|
 | 
						|
def parse_flash_partition(fdt, flash_path):
 | 
						|
    partitions = []
 | 
						|
    fdt_partitions = fdt.to_fdt().resolve_path(flash_path)
 | 
						|
    if fdt_partitions is None:
 | 
						|
        return partitions
 | 
						|
    iter = fdt_partitions.walk()
 | 
						|
    for item in iter:
 | 
						|
        if not isinstance(item[1], pyfdt.FdtNode):
 | 
						|
            continue
 | 
						|
        if "partition_" not in item[1].name:
 | 
						|
            continue
 | 
						|
        partition = dict()
 | 
						|
        partition["name"] = item[1].name
 | 
						|
        iter2 = item[1].walk()
 | 
						|
        for item2 in iter2:
 | 
						|
            if item2[1].name == "label":
 | 
						|
                partition["label"] = item2[1].strings[0]
 | 
						|
            elif item2[1].name == "reg":
 | 
						|
                partition["ofs"] = (item2[1].words[0] <<
 | 
						|
                                    64) | (item2[1].words[1])
 | 
						|
                partition["size"] = (item2[1].words[2] <<
 | 
						|
                                     64) | (item2[1].words[3])
 | 
						|
        partitions.append(partition)
 | 
						|
    return partitions
 | 
						|
 | 
						|
 | 
						|
def parse_nvt_memory_cfg(fdt):
 | 
						|
    nvt_memory_cfgs = []
 | 
						|
    fdt_nvt_memory_cfg = fdt.to_fdt().resolve_path(r"/nvt_memory_cfg")
 | 
						|
    iter = fdt_nvt_memory_cfg.walk()
 | 
						|
    for item in iter:
 | 
						|
        if not isinstance(item[1], pyfdt.FdtNode):
 | 
						|
            continue
 | 
						|
        nvt_memory_cfg = dict()
 | 
						|
        nvt_memory_cfg["name"] = item[1].name
 | 
						|
        iter2 = item[1].walk()
 | 
						|
        for item2 in iter2:
 | 
						|
            if item2[1].name == "reg":
 | 
						|
                nvt_memory_cfg["ofs"] = item2[1].words[0]
 | 
						|
                nvt_memory_cfg["size"] = item2[1].words[1]
 | 
						|
        nvt_memory_cfgs.append(nvt_memory_cfg)
 | 
						|
    return nvt_memory_cfgs
 | 
						|
 | 
						|
 | 
						|
def parse_linux_memory(fdt):
 | 
						|
    linux_memories = []
 | 
						|
    fdt_linux_memory = fdt.to_fdt().resolve_path(r"/memory/reg")
 | 
						|
    for idx in range(int(len(fdt_linux_memory.words)/2)):
 | 
						|
        linux_memory = dict()
 | 
						|
        linux_memory["ofs"] = fdt_linux_memory.words[idx*2]
 | 
						|
        linux_memory["size"] = fdt_linux_memory.words[idx*2+1]
 | 
						|
        linux_memories.append(linux_memory)
 | 
						|
    return linux_memories
 | 
						|
 | 
						|
 | 
						|
def parse_reserved_memory(fdt):
 | 
						|
    reserved_memories = []
 | 
						|
    fdt_reserved_memory = fdt.to_fdt().resolve_path(r"/reserved-memory")
 | 
						|
    if fdt_reserved_memory is None:
 | 
						|
        return reserved_memories
 | 
						|
    iter = fdt_reserved_memory.walk()
 | 
						|
    for item in iter:
 | 
						|
        if not isinstance(item[1], pyfdt.FdtNode):
 | 
						|
            continue
 | 
						|
        reserved_memory = dict()
 | 
						|
        reserved_memory["name"] = item[1].name
 | 
						|
        reserved_memory["ofs"] = item[1][item[1].index("reg")].words[0]
 | 
						|
        reserved_memory["size"] = item[1][item[1].index("reg")].words[1]
 | 
						|
        reserved_memories.append(reserved_memory)
 | 
						|
    return reserved_memories
 | 
						|
 | 
						|
 | 
						|
def parse_hdal_memory(fdt):
 | 
						|
    hdal_memory = dict()
 | 
						|
    fdt_hdal_memory = fdt.to_fdt().resolve_path(r"/hdal-memory/media/reg")
 | 
						|
    hdal_memory["ofs"] = fdt_hdal_memory.words[0]
 | 
						|
    hdal_memory["size"] = fdt_hdal_memory.words[1]
 | 
						|
    return hdal_memory
 | 
						|
 | 
						|
 | 
						|
def parse_nvtpack(fdt, flash_path):
 | 
						|
    nvtpack_items = []
 | 
						|
    fdt_nvtpack = fdt.to_fdt().resolve_path(flash_path + r"/nvtpack/index")
 | 
						|
    if fdt_nvtpack is None:
 | 
						|
        return nvtpack_items
 | 
						|
    iter = fdt_nvtpack.walk()
 | 
						|
    for item in iter:
 | 
						|
        if not isinstance(item[1], pyfdt.FdtNode):
 | 
						|
            continue
 | 
						|
        if "id" not in item[1].name:
 | 
						|
            continue
 | 
						|
        nvtpack_item = dict()
 | 
						|
        nvtpack_item["id"] = item[1].name
 | 
						|
        iter2 = item[1].walk()
 | 
						|
        for item2 in iter2:
 | 
						|
            if item2[1].name == "partition_name":
 | 
						|
                nvtpack_item["partition_name"] = item2[1].strings[0]
 | 
						|
        nvtpack_items.append(nvtpack_item)
 | 
						|
    return nvtpack_items
 | 
						|
 | 
						|
 | 
						|
def parse_top(fdt):
 | 
						|
    top = dict()
 | 
						|
    fdt_top = fdt.to_fdt().resolve_path(r"/top@f0010000")
 | 
						|
    if fdt_top is None:
 | 
						|
        return top
 | 
						|
    iter = fdt_top.walk()
 | 
						|
    for item in iter:
 | 
						|
        if not isinstance(item[1], pyfdt.FdtNode):
 | 
						|
            continue
 | 
						|
        top[item[1].name] = item[1][0].words[0]
 | 
						|
    return top
 | 
						|
 | 
						|
 | 
						|
def check_nvt_info_embmem(nvt_info):
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_NONE":
 | 
						|
        return 0  # no embmem
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_NAND":
 | 
						|
        dbg_err("EMBMEM_NAND has deprecated.".format(
 | 
						|
            nvt_info["EMBMEM"], nvt_info["EMBMEM_BLK_SIZE"]))
 | 
						|
        return -1
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_SPI_NOR" and nvt_info["EMBMEM_BLK_SIZE"] != "0x10000":
 | 
						|
        dbg_err("EMBMEM({}) and EMBMEM_BLK_SIZE({}) are not matched".format(
 | 
						|
            nvt_info["EMBMEM"], nvt_info["EMBMEM_BLK_SIZE"]))
 | 
						|
        return -1
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_SPI_NAND" and nvt_info["EMBMEM_BLK_SIZE"] != "0x20000" and nvt_info["EMBMEM_BLK_SIZE"] != "0x40000":
 | 
						|
        dbg_err("EMBMEM({}) and EMBMEM_BLK_SIZE({}) are not matched".format(
 | 
						|
            nvt_info["EMBMEM"], nvt_info["EMBMEM_BLK_SIZE"]))
 | 
						|
        return -1
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_EMMC" and nvt_info["EMBMEM_BLK_SIZE"] != "0x200":
 | 
						|
        dbg_err("EMBMEM({}) and EMBMEM_BLK_SIZE({}) are not matched".format(
 | 
						|
            nvt_info["EMBMEM"], nvt_info["EMBMEM_BLK_SIZE"]))
 | 
						|
        return -1
 | 
						|
    # check NVT_ROOTFS_TYPE
 | 
						|
    if nvt_info["NVT_ROOTFS_TYPE"] == "NVT_ROOTFS_TYPE_RAMDISK":
 | 
						|
        pass
 | 
						|
    elif nvt_info["NVT_ROOTFS_TYPE"] == "NVT_ROOTFS_TYPE_SQUASH":
 | 
						|
        pass
 | 
						|
    elif nvt_info["EMBMEM"] == "EMBMEM_SPI_NOR" and "NVT_ROOTFS_TYPE_NOR" not in nvt_info["NVT_ROOTFS_TYPE"]:
 | 
						|
        dbg_err("NVT_ROOTFS_TYPE must be NVT_ROOTFS_TYPE_RAMDISK or NVT_ROOTFS_TYPE_NOR* or NVT_ROOTFS_TYPE_SQUASH")
 | 
						|
        return -1
 | 
						|
    elif nvt_info["EMBMEM"] == "EMBMEM_SPI_NAND" and "NVT_ROOTFS_TYPE_NAND" not in nvt_info["NVT_ROOTFS_TYPE"]:
 | 
						|
        dbg_err("NVT_ROOTFS_TYPE must be NVT_ROOTFS_TYPE_RAMDISK or NVT_ROOTFS_TYPE_NAND* or NVT_ROOTFS_TYPE_SQUASH")
 | 
						|
        return -1
 | 
						|
    elif nvt_info["EMBMEM"] == "EMBMEM_EMMC" and "NVT_ROOTFS_TYPE_EXT4" not in nvt_info["NVT_ROOTFS_TYPE"]:
 | 
						|
        dbg_err("NVT_ROOTFS_TYPE must be NVT_ROOTFS_TYPE_RAMDISK or NVT_ROOTFS_TYPE_EXT4* or NVT_ROOTFS_TYPE_SQUASH")
 | 
						|
        return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
def check_flash_partition(nvt_info, partitions):
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_NONE":
 | 
						|
        return 0  # no flash
 | 
						|
 | 
						|
    # check partition flash type matched with EMBMEM
 | 
						|
    if len(partitions[nvt_info["EMBMEM"]]) == 0:
 | 
						|
        dbg_err(
 | 
						|
            "storage-partition type is not matched to {} ".format(nvt_info["EMBMEM"]))
 | 
						|
        return -1
 | 
						|
    # check partition size block
 | 
						|
    blk_size = int(nvt_info["EMBMEM_BLK_SIZE"], 0)
 | 
						|
    partition = partitions[nvt_info["EMBMEM"]]
 | 
						|
 | 
						|
    if len(partition) < 3:
 | 
						|
        dbg_err("flash partition counts are less than 3. it doesn't make scene")
 | 
						|
        return -1
 | 
						|
    # check first must be loader or mbr and their size follow our spec
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_EMMC":
 | 
						|
        if partition[0]["name"] != "partition_mbr":
 | 
						|
            dbg_err("first flash partition must be partition_mbr")
 | 
						|
            return -1
 | 
						|
        if partition[1]["name"] != "partition_fdt":
 | 
						|
            dbg_err("2nd flash partition must be partition_fdt")
 | 
						|
            return -1
 | 
						|
        if partition[1]["ofs"] != 0x40000:
 | 
						|
            dbg_err("2nd flash partition offset must be 0x40000 for EMMC")
 | 
						|
            return -1
 | 
						|
    else:
 | 
						|
        if partition[0]["name"] != "partition_loader":
 | 
						|
            dbg_err("first flash partition must be partition_loader")
 | 
						|
            return -1
 | 
						|
        if partition[1]["name"] != "partition_fdt":
 | 
						|
            dbg_err("2nd flash partition must be partition_fdt")
 | 
						|
            return -1
 | 
						|
        if nvt_info["EMBMEM"] == "EMBMEM_SPI_NAND":
 | 
						|
            if partition[1]["ofs"] != blk_size*2:
 | 
						|
                dbg_err("2nd flash partition offset must be 0x{:X} for EMBMEM_SPI_NAND".format(
 | 
						|
                    blk_size*2))
 | 
						|
                return -1
 | 
						|
        else:
 | 
						|
            if partition[1]["ofs"] != blk_size:
 | 
						|
                dbg_err(
 | 
						|
                    "2nd flash partition offset must be 0x{:X} for EMBMEM_SPI_NOR".format(blk_size))
 | 
						|
                return -1
 | 
						|
    # check if partition_fdt.restore existing
 | 
						|
    if partition[2]["name"] != "partition_fdt.restore":
 | 
						|
        dbg_err("3nd flash partition suggest partition_fdt.restore")
 | 
						|
    for item in partition:
 | 
						|
        if item["size"] % blk_size != 0:
 | 
						|
            dbg_err("flash partition {} is not {} bytes aligned.".format(
 | 
						|
                item["label"], blk_size))
 | 
						|
            return -1
 | 
						|
    # check partition if in order and overlapped
 | 
						|
    for idx in range(len(partition)):
 | 
						|
        if idx == 0:
 | 
						|
            continue
 | 
						|
        if partition[idx]["ofs"] < partition[idx-1]["ofs"]+partition[idx-1]["size"] and partition[idx]["label"] != "all":
 | 
						|
            dbg_err("partition {}@0x{:X}, 0x{:X} overlapped with {}@0x{:X}, 0x{:X}".format(
 | 
						|
                partition[idx]["label"],
 | 
						|
                partition[idx]["ofs"],
 | 
						|
                partition[idx]["size"],
 | 
						|
                partition[idx-1]["label"],
 | 
						|
                partition[idx-1]["ofs"],
 | 
						|
                partition[idx-1]["size"]))
 | 
						|
            return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
def check_nvtpack(nvt_info, partitions, nvtpack_items):
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_NONE":
 | 
						|
        return 0  # no flash
 | 
						|
    # check partition flash type matched with EMBMEM
 | 
						|
    if len(nvtpack_items[nvt_info["EMBMEM"]]) == 0:
 | 
						|
        dbg_err(
 | 
						|
            "nvtpack-partition type is not matched to {} ".format(nvt_info["EMBMEM"]))
 | 
						|
        return -1
 | 
						|
    # check if id's partition_name is matched to storage partition
 | 
						|
    partition = partitions[nvt_info["EMBMEM"]]
 | 
						|
    nvtpack_item = nvtpack_items[nvt_info["EMBMEM"]]
 | 
						|
    n_item = len(partition) if len(partition) < len(
 | 
						|
        nvtpack_item) else len(nvtpack_item)
 | 
						|
    for idx in range(n_item):
 | 
						|
        nvtpack_partition_name = "partition_" + \
 | 
						|
            nvtpack_item[idx]["partition_name"]
 | 
						|
        if nvtpack_partition_name != partition[idx]["name"]:
 | 
						|
            dbg_err("nvtpack index.{} partition name '{}' but '{}' is excepted.".format(
 | 
						|
                idx,
 | 
						|
                nvtpack_item[idx]["partition_name"],
 | 
						|
                partition[idx]["name"].replace("partition_", "")))
 | 
						|
            return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
def check_memory(nvt_memory_cfgs, linux_memories, reserved_memories, hdal_memory):
 | 
						|
    fdt = None
 | 
						|
    rtos = None
 | 
						|
    bridge = None
 | 
						|
    linuxtmp = None
 | 
						|
    uboot = None
 | 
						|
    # nvt_memory_cfgs first must be dram size
 | 
						|
    if nvt_memory_cfgs[0]["name"] != "dram":
 | 
						|
        dbg_err("nvt_memory_cfg first item must be 'dram' but rather '{}'".format(
 | 
						|
            nvt_memory_cfgs[0]["name"]))
 | 
						|
        return -1
 | 
						|
    dram_size = nvt_memory_cfgs[0]["size"]
 | 
						|
    # check each element if is over range
 | 
						|
    for nvt_memory_cfg in nvt_memory_cfgs:
 | 
						|
        if nvt_memory_cfg["ofs"]+nvt_memory_cfg["size"] > dram_size:
 | 
						|
            dbg_err("nvt_memory_cfg's '{}' is out of dram size".format(
 | 
						|
                nvt_memory_cfg["name"]))
 | 
						|
            return -1
 | 
						|
        # keep fdt, rtos, bridge info for checking fastboot sanity later
 | 
						|
        if nvt_memory_cfg["name"] == "fdt":
 | 
						|
            fdt = nvt_memory_cfg
 | 
						|
        elif nvt_memory_cfg["name"] == "rtos":
 | 
						|
            rtos = nvt_memory_cfg
 | 
						|
        elif nvt_memory_cfg["name"] == "bridge":
 | 
						|
            bridge = nvt_memory_cfg
 | 
						|
        elif nvt_memory_cfg["name"] == "linuxtmp":
 | 
						|
            linuxtmp = nvt_memory_cfg
 | 
						|
        elif nvt_memory_cfg["name"] == "uboot":
 | 
						|
            uboot = nvt_memory_cfg
 | 
						|
    # check each element if in order and overlapped (disable it, becase rtos DEMO_EVB, rtos can overlap loader)
 | 
						|
    """
 | 
						|
    for idx in range(len(nvt_memory_cfgs)):
 | 
						|
        if idx == 0:
 | 
						|
            continue
 | 
						|
        if nvt_memory_cfgs[idx]["ofs"] < nvt_memory_cfgs[idx-1]["ofs"]+nvt_memory_cfgs[idx-1]["size"] and nvt_memory_cfgs[idx-1]["name"] != "dram":
 | 
						|
            dbg_err("nvt_memory_cfg {}@0x{:X}, 0x{:X} overlapped with {}@0x{:X}, 0x{:X}".format(
 | 
						|
                nvt_memory_cfgs[idx]["name"],
 | 
						|
                nvt_memory_cfgs[idx]["ofs"],
 | 
						|
                nvt_memory_cfgs[idx]["size"],
 | 
						|
                nvt_memory_cfgs[idx-1]["name"],
 | 
						|
                nvt_memory_cfgs[idx-1]["ofs"],
 | 
						|
                nvt_memory_cfgs[idx-1]["size"]))
 | 
						|
            return -1
 | 
						|
    """
 | 
						|
    # check if linux memory is over range
 | 
						|
    for linux_memory in linux_memories:
 | 
						|
        # linux_memory["ofs"] < dram_size for skipping dram2
 | 
						|
        if linux_memory["ofs"]+linux_memory["size"] > dram_size and linux_memory["ofs"] < dram_size:
 | 
						|
            dbg_err("linux memory is out of dram size")
 | 
						|
            return -1
 | 
						|
    # check if hdal memory is over range
 | 
						|
    # hdal_memory["ofs"] < dram_size for skipping dram2
 | 
						|
    if hdal_memory["ofs"]+hdal_memory["size"] > dram_size and hdal_memory["ofs"] < dram_size:
 | 
						|
        dbg_err("hdal memory is out of dram size")
 | 
						|
        return -1
 | 
						|
 | 
						|
    # uboot memory cannot be overlapped with linux system memory region
 | 
						|
    for linux_memory in linux_memories:
 | 
						|
        if uboot["ofs"] > linux_memory["ofs"] and uboot["ofs"] < linux_memory["ofs"]+linux_memory["size"]:
 | 
						|
            dbg_err(
 | 
						|
                "uboot memory cannot be overlapped with linux system memory region")
 | 
						|
            return -1
 | 
						|
        if uboot["ofs"] < linux_memory["ofs"] and uboot["ofs"]+uboot["size"] > linux_memory["ofs"]:
 | 
						|
            dbg_err(
 | 
						|
                "uboot memory cannot be overlapped with linux system memory region")
 | 
						|
            return -1
 | 
						|
 | 
						|
    # check reserved_memories must be in range of linux-memory and 4MB alignment
 | 
						|
    for reserved_memory in reserved_memories:
 | 
						|
        if (reserved_memory["size"] % 0x400000) != 0:
 | 
						|
            dbg_err("{} size must be 4MB alignment".format(
 | 
						|
                reserved_memory["name"]))
 | 
						|
            return -1
 | 
						|
        valid = 1
 | 
						|
        for linux_memory in linux_memories:
 | 
						|
            valid = 1
 | 
						|
            if reserved_memory["ofs"] < linux_memory["ofs"]:
 | 
						|
                valid = 0
 | 
						|
                continue
 | 
						|
            if reserved_memory["ofs"]+reserved_memory["size"] > linux_memory["ofs"]+linux_memory["size"]:
 | 
						|
                valid = 0
 | 
						|
                continue
 | 
						|
            if valid:
 | 
						|
                break
 | 
						|
        if not valid:
 | 
						|
            dbg_err(
 | 
						|
                "{} is out of linux-memory".format(reserved_memory["name"]))
 | 
						|
            return -1
 | 
						|
    # check if hdal memory overlap with linux-memory
 | 
						|
    for linux_memory in linux_memories:
 | 
						|
        if hdal_memory["ofs"] > linux_memory["ofs"] and hdal_memory["ofs"] < linux_memory["ofs"]+linux_memory["size"]:
 | 
						|
            dbg_err(
 | 
						|
                "hdal_memory memory cannot be overlapped with linux system memory region")
 | 
						|
            return -1
 | 
						|
        if hdal_memory["ofs"] < linux_memory["ofs"] and hdal_memory["ofs"]+hdal_memory["size"] > linux_memory["ofs"]:
 | 
						|
            dbg_err(
 | 
						|
                "uboot memory cannot be overlapped with linux system memory region")
 | 
						|
            return -1
 | 
						|
    # if bridge exist, check fastboot requirement
 | 
						|
    if bridge is not None:
 | 
						|
        # check1: fdt, rtos and bridge memory region must be contiguous.
 | 
						|
        if fdt["ofs"] + fdt["size"] != rtos["ofs"]:
 | 
						|
            dbg_err("fdt, rtos and bridge memory region must be contiguous.")
 | 
						|
            return -1
 | 
						|
        if rtos["ofs"] + rtos["size"] != bridge["ofs"]:
 | 
						|
            dbg_err("fdt, rtos and bridge memory region must be contiguous.")
 | 
						|
            return -1
 | 
						|
        hotplug_mem = dict()
 | 
						|
        hotplug_mem["ofs"] = fdt["ofs"]
 | 
						|
        hotplug_mem["size"] = fdt["size"] + rtos["size"] + bridge["size"]
 | 
						|
        # check2: fdt, rtos and bridge memory region cannot overlap with hdal and linux memory
 | 
						|
        for linux_memory in linux_memories:
 | 
						|
            if hotplug_mem["ofs"] > linux_memory["ofs"] and hotplug_mem["ofs"] < linux_memory["ofs"]+linux_memory["size"]:
 | 
						|
                dbg_err(
 | 
						|
                    "fdt, rtos and bridge memory region cannot overlap with hdal and linux memory")
 | 
						|
                return -1
 | 
						|
            if hotplug_mem["ofs"] < linux_memory["ofs"] and hotplug_mem["ofs"]+hotplug_mem["size"] > linux_memory["ofs"]:
 | 
						|
                dbg_err(
 | 
						|
                    "fdt, rtos and bridge memory region cannot overlap with hdal and linux memory")
 | 
						|
                return -1
 | 
						|
        # check3: fdt, rtos and bridge memory region cannot overlap with linuxtmp
 | 
						|
        if hotplug_mem["ofs"] > linuxtmp["ofs"] and hotplug_mem["ofs"] < linuxtmp["ofs"]+linuxtmp["size"]:
 | 
						|
            dbg_err("fdt, rtos and bridge memory region cannot overlap with linuxtmp")
 | 
						|
            return -1
 | 
						|
        if hotplug_mem["ofs"] < linuxtmp["ofs"] and hotplug_mem["ofs"]+hotplug_mem["size"] > linuxtmp["ofs"]:
 | 
						|
            dbg_err("fdt, rtos and bridge memory region cannot overlap with linuxtmp")
 | 
						|
            return -1
 | 
						|
        # check4: fdt, rtos and bridge memory have to start at 8MB alignment, and the size also needs 8MB alignment
 | 
						|
        if (hotplug_mem["ofs"] % 0x800000) != 0:
 | 
						|
            dbg_err(
 | 
						|
                "fdt, rtos and bridge memory have to start at 8MB alignment, and the size also needs 8MB alignment")
 | 
						|
            return -1
 | 
						|
        if (hotplug_mem["size"] % 0x800000) != 0:
 | 
						|
            dbg_err(
 | 
						|
                "fdt, rtos and bridge memory have to start at 8MB alignment, and the size also needs 8MB alignment")
 | 
						|
            return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
def check_top(top, nvt_info):
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_SPI_NAND" and (top["nand"] & 0xC) == 0xC:
 | 
						|
        dbg_err(
 | 
						|
            "top/nand is incorrect: 0x{:X} for EMBMEM=EMBMEM_SPI_NAND".format(top["nand"]))
 | 
						|
        return -1
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_SPI_NOR" and (top["nand"] & 0xC) == 0xC:
 | 
						|
        dbg_err(
 | 
						|
            "top/nand is incorrect: 0x{:X} for EMBMEM=EMBMEM_SPI_NOR".format(top["nand"]))
 | 
						|
        return -1
 | 
						|
    if nvt_info["EMBMEM"] == "EMBMEM_EMMC" and (top["sdio3"] & 0x3) == 0x0:
 | 
						|
        dbg_err(
 | 
						|
            "top/sdio3 is incorrect: 0x{:X} for EMBMEM=EMBMEM_EMMC".format(top["sdio3"]))
 | 
						|
        return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
def parse_args(argv):
 | 
						|
    parser = argparse.ArgumentParser(description='fdt checker')
 | 
						|
    parser.add_argument('-f', '--file', metavar='.dtb/.bin', required=True,
 | 
						|
                        dest='file', action='store',
 | 
						|
                        help='fdt binary file')
 | 
						|
    args = parser.parse_args()
 | 
						|
    return args
 | 
						|
 | 
						|
 | 
						|
def main(argv):
 | 
						|
    if 0:
 | 
						|
        argv.append(r"-f")
 | 
						|
        # argv.append(r"d:\tmp\nvt-na51055-evb.bin")
 | 
						|
        argv.append(
 | 
						|
            r"Z:\firmware\na51055_dual_sdk\na51055_linux_sdk\output\nvt-na51055-evb.bin")
 | 
						|
 | 
						|
    args = parse_args(argv)
 | 
						|
 | 
						|
    if not os.path.isfile(args.file):
 | 
						|
        print("cannot find {}".format(args.file), file=sys.stderr)
 | 
						|
        return -1
 | 
						|
 | 
						|
    print("verify {}".format(args.file))
 | 
						|
 | 
						|
    with open(args.file, 'rb') as infile:
 | 
						|
        fdt = FdtBlobParse(infile)
 | 
						|
 | 
						|
    nvt_info = parse_nvt_info(fdt)
 | 
						|
    partitions = dict()
 | 
						|
    partitions["EMBMEM_SPI_NAND"] = parse_flash_partition(
 | 
						|
        fdt, r"/nand@f0400000")
 | 
						|
    partitions["EMBMEM_SPI_NOR"] = parse_flash_partition(fdt, r"/nor@f0400000")
 | 
						|
    partitions["EMBMEM_EMMC"] = parse_flash_partition(fdt, r"/mmc@f0510000")
 | 
						|
    nvt_memory_cfgs = parse_nvt_memory_cfg(fdt)
 | 
						|
    linux_memories = parse_linux_memory(fdt)
 | 
						|
    reserved_memories = parse_reserved_memory(fdt)
 | 
						|
    hdal_memory = parse_hdal_memory(fdt)
 | 
						|
    nvtpack_items = dict()
 | 
						|
    nvtpack_items["EMBMEM_SPI_NAND"] = parse_nvtpack(fdt, r"/nand@f0400000")
 | 
						|
    nvtpack_items["EMBMEM_SPI_NOR"] = parse_nvtpack(fdt, r"/nor@f0400000")
 | 
						|
    nvtpack_items["EMBMEM_EMMC"] = parse_nvtpack(fdt, r"/mmc@f0510000")
 | 
						|
    top = parse_top(fdt)
 | 
						|
 | 
						|
    if check_nvt_info_embmem(nvt_info) != 0:
 | 
						|
        return -1
 | 
						|
    if check_flash_partition(nvt_info, partitions) != 0:
 | 
						|
        return -1
 | 
						|
    if check_nvtpack(nvt_info, partitions, nvtpack_items) != 0:
 | 
						|
        return -1
 | 
						|
    if check_memory(nvt_memory_cfgs, linux_memories, reserved_memories, hdal_memory) != 0:
 | 
						|
        return -1
 | 
						|
    if check_top(top, nvt_info) != 0:
 | 
						|
        return -1
 | 
						|
    return 0
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    try:
 | 
						|
        # colorama.init()
 | 
						|
        er = main(sys.argv)
 | 
						|
    except Exception as exp:
 | 
						|
        er = -1
 | 
						|
        print(exp, file=sys.stderr)
 | 
						|
        raise exp
 | 
						|
    sys.exit(er)
 |