Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/linux-sunxi/sunxi-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Przywara <osp@andrep.de>2023-02-21 03:43:09 +0300
committerAndre Przywara <osp@andrep.de>2023-03-06 02:24:33 +0300
commit4a0c8c7ec74f28717db3e89c8f6d384348854302 (patch)
treebe7f49adb8163ea8fd4c0dcd60a2481e3d18c2af
parentc1f947e08570e0db5b62249c649c5202b0163162 (diff)
fel: sid: unify SID functions into fel_read_sid()
At the moment we have two functions reading the SID eFuses: fel_get_sid_root_key() to read the "root key" (the first 128 bits), and fel_get_sid() to read an arbitrary range. The latter does not use the MMIO register workaround on affected SoCs, while the former only reads that specific range of bits. Unify the two functions into one that combines the advantanges of both: we can read any range of eFuses, and it uses the MMIO register access method, if needed. Switch the users to use the new function. Signed-off-by: Andre Przywara <osp@andrep.de>
-rw-r--r--fel.c4
-rw-r--r--fel_lib.c67
-rw-r--r--fel_lib.h8
3 files changed, 39 insertions, 40 deletions
diff --git a/fel.c b/fel.c
index ea641ac..576b0d6 100644
--- a/fel.c
+++ b/fel.c
@@ -433,7 +433,7 @@ void aw_fel_print_sid(feldev_handle *dev, bool force_workaround)
pr_info("SID key (e-fuses) at 0x%08X\n",
soc_info->sid_base + soc_info->sid_offset);
}
- fel_get_sid_root_key(dev, key, force_workaround);
+ fel_read_sid(dev, key, 0, sizeof(key), force_workaround);
/* output SID in "xxxxxxxx:xxxxxxxx:xxxxxxxx:xxxxxxxx" format */
for (unsigned i = 0; i <= 3; i++)
@@ -454,7 +454,7 @@ void aw_fel_dump_sid(feldev_handle *dev)
for (const sid_section *s = soc_info->sid_sections; s->name; s++) {
uint32_t count = s->size_bits / 32;
- if (!fel_get_sid(dev, buffer, s->offset, count)) {
+ if (fel_read_sid(dev, buffer, s->offset, count * 4, false)) {
fprintf(stderr, "Read sid:%s failed\n", s->name);
return;
}
diff --git a/fel_lib.c b/fel_lib.c
index c79eebb..dfb8e98 100644
--- a/fel_lib.c
+++ b/fel_lib.c
@@ -548,7 +548,8 @@ void fel_clrsetbits_le32(feldev_handle *dev,
* SoCs. This function uses an alternative, register-based approach to retrieve
* the values.
*/
-static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result)
+static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result,
+ uint32_t offset, uint32_t length)
{
uint32_t arm_code[] = {
/* <sid_read_root_key>: */
@@ -576,9 +577,9 @@ static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result)
/* <sid_base>: */
htole32(dev->soc_info->sid_base), /* SID base addr */
/* <offset>: */
- htole32(0), /* first word to read */
+ htole32(offset), /* first word to read */
/* <end>: */
- htole32(16), /* where to stop to read */
+ htole32(offset + length), /* where to stop to read */
/* retrieved SID values go here */
};
/* write and execute code */
@@ -586,44 +587,44 @@ static void fel_get_sid_registers(feldev_handle *dev, uint32_t *result)
aw_fel_execute(dev, dev->soc_info->scratch_addr);
/* read back the result */
aw_fel_read(dev, dev->soc_info->scratch_addr + sizeof(arm_code),
- result, 4 * sizeof(uint32_t));
- for (unsigned i = 0; i < 4; i++)
+ result, length);
+ for (unsigned i = 0; i < length / 4; i++)
result[i] = le32toh(result[i]);
}
-/* Read the SID "root" key (128 bits). You need to pass the device handle,
- * a pointer to a result array capable of receiving at least four 32-bit words,
- * and a flag specifying if the register-access workaround should be enforced.
- * Return value indicates whether the result is expected to be usable:
- * The function will return `false` (and zero the result) if it cannot access
- * the SID registers.
+/**
+ * fel_read_sid() - Read the content of the SID eFuses.
+ * @dev: device handle for the FEL device
+ * @result: pointer of a buffer receiving the content of the eFuses
+ * @offset: beginning of the eFuses area to read, in bytes
+ * @length: length of the eFuses area to read, in bytes
+ * @force_workaround: whether to use the MMIO register based read method
+ *
+ * Read the contents of the non-volatile eFuses stored in the SoC. The size
+ * and supposed usage layout differs between SoCs, but the "root" key
+ * (containing some unique serial number) is always in the first 128 bits.
+ *
+ * Return: 0 if the operation was successful, a negative error code otherwise.
*/
-bool fel_get_sid_root_key(feldev_handle *dev, uint32_t *result,
- bool force_workaround)
+int fel_read_sid(feldev_handle *dev, uint32_t *result,
+ unsigned int offset, unsigned int length,
+ bool force_workaround)
{
- if (!dev->soc_info->sid_base) {
- /* SID unavailable */
- for (unsigned i = 0; i < 4; i++) result[i] = 0;
- return false;
- }
+ const soc_info_t *soc = dev->soc_info;
+
+ if (!soc->sid_base) /* SID unavailable */
+ return -2;
+ if ((offset & 3) || (length & 3)) /* needs to be 32-bit aligned */
+ return -3;
- if (dev->soc_info->sid_fix || force_workaround)
+ if (soc->sid_fix || force_workaround)
/* Work around SID issues by using ARM thunk code */
- fel_get_sid_registers(dev, result);
+ fel_get_sid_registers(dev, result, offset, length);
else
/* Read SID directly from memory */
- fel_readl_n(dev, dev->soc_info->sid_base
- + dev->soc_info->sid_offset, result, 4);
- return true;
-}
-
-bool fel_get_sid(feldev_handle *dev, uint32_t *result, uint32_t offset,
- size_t count)
-{
- fel_readl_n(dev, dev->soc_info->sid_base
- + dev->soc_info->sid_offset + offset, result, count);
-
- return true;
+ fel_readl_n(dev, soc->sid_base + soc->sid_offset + offset,
+ result, length);
+ return 0;
}
/* general functions, "FEL device" management */
@@ -859,7 +860,7 @@ feldev_list_entry *list_fel_devices(size_t *count)
strncpy(entry->soc_name, dev->soc_name, sizeof(soc_name_t));
/* retrieve SID bits */
- fel_get_sid_root_key(dev, entry->SID, false);
+ fel_read_sid(dev, entry->SID, 0, 16, false);
feldev_close(dev);
free(dev);
diff --git a/fel_lib.h b/fel_lib.h
index 414f9d9..68b1ab8 100644
--- a/fel_lib.h
+++ b/fel_lib.h
@@ -77,11 +77,9 @@ void fel_clrsetbits_le32(feldev_handle *dev,
#define fel_setbits_le32(dev, addr, value) \
fel_clrsetbits_le32(dev, addr, 0, value)
-/* retrieve SID root key */
-bool fel_get_sid_root_key(feldev_handle *dev, uint32_t *result,
- bool force_workaround);
-bool fel_get_sid(feldev_handle *dev, uint32_t *result, uint32_t offset,
- size_t count);
+int fel_read_sid(feldev_handle *dev, uint32_t *result,
+ unsigned int offset, unsigned int length,
+ bool force_workaround);
bool aw_fel_remotefunc_prepare(feldev_handle *dev,
size_t stack_size,