1# This file describes eFuses fields and registers for ESP32-C2 chip
2#
3# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
4#
5# SPDX-License-Identifier: GPL-2.0-or-later
6
7import copy
8import os
9
10import yaml
11
12from ..mem_definition_base import (
13    EfuseBlocksBase,
14    EfuseFieldsBase,
15    EfuseRegistersBase,
16)
17
18
19class EfuseDefineRegisters(EfuseRegistersBase):
20    EFUSE_MEM_SIZE = 0x01FC + 4
21
22    # EFUSE registers & command/conf values
23    DR_REG_EFUSE_BASE = 0x60008800
24    EFUSE_PGM_DATA0_REG = DR_REG_EFUSE_BASE
25    EFUSE_PGM_CHECK_VALUE0_REG = DR_REG_EFUSE_BASE + 0x020
26    EFUSE_CLK_REG = DR_REG_EFUSE_BASE + 0x88
27    EFUSE_CONF_REG = DR_REG_EFUSE_BASE + 0x8C
28    EFUSE_STATUS_REG = DR_REG_EFUSE_BASE + 0x90
29    EFUSE_CMD_REG = DR_REG_EFUSE_BASE + 0x94
30    EFUSE_RD_REPEAT_ERR_REG = DR_REG_EFUSE_BASE + 0x80
31    EFUSE_RD_RS_ERR_REG = DR_REG_EFUSE_BASE + 0x84
32    EFUSE_WRITE_OP_CODE = 0x5A5A
33    EFUSE_READ_OP_CODE = 0x5AA5
34    EFUSE_PGM_CMD_MASK = 0x3
35    EFUSE_PGM_CMD = 0x2
36    EFUSE_READ_CMD = 0x1
37
38    BLOCK_ERRORS = [
39        # error_reg,                err_num_mask, err_num_offs,     fail_bit
40        (EFUSE_RD_REPEAT_ERR_REG, None, None, None),  # BLOCK0
41        (EFUSE_RD_RS_ERR_REG, 0x7, 0, 3),  # BLOCK1
42        (EFUSE_RD_RS_ERR_REG, 0x7, 4, 7),  # BLOCK2
43        (EFUSE_RD_RS_ERR_REG, 0x7, 8, 11),  # BLOCK3
44    ]
45
46    EFUSE_WR_TIM_CONF2_REG = DR_REG_EFUSE_BASE + 0x118
47    EFUSE_PWR_OFF_NUM_S = 0
48    EFUSE_PWR_OFF_NUM_M = 0xFFFF << EFUSE_PWR_OFF_NUM_S
49
50    EFUSE_WR_TIM_CONF0_REG = DR_REG_EFUSE_BASE + 0x110
51    EFUSE_TPGM_INACTIVE_S = 8
52    EFUSE_TPGM_INACTIVE_M = 0xFF << EFUSE_TPGM_INACTIVE_S
53
54    EFUSE_WR_TIM_CONF1_REG = DR_REG_EFUSE_BASE + 0x114
55    EFUSE_PWR_ON_NUM_S = 8
56    EFUSE_PWR_ON_NUM_M = 0x0000FFFF << EFUSE_PWR_ON_NUM_S
57
58    EFUSE_DAC_CONF_REG = DR_REG_EFUSE_BASE + 0x108
59    EFUSE_DAC_CLK_DIV_S = 0
60    EFUSE_DAC_CLK_DIV_M = 0xFF << EFUSE_DAC_CLK_DIV_S
61
62    # EFUSE_DAC_CONF_REG
63    EFUSE_DAC_NUM_S = 9
64    EFUSE_DAC_NUM_M = 0xFF << EFUSE_DAC_NUM_S
65
66
67class EfuseDefineBlocks(EfuseBlocksBase):
68    __base_rd_regs = EfuseDefineRegisters.DR_REG_EFUSE_BASE
69    __base_wr_regs = EfuseDefineRegisters.EFUSE_PGM_DATA0_REG
70    # List of efuse blocks
71    # fmt: off
72    BLOCKS = [
73        # Name,             Alias,     Index,  Read address,           Write address,  Write protect bit, Read protect bit, Len, key_purpose
74        ("BLOCK0",          ["BLOCK0"],  0,  __base_rd_regs + 0x02C, __base_wr_regs,   None,              None,             2,   None),
75        ("BLOCK1",          ["BLOCK1"],  1,  __base_rd_regs + 0x034, __base_wr_regs,      5,              None,             3,   None),
76        ("BLOCK2",          ["BLOCK2"],  2,  __base_rd_regs + 0x040, __base_wr_regs,      6,              None,             8,   None),
77        ("BLOCK_KEY0",      ["BLOCK3"],  3,  __base_rd_regs + 0x060, __base_wr_regs,      7,              [0, 1],           8,   None),
78    ]
79    # fmt: on
80
81    def get_burn_block_data_names(self):
82        list_of_names = []
83        for block in self.BLOCKS:
84            blk = self.get(block)
85            if blk.name:
86                list_of_names.append(blk.name)
87            if blk.alias:
88                for alias in blk.alias:
89                    list_of_names.append(alias)
90        return list_of_names
91
92    def get_blocks_for_keys(self):
93        return ["BLOCK_KEY0"]
94
95
96class EfuseDefineFields(EfuseFieldsBase):
97    def __init__(self, extend_efuse_table) -> None:
98        # List of efuse fields from TRM the chapter eFuse Controller.
99        self.EFUSES = []
100
101        self.KEYBLOCKS = []
102
103        # if BLK_VERSION_MINOR is 1, these efuse fields are in BLOCK2
104        self.BLOCK2_CALIBRATION_EFUSES = []
105
106        dir_name = os.path.dirname(os.path.abspath(__file__))
107        dir_name, file_name = os.path.split(dir_name)
108        file_name = file_name + ".yaml"
109        dir_name, _ = os.path.split(dir_name)
110        efuse_file = os.path.join(dir_name, "efuse_defs", file_name)
111        with open(f"{efuse_file}", "r") as r_file:
112            e_desc = yaml.safe_load(r_file)
113        super().__init__(e_desc, extend_efuse_table)
114
115        for i, efuse in enumerate(self.ALL_EFUSES):
116            if efuse.name in ["BLOCK_KEY0"]:
117                self.KEYBLOCKS.append(efuse)
118                BLOCK_KEY0_LOW_128 = copy.deepcopy(efuse)
119                BLOCK_KEY0_LOW_128.name = "BLOCK_KEY0_LOW_128"
120                BLOCK_KEY0_LOW_128.type = "bytes:16"
121                BLOCK_KEY0_LOW_128.bit_len = 16 * 8
122                BLOCK_KEY0_LOW_128.description = (
123                    "BLOCK_KEY0 - lower 128-bits. 128-bit key of Flash Encryption"
124                )
125                BLOCK_KEY0_LOW_128.read_disable_bit = efuse.read_disable_bit[0]
126                self.KEYBLOCKS.append(BLOCK_KEY0_LOW_128)
127                BLOCK_KEY0_HI_128 = copy.deepcopy(efuse)
128                BLOCK_KEY0_HI_128.name = "BLOCK_KEY0_HI_128"
129                BLOCK_KEY0_HI_128.word = 4
130                BLOCK_KEY0_HI_128.type = "bytes:16"
131                BLOCK_KEY0_HI_128.bit_len = 16 * 8
132                BLOCK_KEY0_HI_128.description = (
133                    "BLOCK_KEY0 - higher 128-bits. 128-bits key of Secure Boot"
134                )
135                BLOCK_KEY0_HI_128.read_disable_bit = efuse.read_disable_bit[1]
136                self.KEYBLOCKS.append(BLOCK_KEY0_HI_128)
137                self.ALL_EFUSES[i] = None
138
139            elif efuse.category == "calibration":
140                self.BLOCK2_CALIBRATION_EFUSES.append(efuse)
141                self.ALL_EFUSES[i] = None
142
143        for efuse in self.ALL_EFUSES:
144            if efuse is not None:
145                self.EFUSES.append(efuse)
146
147        self.ALL_EFUSES = []
148