Esempio n. 1
0
def generate_config_templates(family: str, output_folder: str) -> None:
    """Generate all possible configuration for selected family."""
    if not family:
        raise SPSDKError("The chip family must be specified.")

    templates: Dict[str, str] = {}
    # 1: Generate all configuration for MBI
    templates.update(mbi_generate_config_templates(family))
    # 2: Add TrustZone Configuration file
    templates.update(TrustZone.generate_config_template(family))
    # 3: Optionally add Secure Binary v3.1 Configuration file
    templates.update(SecureBinary31.generate_config_template(family))

    # And generate all config templates files
    for template in templates:
        file_name = f"{template}.yml"
        if os.path.isfile(output_folder):
            raise SPSDKError(f"The specified path {output_folder} is file.")
        if not os.path.isdir(output_folder):
            os.mkdir(output_folder)
        full_file_name = os.path.join(output_folder, file_name)
        if not os.path.isfile(full_file_name):
            click.echo(f"Creating {file_name} template file.")
            with open(full_file_name, "w") as f:
                f.write(templates[template])
        else:
            click.echo(f"Skip creating {file_name}, this file already exists.")
Esempio n. 2
0
def main(
    ctx: click.Context,
    interface: str,
    log_level: str,
    serial_no: str,
    debug_probe_option: List[str],
    device: str,
    revision: str,
) -> int:
    """NXP Shadow Registers control Tool."""
    logging.basicConfig(level=log_level.upper())
    logger.setLevel(level=log_level.upper())

    config_filename = os.path.join(CONFIG_DIR, CONFIG_FILE)

    probe_user_params = {}
    for par in debug_probe_option:
        if par.count("=") != 1:
            raise SPSDKError(f"Invalid -o parameter {par}!")
        par_splitted = par.split("=")
        probe_user_params[par_splitted[0]] = par_splitted[1]

    ctx.obj = {
        "config_file": config_filename,
        "interface": interface,
        "serial_no": serial_no,
        "debug_probe_params": probe_user_params,
        "device": device,
        "revision": revision or "latest",
    }

    return 0
Esempio n. 3
0
def main(ctx: click.Context, interface: str, log_level: str,
         serial_no: str, debug_probe_option: List[str], device: str) -> int:
    """NXP Shadow Registers control Tool."""
    logging.basicConfig(level=log_level.upper())
    logger.setLevel(level=log_level.upper())

    config_filename = os.path.join(CONFIG_DIR, CONFIG_FILE)

    probe_user_params = {}
    for par in debug_probe_option:
        if par.count("=") != 1:
            raise SPSDKError(f"Invalid -o parameter {par}!")
        else:
            par_splitted = par.split("=")
            probe_user_params[par_splitted[0]] = par_splitted[1]

    ctx.obj = {
        'config_file': config_filename,
        'interface': interface,
        'serial_no': serial_no,
        'debug_probe_params': probe_user_params,
        'device': device
        }

    return 0
Esempio n. 4
0
def main(ctx: click.Context, interface: str, protocol: str, log_level: str,
         timing: float, serial_no: str, debug_probe_option: List[str],
         reset: bool) -> int:
    """NXP Debug Mailbox Tool."""
    logging.basicConfig(level=log_level.upper())
    logger.setLevel(level=log_level.upper())

    probe_user_params = {}
    for par in debug_probe_option:
        if par.count("=") != 1:
            raise SPSDKError(f"Invalid -o parameter {par}!")

        par_splitted = par.split("=")
        probe_user_params[par_splitted[0]] = par_splitted[1]

    ctx.obj = {
        'protocol': protocol,
        'interface': interface,
        'serial_no': serial_no,
        'debug_probe_params': probe_user_params,
        'timing': timing,
        'reset': reset,
    }

    return 0
Esempio n. 5
0
def setreg(pass_obj: dict, reg: str, reg_val: str) -> None:
    """The command sets a value of one shadow register defined by parameter."""
    shadow_regs: ShadowRegisters = _open_registers(pass_obj)
    try:
        shadow_regs.set_register(reg, reg_val)
        click.echo(f"The Shadow register {reg} has been set to {reg_val} value")
    except SPSDKError as exc:
        raise SPSDKError(f"Setting Shadow register failed! ({str(exc)})")
