1#!/usr/bin/env python3
2#
3# Copyright (c) 2024 Nuvoton Technology Corporation
4#
5# SPDX-License-Identifier: Apache-2.0
6
7# This file contains general functions for ESIOST application
8
9import sys
10import argparse
11import colorama
12from colorama import Fore
13
14INVALID_INPUT = -1
15EXIT_FAILURE_STATUS = 1
16
17# Verbose related values
18NO_VERBOSE = 0
19REG_VERBOSE = 1
20
21# argument default values.
22DEFAULT_VERBOSE = NO_VERBOSE
23
24# Chips: convert from name to index.
25CHIPS_INFO = {
26    'npcm400': {'flash_address': 0x80000, 'flash_size': 0x20000, 'ram_address': 0x10008000, 'ram_size': 0xC0000},
27}
28
29DEFAULT_CHIP = 'npcm400'
30
31class EsiostArgs:
32    """creates an arguments object for the ESIOST,
33    the arguments are taken from the command line and/or
34    argument file
35    """
36    error_args = None
37
38    help = False
39    verbose = DEFAULT_VERBOSE
40    input = None
41    output = None
42    args_file = None
43    chip_name = DEFAULT_CHIP
44    chip_ram_address = CHIPS_INFO[DEFAULT_CHIP]['ram_address']
45    chip_ram_size = CHIPS_INFO[DEFAULT_CHIP]['ram_address']
46    chip_flash_address = CHIPS_INFO[DEFAULT_CHIP]['flash_address']
47    chip_flash_size = CHIPS_INFO[DEFAULT_CHIP]['flash_size']
48    firmware_load_address = None
49    firmware_entry_point = None
50    firmware_length = None
51
52    def __init__(self):
53
54        arguments = _create_parser("")
55        valid_arguments = arguments[0]
56        invalid_arguments = arguments[1]
57        self.error_args = invalid_arguments
58
59        _populate_args(self, valid_arguments)
60        _populate_chip_fields(self)
61
62def _populate_chip_fields(self):
63    """populate the chip related fields for the esiost"""
64    self.chip_name = self.chip_name
65    chip = str(self.chip_name).lower()
66
67    if chip not in CHIPS_INFO:
68        self.chip_name = INVALID_INPUT
69        return
70
71    self.chip_ram_address = CHIPS_INFO[chip]['ram_address']
72    self.chip_ram_size = CHIPS_INFO[chip]['ram_size']
73    self.chip_flash_address = CHIPS_INFO[DEFAULT_CHIP]['flash_address']
74    self.chip_flash_size = CHIPS_INFO[DEFAULT_CHIP]['flash_size']
75    if self.firmware_load_address is None:
76        self.firmware_load_address = self.chip_ram_address
77
78def _populate_args(self, argument_list):
79    """populate the esiost arguments according to the command line/ args file"""
80    for arg in vars(argument_list):
81        if (arg == "input") & (argument_list.input is not None):
82            self.input = argument_list.input
83
84        elif (arg == "output") & (argument_list.output is not None):
85            self.output = argument_list.output
86
87        elif (arg == "chip") & (argument_list.chip is not None):
88            self.chip_name = argument_list.chip
89            _populate_chip_fields(self)
90
91        elif (arg == "verbose") & argument_list.verbose:
92            self.verbose = REG_VERBOSE
93
94def _create_parser(arg_list):
95    """create argument parser according to pre-defined arguments
96
97    :param arg_list: when empty, parses command line arguments,
98    else parses the given string
99    """
100
101    parser = argparse.ArgumentParser(conflict_handler='resolve', allow_abbrev=False)
102    parser.add_argument("-i", nargs='?', dest="input")
103    parser.add_argument("-o", nargs='?', dest="output")
104    parser.add_argument("-chip", dest="chip")
105    parser.add_argument("-v", action="store_true", dest="verbose")
106
107    args = parser.parse_known_args(arg_list.split())
108
109    if arg_list == "":
110        args = parser.parse_known_args()
111
112    return args
113
114def exit_with_failure(message):
115    """formatted failure message printer, prints the
116    relevant error message and exits the application.
117
118    :param message: the error message to be printed
119    """
120
121    message = '\n' + message
122    message += '\n'
123    message += '******************************\n'
124    message += '***        FAILED          ***\n'
125    message += '******************************\n'
126    print(Fore.RED + message)
127
128    sys.exit(EXIT_FAILURE_STATUS)
129
130colorama.init()
131