Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | #memory_footprint.py : Script for sending memory footprint data from the TFM CI |
| 4 | #to a SQUAD web interface |
| 5 | # |
Xinyu Zhang | 9a29f03 | 2022-01-19 15:13:24 +0800 | [diff] [blame] | 6 | #Copyright (c) 2020-2022, Arm Limited. All rights reserved. |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 7 | # |
| 8 | #SPDX-License-Identifier: BSD-3-Clause |
| 9 | |
| 10 | |
| 11 | import argparse |
| 12 | import os |
| 13 | import re |
| 14 | import sys |
| 15 | import json |
| 16 | import requests |
| 17 | import subprocess |
| 18 | import configs |
| 19 | from tfm_ci_pylib import utils |
| 20 | |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 21 | # SQAUD constant |
| 22 | SQUAD_TOKEN = sys.argv[1] |
| 23 | SQUAD_BASE_PROJECT_URL = ("https://qa-reports.linaro.org/api/submit/tf/tf-m/") |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 24 | |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 25 | reference_configs = [ |
| 26 | # build type, profile |
| 27 | ["Release", "profile_small"], |
| 28 | ["Minsizerel", "profile_small"], |
| 29 | ["Release", "profile_medium"], |
| 30 | ["Release", "profile_large"], |
| 31 | ] |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 32 | |
| 33 | # This function uses arm_non_eabi_size to get the sizes of a file |
| 34 | # in the build directory of tfm |
| 35 | def get_file_size(filename): |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 36 | f_path = os.path.join(os.getenv('WORKSPACE'), "trusted-firmware-m", "build", "bin", filename) |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 37 | if os.path.exists(f_path) : |
Hugo L'Hostis | 26dc296 | 2021-04-22 15:44:48 +0100 | [diff] [blame] | 38 | file_sizes = utils.arm_non_eabi_size(f_path)[0] |
| 39 | return file_sizes |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 40 | else : |
| 41 | print(f_path + "Not found") |
| 42 | return -1 |
| 43 | |
| 44 | # This function creates a json file containing all the data about |
| 45 | # memory footprint and sends this data to SQUAD |
| 46 | def send_file_size(change_id, config_name, bl2_sizes, tfms_sizes): |
| 47 | url = SQUAD_BASE_PROJECT_URL + change_id + '/' + config_name |
| 48 | |
| 49 | try: |
| 50 | metrics = json.dumps({ "bl2_size" : bl2_sizes["dec"], |
| 51 | "bl2_data" : bl2_sizes["data"], |
| 52 | "bl2_bss" : bl2_sizes["bss"], |
Hugo L'Hostis | 26dc296 | 2021-04-22 15:44:48 +0100 | [diff] [blame] | 53 | "bl2_text" : bl2_sizes["text"], |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 54 | "tfms_size" : tfms_sizes["dec"], |
| 55 | "tfms_data" : tfms_sizes["data"], |
Hugo L'Hostis | 26dc296 | 2021-04-22 15:44:48 +0100 | [diff] [blame] | 56 | "tfms_bss" : tfms_sizes["bss"], |
| 57 | "tfms_text" : tfms_sizes["text"]}) |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 58 | except: |
| 59 | return -1 |
| 60 | |
| 61 | headers = {"Auth-Token": SQUAD_TOKEN} |
| 62 | data= {"metrics": metrics} |
| 63 | |
| 64 | try: |
| 65 | #Sending the data to SQUAD, 40s timeout |
| 66 | result = requests.post(url, headers=headers, data=data, timeout=40) |
| 67 | except: |
| 68 | return -1 |
| 69 | |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 70 | with open(os.path.join(os.getenv('WORKSPACE'), |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 71 | "tf-m-ci-scripts", |
| 72 | "Memory_footprint", |
| 73 | "filesize.json"), "w") as F: |
| 74 | #Storing the json file |
| 75 | F.write(metrics) |
| 76 | |
| 77 | if not result.ok: |
| 78 | print(f"Error submitting to qa-reports: {result.reason}: {result.text}") |
| 79 | return -1 |
| 80 | else : |
| 81 | print ("POST request sent to project " + config_name ) |
| 82 | return 0 |
| 83 | |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 84 | # Function based on get_local_git_info() from utils, getting change id for the tfm repo |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 85 | def get_change_id(repo='trusted-firmware-m'): |
| 86 | directory = os.path.join(os.getenv('WORKSPACE'), repo) |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 87 | cur_dir = os.path.abspath(os.getcwd()) |
| 88 | cmd = "git log HEAD -n 1 --pretty=format:'%b'" |
| 89 | |
| 90 | os.chdir(directory) # Going to the repo's directory |
| 91 | |
| 92 | git_info_rex = re.compile(r'(?P<body>^[\s\S]*?)((?:Change-Id:\s)' |
| 93 | r'(?P<change_id>.*)\n?)', re.MULTILINE) |
| 94 | |
| 95 | r, e = subprocess.Popen(cmd, |
| 96 | shell=True, |
| 97 | stdout=subprocess.PIPE, |
| 98 | stderr=subprocess.PIPE).communicate() |
| 99 | |
| 100 | if e: |
| 101 | print("Error", e) |
| 102 | return -1 |
| 103 | else: |
| 104 | try: |
| 105 | txt_body = r.decode('ascii') |
| 106 | except UnicodeDecodeError as E: |
| 107 | txt_body = r.decode('utf-8') |
| 108 | result = txt_body.rstrip() |
| 109 | |
| 110 | try: |
| 111 | change_id = git_info_rex.search(result).groupdict()["change_id"].strip() |
| 112 | except: |
| 113 | return -1 |
| 114 | |
| 115 | os.chdir(cur_dir) #Going back to the initial directory |
| 116 | return change_id |
| 117 | |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 118 | def is_reference_config() -> bool: |
| 119 | # Only push data for AN521 built with GCC |
| 120 | if (os.getenv('TFM_PLATFORM') != 'arm/mps2/an521' |
| 121 | or os.getenv('COMPILER') != 'GCC_10_3' |
| 122 | or os.getenv('TEST_REGRESSION') == "True"): |
| 123 | return False |
| 124 | |
| 125 | configs = [os.getenv('CMAKE_BUILD_TYPE'), os.getenv('PROFILE')] |
| 126 | if configs in reference_configs: |
| 127 | return True |
| 128 | |
| 129 | return False |
| 130 | |
| 131 | def print_image_sizes(image_sizes): |
| 132 | for sec, size in image_sizes.items(): |
| 133 | print("{:4}: {}".format(sec, size)) |
| 134 | |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 135 | if __name__ == "__main__": |
Xinyu Zhang | 16a218e | 2022-10-11 17:21:39 +0800 | [diff] [blame] | 136 | # Export GCC v10.3 to ENV PATH |
| 137 | os.environ["PATH"] += os.pathsep + os.getenv('GCC_10_3_PATH') |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 138 | if is_reference_config(): |
| 139 | print("Configuration " + os.getenv('CONFIG_NAME') + " is a reference") |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 140 | try : |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 141 | change_id = get_change_id("trusted-firmware-m") |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 142 | except : |
| 143 | change_id = -1 |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 144 | |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 145 | bl2_sizes = get_file_size("bl2.axf") |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 146 | print("------ BL2 Memory Footprint ------") |
| 147 | print_image_sizes(bl2_sizes) |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 148 | tfms_sizes = get_file_size("tfm_s.axf") |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 149 | print("------ TFM Secure Memory Footprint ------") |
| 150 | print_image_sizes(tfms_sizes) |
| 151 | |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 152 | if (bl2_sizes != -1 and change_id != -1) : |
Xinyu Zhang | 470b3c4 | 2022-09-19 14:41:45 +0800 | [diff] [blame] | 153 | squad_config_name = os.getenv('CMAKE_BUILD_TYPE') + os.getenv('PROFILE') |
| 154 | send_file_size(change_id, squad_config_name, bl2_sizes, tfms_sizes) |
Hugo L'Hostis | e55a275 | 2021-01-27 11:09:08 +0000 | [diff] [blame] | 155 | else : |
| 156 | #Directory or file weren't found |
| 157 | if change_id == -1 : |
| 158 | print("Error : trusted-firmware-m repo not found") |
| 159 | else : |
| 160 | print("Error : file not found") |