Esempio n. 6
0
def saveconfig(pass_obj: dict, filename: str = "sr_config.yml", raw: bool = False) -> None:
    """Save current state of shadow registers to YML file."""
    try:
        shadow_regs: ShadowRegisters = _open_registers(pass_obj)
        shadow_regs.reload_registers()
        shadow_regs.create_yml_config(filename, raw)
        click.echo(f"The Shadow registers has been saved into {filename} YAML file")
    except SPSDKError as exc:
        raise SPSDKError(f"Save configuration of Shadow registers failed! ({str(exc)})")
Esempio n. 7
0
def getreg(pass_obj: dict, reg: str) -> None:
    """The command prints the current value of one shadow register."""
    shadow_regs: ShadowRegisters = _open_shadow_registers(pass_obj)
    try:
        register: RegsRegister = shadow_regs.regs.find_reg(reg)
        shadow_regs.reload_register(register)
        click.echo(f"Value of {reg} is: {register.get_hex_value()}")
    except SPSDKError as exc:
        raise SPSDKError(f"Getting Shadow register failed! ({str(exc)})")
Esempio n. 8
0
def loadconfig(pass_obj: dict, filename: str = "sr_config.yml", raw: bool = False) -> None:
    """Load new state of shadow registers from YML file into microcontroller."""
    try:
        shadow_regs: ShadowRegisters = _open_registers(pass_obj)
        shadow_regs.load_yml_config(filename, raw)
        shadow_regs.sets_all_registers()
        click.echo(f"The Shadow registers has been loaded by configuration in {filename} YAML file")
    except SPSDKError as exc:
        raise SPSDKError(f"Load configuration of Shadow registers failed ({str(exc)})!")
Esempio n. 9
0
    def set_register(self, reg_name: str, data: Any) -> None:
        """The function sets the value of the specified register.

        param reg: The register name.
        param data: The new data to be stored to shadow register.
        raises DebugProbeError: The debug probe is not specified.
        """
        if self._probe is None:
            raise DebugProbeError("There is no debug probe.")

        try:
            reg = self.regs.find_reg(reg_name)
            value = value_to_bytes(data)

            start_address = self.offset + reg.offset
            width = reg.width

            if width < len(value) * 8:
                raise SPSDKError(f"Invalid length of data for shadow register write.")

            if width < 32:
                width = 32

            data_alligned = bytearray(math.ceil(width / 8))
            data_alligned[len(data_alligned) - len(value) : len(data_alligned)] = value

            if reg.reverse:
                data_alligned = self._reverse_bytes_in_longs(data_alligned)

            if width == 32:
                self._write_shadow_reg(start_address, int.from_bytes(data_alligned[:4], "big"))
            else:
                end_address = start_address + math.ceil(width / 8)
                addresses = range(start_address, end_address, 4)

                i = 0
                for addr in addresses:
                    self._write_shadow_reg(addr, int.from_bytes(data_alligned[i:i+4], "big"))
                    i += 4

            reg.set_value(value)

        except SPSDKError as exc:
            raise SPSDKError(f"The get shadow register failed({str(exc)}).")
