Message ID | 20190415164738.28024-3-luca@lucaceresoli.net |
---|---|
State | Superseded |
Delegated to: | Michal Simek |
Headers | show |
Series | arm64: zynqmp: pass a PMUFW config object | expand |
Hi, On 15. 04. 19 9:47, Luca Ceresoli wrote: > The recently-added ZYNQMP_LOAD_PM_CFG_OBJ_FILE option allows SPL to load a > PMUFW configuration object from a binary blob. However the configuration > object is produced by Xilinx proprietary tools as a C source file and no > tool exists to easily convert it to a binary blob in an embedded Linux > build system for U-Boot to use. > > Add a simple Python script to do the conversion. > > It is definitely not a complete C language parser, but it is enough to > parse the known patterns generated by Xilinx tools, including: > > - defines > - literal integers, optionally with a 'U' suffix > - bitwise OR between them > > Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> > --- > arch/arm/mach-zynqmp/pm_cfg_obj_convert.py | 302 +++++++++++++++++++++ > 1 file changed, 302 insertions(+) > create mode 100755 arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > > diff --git a/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > new file mode 100755 > index 000000000000..5aea15860319 > --- /dev/null > +++ b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > @@ -0,0 +1,302 @@ > +#!/usr/bin/env python3 > +# SPDX-License-Identifier: GPL-2.0+ > +# Copyright (C) 2019 Luca Ceresoli <luca@lucaceresoli.net> > + > +import sys > +import re > +import struct > +import logging > +import argparse > + > +parser = argparse.ArgumentParser( > + description='Convert a PMU configuration object from C source to a binary blob.', > + allow_abbrev=False) > +parser.add_argument('-D', '--debug', action="store_true") > +parser.add_argument( > + "in_file", metavar='INPUT_FILE', > + help='PMU configuration object (C source as produced by Xilinx XSDK)') > +parser.add_argument( > + "out_file", metavar='OUTPUT_FILE', > + help='PMU configuration object binary blob') > +args = parser.parse_args() > + > +logging.basicConfig(format='%(levelname)s:%(message)s', > + level=(logging.DEBUG if args.debug else logging.WARNING)) > + > +pm_define = { > + 'PM_CAP_ACCESS' : 0x1, > + 'PM_CAP_CONTEXT' : 0x2, > + 'PM_CAP_WAKEUP' : 0x4, > + > + 'NODE_UNKNOWN' : 0, > + 'NODE_APU' : 1, > + 'NODE_APU_0' : 2, > + 'NODE_APU_1' : 3, > + 'NODE_APU_2' : 4, > + 'NODE_APU_3' : 5, > + 'NODE_RPU' : 6, > + 'NODE_RPU_0' : 7, > + 'NODE_RPU_1' : 8, > + 'NODE_PLD' : 9, > + 'NODE_FPD' : 10, > + 'NODE_OCM_BANK_0' : 11, > + 'NODE_OCM_BANK_1' : 12, > + 'NODE_OCM_BANK_2' : 13, > + 'NODE_OCM_BANK_3' : 14, > + 'NODE_TCM_0_A' : 15, > + 'NODE_TCM_0_B' : 16, > + 'NODE_TCM_1_A' : 17, > + 'NODE_TCM_1_B' : 18, > + 'NODE_L2' : 19, > + 'NODE_GPU_PP_0' : 20, > + 'NODE_GPU_PP_1' : 21, > + 'NODE_USB_0' : 22, > + 'NODE_USB_1' : 23, > + 'NODE_TTC_0' : 24, > + 'NODE_TTC_1' : 25, > + 'NODE_TTC_2' : 26, > + 'NODE_TTC_3' : 27, > + 'NODE_SATA' : 28, > + 'NODE_ETH_0' : 29, > + 'NODE_ETH_1' : 30, > + 'NODE_ETH_2' : 31, > + 'NODE_ETH_3' : 32, > + 'NODE_UART_0' : 33, > + 'NODE_UART_1' : 34, > + 'NODE_SPI_0' : 35, > + 'NODE_SPI_1' : 36, > + 'NODE_I2C_0' : 37, > + 'NODE_I2C_1' : 38, > + 'NODE_SD_0' : 39, > + 'NODE_SD_1' : 40, > + 'NODE_DP' : 41, > + 'NODE_GDMA' : 42, > + 'NODE_ADMA' : 43, > + 'NODE_NAND' : 44, > + 'NODE_QSPI' : 45, > + 'NODE_GPIO' : 46, > + 'NODE_CAN_0' : 47, > + 'NODE_CAN_1' : 48, > + 'NODE_EXTERN' : 49, > + 'NODE_APLL' : 50, > + 'NODE_VPLL' : 51, > + 'NODE_DPLL' : 52, > + 'NODE_RPLL' : 53, > + 'NODE_IOPLL' : 54, > + 'NODE_DDR' : 55, > + 'NODE_IPI_APU' : 56, > + 'NODE_IPI_RPU_0' : 57, > + 'NODE_GPU' : 58, > + 'NODE_PCIE' : 59, > + 'NODE_PCAP' : 60, > + 'NODE_RTC' : 61, > + 'NODE_LPD' : 62, > + 'NODE_VCU' : 63, > + 'NODE_IPI_RPU_1' : 64, > + 'NODE_IPI_PL_0' : 65, > + 'NODE_IPI_PL_1' : 66, > + 'NODE_IPI_PL_2' : 67, > + 'NODE_IPI_PL_3' : 68, > + 'NODE_PL' : 69, > + 'NODE_ID_MA' : 70, > + > + 'XILPM_RESET_PCIE_CFG' : 1000, > + 'XILPM_RESET_PCIE_BRIDGE' : 1001, > + 'XILPM_RESET_PCIE_CTRL' : 1002, > + 'XILPM_RESET_DP' : 1003, > + 'XILPM_RESET_SWDT_CRF' : 1004, > + 'XILPM_RESET_AFI_FM5' : 1005, > + 'XILPM_RESET_AFI_FM4' : 1006, > + 'XILPM_RESET_AFI_FM3' : 1007, > + 'XILPM_RESET_AFI_FM2' : 1008, > + 'XILPM_RESET_AFI_FM1' : 1009, > + 'XILPM_RESET_AFI_FM0' : 1010, > + 'XILPM_RESET_GDMA' : 1011, > + 'XILPM_RESET_GPU_PP1' : 1012, > + 'XILPM_RESET_GPU_PP0' : 1013, > + 'XILPM_RESET_GPU' : 1014, > + 'XILPM_RESET_GT' : 1015, > + 'XILPM_RESET_SATA' : 1016, > + 'XILPM_RESET_ACPU3_PWRON' : 1017, > + 'XILPM_RESET_ACPU2_PWRON' : 1018, > + 'XILPM_RESET_ACPU1_PWRON' : 1019, > + 'XILPM_RESET_ACPU0_PWRON' : 1020, > + 'XILPM_RESET_APU_L2' : 1021, > + 'XILPM_RESET_ACPU3' : 1022, > + 'XILPM_RESET_ACPU2' : 1023, > + 'XILPM_RESET_ACPU1' : 1024, > + 'XILPM_RESET_ACPU0' : 1025, > + 'XILPM_RESET_DDR' : 1026, > + 'XILPM_RESET_APM_FPD' : 1027, > + 'XILPM_RESET_SOFT' : 1028, > + 'XILPM_RESET_GEM0' : 1029, > + 'XILPM_RESET_GEM1' : 1030, > + 'XILPM_RESET_GEM2' : 1031, > + 'XILPM_RESET_GEM3' : 1032, > + 'XILPM_RESET_QSPI' : 1033, > + 'XILPM_RESET_UART0' : 1034, > + 'XILPM_RESET_UART1' : 1035, > + 'XILPM_RESET_SPI0' : 1036, > + 'XILPM_RESET_SPI1' : 1037, > + 'XILPM_RESET_SDIO0' : 1038, > + 'XILPM_RESET_SDIO1' : 1039, > + 'XILPM_RESET_CAN0' : 1040, > + 'XILPM_RESET_CAN1' : 1041, > + 'XILPM_RESET_I2C0' : 1042, > + 'XILPM_RESET_I2C1' : 1043, > + 'XILPM_RESET_TTC0' : 1044, > + 'XILPM_RESET_TTC1' : 1045, > + 'XILPM_RESET_TTC2' : 1046, > + 'XILPM_RESET_TTC3' : 1047, > + 'XILPM_RESET_SWDT_CRL' : 1048, > + 'XILPM_RESET_NAND' : 1049, > + 'XILPM_RESET_ADMA' : 1050, > + 'XILPM_RESET_GPIO' : 1051, > + 'XILPM_RESET_IOU_CC' : 1052, > + 'XILPM_RESET_TIMESTAMP' : 1053, > + 'XILPM_RESET_RPU_R50' : 1054, > + 'XILPM_RESET_RPU_R51' : 1055, > + 'XILPM_RESET_RPU_AMBA' : 1056, > + 'XILPM_RESET_OCM' : 1057, > + 'XILPM_RESET_RPU_PGE' : 1058, > + 'XILPM_RESET_USB0_CORERESET' : 1059, > + 'XILPM_RESET_USB1_CORERESET' : 1060, > + 'XILPM_RESET_USB0_HIBERRESET' : 1061, > + 'XILPM_RESET_USB1_HIBERRESET' : 1062, > + 'XILPM_RESET_USB0_APB' : 1063, > + 'XILPM_RESET_USB1_APB' : 1064, > + 'XILPM_RESET_IPI' : 1065, > + 'XILPM_RESET_APM_LPD' : 1066, > + 'XILPM_RESET_RTC' : 1067, > + 'XILPM_RESET_SYSMON' : 1068, > + 'XILPM_RESET_AFI_FM6' : 1069, > + 'XILPM_RESET_LPD_SWDT' : 1070, > + 'XILPM_RESET_FPD' : 1071, > + 'XILPM_RESET_RPU_DBG1' : 1072, > + 'XILPM_RESET_RPU_DBG0' : 1073, > + 'XILPM_RESET_DBG_LPD' : 1074, > + 'XILPM_RESET_DBG_FPD' : 1075, > + 'XILPM_RESET_APLL' : 1076, > + 'XILPM_RESET_DPLL' : 1077, > + 'XILPM_RESET_VPLL' : 1078, > + 'XILPM_RESET_IOPLL' : 1079, > + 'XILPM_RESET_RPLL' : 1080, > + 'XILPM_RESET_GPO3_PL_0' : 1081, > + 'XILPM_RESET_GPO3_PL_1' : 1082, > + 'XILPM_RESET_GPO3_PL_2' : 1083, > + 'XILPM_RESET_GPO3_PL_3' : 1084, > + 'XILPM_RESET_GPO3_PL_4' : 1085, > + 'XILPM_RESET_GPO3_PL_5' : 1086, > + 'XILPM_RESET_GPO3_PL_6' : 1087, > + 'XILPM_RESET_GPO3_PL_7' : 1088, > + 'XILPM_RESET_GPO3_PL_8' : 1089, > + 'XILPM_RESET_GPO3_PL_9' : 1090, > + 'XILPM_RESET_GPO3_PL_10' : 1091, > + 'XILPM_RESET_GPO3_PL_11' : 1092, > + 'XILPM_RESET_GPO3_PL_12' : 1093, > + 'XILPM_RESET_GPO3_PL_13' : 1094, > + 'XILPM_RESET_GPO3_PL_14' : 1095, > + 'XILPM_RESET_GPO3_PL_15' : 1096, > + 'XILPM_RESET_GPO3_PL_16' : 1097, > + 'XILPM_RESET_GPO3_PL_17' : 1098, > + 'XILPM_RESET_GPO3_PL_18' : 1099, > + 'XILPM_RESET_GPO3_PL_19' : 1100, > + 'XILPM_RESET_GPO3_PL_20' : 1101, > + 'XILPM_RESET_GPO3_PL_21' : 1102, > + 'XILPM_RESET_GPO3_PL_22' : 1103, > + 'XILPM_RESET_GPO3_PL_23' : 1104, > + 'XILPM_RESET_GPO3_PL_24' : 1105, > + 'XILPM_RESET_GPO3_PL_25' : 1106, > + 'XILPM_RESET_GPO3_PL_26' : 1107, > + 'XILPM_RESET_GPO3_PL_27' : 1108, > + 'XILPM_RESET_GPO3_PL_28' : 1109, > + 'XILPM_RESET_GPO3_PL_29' : 1110, > + 'XILPM_RESET_GPO3_PL_30' : 1111, > + 'XILPM_RESET_GPO3_PL_31' : 1112, > + 'XILPM_RESET_RPU_LS' : 1113, > + 'XILPM_RESET_PS_ONLY' : 1114, > + 'XILPM_RESET_PL' : 1115, > + 'XILPM_RESET_GPIO5_EMIO_92' : 1116, > + 'XILPM_RESET_GPIO5_EMIO_93' : 1117, > + 'XILPM_RESET_GPIO5_EMIO_94' : 1118, > + 'XILPM_RESET_GPIO5_EMIO_95' : 1119, > + > + 'PM_CONFIG_MASTER_SECTION_ID' : 0x101, > + 'PM_CONFIG_SLAVE_SECTION_ID' : 0x102, > + 'PM_CONFIG_PREALLOC_SECTION_ID' : 0x103, > + 'PM_CONFIG_POWER_SECTION_ID' : 0x104, > + 'PM_CONFIG_RESET_SECTION_ID' : 0x105, > + 'PM_CONFIG_SHUTDOWN_SECTION_ID' : 0x106, > + 'PM_CONFIG_SET_CONFIG_SECTION_ID' : 0x107, > + 'PM_CONFIG_GPO_SECTION_ID' : 0x108, > + > + 'PM_SLAVE_FLAG_IS_SHAREABLE' : 0x1, > + 'PM_MASTER_USING_SLAVE_MASK' : 0x2, > + > + 'PM_CONFIG_GPO1_MIO_PIN_34_MAP' : (1 << 10), > + 'PM_CONFIG_GPO1_MIO_PIN_35_MAP' : (1 << 11), > + 'PM_CONFIG_GPO1_MIO_PIN_36_MAP' : (1 << 12), > + 'PM_CONFIG_GPO1_MIO_PIN_37_MAP' : (1 << 13), > + > + 'PM_CONFIG_GPO1_BIT_2_MASK' : (1 << 2), > + 'PM_CONFIG_GPO1_BIT_3_MASK' : (1 << 3), > + 'PM_CONFIG_GPO1_BIT_4_MASK' : (1 << 4), > + 'PM_CONFIG_GPO1_BIT_5_MASK' : (1 << 5), > + > + 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, > + > + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, > + 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, > + 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, > +} > + > +in_file = open(args.in_file, mode='r') > +out_file = open(args.out_file, mode='wb') > + > +num_re = re.compile(r"^([0-9]+)U?$") > +const_re = re.compile(r"^([A-Z_][A-Z0-9_]*)$") > + > +def process_item(item): > + logging.debug("* ITEM " + item) > + > + value = 0 > + for item in item.split('|'): > + item = item.strip() > + > + num_match = num_re .match(item) > + const_match = const_re.match(item) > + > + if num_match: > + num = int(num_match.group(1)) > + logging.debug(" - num " + str(num)) > + value |= num > + elif const_match: > + name = const_match.group(1) > + if not name in pm_define: > + sys.stderr.write("Unknown define " + name + "!\n") > + exit(1) > + num = pm_define[name] > + logging.debug(" - def " + hex(num)) > + value |= num > + > + logging.debug(" = res " + hex(value)) > + out_file.write(struct.pack('<L', value)) > + > + > +# Read all code > +code = in_file.read() > + > +# remove comments > +code = re.sub('//.*?\n|/\*.*?\*/', '', code, flags=re.DOTALL) > + > +# remove everything outside the XPm_ConfigObject array definition > +code = re.search('const u32 XPm_ConfigObject.*= {\n(.*)};', > + code, flags=re.DOTALL).group(1) > + > +# Process each comma-separated array item > +for item in code.split(','): > + item = item.strip() > + if item: > + process_item(item.strip()) > + > +print("Wrote %d bytes" % out_file.tell()) > I have created simple script for extracting this object also from fsbl elf file. Maybe we should also publish it when this is out. For your reference. #!/bin/bash # Written by Michal Simek FSBL=zynqmp_fsbl PMCFG=pmcfg.bin PM_END=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n '/XPm_ConfigObject/,/^$/p' | head -n -2 | tail -n 1 | cut -c 5-12 | awk '{printf ("0x%s",$1)}'` PM_START=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n '/XPm_ConfigObject/,/^$/p' | head -n 1 | awk '{printf ("0x%s",$1)}'` FSBL_START=`aarch64-linux-gnu-readelf -a ${FSBL}.elf | grep "Entry point address" | awk '{print $4}'` PM_OBJECT_START=`echo $((${PM_START} - ${FSBL_START}))` PM_OBJECT_SIZE=`echo $((${PM_END} - ${PM_START}))` echo "FSBL starting address ${FSBL_START}" echo "FSBL object addresses ${PM_START} ${PM_END}" echo "OBJECT start ${PM_OBJECT_START} size ${PM_OBJECT_SIZE}" aarch64-linux-gnu-objcopy -O binary ${FSBL}.elf ${FSBL}.bin # Extracting config object dd if=${FSBL}.bin of=${PMCFG} bs=1 skip=${PM_OBJECT_START} count=${PM_OBJECT_SIZE} > /dev/null 2>&1 echo "Your object ${PMCFG} is ready" rm -f ${FSBL}.bin *~ Anyway this patch is good. I didn't test it but it looks ok. M
Hi Michal, On 04/05/19 00:31, Michal Simek wrote: > Hi, > > On 15. 04. 19 9:47, Luca Ceresoli wrote: >> The recently-added ZYNQMP_LOAD_PM_CFG_OBJ_FILE option allows SPL to load a >> PMUFW configuration object from a binary blob. However the configuration >> object is produced by Xilinx proprietary tools as a C source file and no >> tool exists to easily convert it to a binary blob in an embedded Linux >> build system for U-Boot to use. >> >> Add a simple Python script to do the conversion. >> >> It is definitely not a complete C language parser, but it is enough to >> parse the known patterns generated by Xilinx tools, including: >> >> - defines >> - literal integers, optionally with a 'U' suffix >> - bitwise OR between them >> >> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> >> --- >> arch/arm/mach-zynqmp/pm_cfg_obj_convert.py | 302 +++++++++++++++++++++ >> 1 file changed, 302 insertions(+) >> create mode 100755 arch/arm/mach-zynqmp/pm_cfg_obj_convert.py >> >> diff --git a/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py >> new file mode 100755 >> index 000000000000..5aea15860319 >> --- /dev/null >> +++ b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py >> @@ -0,0 +1,302 @@ >> +#!/usr/bin/env python3 >> +# SPDX-License-Identifier: GPL-2.0+ >> +# Copyright (C) 2019 Luca Ceresoli <luca@lucaceresoli.net> >> + >> +import sys >> +import re >> +import struct >> +import logging >> +import argparse >> + >> +parser = argparse.ArgumentParser( >> + description='Convert a PMU configuration object from C source to a binary blob.', >> + allow_abbrev=False) >> +parser.add_argument('-D', '--debug', action="store_true") >> +parser.add_argument( >> + "in_file", metavar='INPUT_FILE', >> + help='PMU configuration object (C source as produced by Xilinx XSDK)') >> +parser.add_argument( >> + "out_file", metavar='OUTPUT_FILE', >> + help='PMU configuration object binary blob') >> +args = parser.parse_args() >> + >> +logging.basicConfig(format='%(levelname)s:%(message)s', >> + level=(logging.DEBUG if args.debug else logging.WARNING)) >> + >> +pm_define = { >> + 'PM_CAP_ACCESS' : 0x1, >> + 'PM_CAP_CONTEXT' : 0x2, >> + 'PM_CAP_WAKEUP' : 0x4, >> + >> + 'NODE_UNKNOWN' : 0, >> + 'NODE_APU' : 1, >> + 'NODE_APU_0' : 2, >> + 'NODE_APU_1' : 3, >> + 'NODE_APU_2' : 4, >> + 'NODE_APU_3' : 5, >> + 'NODE_RPU' : 6, >> + 'NODE_RPU_0' : 7, >> + 'NODE_RPU_1' : 8, >> + 'NODE_PLD' : 9, >> + 'NODE_FPD' : 10, >> + 'NODE_OCM_BANK_0' : 11, >> + 'NODE_OCM_BANK_1' : 12, >> + 'NODE_OCM_BANK_2' : 13, >> + 'NODE_OCM_BANK_3' : 14, >> + 'NODE_TCM_0_A' : 15, >> + 'NODE_TCM_0_B' : 16, >> + 'NODE_TCM_1_A' : 17, >> + 'NODE_TCM_1_B' : 18, >> + 'NODE_L2' : 19, >> + 'NODE_GPU_PP_0' : 20, >> + 'NODE_GPU_PP_1' : 21, >> + 'NODE_USB_0' : 22, >> + 'NODE_USB_1' : 23, >> + 'NODE_TTC_0' : 24, >> + 'NODE_TTC_1' : 25, >> + 'NODE_TTC_2' : 26, >> + 'NODE_TTC_3' : 27, >> + 'NODE_SATA' : 28, >> + 'NODE_ETH_0' : 29, >> + 'NODE_ETH_1' : 30, >> + 'NODE_ETH_2' : 31, >> + 'NODE_ETH_3' : 32, >> + 'NODE_UART_0' : 33, >> + 'NODE_UART_1' : 34, >> + 'NODE_SPI_0' : 35, >> + 'NODE_SPI_1' : 36, >> + 'NODE_I2C_0' : 37, >> + 'NODE_I2C_1' : 38, >> + 'NODE_SD_0' : 39, >> + 'NODE_SD_1' : 40, >> + 'NODE_DP' : 41, >> + 'NODE_GDMA' : 42, >> + 'NODE_ADMA' : 43, >> + 'NODE_NAND' : 44, >> + 'NODE_QSPI' : 45, >> + 'NODE_GPIO' : 46, >> + 'NODE_CAN_0' : 47, >> + 'NODE_CAN_1' : 48, >> + 'NODE_EXTERN' : 49, >> + 'NODE_APLL' : 50, >> + 'NODE_VPLL' : 51, >> + 'NODE_DPLL' : 52, >> + 'NODE_RPLL' : 53, >> + 'NODE_IOPLL' : 54, >> + 'NODE_DDR' : 55, >> + 'NODE_IPI_APU' : 56, >> + 'NODE_IPI_RPU_0' : 57, >> + 'NODE_GPU' : 58, >> + 'NODE_PCIE' : 59, >> + 'NODE_PCAP' : 60, >> + 'NODE_RTC' : 61, >> + 'NODE_LPD' : 62, >> + 'NODE_VCU' : 63, >> + 'NODE_IPI_RPU_1' : 64, >> + 'NODE_IPI_PL_0' : 65, >> + 'NODE_IPI_PL_1' : 66, >> + 'NODE_IPI_PL_2' : 67, >> + 'NODE_IPI_PL_3' : 68, >> + 'NODE_PL' : 69, >> + 'NODE_ID_MA' : 70, >> + >> + 'XILPM_RESET_PCIE_CFG' : 1000, >> + 'XILPM_RESET_PCIE_BRIDGE' : 1001, >> + 'XILPM_RESET_PCIE_CTRL' : 1002, >> + 'XILPM_RESET_DP' : 1003, >> + 'XILPM_RESET_SWDT_CRF' : 1004, >> + 'XILPM_RESET_AFI_FM5' : 1005, >> + 'XILPM_RESET_AFI_FM4' : 1006, >> + 'XILPM_RESET_AFI_FM3' : 1007, >> + 'XILPM_RESET_AFI_FM2' : 1008, >> + 'XILPM_RESET_AFI_FM1' : 1009, >> + 'XILPM_RESET_AFI_FM0' : 1010, >> + 'XILPM_RESET_GDMA' : 1011, >> + 'XILPM_RESET_GPU_PP1' : 1012, >> + 'XILPM_RESET_GPU_PP0' : 1013, >> + 'XILPM_RESET_GPU' : 1014, >> + 'XILPM_RESET_GT' : 1015, >> + 'XILPM_RESET_SATA' : 1016, >> + 'XILPM_RESET_ACPU3_PWRON' : 1017, >> + 'XILPM_RESET_ACPU2_PWRON' : 1018, >> + 'XILPM_RESET_ACPU1_PWRON' : 1019, >> + 'XILPM_RESET_ACPU0_PWRON' : 1020, >> + 'XILPM_RESET_APU_L2' : 1021, >> + 'XILPM_RESET_ACPU3' : 1022, >> + 'XILPM_RESET_ACPU2' : 1023, >> + 'XILPM_RESET_ACPU1' : 1024, >> + 'XILPM_RESET_ACPU0' : 1025, >> + 'XILPM_RESET_DDR' : 1026, >> + 'XILPM_RESET_APM_FPD' : 1027, >> + 'XILPM_RESET_SOFT' : 1028, >> + 'XILPM_RESET_GEM0' : 1029, >> + 'XILPM_RESET_GEM1' : 1030, >> + 'XILPM_RESET_GEM2' : 1031, >> + 'XILPM_RESET_GEM3' : 1032, >> + 'XILPM_RESET_QSPI' : 1033, >> + 'XILPM_RESET_UART0' : 1034, >> + 'XILPM_RESET_UART1' : 1035, >> + 'XILPM_RESET_SPI0' : 1036, >> + 'XILPM_RESET_SPI1' : 1037, >> + 'XILPM_RESET_SDIO0' : 1038, >> + 'XILPM_RESET_SDIO1' : 1039, >> + 'XILPM_RESET_CAN0' : 1040, >> + 'XILPM_RESET_CAN1' : 1041, >> + 'XILPM_RESET_I2C0' : 1042, >> + 'XILPM_RESET_I2C1' : 1043, >> + 'XILPM_RESET_TTC0' : 1044, >> + 'XILPM_RESET_TTC1' : 1045, >> + 'XILPM_RESET_TTC2' : 1046, >> + 'XILPM_RESET_TTC3' : 1047, >> + 'XILPM_RESET_SWDT_CRL' : 1048, >> + 'XILPM_RESET_NAND' : 1049, >> + 'XILPM_RESET_ADMA' : 1050, >> + 'XILPM_RESET_GPIO' : 1051, >> + 'XILPM_RESET_IOU_CC' : 1052, >> + 'XILPM_RESET_TIMESTAMP' : 1053, >> + 'XILPM_RESET_RPU_R50' : 1054, >> + 'XILPM_RESET_RPU_R51' : 1055, >> + 'XILPM_RESET_RPU_AMBA' : 1056, >> + 'XILPM_RESET_OCM' : 1057, >> + 'XILPM_RESET_RPU_PGE' : 1058, >> + 'XILPM_RESET_USB0_CORERESET' : 1059, >> + 'XILPM_RESET_USB1_CORERESET' : 1060, >> + 'XILPM_RESET_USB0_HIBERRESET' : 1061, >> + 'XILPM_RESET_USB1_HIBERRESET' : 1062, >> + 'XILPM_RESET_USB0_APB' : 1063, >> + 'XILPM_RESET_USB1_APB' : 1064, >> + 'XILPM_RESET_IPI' : 1065, >> + 'XILPM_RESET_APM_LPD' : 1066, >> + 'XILPM_RESET_RTC' : 1067, >> + 'XILPM_RESET_SYSMON' : 1068, >> + 'XILPM_RESET_AFI_FM6' : 1069, >> + 'XILPM_RESET_LPD_SWDT' : 1070, >> + 'XILPM_RESET_FPD' : 1071, >> + 'XILPM_RESET_RPU_DBG1' : 1072, >> + 'XILPM_RESET_RPU_DBG0' : 1073, >> + 'XILPM_RESET_DBG_LPD' : 1074, >> + 'XILPM_RESET_DBG_FPD' : 1075, >> + 'XILPM_RESET_APLL' : 1076, >> + 'XILPM_RESET_DPLL' : 1077, >> + 'XILPM_RESET_VPLL' : 1078, >> + 'XILPM_RESET_IOPLL' : 1079, >> + 'XILPM_RESET_RPLL' : 1080, >> + 'XILPM_RESET_GPO3_PL_0' : 1081, >> + 'XILPM_RESET_GPO3_PL_1' : 1082, >> + 'XILPM_RESET_GPO3_PL_2' : 1083, >> + 'XILPM_RESET_GPO3_PL_3' : 1084, >> + 'XILPM_RESET_GPO3_PL_4' : 1085, >> + 'XILPM_RESET_GPO3_PL_5' : 1086, >> + 'XILPM_RESET_GPO3_PL_6' : 1087, >> + 'XILPM_RESET_GPO3_PL_7' : 1088, >> + 'XILPM_RESET_GPO3_PL_8' : 1089, >> + 'XILPM_RESET_GPO3_PL_9' : 1090, >> + 'XILPM_RESET_GPO3_PL_10' : 1091, >> + 'XILPM_RESET_GPO3_PL_11' : 1092, >> + 'XILPM_RESET_GPO3_PL_12' : 1093, >> + 'XILPM_RESET_GPO3_PL_13' : 1094, >> + 'XILPM_RESET_GPO3_PL_14' : 1095, >> + 'XILPM_RESET_GPO3_PL_15' : 1096, >> + 'XILPM_RESET_GPO3_PL_16' : 1097, >> + 'XILPM_RESET_GPO3_PL_17' : 1098, >> + 'XILPM_RESET_GPO3_PL_18' : 1099, >> + 'XILPM_RESET_GPO3_PL_19' : 1100, >> + 'XILPM_RESET_GPO3_PL_20' : 1101, >> + 'XILPM_RESET_GPO3_PL_21' : 1102, >> + 'XILPM_RESET_GPO3_PL_22' : 1103, >> + 'XILPM_RESET_GPO3_PL_23' : 1104, >> + 'XILPM_RESET_GPO3_PL_24' : 1105, >> + 'XILPM_RESET_GPO3_PL_25' : 1106, >> + 'XILPM_RESET_GPO3_PL_26' : 1107, >> + 'XILPM_RESET_GPO3_PL_27' : 1108, >> + 'XILPM_RESET_GPO3_PL_28' : 1109, >> + 'XILPM_RESET_GPO3_PL_29' : 1110, >> + 'XILPM_RESET_GPO3_PL_30' : 1111, >> + 'XILPM_RESET_GPO3_PL_31' : 1112, >> + 'XILPM_RESET_RPU_LS' : 1113, >> + 'XILPM_RESET_PS_ONLY' : 1114, >> + 'XILPM_RESET_PL' : 1115, >> + 'XILPM_RESET_GPIO5_EMIO_92' : 1116, >> + 'XILPM_RESET_GPIO5_EMIO_93' : 1117, >> + 'XILPM_RESET_GPIO5_EMIO_94' : 1118, >> + 'XILPM_RESET_GPIO5_EMIO_95' : 1119, >> + >> + 'PM_CONFIG_MASTER_SECTION_ID' : 0x101, >> + 'PM_CONFIG_SLAVE_SECTION_ID' : 0x102, >> + 'PM_CONFIG_PREALLOC_SECTION_ID' : 0x103, >> + 'PM_CONFIG_POWER_SECTION_ID' : 0x104, >> + 'PM_CONFIG_RESET_SECTION_ID' : 0x105, >> + 'PM_CONFIG_SHUTDOWN_SECTION_ID' : 0x106, >> + 'PM_CONFIG_SET_CONFIG_SECTION_ID' : 0x107, >> + 'PM_CONFIG_GPO_SECTION_ID' : 0x108, >> + >> + 'PM_SLAVE_FLAG_IS_SHAREABLE' : 0x1, >> + 'PM_MASTER_USING_SLAVE_MASK' : 0x2, >> + >> + 'PM_CONFIG_GPO1_MIO_PIN_34_MAP' : (1 << 10), >> + 'PM_CONFIG_GPO1_MIO_PIN_35_MAP' : (1 << 11), >> + 'PM_CONFIG_GPO1_MIO_PIN_36_MAP' : (1 << 12), >> + 'PM_CONFIG_GPO1_MIO_PIN_37_MAP' : (1 << 13), >> + >> + 'PM_CONFIG_GPO1_BIT_2_MASK' : (1 << 2), >> + 'PM_CONFIG_GPO1_BIT_3_MASK' : (1 << 3), >> + 'PM_CONFIG_GPO1_BIT_4_MASK' : (1 << 4), >> + 'PM_CONFIG_GPO1_BIT_5_MASK' : (1 << 5), >> + >> + 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, >> + >> + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, >> + 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, >> + 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, >> +} >> + >> +in_file = open(args.in_file, mode='r') >> +out_file = open(args.out_file, mode='wb') >> + >> +num_re = re.compile(r"^([0-9]+)U?$") >> +const_re = re.compile(r"^([A-Z_][A-Z0-9_]*)$") >> + >> +def process_item(item): >> + logging.debug("* ITEM " + item) >> + >> + value = 0 >> + for item in item.split('|'): >> + item = item.strip() >> + >> + num_match = num_re .match(item) >> + const_match = const_re.match(item) >> + >> + if num_match: >> + num = int(num_match.group(1)) >> + logging.debug(" - num " + str(num)) >> + value |= num >> + elif const_match: >> + name = const_match.group(1) >> + if not name in pm_define: >> + sys.stderr.write("Unknown define " + name + "!\n") >> + exit(1) >> + num = pm_define[name] >> + logging.debug(" - def " + hex(num)) >> + value |= num >> + >> + logging.debug(" = res " + hex(value)) >> + out_file.write(struct.pack('<L', value)) >> + >> + >> +# Read all code >> +code = in_file.read() >> + >> +# remove comments >> +code = re.sub('//.*?\n|/\*.*?\*/', '', code, flags=re.DOTALL) >> + >> +# remove everything outside the XPm_ConfigObject array definition >> +code = re.search('const u32 XPm_ConfigObject.*= {\n(.*)};', >> + code, flags=re.DOTALL).group(1) >> + >> +# Process each comma-separated array item >> +for item in code.split(','): >> + item = item.strip() >> + if item: >> + process_item(item.strip()) >> + >> +print("Wrote %d bytes" % out_file.tell()) >> > > > I have created simple script for extracting this object also from fsbl > elf file. Maybe we should also publish it when this is out. > For your reference. > > #!/bin/bash > # Written by Michal Simek > > FSBL=zynqmp_fsbl > PMCFG=pmcfg.bin > > PM_END=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n > '/XPm_ConfigObject/,/^$/p' | head -n -2 | tail -n 1 | cut -c 5-12 | awk > '{printf ("0x%s",$1)}'` > PM_START=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n > '/XPm_ConfigObject/,/^$/p' | head -n 1 | awk '{printf ("0x%s",$1)}'` > > FSBL_START=`aarch64-linux-gnu-readelf -a ${FSBL}.elf | grep "Entry point > address" | awk '{print $4}'` > > PM_OBJECT_START=`echo $((${PM_START} - ${FSBL_START}))` > PM_OBJECT_SIZE=`echo $((${PM_END} - ${PM_START}))` > > echo "FSBL starting address ${FSBL_START}" > echo "FSBL object addresses ${PM_START} ${PM_END}" > echo "OBJECT start ${PM_OBJECT_START} size ${PM_OBJECT_SIZE}" > > aarch64-linux-gnu-objcopy -O binary ${FSBL}.elf ${FSBL}.bin > > # Extracting config object > dd if=${FSBL}.bin of=${PMCFG} bs=1 skip=${PM_OBJECT_START} > count=${PM_OBJECT_SIZE} > /dev/null 2>&1 > > echo "Your object ${PMCFG} is ready" > > rm -f ${FSBL}.bin *~ > > Anyway this patch is good. I didn't test it but it looks ok. Ok, thanks. In the meantime I have been wondering whether it should be moved from arch/arm/mach-zynqmp/pm_cfg_obj_convert.py to tools/ (and prefixed with zynqmp_), where other tools are.
Hi, pá 3. 5. 2019 v 23:15 odesílatel Luca Ceresoli <luca@lucaceresoli.net> napsal: > Hi Michal, > > On 04/05/19 00:31, Michal Simek wrote: > > Hi, > > > > On 15. 04. 19 9:47, Luca Ceresoli wrote: > >> The recently-added ZYNQMP_LOAD_PM_CFG_OBJ_FILE option allows SPL to > load a > >> PMUFW configuration object from a binary blob. However the configuration > >> object is produced by Xilinx proprietary tools as a C source file and no > >> tool exists to easily convert it to a binary blob in an embedded Linux > >> build system for U-Boot to use. > >> > >> Add a simple Python script to do the conversion. > >> > >> It is definitely not a complete C language parser, but it is enough to > >> parse the known patterns generated by Xilinx tools, including: > >> > >> - defines > >> - literal integers, optionally with a 'U' suffix > >> - bitwise OR between them > >> > >> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> > >> --- > >> arch/arm/mach-zynqmp/pm_cfg_obj_convert.py | 302 +++++++++++++++++++++ > >> 1 file changed, 302 insertions(+) > >> create mode 100755 arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > >> > >> diff --git a/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > >> new file mode 100755 > >> index 000000000000..5aea15860319 > >> --- /dev/null > >> +++ b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py > >> @@ -0,0 +1,302 @@ > >> +#!/usr/bin/env python3 > >> +# SPDX-License-Identifier: GPL-2.0+ > >> +# Copyright (C) 2019 Luca Ceresoli <luca@lucaceresoli.net> > >> + > >> +import sys > >> +import re > >> +import struct > >> +import logging > >> +import argparse > >> + > >> +parser = argparse.ArgumentParser( > >> + description='Convert a PMU configuration object from C source to a > binary blob.', > >> + allow_abbrev=False) > >> +parser.add_argument('-D', '--debug', action="store_true") > >> +parser.add_argument( > >> + "in_file", metavar='INPUT_FILE', > >> + help='PMU configuration object (C source as produced by Xilinx > XSDK)') > >> +parser.add_argument( > >> + "out_file", metavar='OUTPUT_FILE', > >> + help='PMU configuration object binary blob') > >> +args = parser.parse_args() > >> + > >> +logging.basicConfig(format='%(levelname)s:%(message)s', > >> + level=(logging.DEBUG if args.debug else > logging.WARNING)) > >> + > >> +pm_define = { > >> + 'PM_CAP_ACCESS' : 0x1, > >> + 'PM_CAP_CONTEXT' : 0x2, > >> + 'PM_CAP_WAKEUP' : 0x4, > >> + > >> + 'NODE_UNKNOWN' : 0, > >> + 'NODE_APU' : 1, > >> + 'NODE_APU_0' : 2, > >> + 'NODE_APU_1' : 3, > >> + 'NODE_APU_2' : 4, > >> + 'NODE_APU_3' : 5, > >> + 'NODE_RPU' : 6, > >> + 'NODE_RPU_0' : 7, > >> + 'NODE_RPU_1' : 8, > >> + 'NODE_PLD' : 9, > >> + 'NODE_FPD' : 10, > >> + 'NODE_OCM_BANK_0' : 11, > >> + 'NODE_OCM_BANK_1' : 12, > >> + 'NODE_OCM_BANK_2' : 13, > >> + 'NODE_OCM_BANK_3' : 14, > >> + 'NODE_TCM_0_A' : 15, > >> + 'NODE_TCM_0_B' : 16, > >> + 'NODE_TCM_1_A' : 17, > >> + 'NODE_TCM_1_B' : 18, > >> + 'NODE_L2' : 19, > >> + 'NODE_GPU_PP_0' : 20, > >> + 'NODE_GPU_PP_1' : 21, > >> + 'NODE_USB_0' : 22, > >> + 'NODE_USB_1' : 23, > >> + 'NODE_TTC_0' : 24, > >> + 'NODE_TTC_1' : 25, > >> + 'NODE_TTC_2' : 26, > >> + 'NODE_TTC_3' : 27, > >> + 'NODE_SATA' : 28, > >> + 'NODE_ETH_0' : 29, > >> + 'NODE_ETH_1' : 30, > >> + 'NODE_ETH_2' : 31, > >> + 'NODE_ETH_3' : 32, > >> + 'NODE_UART_0' : 33, > >> + 'NODE_UART_1' : 34, > >> + 'NODE_SPI_0' : 35, > >> + 'NODE_SPI_1' : 36, > >> + 'NODE_I2C_0' : 37, > >> + 'NODE_I2C_1' : 38, > >> + 'NODE_SD_0' : 39, > >> + 'NODE_SD_1' : 40, > >> + 'NODE_DP' : 41, > >> + 'NODE_GDMA' : 42, > >> + 'NODE_ADMA' : 43, > >> + 'NODE_NAND' : 44, > >> + 'NODE_QSPI' : 45, > >> + 'NODE_GPIO' : 46, > >> + 'NODE_CAN_0' : 47, > >> + 'NODE_CAN_1' : 48, > >> + 'NODE_EXTERN' : 49, > >> + 'NODE_APLL' : 50, > >> + 'NODE_VPLL' : 51, > >> + 'NODE_DPLL' : 52, > >> + 'NODE_RPLL' : 53, > >> + 'NODE_IOPLL' : 54, > >> + 'NODE_DDR' : 55, > >> + 'NODE_IPI_APU' : 56, > >> + 'NODE_IPI_RPU_0' : 57, > >> + 'NODE_GPU' : 58, > >> + 'NODE_PCIE' : 59, > >> + 'NODE_PCAP' : 60, > >> + 'NODE_RTC' : 61, > >> + 'NODE_LPD' : 62, > >> + 'NODE_VCU' : 63, > >> + 'NODE_IPI_RPU_1' : 64, > >> + 'NODE_IPI_PL_0' : 65, > >> + 'NODE_IPI_PL_1' : 66, > >> + 'NODE_IPI_PL_2' : 67, > >> + 'NODE_IPI_PL_3' : 68, > >> + 'NODE_PL' : 69, > >> + 'NODE_ID_MA' : 70, > >> + > >> + 'XILPM_RESET_PCIE_CFG' : 1000, > >> + 'XILPM_RESET_PCIE_BRIDGE' : 1001, > >> + 'XILPM_RESET_PCIE_CTRL' : 1002, > >> + 'XILPM_RESET_DP' : 1003, > >> + 'XILPM_RESET_SWDT_CRF' : 1004, > >> + 'XILPM_RESET_AFI_FM5' : 1005, > >> + 'XILPM_RESET_AFI_FM4' : 1006, > >> + 'XILPM_RESET_AFI_FM3' : 1007, > >> + 'XILPM_RESET_AFI_FM2' : 1008, > >> + 'XILPM_RESET_AFI_FM1' : 1009, > >> + 'XILPM_RESET_AFI_FM0' : 1010, > >> + 'XILPM_RESET_GDMA' : 1011, > >> + 'XILPM_RESET_GPU_PP1' : 1012, > >> + 'XILPM_RESET_GPU_PP0' : 1013, > >> + 'XILPM_RESET_GPU' : 1014, > >> + 'XILPM_RESET_GT' : 1015, > >> + 'XILPM_RESET_SATA' : 1016, > >> + 'XILPM_RESET_ACPU3_PWRON' : 1017, > >> + 'XILPM_RESET_ACPU2_PWRON' : 1018, > >> + 'XILPM_RESET_ACPU1_PWRON' : 1019, > >> + 'XILPM_RESET_ACPU0_PWRON' : 1020, > >> + 'XILPM_RESET_APU_L2' : 1021, > >> + 'XILPM_RESET_ACPU3' : 1022, > >> + 'XILPM_RESET_ACPU2' : 1023, > >> + 'XILPM_RESET_ACPU1' : 1024, > >> + 'XILPM_RESET_ACPU0' : 1025, > >> + 'XILPM_RESET_DDR' : 1026, > >> + 'XILPM_RESET_APM_FPD' : 1027, > >> + 'XILPM_RESET_SOFT' : 1028, > >> + 'XILPM_RESET_GEM0' : 1029, > >> + 'XILPM_RESET_GEM1' : 1030, > >> + 'XILPM_RESET_GEM2' : 1031, > >> + 'XILPM_RESET_GEM3' : 1032, > >> + 'XILPM_RESET_QSPI' : 1033, > >> + 'XILPM_RESET_UART0' : 1034, > >> + 'XILPM_RESET_UART1' : 1035, > >> + 'XILPM_RESET_SPI0' : 1036, > >> + 'XILPM_RESET_SPI1' : 1037, > >> + 'XILPM_RESET_SDIO0' : 1038, > >> + 'XILPM_RESET_SDIO1' : 1039, > >> + 'XILPM_RESET_CAN0' : 1040, > >> + 'XILPM_RESET_CAN1' : 1041, > >> + 'XILPM_RESET_I2C0' : 1042, > >> + 'XILPM_RESET_I2C1' : 1043, > >> + 'XILPM_RESET_TTC0' : 1044, > >> + 'XILPM_RESET_TTC1' : 1045, > >> + 'XILPM_RESET_TTC2' : 1046, > >> + 'XILPM_RESET_TTC3' : 1047, > >> + 'XILPM_RESET_SWDT_CRL' : 1048, > >> + 'XILPM_RESET_NAND' : 1049, > >> + 'XILPM_RESET_ADMA' : 1050, > >> + 'XILPM_RESET_GPIO' : 1051, > >> + 'XILPM_RESET_IOU_CC' : 1052, > >> + 'XILPM_RESET_TIMESTAMP' : 1053, > >> + 'XILPM_RESET_RPU_R50' : 1054, > >> + 'XILPM_RESET_RPU_R51' : 1055, > >> + 'XILPM_RESET_RPU_AMBA' : 1056, > >> + 'XILPM_RESET_OCM' : 1057, > >> + 'XILPM_RESET_RPU_PGE' : 1058, > >> + 'XILPM_RESET_USB0_CORERESET' : 1059, > >> + 'XILPM_RESET_USB1_CORERESET' : 1060, > >> + 'XILPM_RESET_USB0_HIBERRESET' : 1061, > >> + 'XILPM_RESET_USB1_HIBERRESET' : 1062, > >> + 'XILPM_RESET_USB0_APB' : 1063, > >> + 'XILPM_RESET_USB1_APB' : 1064, > >> + 'XILPM_RESET_IPI' : 1065, > >> + 'XILPM_RESET_APM_LPD' : 1066, > >> + 'XILPM_RESET_RTC' : 1067, > >> + 'XILPM_RESET_SYSMON' : 1068, > >> + 'XILPM_RESET_AFI_FM6' : 1069, > >> + 'XILPM_RESET_LPD_SWDT' : 1070, > >> + 'XILPM_RESET_FPD' : 1071, > >> + 'XILPM_RESET_RPU_DBG1' : 1072, > >> + 'XILPM_RESET_RPU_DBG0' : 1073, > >> + 'XILPM_RESET_DBG_LPD' : 1074, > >> + 'XILPM_RESET_DBG_FPD' : 1075, > >> + 'XILPM_RESET_APLL' : 1076, > >> + 'XILPM_RESET_DPLL' : 1077, > >> + 'XILPM_RESET_VPLL' : 1078, > >> + 'XILPM_RESET_IOPLL' : 1079, > >> + 'XILPM_RESET_RPLL' : 1080, > >> + 'XILPM_RESET_GPO3_PL_0' : 1081, > >> + 'XILPM_RESET_GPO3_PL_1' : 1082, > >> + 'XILPM_RESET_GPO3_PL_2' : 1083, > >> + 'XILPM_RESET_GPO3_PL_3' : 1084, > >> + 'XILPM_RESET_GPO3_PL_4' : 1085, > >> + 'XILPM_RESET_GPO3_PL_5' : 1086, > >> + 'XILPM_RESET_GPO3_PL_6' : 1087, > >> + 'XILPM_RESET_GPO3_PL_7' : 1088, > >> + 'XILPM_RESET_GPO3_PL_8' : 1089, > >> + 'XILPM_RESET_GPO3_PL_9' : 1090, > >> + 'XILPM_RESET_GPO3_PL_10' : 1091, > >> + 'XILPM_RESET_GPO3_PL_11' : 1092, > >> + 'XILPM_RESET_GPO3_PL_12' : 1093, > >> + 'XILPM_RESET_GPO3_PL_13' : 1094, > >> + 'XILPM_RESET_GPO3_PL_14' : 1095, > >> + 'XILPM_RESET_GPO3_PL_15' : 1096, > >> + 'XILPM_RESET_GPO3_PL_16' : 1097, > >> + 'XILPM_RESET_GPO3_PL_17' : 1098, > >> + 'XILPM_RESET_GPO3_PL_18' : 1099, > >> + 'XILPM_RESET_GPO3_PL_19' : 1100, > >> + 'XILPM_RESET_GPO3_PL_20' : 1101, > >> + 'XILPM_RESET_GPO3_PL_21' : 1102, > >> + 'XILPM_RESET_GPO3_PL_22' : 1103, > >> + 'XILPM_RESET_GPO3_PL_23' : 1104, > >> + 'XILPM_RESET_GPO3_PL_24' : 1105, > >> + 'XILPM_RESET_GPO3_PL_25' : 1106, > >> + 'XILPM_RESET_GPO3_PL_26' : 1107, > >> + 'XILPM_RESET_GPO3_PL_27' : 1108, > >> + 'XILPM_RESET_GPO3_PL_28' : 1109, > >> + 'XILPM_RESET_GPO3_PL_29' : 1110, > >> + 'XILPM_RESET_GPO3_PL_30' : 1111, > >> + 'XILPM_RESET_GPO3_PL_31' : 1112, > >> + 'XILPM_RESET_RPU_LS' : 1113, > >> + 'XILPM_RESET_PS_ONLY' : 1114, > >> + 'XILPM_RESET_PL' : 1115, > >> + 'XILPM_RESET_GPIO5_EMIO_92' : 1116, > >> + 'XILPM_RESET_GPIO5_EMIO_93' : 1117, > >> + 'XILPM_RESET_GPIO5_EMIO_94' : 1118, > >> + 'XILPM_RESET_GPIO5_EMIO_95' : 1119, > >> + > >> + 'PM_CONFIG_MASTER_SECTION_ID' : 0x101, > >> + 'PM_CONFIG_SLAVE_SECTION_ID' : 0x102, > >> + 'PM_CONFIG_PREALLOC_SECTION_ID' : 0x103, > >> + 'PM_CONFIG_POWER_SECTION_ID' : 0x104, > >> + 'PM_CONFIG_RESET_SECTION_ID' : 0x105, > >> + 'PM_CONFIG_SHUTDOWN_SECTION_ID' : 0x106, > >> + 'PM_CONFIG_SET_CONFIG_SECTION_ID' : 0x107, > >> + 'PM_CONFIG_GPO_SECTION_ID' : 0x108, > >> + > >> + 'PM_SLAVE_FLAG_IS_SHAREABLE' : 0x1, > >> + 'PM_MASTER_USING_SLAVE_MASK' : 0x2, > >> + > >> + 'PM_CONFIG_GPO1_MIO_PIN_34_MAP' : (1 << 10), > >> + 'PM_CONFIG_GPO1_MIO_PIN_35_MAP' : (1 << 11), > >> + 'PM_CONFIG_GPO1_MIO_PIN_36_MAP' : (1 << 12), > >> + 'PM_CONFIG_GPO1_MIO_PIN_37_MAP' : (1 << 13), > >> + > >> + 'PM_CONFIG_GPO1_BIT_2_MASK' : (1 << 2), > >> + 'PM_CONFIG_GPO1_BIT_3_MASK' : (1 << 3), > >> + 'PM_CONFIG_GPO1_BIT_4_MASK' : (1 << 4), > >> + 'PM_CONFIG_GPO1_BIT_5_MASK' : (1 << 5), > >> + > >> + 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, > >> + > >> + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, > >> + 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, > >> + 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, > >> +} > >> + > >> +in_file = open(args.in_file, mode='r') > >> +out_file = open(args.out_file, mode='wb') > >> + > >> +num_re = re.compile(r"^([0-9]+)U?$") > >> +const_re = re.compile(r"^([A-Z_][A-Z0-9_]*)$") > >> + > >> +def process_item(item): > >> + logging.debug("* ITEM " + item) > >> + > >> + value = 0 > >> + for item in item.split('|'): > >> + item = item.strip() > >> + > >> + num_match = num_re .match(item) > >> + const_match = const_re.match(item) > >> + > >> + if num_match: > >> + num = int(num_match.group(1)) > >> + logging.debug(" - num " + str(num)) > >> + value |= num > >> + elif const_match: > >> + name = const_match.group(1) > >> + if not name in pm_define: > >> + sys.stderr.write("Unknown define " + name + "!\n") > >> + exit(1) > >> + num = pm_define[name] > >> + logging.debug(" - def " + hex(num)) > >> + value |= num > >> + > >> + logging.debug(" = res " + hex(value)) > >> + out_file.write(struct.pack('<L', value)) > >> + > >> + > >> +# Read all code > >> +code = in_file.read() > >> + > >> +# remove comments > >> +code = re.sub('//.*?\n|/\*.*?\*/', '', code, flags=re.DOTALL) > >> + > >> +# remove everything outside the XPm_ConfigObject array definition > >> +code = re.search('const u32 XPm_ConfigObject.*= {\n(.*)};', > >> + code, flags=re.DOTALL).group(1) > >> + > >> +# Process each comma-separated array item > >> +for item in code.split(','): > >> + item = item.strip() > >> + if item: > >> + process_item(item.strip()) > >> + > >> +print("Wrote %d bytes" % out_file.tell()) > >> > > > > > > I have created simple script for extracting this object also from fsbl > > elf file. Maybe we should also publish it when this is out. > > For your reference. > > > > #!/bin/bash > > # Written by Michal Simek > > > > FSBL=zynqmp_fsbl > > PMCFG=pmcfg.bin > > > > PM_END=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n > > '/XPm_ConfigObject/,/^$/p' | head -n -2 | tail -n 1 | cut -c 5-12 | awk > > '{printf ("0x%s",$1)}'` > > PM_START=`aarch64-linux-gnu-objdump -D ${FSBL}.elf | sed -n > > '/XPm_ConfigObject/,/^$/p' | head -n 1 | awk '{printf ("0x%s",$1)}'` > > > > FSBL_START=`aarch64-linux-gnu-readelf -a ${FSBL}.elf | grep "Entry point > > address" | awk '{print $4}'` > > > > PM_OBJECT_START=`echo $((${PM_START} - ${FSBL_START}))` > > PM_OBJECT_SIZE=`echo $((${PM_END} - ${PM_START}))` > > > > echo "FSBL starting address ${FSBL_START}" > > echo "FSBL object addresses ${PM_START} ${PM_END}" > > echo "OBJECT start ${PM_OBJECT_START} size ${PM_OBJECT_SIZE}" > > > > aarch64-linux-gnu-objcopy -O binary ${FSBL}.elf ${FSBL}.bin > > > > # Extracting config object > > dd if=${FSBL}.bin of=${PMCFG} bs=1 skip=${PM_OBJECT_START} > > count=${PM_OBJECT_SIZE} > /dev/null 2>&1 > > > > echo "Your object ${PMCFG} is ready" > > > > rm -f ${FSBL}.bin *~ > > > > Anyway this patch is good. I didn't test it but it looks ok. > > Ok, thanks. > > In the meantime I have been wondering whether it should be moved from > arch/arm/mach-zynqmp/pm_cfg_obj_convert.py to tools/ (and prefixed with > zynqmp_), where other tools are. > > Not a problem with it. M
diff --git a/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py new file mode 100755 index 000000000000..5aea15860319 --- /dev/null +++ b/arch/arm/mach-zynqmp/pm_cfg_obj_convert.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2019 Luca Ceresoli <luca@lucaceresoli.net> + +import sys +import re +import struct +import logging +import argparse + +parser = argparse.ArgumentParser( + description='Convert a PMU configuration object from C source to a binary blob.', + allow_abbrev=False) +parser.add_argument('-D', '--debug', action="store_true") +parser.add_argument( + "in_file", metavar='INPUT_FILE', + help='PMU configuration object (C source as produced by Xilinx XSDK)') +parser.add_argument( + "out_file", metavar='OUTPUT_FILE', + help='PMU configuration object binary blob') +args = parser.parse_args() + +logging.basicConfig(format='%(levelname)s:%(message)s', + level=(logging.DEBUG if args.debug else logging.WARNING)) + +pm_define = { + 'PM_CAP_ACCESS' : 0x1, + 'PM_CAP_CONTEXT' : 0x2, + 'PM_CAP_WAKEUP' : 0x4, + + 'NODE_UNKNOWN' : 0, + 'NODE_APU' : 1, + 'NODE_APU_0' : 2, + 'NODE_APU_1' : 3, + 'NODE_APU_2' : 4, + 'NODE_APU_3' : 5, + 'NODE_RPU' : 6, + 'NODE_RPU_0' : 7, + 'NODE_RPU_1' : 8, + 'NODE_PLD' : 9, + 'NODE_FPD' : 10, + 'NODE_OCM_BANK_0' : 11, + 'NODE_OCM_BANK_1' : 12, + 'NODE_OCM_BANK_2' : 13, + 'NODE_OCM_BANK_3' : 14, + 'NODE_TCM_0_A' : 15, + 'NODE_TCM_0_B' : 16, + 'NODE_TCM_1_A' : 17, + 'NODE_TCM_1_B' : 18, + 'NODE_L2' : 19, + 'NODE_GPU_PP_0' : 20, + 'NODE_GPU_PP_1' : 21, + 'NODE_USB_0' : 22, + 'NODE_USB_1' : 23, + 'NODE_TTC_0' : 24, + 'NODE_TTC_1' : 25, + 'NODE_TTC_2' : 26, + 'NODE_TTC_3' : 27, + 'NODE_SATA' : 28, + 'NODE_ETH_0' : 29, + 'NODE_ETH_1' : 30, + 'NODE_ETH_2' : 31, + 'NODE_ETH_3' : 32, + 'NODE_UART_0' : 33, + 'NODE_UART_1' : 34, + 'NODE_SPI_0' : 35, + 'NODE_SPI_1' : 36, + 'NODE_I2C_0' : 37, + 'NODE_I2C_1' : 38, + 'NODE_SD_0' : 39, + 'NODE_SD_1' : 40, + 'NODE_DP' : 41, + 'NODE_GDMA' : 42, + 'NODE_ADMA' : 43, + 'NODE_NAND' : 44, + 'NODE_QSPI' : 45, + 'NODE_GPIO' : 46, + 'NODE_CAN_0' : 47, + 'NODE_CAN_1' : 48, + 'NODE_EXTERN' : 49, + 'NODE_APLL' : 50, + 'NODE_VPLL' : 51, + 'NODE_DPLL' : 52, + 'NODE_RPLL' : 53, + 'NODE_IOPLL' : 54, + 'NODE_DDR' : 55, + 'NODE_IPI_APU' : 56, + 'NODE_IPI_RPU_0' : 57, + 'NODE_GPU' : 58, + 'NODE_PCIE' : 59, + 'NODE_PCAP' : 60, + 'NODE_RTC' : 61, + 'NODE_LPD' : 62, + 'NODE_VCU' : 63, + 'NODE_IPI_RPU_1' : 64, + 'NODE_IPI_PL_0' : 65, + 'NODE_IPI_PL_1' : 66, + 'NODE_IPI_PL_2' : 67, + 'NODE_IPI_PL_3' : 68, + 'NODE_PL' : 69, + 'NODE_ID_MA' : 70, + + 'XILPM_RESET_PCIE_CFG' : 1000, + 'XILPM_RESET_PCIE_BRIDGE' : 1001, + 'XILPM_RESET_PCIE_CTRL' : 1002, + 'XILPM_RESET_DP' : 1003, + 'XILPM_RESET_SWDT_CRF' : 1004, + 'XILPM_RESET_AFI_FM5' : 1005, + 'XILPM_RESET_AFI_FM4' : 1006, + 'XILPM_RESET_AFI_FM3' : 1007, + 'XILPM_RESET_AFI_FM2' : 1008, + 'XILPM_RESET_AFI_FM1' : 1009, + 'XILPM_RESET_AFI_FM0' : 1010, + 'XILPM_RESET_GDMA' : 1011, + 'XILPM_RESET_GPU_PP1' : 1012, + 'XILPM_RESET_GPU_PP0' : 1013, + 'XILPM_RESET_GPU' : 1014, + 'XILPM_RESET_GT' : 1015, + 'XILPM_RESET_SATA' : 1016, + 'XILPM_RESET_ACPU3_PWRON' : 1017, + 'XILPM_RESET_ACPU2_PWRON' : 1018, + 'XILPM_RESET_ACPU1_PWRON' : 1019, + 'XILPM_RESET_ACPU0_PWRON' : 1020, + 'XILPM_RESET_APU_L2' : 1021, + 'XILPM_RESET_ACPU3' : 1022, + 'XILPM_RESET_ACPU2' : 1023, + 'XILPM_RESET_ACPU1' : 1024, + 'XILPM_RESET_ACPU0' : 1025, + 'XILPM_RESET_DDR' : 1026, + 'XILPM_RESET_APM_FPD' : 1027, + 'XILPM_RESET_SOFT' : 1028, + 'XILPM_RESET_GEM0' : 1029, + 'XILPM_RESET_GEM1' : 1030, + 'XILPM_RESET_GEM2' : 1031, + 'XILPM_RESET_GEM3' : 1032, + 'XILPM_RESET_QSPI' : 1033, + 'XILPM_RESET_UART0' : 1034, + 'XILPM_RESET_UART1' : 1035, + 'XILPM_RESET_SPI0' : 1036, + 'XILPM_RESET_SPI1' : 1037, + 'XILPM_RESET_SDIO0' : 1038, + 'XILPM_RESET_SDIO1' : 1039, + 'XILPM_RESET_CAN0' : 1040, + 'XILPM_RESET_CAN1' : 1041, + 'XILPM_RESET_I2C0' : 1042, + 'XILPM_RESET_I2C1' : 1043, + 'XILPM_RESET_TTC0' : 1044, + 'XILPM_RESET_TTC1' : 1045, + 'XILPM_RESET_TTC2' : 1046, + 'XILPM_RESET_TTC3' : 1047, + 'XILPM_RESET_SWDT_CRL' : 1048, + 'XILPM_RESET_NAND' : 1049, + 'XILPM_RESET_ADMA' : 1050, + 'XILPM_RESET_GPIO' : 1051, + 'XILPM_RESET_IOU_CC' : 1052, + 'XILPM_RESET_TIMESTAMP' : 1053, + 'XILPM_RESET_RPU_R50' : 1054, + 'XILPM_RESET_RPU_R51' : 1055, + 'XILPM_RESET_RPU_AMBA' : 1056, + 'XILPM_RESET_OCM' : 1057, + 'XILPM_RESET_RPU_PGE' : 1058, + 'XILPM_RESET_USB0_CORERESET' : 1059, + 'XILPM_RESET_USB1_CORERESET' : 1060, + 'XILPM_RESET_USB0_HIBERRESET' : 1061, + 'XILPM_RESET_USB1_HIBERRESET' : 1062, + 'XILPM_RESET_USB0_APB' : 1063, + 'XILPM_RESET_USB1_APB' : 1064, + 'XILPM_RESET_IPI' : 1065, + 'XILPM_RESET_APM_LPD' : 1066, + 'XILPM_RESET_RTC' : 1067, + 'XILPM_RESET_SYSMON' : 1068, + 'XILPM_RESET_AFI_FM6' : 1069, + 'XILPM_RESET_LPD_SWDT' : 1070, + 'XILPM_RESET_FPD' : 1071, + 'XILPM_RESET_RPU_DBG1' : 1072, + 'XILPM_RESET_RPU_DBG0' : 1073, + 'XILPM_RESET_DBG_LPD' : 1074, + 'XILPM_RESET_DBG_FPD' : 1075, + 'XILPM_RESET_APLL' : 1076, + 'XILPM_RESET_DPLL' : 1077, + 'XILPM_RESET_VPLL' : 1078, + 'XILPM_RESET_IOPLL' : 1079, + 'XILPM_RESET_RPLL' : 1080, + 'XILPM_RESET_GPO3_PL_0' : 1081, + 'XILPM_RESET_GPO3_PL_1' : 1082, + 'XILPM_RESET_GPO3_PL_2' : 1083, + 'XILPM_RESET_GPO3_PL_3' : 1084, + 'XILPM_RESET_GPO3_PL_4' : 1085, + 'XILPM_RESET_GPO3_PL_5' : 1086, + 'XILPM_RESET_GPO3_PL_6' : 1087, + 'XILPM_RESET_GPO3_PL_7' : 1088, + 'XILPM_RESET_GPO3_PL_8' : 1089, + 'XILPM_RESET_GPO3_PL_9' : 1090, + 'XILPM_RESET_GPO3_PL_10' : 1091, + 'XILPM_RESET_GPO3_PL_11' : 1092, + 'XILPM_RESET_GPO3_PL_12' : 1093, + 'XILPM_RESET_GPO3_PL_13' : 1094, + 'XILPM_RESET_GPO3_PL_14' : 1095, + 'XILPM_RESET_GPO3_PL_15' : 1096, + 'XILPM_RESET_GPO3_PL_16' : 1097, + 'XILPM_RESET_GPO3_PL_17' : 1098, + 'XILPM_RESET_GPO3_PL_18' : 1099, + 'XILPM_RESET_GPO3_PL_19' : 1100, + 'XILPM_RESET_GPO3_PL_20' : 1101, + 'XILPM_RESET_GPO3_PL_21' : 1102, + 'XILPM_RESET_GPO3_PL_22' : 1103, + 'XILPM_RESET_GPO3_PL_23' : 1104, + 'XILPM_RESET_GPO3_PL_24' : 1105, + 'XILPM_RESET_GPO3_PL_25' : 1106, + 'XILPM_RESET_GPO3_PL_26' : 1107, + 'XILPM_RESET_GPO3_PL_27' : 1108, + 'XILPM_RESET_GPO3_PL_28' : 1109, + 'XILPM_RESET_GPO3_PL_29' : 1110, + 'XILPM_RESET_GPO3_PL_30' : 1111, + 'XILPM_RESET_GPO3_PL_31' : 1112, + 'XILPM_RESET_RPU_LS' : 1113, + 'XILPM_RESET_PS_ONLY' : 1114, + 'XILPM_RESET_PL' : 1115, + 'XILPM_RESET_GPIO5_EMIO_92' : 1116, + 'XILPM_RESET_GPIO5_EMIO_93' : 1117, + 'XILPM_RESET_GPIO5_EMIO_94' : 1118, + 'XILPM_RESET_GPIO5_EMIO_95' : 1119, + + 'PM_CONFIG_MASTER_SECTION_ID' : 0x101, + 'PM_CONFIG_SLAVE_SECTION_ID' : 0x102, + 'PM_CONFIG_PREALLOC_SECTION_ID' : 0x103, + 'PM_CONFIG_POWER_SECTION_ID' : 0x104, + 'PM_CONFIG_RESET_SECTION_ID' : 0x105, + 'PM_CONFIG_SHUTDOWN_SECTION_ID' : 0x106, + 'PM_CONFIG_SET_CONFIG_SECTION_ID' : 0x107, + 'PM_CONFIG_GPO_SECTION_ID' : 0x108, + + 'PM_SLAVE_FLAG_IS_SHAREABLE' : 0x1, + 'PM_MASTER_USING_SLAVE_MASK' : 0x2, + + 'PM_CONFIG_GPO1_MIO_PIN_34_MAP' : (1 << 10), + 'PM_CONFIG_GPO1_MIO_PIN_35_MAP' : (1 << 11), + 'PM_CONFIG_GPO1_MIO_PIN_36_MAP' : (1 << 12), + 'PM_CONFIG_GPO1_MIO_PIN_37_MAP' : (1 << 13), + + 'PM_CONFIG_GPO1_BIT_2_MASK' : (1 << 2), + 'PM_CONFIG_GPO1_BIT_3_MASK' : (1 << 3), + 'PM_CONFIG_GPO1_BIT_4_MASK' : (1 << 4), + 'PM_CONFIG_GPO1_BIT_5_MASK' : (1 << 5), + + 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, + + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, + 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, + 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, +} + +in_file = open(args.in_file, mode='r') +out_file = open(args.out_file, mode='wb') + +num_re = re.compile(r"^([0-9]+)U?$") +const_re = re.compile(r"^([A-Z_][A-Z0-9_]*)$") + +def process_item(item): + logging.debug("* ITEM " + item) + + value = 0 + for item in item.split('|'): + item = item.strip() + + num_match = num_re .match(item) + const_match = const_re.match(item) + + if num_match: + num = int(num_match.group(1)) + logging.debug(" - num " + str(num)) + value |= num + elif const_match: + name = const_match.group(1) + if not name in pm_define: + sys.stderr.write("Unknown define " + name + "!\n") + exit(1) + num = pm_define[name] + logging.debug(" - def " + hex(num)) + value |= num + + logging.debug(" = res " + hex(value)) + out_file.write(struct.pack('<L', value)) + + +# Read all code +code = in_file.read() + +# remove comments +code = re.sub('//.*?\n|/\*.*?\*/', '', code, flags=re.DOTALL) + +# remove everything outside the XPm_ConfigObject array definition +code = re.search('const u32 XPm_ConfigObject.*= {\n(.*)};', + code, flags=re.DOTALL).group(1) + +# Process each comma-separated array item +for item in code.split(','): + item = item.strip() + if item: + process_item(item.strip()) + +print("Wrote %d bytes" % out_file.tell())
The recently-added ZYNQMP_LOAD_PM_CFG_OBJ_FILE option allows SPL to load a PMUFW configuration object from a binary blob. However the configuration object is produced by Xilinx proprietary tools as a C source file and no tool exists to easily convert it to a binary blob in an embedded Linux build system for U-Boot to use. Add a simple Python script to do the conversion. It is definitely not a complete C language parser, but it is enough to parse the known patterns generated by Xilinx tools, including: - defines - literal integers, optionally with a 'U' suffix - bitwise OR between them Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net> --- arch/arm/mach-zynqmp/pm_cfg_obj_convert.py | 302 +++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100755 arch/arm/mach-zynqmp/pm_cfg_obj_convert.py