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:
-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,