Esempio n. 10
0
def _open_shadow_registers(pass_obj: Dict) -> ShadowRegisters:
    """Method opens ShadowRegisters object based on input arguments.

    :param pass_obj: Input dictionary with arguments.
    :return: Active ShadowRegisters object.
    :raises SPSDKError: Raised with any kind of problems with debug probe.
    """
    config_file = pass_obj["config_file"]
    interface = pass_obj["interface"]
    serial_no = pass_obj["serial_no"]
    debug_probe_params = pass_obj["debug_probe_params"]
    device = pass_obj["device"]
    revision = pass_obj["revision"]

    if device not in RegConfig.devices(config_file):
        raise SPSDKError(
            "Invalid or none device parameter(-dev). Use 'listdevs' command to get supported devices."
        )

    regs_cfg = RegConfig(config_file)

    try:
        debug_probes = DebugProbeUtils.get_connected_probes(
            interface=interface,
            hardware_id=serial_no,
            user_params=debug_probe_params)
        selected_probe = debug_probes.select_probe()
        debug_probe = selected_probe.get_probe(debug_probe_params)
        debug_probe.open()
        if not enable_debug(debug_probe):
            raise SPSDKError("Cannot enable debug interface")

        debug_probe.enable_memory_interface()
    except SPSDKError as exc:
        raise SPSDKError(
            f"Error with opening debug probe: ({str(exc)})") from exc

    return ShadowRegisters(debug_probe=debug_probe,
                           config=regs_cfg,
                           device=device,
                           revision=revision)
Esempio n. 11
0
    def _decode_report(raw_data: bytes) -> Union[CmdResponse, bytes]:
        """Decodes the data read on USB interface.

        :param raw_data: Data received
        :type raw_data: bytes
        :return: CmdResponse object or data read
        :raises SPSDKError: Transaction aborted by target
        """
        logger.debug(
            f"IN [{len(raw_data)}]: {', '.join(f'{b:02X}' for b in raw_data)}")
        report_id, _, plen = unpack_from('<2BH', raw_data)
        if plen == 0:
            logger.debug("Received an abort package")
            raise SPSDKError('Transaction aborted')
        data = raw_data[4:4 + plen]
        if report_id == REPORT_ID['CMD_IN']:
            return parse_cmd_response(data)
        return data
Esempio n. 12
0
def printregs(pass_obj: dict, rich: bool = False) -> None:
    """Print all Shadow registers including theirs current values.

    In case of needed more information, there is also provided rich format of print.
    """
    try:
        shadow_regs: ShadowRegisters = _open_shadow_registers(pass_obj)
        shadow_regs.reload_registers()

        for reg in shadow_regs.regs.get_registers():
            click.echo(f"Register Name:        {reg.name}")
            click.echo(f"Register value:       {reg.get_hex_value()}")
            if rich:
                click.echo(f"Register description: {reg.description}")
                address = shadow_regs.offset + reg.offset
                click.echo(f"Register address:     0x{address:08X}")
                click.echo(f"Register width:       {reg.width} bits")
            click.echo()
    except SPSDKError as exc:
        raise SPSDKError(f"Print of Shadow registers failed! ({str(exc)})")
Esempio n. 13
0
    def mem_reg_write(self, addr: int = 0, data: int = 0) -> None:
        """Write 32-bit register in memory space of MCU.

        This is write 32-bit register in memory space of MCU function for SPSDK library
        to support various DEBUG PROBES.

        :param addr: the register address
        :param data: the data to be written into register
        :raises DebugProbeNotOpenError: The Pemicro probe is NOT opened
        :raises SPSDKError: The Pemicro probe has failed during write operation
        """
        if self.pemicro is None:
            raise DebugProbeNotOpenError(
                "The Pemicro debug probe is not opened yet")

        self.last_access_memory = True
        try:
            self.pemicro.write_32bit(address=addr, data=data)
        except PEMicroException as exc:
            logger.error(f"Failed write memory({str(exc)}).")
            raise SPSDKError(str(exc))
Esempio n. 14
0
    def mem_reg_read(self, addr: int = 0) -> int:
        """Read 32-bit register in memory space of MCU.

        This is read 32-bit register in memory space of MCU function for SPSDK library
        to support various DEBUG PROBES.

        :param addr: the register address
        :return: The read value of addressed register (4 bytes)
        :raises DebugProbeNotOpenError: The Pemicro probe is NOT opened
        :raises SPSDKError: The Pemicro probe has failed during read operation
        """
        if self.pemicro is None:
            raise DebugProbeNotOpenError(
                "The Pemicro debug probe is not opened yet")

        self.last_access_memory = True
        reg = 0
        try:
            reg = self.pemicro.read_32bit(addr)
        except PEMicroException as exc:
            logger.error(f"Failed read memory({str(exc)}).")
            raise SPSDKError(str(exc))
        return reg
