[Feature][T108][task-view-1706] enable fastboot && auto make mtdpartinfo from dtsi fiel by self-config

    Only Configure: No
    Affected branch: GSW_V1453
    Affected module: SDK
    Is it affected on IC: only ASR
    Self-test: yes
    Doc Update: no

Change-Id: If72389ab2adb601c19bfa30491c03424444d47f1
diff --git a/config_fast_partition_list.sh b/config_fast_partition_list.sh
new file mode 100755
index 0000000..44456d3
--- /dev/null
+++ b/config_fast_partition_list.sh
@@ -0,0 +1,202 @@
+#!/bin/bash
+# ASR1806 Fast Partition Configuration Generator
+# Usage: ./config_fast_partion_list.sh --dtsi <dtsi> --config <json> --output <header>
+
+set -eo pipefail
+
+# ---------------------------
+# 彩色输出定义
+# ---------------------------
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# ---------------------------
+# 日志函数
+# ---------------------------
+timestamp() {
+    date "+%Y-%m-%d %H:%M:%S"
+}
+
+log() {
+    echo -e "[$(timestamp)] $1"
+}
+
+log_success() {
+    echo -e "[$(timestamp)] ${GREEN}SUCCESS${NC} $1"
+}
+
+log_warning() {
+    echo -e "[$(timestamp)] ${YELLOW}WARNING${NC} $1"
+}
+
+log_error() {
+    echo -e "[$(timestamp)] ${RED}ERROR${NC} $1" >&2
+}
+
+# ---------------------------
+# 参数处理
+# ---------------------------
+show_help() {
+    echo -e "${GREEN}Usage:${NC} $0 [options]"
+    echo
+    echo -e "${YELLOW}Mandatory Options:${NC}"
+    echo "  -d, --dtsi     Path to input DTSI partition file"
+    echo "  -c, --config   Path to JSON configuration file"
+    echo "  -o, --output   Path to output header file"
+    echo
+    echo -e "${YELLOW}Optional Options:${NC}"
+    echo "  -v, --verbose  Enable verbose output"
+    echo "  -h, --help     Show this help message"
+    exit 0
+}
+
+# 解析参数
+while [[ $# -gt 0 ]]; do
+    case "$1" in
+        -d|--dtsi)
+            DTSI_FILE="$2"
+            shift 2
+            ;;
+        -c|--config)
+            CONFIG_FILE="$2"
+            shift 2
+            ;;
+        -o|--output)
+            HEADER_FILE="$2"
+            shift 2
+            ;;
+        -v|--verbose)
+            VERBOSE=true
+            shift
+            ;;
+        -h|--help)
+            show_help
+            ;;
+        *)
+            log_error "Unknown option: $1"
+            show_help
+            exit 1
+            ;;
+    esac
+done
+
+# ---------------------------
+# 环境检查
+# ---------------------------
+check_requirements() {
+    log "Checking system requirements..."
+    
+    # 检查必需参数
+    local missing=()
+    [[ -z "$DTSI_FILE" ]] && missing+=("--dtsi")
+    [[ -z "$CONFIG_FILE" ]] && missing+=("--config")
+    [[ -z "$HEADER_FILE" ]] && missing+=("--output")
+
+    if [[ ${#missing[@]} -gt 0 ]]; then
+        log_error "Missing required options: ${missing[*]}"
+        show_help
+        exit 1
+    fi
+
+    # 检查依赖
+    if ! command -v python3 &>/dev/null; then
+        log_error "python3 is required but not installed"
+        exit 1
+    fi
+
+    log_success "All requirements satisfied"
+}
+
+validate_paths() {
+    log "Validating input paths..."
+    
+    # 检查输入文件
+    for file in "$DTSI_FILE" "$CONFIG_FILE"; do
+        if [[ ! -f "$file" ]]; then
+            log_error "File not found: $file"
+            exit 1
+        fi
+        log "Found: $file"
+    done
+
+    # 准备输出目录
+    mkdir -p "$(dirname "$HEADER_FILE")" || {
+        log_error "Failed to create output directory: $(dirname "$HEADER_FILE")"
+        exit 1
+    }
+    log "Output will be written to: $HEADER_FILE"
+
+    log_success "Path validation passed"
+}
+
+# ---------------------------
+# 主逻辑
+# ---------------------------
+generate_partitions() {
+    local py_script="$(dirname "$0")/generate_partitions.py"
+    
+    log "Starting partition configuration generation..."
+    log "--------------------------------------------"
+    log "Input DTSI:    $DTSI_FILE"
+    log "Config JSON:   $CONFIG_FILE"
+    log "Output Header: $HEADER_FILE"
+    log "Python Script: $py_script"
+    log "--------------------------------------------"
+
+    local py_cmd=(python3 "$py_script"
+        --dtsi "$DTSI_FILE"
+        --config "$CONFIG_FILE"
+        --header "$HEADER_FILE"
+    )
+    
+    [[ $VERBOSE == true ]] && py_cmd+=(--verbose)
+
+    if ! "${py_cmd[@]}"; then
+        log_error "Partition generation failed"
+        exit 1
+    fi
+
+    log_success "Configuration generated successfully"
+}
+
+verify_output() {
+    log "Verifying output file..."
+    
+    if [[ ! -f "$HEADER_FILE" ]]; then
+        log_error "Output file was not created: $HEADER_FILE"
+        exit 1
+    fi
+
+    local line_count=$(wc -l < "$HEADER_FILE")
+    local generated_lines=$(grep -c "Auto-generated partition config" "$HEADER_FILE")
+    
+    log "Output file info:"
+    log "  Path:       $HEADER_FILE"
+    log "  Lines:      $line_count"
+    log "  Generated:  $generated_lines"
+    
+    if [[ $generated_lines -eq 0 ]]; then
+        log_warning "No generated content found in output file"
+    fi
+
+    log_success "Output verification passed"
+}
+
+# ---------------------------
+# 主流程
+# ---------------------------
+main() {
+    echo -e "\n${GREEN}=== ASR1806 Partition Config Generator ===${NC}"
+    
+    check_requirements
+    validate_paths
+    generate_partitions
+    verify_output
+    
+    echo -e "\n${GREEN}=== Operation Completed Successfully ===${NC}"
+    echo -e "Output file created: ${YELLOW}$HEADER_FILE${NC}"
+}
+
+main
\ No newline at end of file
diff --git a/generate_partitions.py b/generate_partitions.py
new file mode 100755
index 0000000..f114e1b
--- /dev/null
+++ b/generate_partitions.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python3
+# ASR1806 Partition Configuration Generator (Final Correct Format)
+
+import re
+import json
+import sys
+import os
+import argparse
+from collections import OrderedDict
+from pathlib import Path
+
+def validate_file(path, description):
+    """Validate input file exists and is readable"""
+    path_obj = Path(path)
+    if not path_obj.exists():
+        raise FileNotFoundError(f"{description} not found: {path}")
+    if not path_obj.is_file():
+        raise IOError(f"{description} path is not a file: {path}")
+    if not os.access(str(path_obj), os.R_OK):
+        raise PermissionError(f"Cannot read {description}: {path}")
+    return path_obj
+
+def parse_dtsi_partitions(dtsi_file):
+    """Parse partition information from DTSI file"""
+    partitions = OrderedDict()
+    try:
+        with open(dtsi_file, 'r', encoding='utf-8') as f:
+            content = f.read()
+        
+        pattern = re.compile(
+            r'partition@([0-9A-Fa-f]+)\s*{\s*.*?label\s*=\s*"([^"]+)";\s*.*?reg\s*=\s*<([^>]+)>;\s*.*?};',
+            re.DOTALL
+        )
+        
+        for match in pattern.finditer(content):
+            try:
+                start_addr = int(match.group(1), 16)
+                label = match.group(2).strip()
+                reg_values = [int(x, 16) for x in match.group(3).split()]
+                
+                if not reg_values:
+                    print(f"Invalid reg value for partition {label}", file=sys.stderr)
+                    continue
+                    
+                size = reg_values[-1] if len(reg_values) > 1 else reg_values[0]
+                
+                partitions[label] = {
+                    'start_addr': f"0x{start_addr:08X}",
+                    'size': f"0x{size:08X}",
+                    'size_bytes': size
+                }
+            except ValueError as e:
+                print(f"Failed to parse partition data: {e}", file=sys.stderr)
+                continue
+        
+        if not partitions:
+            raise ValueError("No valid partitions found in DTSI file")
+            
+        print(f"Parsed {len(partitions)} partitions from {dtsi_file}")
+        return partitions
+    except Exception as e:
+        raise RuntimeError(f"DTSI parse failed: {str(e)}") from e
+
+def load_config(config_file):
+    """Load and validate partition configuration"""
+    try:
+        with open(config_file, 'r', encoding='utf-8') as f:
+            config = json.load(f, object_pairs_hook=OrderedDict)
+        
+        required = {
+            'mtdparts_order': list,
+            'partition_aliases': dict
+        }
+        for key, typ in required.items():
+            if key not in config:
+                raise KeyError(f"Missing required key: {key}")
+            if not isinstance(config[key], typ):
+                raise TypeError(f"{key} must be {typ.__name__}")
+        
+        print(f"Loaded config from {config_file}")
+        return config
+    except json.JSONDecodeError as e:
+        raise RuntimeError(f"Invalid JSON format: {str(e)}") from e
+    except Exception as e:
+        raise RuntimeError(f"Config load failed: {str(e)}") from e
+
+def generate_complete_config(partitions, config):
+    """Generate the complete configuration block with exact formatting"""
+    # 1. Generate partition defines
+    defines = []
+    for part_name, alias in config['partition_aliases'].items():
+        if part_name not in partitions:
+            print(f"Config references unknown partition: {part_name}", file=sys.stderr)
+            continue
+        defines.append(f'#define {alias} "{part_name}"')
+    defines_section = "\n".join(defines)
+
+    # 2. Generate MTDPARTS content with exact formatting
+    mtdparts = []
+    valid_parts = [p for p in config['mtdparts_order'] if p in partitions and p in config['partition_aliases']]
+    num_parts = len(valid_parts)
+    
+    for i, part_name in enumerate(valid_parts):
+        part = partitions[part_name]
+        alias = config['partition_aliases'][part_name]
+        
+        # 构建每个分区的定义,格式为 "0x00180000@0x02600000("UBOOT_MTD_PART_A"),"
+        mtd_entry = f'0x{part["size"][2:]}@0x{part["start_addr"][2:]}("{alias}")'
+        if i < num_parts - 1:
+            mtd_entry += ','  # 除最后一个分区外,每个分区后加逗号
+        
+        # 每个分区定义用双引号包裹,并添加行继续符和缩进
+        if i == 0:
+            # 第一个分区不需要额外缩进
+            mtdparts.append(f'"mtdparts=nand_mtd:{mtd_entry}"\\')
+        else:
+            # 后续分区需要 5 个空格缩进
+            mtdparts.append(f'     "{mtd_entry}"\\')
+    
+    # 最后一行需要单独处理,确保没有双引号和反斜杠
+    if mtdparts:
+        last_line = mtdparts.pop()  # 移除最后一行
+        # 构建不带双引号和反斜杠的最后一行
+        mtdparts.append(last_line.replace('\\"', '').replace('\\', ''))
+    
+    # 连接所有分区定义
+    mtdparts_joined = '\n'.join(mtdparts)
+    
+    # 构建最终的 MTDPARTS 部分
+    mtdparts_section = f"""#ifdef CONFIG_CMD_FASTBOOT
+#define CONFIG_MTDPARTS \\
+{mtdparts_joined}
+#endif /* CONFIG_CMD_FASTBOOT */"""
+
+    # 3. Combine into complete block
+    complete_content = f"""{defines_section}
+
+{mtdparts_section}"""
+    
+    return complete_content
+
+def update_header_file(header_file, complete_content):
+    """Replace ONLY the content between dynamic markers"""
+    try:
+        header_file.parent.mkdir(parents=True, exist_ok=True)
+        
+        if not header_file.exists():
+            raise RuntimeError(f"Header file does not exist: {header_file}")
+        
+        # Read existing content
+        with open(header_file, 'r', encoding='utf-8') as f:
+            content = f.read()
+        original_mode = header_file.stat().st_mode
+        
+        # Pattern to find the exact block to replace
+        pattern = re.compile(
+            r'(/\* add mtd parts dynamically \*/\n)(.*?)(\n#else)',
+            re.DOTALL
+        )
+        
+        match = pattern.search(content)
+        if not match:
+            raise RuntimeError("Could not find the replacement markers ('/* add mtd parts dynamically */' to '#else')")
+        
+        # Replace only the middle part
+        updated_content = (
+            content[:match.start(2)] + 
+            complete_content + 
+            content[match.end(2):]
+        )
+        
+        # Write updated content
+        with open(header_file, 'w', encoding='utf-8') as f:
+            f.write(updated_content)
+        header_file.chmod(original_mode)
+        
+        print(f"Successfully updated {header_file}")
+        return True
+        
+    except Exception as e:
+        raise RuntimeError(f"Header update failed: {str(e)}") from e
+
+def main():
+    parser = argparse.ArgumentParser(
+        description='Generate partition configuration between markers',
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    
+    parser.add_argument('--dtsi', required=True,
+                       help='Input DTSI file with partition layout')
+    parser.add_argument('--config', required=True,
+                       help='JSON config file with partition aliases')
+    parser.add_argument('--header', required=True,
+                       help='Output header file path')
+    parser.add_argument('--verbose', action='store_true',
+                       help='Show detailed processing info')
+    
+    args = parser.parse_args()
+    
+    try:
+        dtsi_path = validate_file(args.dtsi, "DTSI file")
+        config_path = validate_file(args.config, "Config file")
+        header_path = Path(args.header).resolve()
+        
+        if args.verbose:
+            print(f"Processing:\n- DTSI: {dtsi_path}\n- Config: {config_path}\n- Output: {header_path}")
+        
+        partitions = parse_dtsi_partitions(dtsi_path)
+        config = load_config(config_path)
+        
+        # Verify all configured partitions exist
+        missing = [p for p in config['mtdparts_order'] if p not in partitions]
+        if missing:
+            print(f"Missing partitions in DTSI: {', '.join(missing)}", file=sys.stderr)
+        
+        complete_content = generate_complete_config(partitions, config)
+        
+        if args.verbose:
+            print("\nGenerated content to insert:")
+            print("-" * 40)
+            print(complete_content)
+            print("-" * 40)
+        
+        updated = update_header_file(header_path, complete_content)
+        
+        if updated:
+            print("Update completed successfully")
+        
+        return 0
+        
+    except Exception as e:
+        print(f"Error: {str(e)}", file=sys.stderr)
+        return 1
+
+if __name__ == "__main__":
+    sys.exit(main())
\ No newline at end of file
diff --git a/marvell/uboot/drivers/usb/gadget/fastboot.c b/marvell/uboot/drivers/usb/gadget/fastboot.c
index 38ce796..04fc959 100644
--- a/marvell/uboot/drivers/usb/gadget/fastboot.c
+++ b/marvell/uboot/drivers/usb/gadget/fastboot.c
@@ -232,6 +232,10 @@
 
 static void rx_complete(struct usb_ep *ep, struct usb_request *req)
 {
+        if (req->actual < req->length)
+        {
+            *(u8 *)(((u8 *)req->buf) + req->actual) = 0x0;
+        }
 	rcv_cmd();
 	req->length = 512;
 	req->complete = rx_complete;
diff --git a/marvell/uboot/include/configs/fact_p301.h b/marvell/uboot/include/configs/fact_p301.h
index 9b5daf4..dcd65bd 100755
--- a/marvell/uboot/include/configs/fact_p301.h
+++ b/marvell/uboot/include/configs/fact_p301.h
@@ -187,9 +187,7 @@
 #define CONFIG_URB_BUF_SIZE	256
 #define CONFIG_USB_REG_BASE	0xc0000000
 #define CONFIG_USB_PHY_BASE	0xd4207000
-#ifdef CONFIG_TEE_OS
 #define CONFIG_CMD_FASTBOOT	1
-#endif
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/package/boot/uboot-mmp/Makefile b/package/boot/uboot-mmp/Makefile
index cbc1258..719b588 100755
--- a/package/boot/uboot-mmp/Makefile
+++ b/package/boot/uboot-mmp/Makefile
@@ -15,6 +15,12 @@
 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
 
+#add dtsi DIR
+HEADFILE_DIR:=$(TOPDIR)/marvell/uboot/include/configs
+DTSIFILE_DIR:=$(TOPDIR)/marvell/linux/arch/arm/boot/dts
+PATCONFFILE_DIR:=$(TOPDIR)
+SHELLFIE_DIR:=$(TOPDIR)
+
 include $(INCLUDE_DIR)/package.mk
 
 define uboot/Default
@@ -96,6 +102,10 @@
 endif
 
 define Build/Configure
+	/bin/bash $(TOPDIR)/config_fast_partition_list.sh \
+		--dtsi $(DTSIFILE_DIR)/asr1806_ab_flash_layout.dtsi \
+		--config $(PATCONFFILE_DIR)/partition_config.json \
+		--output $(HEADFILE_DIR)/fact_p301.h
 	@if [ -d $(PKG_BUILD_DIR) ]; then \
 		$(MAKE) CONFIG_SECURE_DM=$(CONFIG_SECURE_DM) CONFIG_SECURE_IMA=$(CONFIG_SECURE_IMA) \
 			CONFIG_HARDWARE_AES_ENGINE=$(CONFIG_HARDWARE_AES_ENGINE) CONFIG_SECURE_DM_CRYPT=$(CONFIG_SECURE_DM_CRYPT) \
diff --git a/partition_config.json b/partition_config.json
new file mode 100755
index 0000000..fd29c86
--- /dev/null
+++ b/partition_config.json
@@ -0,0 +1,16 @@
+{
+    "mtdparts_order": [
+        "u-boot-a",
+        "u-boot-b",
+        "oemapp-a",
+        "oemapp-b",
+        "oemdata"
+    ],
+    "partition_aliases": {
+        "u-boot-a": "UBOOT_MTD_PART_A",
+        "u-boot-b": "UBOOT_MTD_PART_B",
+        "oemapp-a": "OEM_APP_MTD_PART_A",
+        "oemapp-b": "OEM_APP_MTD_PART_B",
+        "oemdata": "OEM_DATA_MTD_PART"
+    }
+}