Esempio n. 15
0
    def get_register(self, reg_name: str) -> bytes:
        """The function returns value of the requested register.

        param reg: The register name.
        return: The value of requested register in bytes
        raises DebugProbeError: The debug probe is not specified.
        """
        if self._probe is None:
            raise DebugProbeError("There is no debug probe.")

        result = bytearray()
        try:
            reg = self.regs.find_reg(reg_name)

            start_address = self.offset + reg.offset
            width = reg.width

            if width < 32:
                width = 32

            if width == 32:
                result.extend(self._probe.mem_reg_read(start_address).to_bytes(4, "big"))
            else:
                end_address = start_address + math.ceil(width / 8)
                addresses = range(start_address, end_address, 4)

                for addr in addresses:
                    result.extend(self._probe.mem_reg_read(addr).to_bytes(4, "big"))

            if reg.reverse:
                result = self._reverse_bytes_in_longs(result)

        except SPSDKError as exc:
            raise SPSDKError(f"The get shadow register failed({str(exc)}).")

        return result
Esempio n. 16
0
def enable_debug(probe: DebugProbe, ap_mem: int = 0) -> bool:
    """Function that enables debug access ports on devices with debug mailbox.

    :param probe: Initialized debug probe.
    :param ap_mem: Index of Debug access port for memory interface.
    :return: True if debug port is enabled, False otherwise
    :raises SPSDKError: Unlock method failed.
    """
    debug_enabled = False
    try:
        def test_ahb_access(ap_mem: int) -> bool:
            logger.debug("step T.1: Activate the correct AP")
            probe.coresight_reg_write(access_port=False, addr=2*4, data=ap_mem)

            logger.debug("step T.2: Set the AP access size and address mode")
            probe.coresight_reg_write(access_port=True,
                                      addr=probe.get_coresight_ap_address(ap_mem, 0*4),
                                      data=0x22000012)

            logger.debug("step T.3: Set the initial AHB address to access")
            probe.coresight_reg_write(access_port=True,
                                      addr=probe.get_coresight_ap_address(ap_mem, 1*4),
                                      data=0xE000ED00)

            logger.debug("step T.4: Access the memory system at that address")
            try:
                chip_id = probe.coresight_reg_read(access_port=True,
                                                   addr=probe.get_coresight_ap_address(ap_mem, 3*4))
                logger.debug(f"ChipID={chip_id:08X}")
            except DebugProbeError:
                chip_id = 0xFFFFFFFF
                logger.debug(f"ChipID can't be read")

            # Check if the device is locked
            return chip_id not in (0xFFFFFFFF, 0)

        logger.debug("step 3: Check if AHB is enabled")

        if not test_ahb_access(ap_mem):
            logger.debug("Locked Device. Launching unlock sequence.")

            # Start debug mailbox system
            dbg_mlbx = DebugMailbox(debug_probe=probe)
            StartDebugSession(dm=dbg_mlbx).run()

            # Recheck the AHB access
            if test_ahb_access(ap_mem):
                logger.debug(f"Access granted")
                debug_enabled = True
            else:
                logger.debug(f"Enable debug operation failed!")
        else:
            logger.debug("Unlocked Device")
            debug_enabled = True

    except AttributeError as exc:
        raise SPSDKError(f"Invalid input parameters({str(exc)})")

    except DebugProbeError as exc:
        raise SPSDKError(f"Can't unlock device ({str(exc)})")

    return debug_enabled
Esempio n. 17
0
    def _connect_jlink(self) -> None:
        """Custom J-Link connect function.

        :raises SPSDKError: Unsupported communication protocol.
        :raises SPSDKDebugProbeNotOpenError: The PyOCD probe is NOT opened
        :raises SPSDKDebugProbeError: General error with probe.
        """
        if self.pyocd_session is None:
            raise SPSDKDebugProbeNotOpenError(
                "The PyOCD debug probe is not opened yet")

        # Attempt to connect.
        debug_probe = self.pyocd_session.target.dp
        probe = debug_probe.probe
        protocol = debug_probe._protocol

        # Connect to the target via JTAG or SWD.

        # Handle default protocol.
        if (protocol is None) or (
                protocol
                == pyocd.probe.debug_probe.DebugProbe.Protocol.DEFAULT):
            protocol = probe._default_protocol

        # Validate selected protocol.
        if protocol not in probe._supported_protocols:
            raise SPSDKError(f"unsupported wire protocol {protocol}")

        # Convert protocol to port enum.
        if protocol == PyOCDDebugProbe.Protocol.SWD:
            interface = pylink.enums.JLinkInterfaces.SWD
        elif protocol == PyOCDDebugProbe.Protocol.JTAG:
            interface = pylink.enums.JLinkInterfaces.JTAG

        try:
            probe._link.set_tif(interface)
            if probe.session.options.get("jlink.power"):
                probe._link.power_on()
            # device_name = probe.session.options.get('jlink.device') or "Cortex-M4"
            # probe._link.connect(device_name, speed=200)
            probe._link.coresight_configure()
            probe._protocol = protocol
        except JLinkException as exc:
            raise SPSDKDebugProbeError(probe._convert_exception(exc)) from exc

        def __read_idr(probe) -> int:
            """Read IDR register and get DP version."""
            dpidr = probe.read_dp(dap.DP_IDR, now=True)
            dp_partno = (dpidr
                         & dap.DPIDR_PARTNO_MASK) >> dap.DPIDR_PARTNO_SHIFT
            dp_version = (dpidr
                          & dap.DPIDR_VERSION_MASK) >> dap.DPIDR_VERSION_SHIFT
            dp_revision = (
                dpidr & dap.DPIDR_REVISION_MASK) >> dap.DPIDR_REVISION_SHIFT
            is_mindp = (dpidr & dap.DPIDR_MIN_MASK) != 0
            return dap.DPIDR(dpidr, dp_partno, dp_version, dp_revision,
                             is_mindp)

        # Report on DP version.
        debug_probe.dpidr = probe.dpidr = __read_idr(probe)
        mindp = " MINDP" if probe.dpidr.mindp else ""
        logger.info(
            f"DP IDR = 0x{probe.dpidr.idr:08X} (v{probe.dpidr.version}{mindp} rev{probe.dpidr.revision})"
        )
Esempio n. 18
0
def generate_secure_binary_21(
    bd_file_path: click.Path,
    output_file_path: click.Path,
    key_file_path: click.Path,
    private_key_file_path: click.Path,
    signing_certificate_file_paths: List[click.Path],
    root_key_certificate_paths: List[click.Path],
    hoh_out_path: click.Path,
    external_files: List[click.Path],
) -> None:
    """Generate SecureBinary image from BD command file.

    :param bd_file_path: path to BD file.
    :param output_file_path: output path to generated secure binary file.
    :param key_file_path: path to key file.
    :param private_key_file_path: path to private key file for signing. This key
    relates to last certificate from signing certificate chain.
    :param signing_certificate_file_paths: signing certificate chain.
    :param root_key_certificate_paths: paths to root key certificate(s) for
    verifying other certificates. Only 4 root key certificates are allowed,
    others are ignored. One of the certificates must match the first certificate
    passed in signing_certificate_file_paths.
    :param hoh_out_path: output path to hash of hashes of root keys. If set to
    None, 'hash.bin' is created under working directory.
    :param external_files: external files referenced from BD file.

    :raises SPSDKError: If incorrect bf file is provided
    """
    # Create lexer and parser, load the BD file content and parse it for
    # further execution - the parsed BD file is a dictionary in JSON format
    with open(str(bd_file_path)) as bd_file:
        bd_file_content = bd_file.read()

    parser = bd_parser.BDParser()

    parsed_bd_file = parser.parse(text=bd_file_content, extern=external_files)
    if parsed_bd_file is None:
        raise SPSDKError(
            "Invalid bd file, secure binary file generation terminated")

    # The dictionary contains following content:
    # {
    #   options: {
    #       opt1: value,...
    #   },
    #   sections: [
    #       {section_id: value, options: {}, commands: {}},
    #       {section_id: value, options: {}, commands: {}}
    #   ]
    # }
    # TODO check, that section_ids differ in sections???

    # we need to encrypt and sign the image, let's check, whether we have
    # everything we need
    # It appears, that flags option in BD file are irrelevant for 2.1 secure
    # binary images regarding encryption/signing - SB 2.1 must be encrypted
    # and signed.
    # However, bit 15 represents, whether the final SB 2.1 must include a
    # SHA-256 of the botable section.
    flags = parsed_bd_file["options"].get(
        "flags", BootImageV21.FLAGS_SHA_PRESENT_BIT
        | BootImageV21.FLAGS_ENCRYPTED_SIGNED_BIT)
    if (private_key_file_path is None or signing_certificate_file_paths is None
            or root_key_certificate_paths is None):
        click.echo(
            "error: Signed image requires private key with -s option, "
            "one or more certificate(s) using -S option and one or more root key "
            "certificates using -R option")
        sys.exit(1)

    # Versions and build number are up to the user. If he doesn't provide any,
    # we set these to following values.
    product_version = parsed_bd_file["options"].get("productVersion", "")
    component_version = parsed_bd_file["options"].get("componentVersion", "")
    build_number = parsed_bd_file["options"].get("buildNumber", -1)

    if not product_version:
        product_version = "1.0.0"
        click.echo(
            "warning: production version not defined, defaults to '1.0.0'")

    if not component_version:
        component_version = "1.0.0"
        click.echo(
            "warning: component version not defined, defaults to '1.0.0'")

    if build_number == -1:
        build_number = 1
        click.echo("warning: build number not defined, defaults to '1.0.0'")

    if key_file_path is None:
        # Legacy elf2sb doesn't report no key provided, but this should
        # be definitely reported to tell the user, what kind of key is being
        # used
        click.echo("warning: no KEK key provided, using a zero KEK key")
        sb_kek = bytes.fromhex("0" * 64)
    else:
        with open(str(key_file_path)) as kek_key_file:
            # TODO maybe we should validate the key length and content, to make
            # sure the key provided in the file is valid??
            sb_kek = bytes.fromhex(kek_key_file.readline())

    # validate keyblobs and perform appropriate actions
    keyblobs = parsed_bd_file.get("keyblobs", [])

    # Based on content of parsed BD file, create a BootSectionV2 and assign
    # commands to them.
    # The content of section looks like this:
    # sections: [
    #   {
    #       section_id: <number>,
    #       options: {}, this is left empty for now...
    #       commands: [
    #           {<cmd1>: {<param1>: value, ...}},
    #           {<cmd2>: {<param1>: value, ...}},
    #           ...
    #       ]
    #   },
    #   {
    #       section_id: <number>,
    #       ...
    #   }
    # ]
    sb_sections = []
    bd_sections = parsed_bd_file["sections"]
    for bd_section in bd_sections:
        section_id = bd_section["section_id"]
        commands = []
        for cmd in bd_section["commands"]:
            for key, value in cmd.items():
                # we use a helper function, based on the key ('load', 'erase'
                # etc.) to create a command object. The helper function knows
                # how to handle the parameters of each command.
                # TODO Only load, fill, erase and enable commands are supported
                # for now. But there are few more to be supported...
                cmd_fce = elf2sb_helper21.get_command(key)
                if key in ("keywrap", "encrypt"):
                    keyblob = {"keyblobs": keyblobs}
                    value.update(keyblob)
                cmd = cmd_fce(value)
                commands.append(cmd)

        sb_sections.append(BootSectionV2(section_id, *commands))

    # We have a list of sections and their respective commands, lets create
    # a boot image v2.1 object
    secure_binary = BootImageV21(
        sb_kek,
        *sb_sections,
        product_version=product_version,
        component_version=component_version,
        build_number=build_number,
        flags=flags,
    )

    # create certificate block
    cert_block = CertBlockV2(build_number=build_number)
    for cert_path in signing_certificate_file_paths:
        cert_data = load_certificate_as_bytes(str(cert_path))
        cert_block.add_certificate(cert_data)
    for cert_idx, cert_path in enumerate(root_key_certificate_paths):
        cert_data = load_certificate_as_bytes(str(cert_path))
        cert_block.set_root_key_hash(cert_idx, Certificate(cert_data))

    # We have our secure binary, now we attach to it the certificate block and
    # the private key content
    # TODO legacy elf2sb doesn't require you to use certificates and private key,
    # so maybe we should make sure this is not necessary???
    # The -s/-R/-S are mandatory, 2.0 format not supported!!!
    secure_binary.cert_block = cert_block
    secure_binary.private_key_pem_data = load_binary(
        str(private_key_file_path))

    if hoh_out_path is None:
        hoh_out_path = os.path.join(os.getcwd(), "hash.bin")

    with open(str(hoh_out_path), "wb") as rkht_file:
        rkht_file.write(secure_binary.cert_block.rkht)

    with open(str(output_file_path), "wb") as sb_file_output:
        sb_file_output.write(secure_binary.export())

    click.echo(f"Success. (Secure binary 2.1: {output_file_path} created.)")
Esempio n. 19
0
    def load_yml_config(self, file_name: str, raw: bool = False) -> None:
        """The function loads the configuration from YML file.

        :param file_name: The file_name (without extension) of stored configuration.
        :param raw: Raw input of configuration (including computed fields and anti-pole registers)
        :raise SPSDKError: When the configuration file not found.
        """
        antipole_regs = self.config.get_antipole_regs(self.device)
        computed_fields = self.config.get_computed_fields(self.device)
        try:
            with open(file_name, "r") as yml_config_file:
                yaml = YAML()
                yaml.indent(sequence=4, offset=2)
                data = yaml.load(yml_config_file)
        except FileNotFoundError:
            raise SPSDKError("File with YML configuration doesn't exists.")

        for reg in data["registers"].keys():
            if not raw and reg in antipole_regs.values():
                continue
            if reg not in self.regs.get_reg_names():
                continue
            #The loaded register is our
            if "value" in data["registers"][reg].keys():
                val = data['registers'][reg]['value']
                val = val.replace("0x", "")
                self.regs.find_reg(reg).set_value(bytes.fromhex(val))
            elif "bitfields" in data["registers"][reg].keys():
                for bitf_name in data["registers"][reg]["bitfields"]:
                    try:
                        self.regs.find_reg(reg).find_bitfield(bitf_name)
                    except BitfieldNotFound:
                        continue
                    if not raw and reg in computed_fields.keys() and bitf_name in computed_fields[reg].keys():
                        continue
                    bitf = self.regs.find_reg(reg).find_bitfield(bitf_name)
                    if bitf.has_enums():
                        #solve the bitfields store in enums string
                        bitf.set_enum_value(data["registers"][reg]["bitfields"][bitf_name])
                    else:
                        #load bitfield data
                        bitf.set_value(int(data["registers"][reg]["bitfields"][bitf_name]))
            else:
                logger.error(f"There are no data for {reg} register.")

            if not raw and reg in computed_fields.keys():
                # Check the computed fields
                for field in computed_fields[reg].keys():
                    val = self.regs.find_reg(reg).get_value()
                    if hasattr(self, computed_fields[reg][field]):
                        method = getattr(self, computed_fields[reg][field], None)
                        computed_val = method(val)
                        self.regs.find_reg(reg).set_value(computed_val)
                    else:
                        raise SPSDKError(f"The '{computed_fields[reg][field]}' compute function doesn't exists.")

            if not raw and reg in antipole_regs.keys():
                #Write also anti-pole value
                val = self.regs.find_reg(reg).get_value()
                self.regs.find_reg(antipole_regs[reg]).set_value(self.antipolize_reg(val))

            logger.debug(f"The register {reg} has been loaded from configuration.")