summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Liu <victorliu@google.com>2023-11-30 18:13:47 +0000
committerVictor Liu <victorliu@google.com>2023-11-30 19:23:46 +0000
commitcf75cc1a7719ece45601b0fcd574db10c0817978 (patch)
tree89ee50561dedb85829181eedeb90fbdbf66fdd1e
parent603d2a2827357e08d8b53e2198bc6b5bfa4f11ce (diff)
downloaduwb-android-gs-shusky-5.15-android14-qpr2-beta.tar.gz
Revert submission 2615259-R-7.2.0 Reason for revert: b/311753464 - fw 6.3.11 for additional soak in main Reverted changes: /q/submissionid:2615259-R-7.2.0 Bug: 311753464 Change-Id: Ib423da42e3b441e4ffcace355fff4e66e49df915 Signed-off-by: Victor Liu <victorliu@google.com>
-rw-r--r--Kbuild9
-rw-r--r--debug.c4
-rw-r--r--debug_qmrom.c224
-rw-r--r--hsspi.c4
-rw-r--r--hsspi.h1
-rw-r--r--hsspi_coredump.c7
-rw-r--r--hsspi_test.c14
-rw-r--r--libfwupdater/CMakeLists.txt17
-rw-r--r--libfwupdater/include/fwupdater.h75
-rw-r--r--libfwupdater/src/fwupdater.c343
-rw-r--r--libfwupdater/tests/comms_tests.c61
-rw-r--r--libfwupdater/tests/fwpkg_tests.c94
-rw-r--r--libfwupdater/tests/fwupdater_unit_tests.c16
-rw-r--r--libfwupdater/tests/unit_tests.h22
-rw-r--r--libqmrom/CMakeLists.txt6
-rw-r--r--libqmrom/include/qm357xx_fwpkg.h132
-rw-r--r--libqmrom/include/qm357xx_rom.h95
-rw-r--r--libqmrom/include/qmrom.h89
-rw-r--r--libqmrom/include/qmrom_spi.h4
-rw-r--r--libqmrom/include/qmrom_utils.h11
-rw-r--r--libqmrom/src/qm357xx_rom_common.c414
-rw-r--r--libqmrom/src/qmrom_a0.c240
-rw-r--r--libqmrom/src/qmrom_b0.c (renamed from libqmrom/src/qm357xx_rom_b0.c)162
-rw-r--r--libqmrom/src/qmrom_c0.c (renamed from libqmrom/src/qm357xx_rom_c0.c)260
-rw-r--r--libqmrom/src/qmrom_common.c263
-rw-r--r--qm35-spi.c266
-rw-r--r--qm35.h11
-rw-r--r--qmrom_spi.c78
28 files changed, 899 insertions, 2023 deletions
diff --git a/Kbuild b/Kbuild
index 7e16ab7..c2fd666 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1,4 +1,4 @@
-ccflags-y := -I$(srctree)/$(src)/libqmrom/include -I$(srctree)/$(src)/libfwupdater/include -Werror
+ccflags-y := -I$(srctree)/$(src)/libqmrom/include -Werror
obj-$(CONFIG_QM35_SPI) := qm35.o
@@ -7,11 +7,10 @@ qm35-y := \
qm35_rb.o \
qmrom_spi.o \
libqmrom/src/qmrom_common.o \
- libqmrom/src/qm357xx_rom_common.o \
- libqmrom/src/qm357xx_rom_b0.o \
- libqmrom/src/qm357xx_rom_c0.o \
+ libqmrom/src/qmrom_a0.o \
+ libqmrom/src/qmrom_b0.o \
+ libqmrom/src/qmrom_c0.o \
libqmrom/src/qmrom_log.o \
- libfwupdater/src/fwupdater.o \
hsspi.o \
hsspi_uci.o \
hsspi_log.o \
diff --git a/debug.c b/debug.c
index dcfb9a1..6b80fd4 100644
--- a/debug.c
+++ b/debug.c
@@ -390,14 +390,14 @@ static int debug_devid_show(struct seq_file *s, void *unused)
static int debug_socid_show(struct seq_file *s, void *unused)
{
struct debug *debug = (struct debug *)s->private;
- uint8_t soc_id[QM357XX_ROM_SOC_ID_LEN];
+ uint8_t soc_id[ROM_SOC_ID_LEN];
int rc;
if (debug->trace_ops && debug->trace_ops->get_soc_id) {
rc = debug->trace_ops->get_soc_id(debug, soc_id);
if (rc < 0)
return -EIO;
- seq_printf(s, "%*phN\n", QM357XX_ROM_SOC_ID_LEN, soc_id);
+ seq_printf(s, "%*phN\n", ROM_SOC_ID_LEN, soc_id);
}
return 0;
}
diff --git a/debug_qmrom.c b/debug_qmrom.c
index 9b10c44..8c77bd3 100644
--- a/debug_qmrom.c
+++ b/debug_qmrom.c
@@ -25,7 +25,6 @@
* QM35 LOG layer HSSPI Protocol
*/
-#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/printk.h>
#include <linux/debugfs.h>
@@ -40,16 +39,10 @@
#include <qmrom.h>
#include <qmrom_log.h>
#include <qmrom_spi.h>
-#include <qmrom_utils.h>
-
-#include <fwupdater.h>
#include "qm35.h"
#include "debug.h"
-extern int fu_spi_speed_hz;
-extern int qmrom_spi_speed_hz;
-
#define QMROM_RETRIES 10
static void *priv_from_file(const struct file *filp)
@@ -61,31 +54,19 @@ static struct qm35_ctx *rom_test_prepare(struct file *filp)
{
struct debug *debug = priv_from_file(filp);
struct qm35_ctx *qm35_hdl = container_of(debug, struct qm35_ctx, debug);
- int irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
qm35_hsspi_stop(qm35_hdl);
qmrom_set_log_device(&qm35_hdl->spi->dev, LOG_DBG);
-
- if (irq >= 0)
- enable_irq(irq);
-
- qm35_hdl->flashing = true;
return qm35_hdl;
}
static void rom_test_unprepare(struct qm35_ctx *qm35_hdl)
{
- int irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
-
- if (irq >= 0)
- disable_irq_nosync(irq);
-
- qm35_hdl->flashing = false;
qmrom_set_log_device(&qm35_hdl->spi->dev, LOG_WARN);
qm35_hsspi_start(qm35_hdl);
}
-static struct firmware *file2firmware(const char *filename)
+static struct firmware *file2firmware(const char *filename, size_t file_size)
{
struct firmware *firmware =
kmalloc(sizeof(struct firmware), GFP_KERNEL | __GFP_ZERO);
@@ -99,12 +80,12 @@ static struct firmware *file2firmware(const char *filename)
filename, 0, (void **)&firmware->data, INT_MAX,
&firmware->size, READING_FIRMWARE);
if (bytes_read < 0) {
- pr_err("qm35: kernel_read_file_from_path(%s) returned %d\n",
+ pr_err("kernel_read_file_from_path(%s) returned %d\n",
filename, (int)bytes_read);
goto fail;
}
if (bytes_read != firmware->size) {
- pr_err("qm35: kernel_read_file_from_path returned %zu; expected %zu\n",
+ pr_err("kernel_read_file_from_path returned %zu; expected %zu\n",
bytes_read, firmware->size);
goto fail;
}
@@ -117,7 +98,7 @@ static struct firmware *file2firmware(const char *filename)
&size, INT_MAX,
READING_FIRMWARE);
if (ret < 0) {
- pr_err("qm35: kernel_read_file_from_path(%s) returned %d\n",
+ pr_err("kernel_read_file_from_path(%s) returned %d\n",
filename, ret);
goto fail;
}
@@ -125,8 +106,8 @@ static struct firmware *file2firmware(const char *filename)
}
#endif
- print_hex_dump(KERN_DEBUG, "qm35: Bin file:", DUMP_PREFIX_ADDRESS, 16,
- 1, firmware->data, 16, false);
+ print_hex_dump(KERN_DEBUG, "Bin file:", DUMP_PREFIX_ADDRESS, 16, 1,
+ firmware->data, 16, false);
return firmware;
fail:
@@ -144,29 +125,24 @@ static ssize_t rom_probe(struct file *filp, const char __user *buff,
struct qm35_ctx *qm35_hdl = rom_test_prepare(filp);
struct qmrom_handle *h;
- pr_info("qm35: Starting the probe test...\n");
- h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
- qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+ pr_info("Starting the probe test...\n");
+ h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+ QMROM_RETRIES, qmrom_spi_reset_device);
if (!h) {
- pr_err("qm35: qmrom_init failed\n");
+ pr_err("qmrom_init failed\n");
goto end;
}
- pr_info("qm35: chip_revision %#2x\n", h->chip_rev);
- pr_info("qm35: device version %#02x\n", h->device_version);
+ pr_info("chip_revision %#2x\n", h->chip_rev);
+ pr_info("device version %#02x\n", h->device_version);
if (h->chip_rev != 0xa001) {
- pr_info("qm35: lcs_state %u\n", h->qm357xx_soc_info.lcs_state);
- print_hex_dump(KERN_DEBUG, "qm35: soc_id:", DUMP_PREFIX_NONE,
- 16, 1, h->qm357xx_soc_info.soc_id,
- sizeof(h->qm357xx_soc_info.soc_id), false);
- print_hex_dump(KERN_DEBUG, "qm35: uuid:", DUMP_PREFIX_NONE, 16,
- 1, h->qm357xx_soc_info.uuid,
- sizeof(h->qm357xx_soc_info.uuid), false);
+ pr_info("lcs_state %d\n", h->lcs_state);
+ print_hex_dump(KERN_DEBUG, "soc_id:", DUMP_PREFIX_NONE, 16, 1,
+ h->soc_id, sizeof(h->soc_id), false);
+ print_hex_dump(KERN_DEBUG, "uuid:", DUMP_PREFIX_NONE, 16, 1,
+ h->uuid, sizeof(h->uuid), false);
}
qmrom_deinit(h);
- qmrom_spi_reset_device(qm35_hdl);
- qmrom_msleep(100);
end:
rom_test_unprepare(qm35_hdl);
@@ -190,15 +166,14 @@ static ssize_t rom_flash_dbg_cert(struct file *filp, const char __user *buff,
err = copy_from_user(filename, buff, count);
if (err) {
- pr_err("qm35: copy_from_user failed with error %d\n", err);
+ pr_err("copy_from_user failed with error %d\n", err);
count = err;
goto end;
}
filename[count - 1] = '\0';
- certificate = file2firmware(filename);
- if (!certificate || certificate->size != DEBUG_CERTIFICATE_SIZE) {
- pr_err("qm35: %s: file retrieval failed, abort (%s)\n",
- __func__, certificate ? "wrong size" : "not found");
+ certificate = file2firmware(filename, DEBUG_CERTIFICATE_SIZE);
+ if (!certificate) {
+ pr_err("%s: file retrieval failed, abort\n", __func__);
count = -1;
goto end;
}
@@ -206,20 +181,18 @@ static ssize_t rom_flash_dbg_cert(struct file *filp, const char __user *buff,
/* Flash the debug certificate */
pr_info("Flashing debug certificate %s...\n", filename);
- h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
- qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+ h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+ QMROM_RETRIES, qmrom_spi_reset_device);
if (!h) {
- pr_err("qm35: qmrom_init failed\n");
+ pr_err("qmrom_init failed\n");
goto end;
}
- err = qm357xx_rom_flash_dbg_cert(h, certificate);
+ err = qmrom_flash_dbg_cert(h, certificate);
if (err)
- pr_err("qm35: Flashing debug certificate %s failed with %d!\n",
+ pr_err("Flashing debug certificate %s failed with %d!\n",
filename, err);
else
- pr_info("qm35: Flashing debug certificate %s succeeded!\n",
- filename);
+ pr_info("Flashing debug certificate %s succeeded!\n", filename);
end:
if (h)
@@ -229,9 +202,6 @@ end:
vfree(certificate->data);
kfree(certificate);
}
- qmrom_spi_reset_device(qm35_hdl);
- qmrom_msleep(100);
-
rom_test_unprepare(qm35_hdl);
return count;
}
@@ -243,29 +213,23 @@ static ssize_t rom_erase_dbg_cert(struct file *filp, const char __user *buff,
struct qmrom_handle *h = NULL;
int err;
- pr_info("qm35: Erasing debug certificate...\n");
+ pr_info("Erasing debug certificate...\n");
- h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
- qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+ h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+ QMROM_RETRIES, qmrom_spi_reset_device);
if (!h) {
- pr_err("qm35: qmrom_init failed\n");
+ pr_err("qmrom_init failed\n");
goto end;
}
- err = qm357xx_rom_erase_dbg_cert(h);
+ err = qmrom_erase_dbg_cert(h);
if (err)
- pr_err("qm35: Erasing debug certificate failed with %d!\n",
- err);
+ pr_err("Erasing debug certificate failed with %d!\n", err);
else
- pr_info("qm35: Erasing debug certificate succeeded!\n");
+ pr_info("Erasing debug certificate succeeded!\n");
end:
if (h)
qmrom_deinit(h);
-
- qmrom_spi_reset_device(qm35_hdl);
- qmrom_msleep(100);
-
rom_test_unprepare(qm35_hdl);
return count;
}
@@ -287,122 +251,34 @@ static ssize_t rom_flash_fw(struct file *filp, const char __user *buff,
rc = copy_from_user(filename, buff, count);
if (rc) {
- pr_err("qm35: copy_from_user failed with error %d\n", rc);
+ pr_err("copy_from_user failed with error %d\n", rc);
goto end;
}
filename[count - 1] = '\0';
- fw = file2firmware(filename);
+ fw = file2firmware(filename, 0);
if (!fw) {
- pr_err("qm35: %s: file %s retrieval failed, abort\n", __func__,
- filename);
+ pr_err("%s: file retrieval failed, abort\n", __func__);
rc = -1;
goto end;
}
- pr_info("qm35: Flashing image %s (%pK->data %pK)...\n", filename, fw,
+ pr_info("Flashing image %s (%pK->data %pK)...\n", filename, fw,
fw->data);
- h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
- qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+ h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+ QMROM_RETRIES, qmrom_spi_reset_device);
if (!h) {
- pr_err("qm35: qmrom_init failed\n");
+ pr_err("qmrom_init failed\n");
rc = -1;
goto end;
}
- rc = qm357xx_rom_flash_fw(h, fw);
+ rc = qmrom_flash_fw(h, fw);
if (rc)
- pr_err("qm35: Flashing firmware %s failed with %d!\n", filename,
- rc);
+ pr_err("Flashing firmware %s failed with %d!\n", filename, rc);
else
- pr_info("qm35: Flashing firmware %s succeeded!\n", filename);
+ pr_info("Flashing firmware %s succeeded!\n", filename);
end:
- kfree(filename);
- if (h)
- qmrom_deinit(h);
- if (fw) {
- if (fw->data)
- vfree(fw->data);
- kfree(fw);
- }
- rom_test_unprepare(qm35_hdl);
- return count;
-}
-
-static ssize_t rom_flash_fw_pkg(struct file *filp, const char __user *buff,
- size_t count, loff_t *off)
-{
- struct qm35_ctx *qm35_hdl = rom_test_prepare(filp);
- const struct firmware *fw = NULL;
- struct qmrom_handle *h = NULL;
- char *filename = NULL, *fw_data;
- uint32_t fw_size;
- int rc;
-
- if (fu_spi_speed_hz == 0)
- fu_spi_speed_hz = FWUPDATER_SPI_SPEED_HZ;
-
- filename = kmalloc(count, GFP_KERNEL);
- if (!filename) {
- count = -ENOMEM;
- goto end;
- }
- rc = copy_from_user(filename, buff, count);
- if (rc) {
- pr_err("qm35: copy_from_user failed with error %d\n", rc);
- goto end;
- }
- filename[count - 1] = '\0';
- fw = file2firmware(filename);
- if (!fw || !fw->data) {
- pr_err("qm35: %s file %s retrieval failed (%s), abort\n",
- __func__, filename, fw ? "no data read" : "not found");
- rc = -1;
- goto end;
- }
-
- pr_info("qm35: Flashing fw_updater...\n");
- h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
- qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
- if (!h) {
- pr_err("qm35: qmrom_init failed\n");
- rc = -1;
- goto end;
- }
- rc = qm357xx_rom_flash_fw(h, fw);
- if (rc) {
- pr_err("qm35: Flashing fw_updater failed with %d!\n", rc);
- goto end;
- }
-
- pr_info("qm35: Flashing fw_updater succeeded, flashing the fw package now...\n");
- qmrom_spi_set_freq(fu_spi_speed_hz);
-
- rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 1, &fw_size, &fw_data);
- if (rc) {
- pr_err("qm35: %s FW MACRO PACKAGE corrupted = %d\n", __func__,
- rc);
- goto end;
- }
-
- if (*(uint32_t *)fw_data == CRYPTO_FIRMWARE_PACK_MAGIC_VALUE) {
- rc = run_fwupdater(h, fw_data, fw_size);
- } else {
- rc = -EINVAL;
- pr_err("qm35: FW PACKAGE not found - %04x! fw_size = %d\n",
- *(uint32_t *)fw_data, fw_size);
- goto end;
- }
- pr_info("qm35: FW package flashing %s (rc = %d), rebooting the QM...\n",
- rc ? "failed" : "succeeded", rc);
-
-end:
- qmrom_spi_reset_device(qm35_hdl);
-
- if (filename)
- kfree(filename);
if (h)
qmrom_deinit(h);
if (fw) {
@@ -432,11 +308,6 @@ static const struct file_operations rom_flash_fw_fops = {
.write = rom_flash_fw
};
-static const struct file_operations rom_flash_fw_pkg_fops = {
- .owner = THIS_MODULE,
- .write = rom_flash_fw_pkg
-};
-
void debug_rom_code_init(struct debug *debug)
{
struct dentry *file;
@@ -467,11 +338,4 @@ void debug_rom_code_init(struct debug *debug)
pr_err("qm35: failed to create uwb0/fw/rom_flash_fw\n");
return;
}
-
- file = debugfs_create_file("rom_flash_fw_pkg", 0200, debug->fw_dir,
- debug, &rom_flash_fw_pkg_fops);
- if (!file) {
- pr_err("qm35: failed to create uwb0/fw/rom_flash_fw_pkg\n");
- return;
- }
}
diff --git a/hsspi.c b/hsspi.c
index 3b39ae7..1170ca1 100644
--- a/hsspi.c
+++ b/hsspi.c
@@ -52,8 +52,6 @@
#define HSSPI_MANUAL_CS_SETUP_US SPI_CS_SETUP_DELAY_US
#endif
-extern int spi_speed_hz;
-
struct hsspi_work {
struct list_head list;
enum hsspi_work_type type;
@@ -217,13 +215,11 @@ static int spi_xfer(struct hsspi *hsspi, const void *tx, void *rx,
.tx_buf = hsspi->host,
.rx_buf = hsspi->soc,
.len = sizeof(*(hsspi->host)),
- .speed_hz = spi_speed_hz,
},
{
.tx_buf = tx,
.rx_buf = rx,
.len = length,
- .speed_hz = spi_speed_hz,
},
};
int ret, retry = 5;
diff --git a/hsspi.h b/hsspi.h
index 9cb62cc..c57c849 100644
--- a/hsspi.h
+++ b/hsspi.h
@@ -173,6 +173,7 @@ struct hsspi {
struct gpio_desc *gpio_ss_rdy;
struct gpio_desc *gpio_exton;
+ volatile bool xfer_ongoing;
volatile bool waiting_ss_rdy;
};
diff --git a/hsspi_coredump.c b/hsspi_coredump.c
index 0172ef4..36ddbb6 100644
--- a/hsspi_coredump.c
+++ b/hsspi_coredump.c
@@ -234,12 +234,6 @@ static void coredump_received(struct hsspi_layer *hlayer,
break;
case COREDUMP_BODY_NTF:
- pr_debug(
- "qm35: coredump: saving coredump data with len: %d [%d/%d]\n",
- cch_body_size,
- layer->coredump_data_wr_idx + cch_body_size,
- layer->coredump_size);
-
if (coredump_body_ntf_received(layer, cch_body, cch_body_size))
break;
@@ -346,6 +340,5 @@ int coredump_layer_init(struct coredump_layer *layer, struct debug *debug)
void coredump_layer_deinit(struct coredump_layer *layer)
{
- del_timer_sync(&layer->timer);
kfree(layer->coredump_data);
}
diff --git a/hsspi_test.c b/hsspi_test.c
index 2ac5e21..ae02d52 100644
--- a/hsspi_test.c
+++ b/hsspi_test.c
@@ -114,7 +114,6 @@ void hsspi_test_received(struct hsspi_layer *layer, struct hsspi_block *blk,
{
static uint64_t bytes, msgs, errors, bytes0, msgs0, errors0;
static time64_t last_perf_dump;
- uint32_t rem;
int error = check_rx(blk->data, blk->length) ? 1 : 0;
time64_t now;
errors += error;
@@ -143,8 +142,7 @@ void hsspi_test_received(struct hsspi_layer *layer, struct hsspi_block *blk,
bytes += blk->length;
msgs++;
error |= hsspi_send(ghsspi, layer, blk);
- div_u64_rem(msgs, 100, &rem);
- if (error || (rem == 0))
+ if (error || ((msgs % 100) == 0))
pr_info("hsspi test: bytes received %llu, msgs %llu, errors %llu\n",
bytes, msgs, errors);
if (now > last_perf_dump) {
@@ -155,9 +153,9 @@ void hsspi_test_received(struct hsspi_layer *layer, struct hsspi_block *blk,
uint64_t derrors = errors >= errors0 ? errors - errors0 :
~0ULL - errors0 + errors;
pr_info("hsspi test perfs: %llu B/s, %llu msgs/s, %llu errors/s\n",
- div_u64(dbytes, (now - last_perf_dump)),
- div_u64(dmsgs, (now - last_perf_dump)),
- div_u64(derrors, (now - last_perf_dump)));
+ dbytes / (now - last_perf_dump),
+ dmsgs / (now - last_perf_dump),
+ derrors / (now - last_perf_dump));
bytes0 = bytes;
msgs0 = msgs;
errors0 = errors;
@@ -169,12 +167,10 @@ void hsspi_test_sent(struct hsspi_layer *layer, struct hsspi_block *blk,
int status)
{
static uint64_t bytes, msgs, errors;
- uint32_t rem;
errors += status ? 1 : 0;
msgs++;
bytes += blk->length;
- div_u64_rem(msgs, 100, &rem);
- if (status || (rem == 0))
+ if (status || ((msgs % 100) == 0))
pr_info("hsspi test: bytes sent %llu, msgs %llu, errors %llu\n",
bytes, msgs, errors);
kfree(blk);
diff --git a/libfwupdater/CMakeLists.txt b/libfwupdater/CMakeLists.txt
deleted file mode 100644
index 8f18673..0000000
--- a/libfwupdater/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(SOURCES
- src/fwupdater.c
- tests/fwupdater_unit_tests.c
- tests/comms_tests.c
- tests/fwpkg_tests.c
-)
-
-add_library(fwupdater SHARED ${SOURCES})
-
-target_include_directories(fwupdater PUBLIC
- include
-)
-
-target_link_libraries(fwupdater
- PRIVATE
- qmrom
-)
diff --git a/libfwupdater/include/fwupdater.h b/libfwupdater/include/fwupdater.h
deleted file mode 100644
index 2875090..0000000
--- a/libfwupdater/include/fwupdater.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __FWUPDATER_H__
-#define __FWUPDATER_H__
-
-#ifndef __KERNEL__
-#include <stdint.h>
-#include <stddef.h>
-#else
-#include <linux/types.h>
-#endif
-
-#include <qmrom.h>
-#include <qm357xx_fwpkg.h>
-
-#ifndef CONFIG_NB_RETRIES
-#define CONFIG_NB_RETRIES 10
-#endif
-
-// #define CONFIG_INJECT_ERROR 1
-
-enum fw_pkg_error_e {
- FW_PKG_SUCCESS = 0,
- FW_PKG_DOWNLOAD_ERROR,
- FW_PKG_MAGIC_NUM_INVALID,
- FW_PKG_VERSION_INVALID,
- FW_PKG_ENCRYPTION_MODE_INVALID,
- FW_PKG_IMG_HDR_MAGIC_NUM_INVALID,
- FW_PKG_IMG_HDR_VERSION_INVALID,
- FW_PKG_IMG_HDR_CERT_SIZE_INVALID,
- FW_PKG_IMG_HDR_IMG_NUM_INVALID,
- FW_PKG_PLD_CHK_MAGIC_NUM_INVALID,
- FW_PKG_PLD_CHK_VERSION_INVALID,
- FW_PKG_PLD_CHK_LENGTH_INVALID,
- FW_PKG_HDR_CRYPTO_ERROR,
- FW_PKG_HDR_CRYPTO_INVALID,
- FW_PKG_HDR_PAYLOAD_SIZE_INVALID,
- FW_PKG_IMG_HDR_SIZE_INVALID,
- FW_PKG_IMG_HDR_CRYPTO_ERROR,
- FW_PKG_IMG_HDR_NUMDESCS_INVALID,
- FW_PKG_CERT_CHAIN_SIZE_INVALID,
- FW_PKG_CERT_CHAIN_INVALID,
- FW_PKG_CERT_INSTALLED_FW_VERSION_INVALID,
- FW_PKG_CERT_KEY1_CHECK_INVALID,
- FW_PKG_CERT_KEY2_CHECK_INVALID,
- FW_PKG_CERT_CONTENT_CHECK_INVALID,
- FW_PKG_CERT_CHAIN_CRYPTO_ERROR,
- FW_PKG_CERT_CHAIN_IMG_RANGE_INVALID,
- FW_PKG_CERT_CHAIN_WRITE_ERROR,
- FW_PKG_IMG_CHUNK_CRYPTO_ERROR,
- FW_PKG_IMG_CHUNK_WRITE_ERROR,
- FW_PKG_IMG_FIXUP_FAILED
-};
-
-/*! Firmware Update Status fields */
-struct fw_updater_status_t {
- uint32_t magic;
- uint32_t status;
- uint32_t suberror;
- uint32_t spi_errors;
- uint32_t cksum_errors;
- uint32_t rram_errors;
- uint32_t crypto_errors;
-} __attribute__((packed));
-
-#define FWUPDATER_STATUS_MAGIC 0xCAFECAFE
-
-void run_fwupdater_unit_tests(void *spi_handle);
-int run_fwupdater(struct qmrom_handle *handle, char *fwpkg_bin, size_t size);
-
-#endif /* __FWUPDATER_H__ */
diff --git a/libfwupdater/src/fwupdater.c b/libfwupdater/src/fwupdater.c
deleted file mode 100644
index 187e703..0000000
--- a/libfwupdater/src/fwupdater.c
+++ /dev/null
@@ -1,343 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __KERNEL__
-#include <stddef.h>
-#endif
-
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-#include <spi_rom_protocol.h>
-
-#include <fwupdater.h>
-
-/* Extract from C0 rom code */
-#define MAX_CERTIFICATE_SIZE 0x400
-#define MAX_CHUNK_SIZE 3072
-#define WAIT_SS_RDY_CHUNK_TIMEOUT 100
-#define WAIT_SS_RDY_STATUS_TIMEOUT 10
-#define RESULT_RETRIES 3
-#define RESULT_CMD_INTERVAL_MS 50
-#define CKSUM_TYPE uint32_t
-#define CKSUM_SIZE (sizeof(CKSUM_TYPE))
-#define TRANPORT_HEADER_SIZE (sizeof(struct stc) + CKSUM_SIZE)
-#define EMERGENCY_SPI_FREQ 1000000 /* 1MHz */
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#ifndef __KERNEL__
-_Static_assert(MAX_CHUNK_SIZE >= CRYPTO_IMAGES_CERT_PKG_SIZE);
-_Static_assert(TRANPORT_HEADER_SIZE + MAX_CERTIFICATE_SIZE < MAX_CHUNK_SIZE);
-#endif
-
-/* local stats */
-static int gstats_spi_errors;
-static int gstats_ss_rdy_timeouts;
-
-static int send_data_chunks(struct qmrom_handle *handle, char *data,
- size_t size);
-
-int run_fwupdater(struct qmrom_handle *handle, char *fwpkg_bin, size_t size)
-{
- int rc;
-
- gstats_spi_errors = 0;
- gstats_ss_rdy_timeouts = 0;
-
- if (size < sizeof(struct fw_pkg_hdr_t) +
- sizeof(struct fw_pkg_img_hdr_t) +
- CRYPTO_IMAGES_CERT_PKG_SIZE +
- CRYPTO_FIRMWARE_CHUNK_MIN_SIZE) {
- LOG_ERR("Cannot extract enough data from fw package binary\n");
- return -EINVAL;
- }
-
- rc = send_data_chunks(handle, fwpkg_bin, size);
- if (rc) {
- LOG_ERR("Sending image failed with %d\n", rc);
- return rc;
- }
- return 0;
-}
-
-static int run_fwupdater_get_status(struct qmrom_handle *handle,
- struct stc *hstc, struct stc *sstc,
- struct fw_updater_status_t *status)
-{
- uint32_t i = 0;
- CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
- bool owa;
- memset(hstc, 0, TRANPORT_HEADER_SIZE + sizeof(*status));
-
- while (i++ < RESULT_RETRIES) {
- // Poll the QM
- sstc->all = 0;
- hstc->all = 0;
- *cksum = 0;
- qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
- (const char *)hstc, TRANPORT_HEADER_SIZE);
- qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
- WAIT_SS_RDY_STATUS_TIMEOUT);
- sstc->all = 0;
- hstc->all = 0;
- hstc->host_flags.pre_read = 1;
- *cksum = 0;
- qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
- (const char *)hstc, TRANPORT_HEADER_SIZE);
- // LOG_INFO("Pre-Read received:\n");
- // hexdump(LOG_INFO, sstc, sizeof(sstc));
-
- /* Stops the loop when QM has a result to share */
- owa = sstc->soc_flags.out_waiting;
- qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
- WAIT_SS_RDY_STATUS_TIMEOUT);
- sstc->all = 0;
- hstc->all = 0;
- hstc->host_flags.read = 1;
- hstc->len = sizeof(*status);
- *cksum = 0;
- qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
- (const char *)hstc,
- TRANPORT_HEADER_SIZE + sizeof(*status));
- // LOG_INFO("Read received:\n");
- // hexdump(LOG_INFO, sstc, sizeof(*hstc) + sizeof(uint32_t));
- if (owa) {
- memcpy(status, sstc->payload, sizeof(*status));
- if (status->magic == FWUPDATER_STATUS_MAGIC)
- break;
- }
- qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
- WAIT_SS_RDY_STATUS_TIMEOUT);
- // Failed to get the status, reduces the spi speed to
- // an emergency speed to maximize the chance to get the
- // final status
- qmrom_spi_set_freq(EMERGENCY_SPI_FREQ);
- gstats_spi_errors++;
- }
- if (status->magic != FWUPDATER_STATUS_MAGIC) {
- LOG_ERR("Timedout waiting for result\n");
- return -1;
- }
- return 0;
-}
-
-static CKSUM_TYPE checksum(const void *data, const size_t size)
-{
- CKSUM_TYPE cksum = 0;
- CKSUM_TYPE *ptr = (CKSUM_TYPE *)data;
- CKSUM_TYPE remainder = size & (CKSUM_SIZE - 1);
- size_t idx;
-
- for (idx = 0; idx < size; idx += CKSUM_SIZE, ptr++)
- cksum += *ptr;
-
- if (!remainder)
- return cksum;
-
- cksum += ((uint8_t *)data)[size - 1];
- if (remainder > 1) {
- cksum += ((uint8_t *)data)[size - 2];
- if (remainder > 2) {
- cksum += ((uint8_t *)data)[size - 3];
- }
- }
-
- return cksum;
-}
-
-static void prepare_hstc(struct stc *hstc, char *data, size_t len)
-{
- CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
- void *payload = cksum + 1;
-
- hstc->all = 0;
- hstc->host_flags.write = 1;
- hstc->len = len + CKSUM_SIZE;
- *cksum = checksum(data, len);
-#if IS_ENABLED(CONFIG_INJECT_ERROR)
- *cksum += 2;
-#endif
- memcpy(payload, data, len);
-}
-
-static int xfer_payload_prep_next(struct qmrom_handle *handle,
- const char *step_name, struct stc *hstc,
- struct stc *sstc, struct stc *hstc_next,
- char **data, size_t *size)
-{
- int rc = 0, nb_retry = CONFIG_NB_RETRIES;
- CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
-
- do {
- int ss_rdy_rc, irq_up;
- sstc->all = 0;
- rc = qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
- (const char *)hstc,
- hstc->len + sizeof(struct stc));
- if (hstc_next) {
- /* Don't wait idle, prepare the next hstc to be sent */
- size_t to_send = MIN(MAX_CHUNK_SIZE, *size);
- prepare_hstc(hstc_next, *data, to_send);
- *size -= to_send;
- *data += to_send;
- hstc_next = NULL;
- }
- ss_rdy_rc = qmrom_spi_wait_for_ready_line(
- handle->ss_rdy_handle, WAIT_SS_RDY_CHUNK_TIMEOUT);
- if (ss_rdy_rc) {
- LOG_ERR("%s Waiting for ss-rdy failed with %d (nb_retry %d , cksum 0x%x)\n",
- step_name, ss_rdy_rc, nb_retry, *cksum);
- gstats_ss_rdy_timeouts++;
- rc = -EAGAIN;
- }
- irq_up = qmrom_spi_read_irq_line(handle->ss_irq_handle);
- if ((!rc && !sstc->soc_flags.ready) || irq_up) {
- LOG_ERR("%s Retry rc %d, sstc 0x%08x, irq %d, cksum %08x\n",
- step_name, rc, sstc->all, irq_up, *cksum);
- rc = -EAGAIN;
- gstats_spi_errors++;
- }
-#if IS_ENABLED(CONFIG_INJECT_ERROR)
- (*cksum)--;
-#endif
- } while (rc && --nb_retry > 0);
- if (rc) {
- LOG_ERR("%s transfer failed with %d - (sstc 0x%08x)\n",
- step_name, rc, sstc->all);
- }
- return rc;
-}
-
-static int xfer_payload(struct qmrom_handle *handle, const char *step_name,
- struct stc *hstc, struct stc *sstc)
-{
- return xfer_payload_prep_next(handle, step_name, hstc, sstc, NULL, NULL,
- NULL);
-}
-
-static int send_data_chunks(struct qmrom_handle *handle, char *data,
- size_t size)
-{
- struct fw_updater_status_t status;
- uint32_t chunk_nr = 0;
- struct stc *hstc, *sstc, *hstc_current, *hstc_next;
- char *rx, *tx;
- CKSUM_TYPE *cksum;
- int rc = 0;
-
- qmrom_alloc(rx, MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE);
- qmrom_alloc(tx, 2 * (MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE));
- if (!rx || !tx) {
- LOG_ERR("Rx/Tx buffers allocation failure\n");
- rc = -ENOMEM;
- goto exit_nomem;
- }
-
- sstc = (struct stc *)rx;
- hstc = (struct stc *)tx;
- hstc_current = hstc;
- hstc_next = (struct stc *)&tx[MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE];
- cksum = (CKSUM_TYPE *)(hstc + 1);
-
- /* wait for the QM to be ready */
- rc = qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
- WAIT_SS_RDY_CHUNK_TIMEOUT);
- if (rc)
- LOG_ERR("Waiting for ss-rdy failed with %d\n", rc);
-
- /* Sending the fw package header */
- prepare_hstc(hstc, data, sizeof(struct fw_pkg_hdr_t));
- LOG_INFO("Sending the fw package header (%zu bytes, cksum is 0x%08x)\n",
- sizeof(struct fw_pkg_hdr_t), *cksum);
- // hexdump(LOG_INFO, hstc->payload + 4, sizeof(struct fw_pkg_hdr_t));
- rc = xfer_payload(handle, "fw package header", hstc, sstc);
- if (rc)
- goto exit;
- /* Move the data to the next offset minus the header footprint */
- size -= sizeof(struct fw_pkg_hdr_t);
- data += sizeof(struct fw_pkg_hdr_t);
-
- /* Sending the image header */
- prepare_hstc(hstc, data, sizeof(struct fw_pkg_img_hdr_t));
- LOG_INFO("Sending the image header (%zu bytes cksum 0x%08x)\n",
- sizeof(struct fw_pkg_img_hdr_t), *cksum);
- // hexdump(LOG_INFO, hstc->payload + 4, sizeof(struct fw_pkg_img_hdr_t));
- rc = xfer_payload(handle, "image header", hstc, sstc);
- if (rc)
- goto exit;
- size -= sizeof(struct fw_pkg_img_hdr_t);
- data += sizeof(struct fw_pkg_img_hdr_t);
-
- /* Sending the cert chain */
- prepare_hstc(hstc, data, CRYPTO_IMAGES_CERT_PKG_SIZE);
- LOG_INFO("Sending the cert chain (%d bytes cksum 0x%08x)\n",
- CRYPTO_IMAGES_CERT_PKG_SIZE, *cksum);
- rc = xfer_payload(handle, "cert chain", hstc, sstc);
- if (rc)
- goto exit;
- size -= CRYPTO_IMAGES_CERT_PKG_SIZE;
- data += CRYPTO_IMAGES_CERT_PKG_SIZE;
-
- /* Sending the fw image */
- LOG_INFO("Sending the image (%zu bytes)\n", size);
- LOG_DBG("Sending a chunk (%zu bytes cksum 0x%08x)\n",
- MIN(MAX_CHUNK_SIZE, size), *cksum);
- prepare_hstc(hstc_current, data, MIN(MAX_CHUNK_SIZE, size));
- size -= hstc_current->len - CKSUM_SIZE;
- data += hstc_current->len - CKSUM_SIZE;
- do {
- rc = xfer_payload_prep_next(handle, "data chunk", hstc_current,
- sstc, hstc_next, &data, &size);
- if (rc)
- goto exit;
- chunk_nr++;
- /* swap hstcs */
- hstc = hstc_current;
- hstc_current = hstc_next;
- hstc_next = hstc;
- } while (size);
-
- /* Sends the last now */
- rc = xfer_payload_prep_next(handle, "data chunk", hstc_current, sstc,
- NULL, NULL, NULL);
-
-exit:
- // tries to get the flashing status anyway...
- rc = run_fwupdater_get_status(handle, hstc, sstc, &status);
- if (!rc) {
- if (status.status) {
- LOG_ERR("Flashing failed, fw updater status %#x (errors: sub %#x, cksum %u, rram %u, crypto %d)\n",
- status.status, status.suberror,
- status.cksum_errors, status.rram_errors,
- status.crypto_errors);
- rc = status.status;
- } else {
- if (gstats_ss_rdy_timeouts + gstats_spi_errors +
- status.cksum_errors + status.rram_errors +
- status.crypto_errors) {
- LOG_WARN(
- "Flashing succeeded with errors (host %u, ss_rdy_timeout %u, QM %u, cksum %u, rram %u, crypto %d)\n",
- gstats_spi_errors,
- gstats_ss_rdy_timeouts,
- status.spi_errors, status.cksum_errors,
- status.rram_errors,
- status.crypto_errors);
- } else {
- LOG_INFO(
- "Flashing succeeded without any errors\n");
- }
- }
- } else {
- LOG_ERR("run_fwupdater_get_status returned %d\n", rc);
- }
-exit_nomem:
- if (rx)
- qmrom_free(rx);
- if (tx)
- qmrom_free(tx);
- return rc;
-}
diff --git a/libfwupdater/tests/comms_tests.c b/libfwupdater/tests/comms_tests.c
deleted file mode 100644
index 6ce3333..0000000
--- a/libfwupdater/tests/comms_tests.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include <stddef.h>
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-
-#include "unit_tests.h"
-
-void run_fwupdater_read_test(void *spi_handle)
-{
- u_int8_t rx[MESSAGE_LEN];
- u_int8_t tx_poll[STC_LEN] = { 0 };
- u_int8_t tx[MESSAGE_LEN] = { 0x80, 0x00, MESSAGE_LEN - 4,
- 0x00, 0x01, 0x02,
- 0x03, 0x4, 0x5,
- 0x6, 0x7, 0x8 };
- qmrom_msleep(100);
-
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx_poll, sizeof(tx_poll));
- memset(rx, 0, sizeof(tx_poll));
-
- for (int i = 0; i < NB_RX_MESSAGES; i++) {
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
- tx[4]++;
- LOG_INFO("received:\n");
- hexdump(LOG_INFO, rx, sizeof(rx));
- memset(rx, 0, sizeof(rx));
- }
-
- LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_write_test(void *spi_handle)
-{
- u_int8_t rx[MESSAGE_LEN];
- u_int8_t tx_prd[STC_LEN] = { 0x40, 0x00, 0x00, 0x00 };
- u_int8_t tx[MESSAGE_LEN] = { 0x20, 0x00, MESSAGE_LEN - 4,
- 0x00, 0x01, 0x02,
- 0x03, 0x4, 0x5,
- 0x6, 0x7, 0x8 };
-
- for (int i = 0; i < NB_TX_MESSAGES; i++) {
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx_prd, sizeof(tx_prd));
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
- tx[4]++;
- LOG_INFO("received:\n");
- hexdump(LOG_INFO, rx, sizeof(rx));
- memset(rx, 0, sizeof(rx));
- }
-
- LOG_INFO("%s done\n", __func__);
-}
diff --git a/libfwupdater/tests/fwpkg_tests.c b/libfwupdater/tests/fwpkg_tests.c
deleted file mode 100644
index 035668a..0000000
--- a/libfwupdater/tests/fwpkg_tests.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include <stddef.h>
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-
-#include <fwupdater.h>
-
-#include "unit_tests.h"
-
-#define PLD_CHK_PLD_SIZE 16
-#define PLD_CHK_TOTAL_SIZE \
- (sizeof(struct fw_pkg_payload_chunk_t) + PLD_CHK_PLD_SIZE)
-
-void run_fwupdater_download_fwpkg_test(void *spi_handle)
-{
- uint8_t rx[STC_LEN + sizeof(struct fw_pkg_hdr_t)] = { 0 };
- uint8_t tx[STC_LEN + sizeof(struct fw_pkg_hdr_t)] = {
- 0x80, 0x00, sizeof(struct fw_pkg_hdr_t), 0x00
- };
- struct fw_pkg_hdr_t *fwpkg = (struct fw_pkg_hdr_t *)&tx[STC_LEN];
-
- /* Setup the expected fw package */
- fwpkg->magic = CRYPTO_FIRMWARE_PACK_MAGIC_VALUE;
- fwpkg->version = CRYPTO_FIRMWARE_PACK_VERSION;
- fwpkg->enc_mode = CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED;
- fwpkg->package_type = CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_ICV;
- fwpkg->enc_mode = CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED;
- fwpkg->enc_algo = CRYPTO_FIRMWARE_PACK_ENC_ALGO_128BIT_AES_CTR;
- strcpy((char *)fwpkg->enc_data, "encrypted data");
- strcpy((char *)fwpkg->fw_version, "firmware version");
- fwpkg->payload_len = 0xDEADBEEF;
- strcpy((char *)fwpkg->tag, "AES-CMAC Tag");
-
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, (char *)rx, (char *)tx, sizeof(tx));
- LOG_INFO("received:\n");
- hexdump(LOG_INFO, rx, sizeof(tx));
-
- LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_download_img_hdr_test(void *spi_handle)
-{
- char rx[STC_LEN + CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE] = { 0 };
- char tx[STC_LEN + CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE] = {
- (char)0x80, 0x00, CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE, 0x00
- };
- struct fw_pkg_img_hdr_t *imghdr =
- (struct fw_pkg_img_hdr_t *)&tx[STC_LEN];
-
- /* Setup the expected fw package */
- imghdr->magic = CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE;
- imghdr->version = CRYPTO_FIRMWARE_IMAGE_VERSION;
- imghdr->cert_chain_length = CRYPTO_IMAGES_CERT_PKG_SIZE;
- imghdr->cert_chain_offset = 0xDEADBEEF;
- imghdr->num_descs = 1;
- imghdr->descs[0].offset = 0xDEADBEEF;
- imghdr->descs[0].length = 0xDEADBEEF;
-
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
- LOG_INFO("received:\n");
- hexdump(LOG_INFO, rx, sizeof(tx));
-
- LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_download_pld_chk_test(void *spi_handle)
-{
- char rx[STC_LEN + PLD_CHK_TOTAL_SIZE] = { 0 };
- char tx[STC_LEN + PLD_CHK_TOTAL_SIZE] = { (char)0x80, 0x00,
- PLD_CHK_TOTAL_SIZE, 0x00 };
- struct fw_pkg_payload_chunk_t *pldchk =
- (struct fw_pkg_payload_chunk_t *)&tx[STC_LEN];
-
- /* Setup the expected fw package */
- pldchk->magic = CRYPTO_FIRMWARE_CHUNK_MAGIC_VALUE;
- pldchk->version = CRYPTO_FIRMWARE_CHUNK_VERSION;
- pldchk->length = PLD_CHK_PLD_SIZE;
- strcpy((char *)pldchk->payload, "payload");
-
- qmrom_spi_wait_for_ready_line(spi_handle, 100);
- qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
- LOG_INFO("received:\n");
- hexdump(LOG_INFO, rx, sizeof(tx));
-
- LOG_INFO("%s done\n", __func__);
-}
diff --git a/libfwupdater/tests/fwupdater_unit_tests.c b/libfwupdater/tests/fwupdater_unit_tests.c
deleted file mode 100644
index b17f4ac..0000000
--- a/libfwupdater/tests/fwupdater_unit_tests.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include "unit_tests.h"
-
-void run_fwupdater_unit_tests(void *spi_handle)
-{
- run_fwupdater_download_fwpkg_test(spi_handle);
- run_fwupdater_download_img_hdr_test(spi_handle);
- run_fwupdater_download_pld_chk_test(spi_handle);
- run_fwupdater_read_test(spi_handle);
- run_fwupdater_write_test(spi_handle);
-}
diff --git a/libfwupdater/tests/unit_tests.h b/libfwupdater/tests/unit_tests.h
deleted file mode 100644
index 78d0729..0000000
--- a/libfwupdater/tests/unit_tests.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __UNITTESTS_H__
-#define __UNITTESTS_H__
-
-#define NB_RX_MESSAGES 5
-#define NB_TX_MESSAGES 5
-#define MESSAGE_LEN 16
-#define STC_LEN 4
-
-void run_fwupdater_read_test(void *spi_handle);
-void run_fwupdater_write_test(void *spi_handle);
-
-void run_fwupdater_download_fwpkg_test(void *spi_handle);
-void run_fwupdater_download_img_hdr_test(void *spi_handle);
-void run_fwupdater_download_pld_chk_test(void *spi_handle);
-
-#endif /* __UNITTESTS_H__ */
diff --git a/libqmrom/CMakeLists.txt b/libqmrom/CMakeLists.txt
index 7227f2d..3e11781 100644
--- a/libqmrom/CMakeLists.txt
+++ b/libqmrom/CMakeLists.txt
@@ -1,8 +1,8 @@
set(SOURCES
- src/qm357xx_rom_b0.c
- src/qm357xx_rom_c0.c
- src/qm357xx_rom_common.c
src/qmrom_common.c
+ src/qmrom_a0.c
+ src/qmrom_b0.c
+ src/qmrom_c0.c
src/qmrom_log.c
)
diff --git a/libqmrom/include/qm357xx_fwpkg.h b/libqmrom/include/qm357xx_fwpkg.h
deleted file mode 100644
index 213baa0..0000000
--- a/libqmrom/include/qm357xx_fwpkg.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2021 Qorvo US, Inc.
- *
- */
-
-#ifndef __QM357XX_FWPKG_H__
-#define __QM357XX_FWPKG_H__
-
-/* Pkg version word conversion macro */
-#define PKG_VER_TO_U32(maj, min) (((maj) << 16) | ((min) << 24))
-
-/* Pkg magic word conversion macro */
-#define MAGIC_STR_TO_U32(x) \
- ((uint32_t)(((x)[3]) | ((x)[2] << 8) | ((x)[1] << 16) | ((x)[0] << 24)))
-
-/* Package size defines */
-#define CRYPTO_FIRMWARE_PACK_ENC_DATA_SIZE 16
-#define CRYPTO_FIRMWARE_PACK_FW_VERSION_SIZE 32
-#define CRYPTO_FIRMWARE_PACK_TAG_SIZE 16
-
-/* Firmware image size define */
-#define CRYPTO_FW_PKG_IMG_HDR_IMG_NUM_MAX 8
-
-/* Field values for macro firmware package */
-#define CRYPTO_MACRO_FIRMWARE_PACK_MAGIC_VALUE MAGIC_STR_TO_U32("FWMP")
-
-/* Field values for firmware package */
-#define CRYPTO_FIRMWARE_PACK_MAGIC_VALUE MAGIC_STR_TO_U32("CFWP")
-#define CRYPTO_FIRMWARE_PACK_VERSION PKG_VER_TO_U32(1, 0)
-#define CRYPTO_FIRMWARE_PACK_ENC_MODE_NOT_ENCRYPTED 0x0
-#define CRYPTO_FIRMWARE_PACK_ENC_ALGO_128BIT_AES_CTR 0x00
-#define CRYPTO_FIRMWARE_PACK_ENC_KEY_L2_SIZE 64
-
-/* Field values for firmware image */
-#define CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE MAGIC_STR_TO_U32("IMGS")
-#define CRYPTO_FIRMWARE_IMAGE_VERSION PKG_VER_TO_U32(1, 0)
-
-/* Field values for firmware chunks */
-#define CRYPTO_FIRMWARE_CHUNK_MAGIC_VALUE MAGIC_STR_TO_U32("CFWC")
-#define CRYPTO_FIRMWARE_CHUNK_VERSION PKG_VER_TO_U32(1, 0)
-#define CRYPTO_FIRMWARE_CHUNK_MIN_SIZE 16
-
-/* fw certificate sizes */
-#define CRYPTO_IMAGES_CERT_KEY_SIZE 840
-#define CRYPTO_IMAGES_CERT_CONTENT_SIZE 868
-#define CRYPTO_IMAGES_CERT_PKG_SIZE \
- (2 * CRYPTO_IMAGES_CERT_KEY_SIZE + CRYPTO_IMAGES_CERT_CONTENT_SIZE)
-#define CRYPTO_IMAGES_NB_CERTS 3
-#define CRYPTO_IMAGES_MAX_NB_IMAGES 8
-
-#define CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE \
- (sizeof(struct fw_pkg_img_hdr_t) + \
- CRYPTO_IMAGES_NB_CERTS * sizeof(struct fw_img_desc_t))
-
-/* Encryption mode enum. */
-enum fw_pkg_enc_mode_e {
- CRYPTO_FIRMWARE_PACK_ENC_MODE_NONE,
- CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED
-};
-
-/* Package type enum. */
-enum fw_pkg_package_type_e {
- CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_ICV = 0x01,
- CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_OEM = 0x02
-};
-
-/* IV type enum. */
-enum fw_pkg_iv_type_e {
- CRYPTO_FIRMWARE_PACK_IV_TYPE_HDR,
- CRYPTO_FIRMWARE_PACK_IV_TYPE_IMG
-};
-
-/* Firmware Package Header fields */
-struct fw_pkg_hdr_t {
- uint32_t magic; /**< Magic number. */
- uint32_t version; /**< Version. */
- uint8_t package_type; /**< Package type. */
- uint8_t enc_mode; /**< Encryption mode. */
- uint8_t enc_algo; /**< Encryption algorithm. */
- uint8_t reserved; /**< Reserved for alignment. */
- uint8_t enc_data
- [CRYPTO_FIRMWARE_PACK_ENC_DATA_SIZE]; /**< Encryption data. */
- uint8_t enc_key_l2
- [CRYPTO_FIRMWARE_PACK_ENC_KEY_L2_SIZE]; /**< Code encryption L2 key data. */
- uint8_t fw_version
- [CRYPTO_FIRMWARE_PACK_FW_VERSION_SIZE]; /**< Firmware version included in the package. */
- uint32_t payload_len; /**< Payload length. */
- uint8_t tag[CRYPTO_FIRMWARE_PACK_TAG_SIZE]; /**< AES-CMAC Tag. */
-} __attribute__((packed));
-
-/* Firmware Image Metadata fields */
-struct fw_img_desc_t {
- uint32_t offset; /**< Offset. */
- uint32_t length; /**< Length. */
-} __attribute__((packed));
-
-/* Firmware Image Header fields */
-struct fw_pkg_img_hdr_t {
- uint32_t magic; /**< Magic number. */
- uint32_t version; /**< Version number. */
- uint32_t cert_chain_offset; /**< Certificate chain offset. */
- uint16_t cert_chain_length; /**< Certificate chain length. */
- uint8_t num_descs; /**< Number of images descriptors. */
- uint8_t reserved; /**< Reserved data. */
- struct fw_img_desc_t descs
- [CRYPTO_FW_PKG_IMG_HDR_IMG_NUM_MAX]; /**< Firmware image metadata. */
-} __attribute__((packed));
-
-/* Firmware Chunk fields */
-struct fw_pkg_payload_chunk_t {
- uint32_t magic; /**< Magic number. */
- uint32_t version; /**< Version number. */
- uint32_t length; /**< Length. */
- uint8_t payload[]; /**< Payload data pointer. */
-} __attribute__((packed));
-
-/* Firmware Macro Package Header fields */
-struct fw_macro_pkg_hdr_t {
- uint32_t magic; /**< Magic number. */
- uint32_t version; /**< Version. */
- uint8_t nb_descriptors;
- uint8_t reserved[3];
- struct fw_img_desc_t img_desc[];
-} __attribute__((packed));
-
-#define MACRO_PKG_HASH_SIZE (32)
-#define COMPUTE_FW_MACRO_PKG_HDR_SIZE(ndescs) \
- (sizeof(struct fw_macro_pkg_hdr_t) + \
- ndescs * sizeof(struct fw_img_desc_t) + MACRO_PKG_HASH_SIZE)
-
-#endif /* __QM357XX_FWPKG_H__ */
diff --git a/libqmrom/include/qm357xx_rom.h b/libqmrom/include/qm357xx_rom.h
deleted file mode 100644
index 9592004..0000000
--- a/libqmrom/include/qm357xx_rom.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2021 Qorvo US, Inc.
- *
- */
-
-#ifndef __QM357XX_ROM_H__
-#define __QM357XX_ROM_H__
-
-#define PEG_ERR_TIMEOUT PEG_ERR_BASE - 1
-#define PEG_ERR_ROM_NOT_READY PEG_ERR_BASE - 2
-#define PEG_ERR_SEND_CERT_WRITE PEG_ERR_BASE - 3
-#define PEG_ERR_WRONG_REVISION PEG_ERR_BASE - 4
-#define PEG_ERR_FIRST_KEY_CERT_OR_FW_VER PEG_ERR_BASE - 5
-
-#define HBK_LOC 12
-typedef enum {
- HBK_2E_ICV,
- HBK_2E_OEM,
- HBK_1E_ICV_OEM,
-} hbk_t;
-
-#define ROM_VERSION_A0 0x01a0
-#define ROM_VERSION_B0 0xb000
-
-#define QM357XX_ROM_SOC_ID_LEN 0x20
-#define QM357XX_ROM_UUID_LEN 0x10
-
-/* Life cycle state definitions. */
-
-/*! Defines the CM life-cycle state value. */
-#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0
-/*! Defines the DM life-cycle state value. */
-#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1
-/*! Defines the Secure life-cycle state value. */
-#define CC_BSV_SECURE_LCS 0x5
-/*! Defines the RMA life-cycle state value. */
-#define CC_BSV_RMA_LCS 0x7
-
-struct unstitched_firmware {
- struct firmware *fw_img;
- struct firmware *fw_crt;
- struct firmware *key1_crt;
- struct firmware *key2_crt;
-};
-
-/* Those functions allow the libqmrom to call
- * revision specific functions
- */
-typedef int (*flash_fw_fn)(struct qmrom_handle *handle,
- const struct firmware *fw);
-typedef int (*flash_unstitched_fw_fn)(struct qmrom_handle *handle,
- const struct unstitched_firmware *fw);
-typedef int (*flash_debug_cert_fn)(struct qmrom_handle *handle,
- struct firmware *dbg_cert);
-typedef int (*erase_debug_cert_fn)(struct qmrom_handle *handle);
-
-struct qm357xx_rom_code_ops {
- flash_fw_fn flash_fw;
- flash_unstitched_fw_fn flash_unstitched_fw;
- flash_debug_cert_fn flash_debug_cert;
- erase_debug_cert_fn erase_debug_cert;
-};
-
-struct qm357xx_soc_infos {
- uint8_t soc_id[QM357XX_ROM_SOC_ID_LEN];
- uint8_t uuid[QM357XX_ROM_UUID_LEN];
- uint32_t lcs_state;
-};
-
-int qm357xx_rom_unstitch_fw(const struct firmware *fw,
- struct unstitched_firmware *unstitched_fw,
- enum chip_revision_e revision);
-int qm357xx_rom_fw_macro_pkg_get_fw_idx(const struct firmware *fw, int idx,
- uint32_t *fw_size, char **fw_fata);
-int qm357xx_rom_unpack_fw_macro_pkg(const struct firmware *fw,
- struct unstitched_firmware *all_fws);
-int qm357xx_rom_unpack_fw_pkg(const struct firmware *fw_pkg,
- struct unstitched_firmware *all_fws);
-int qm357xx_rom_flash_dbg_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert);
-int qm357xx_rom_erase_dbg_cert(struct qmrom_handle *handle);
-int qm357xx_rom_flash_fw(struct qmrom_handle *handle,
- const struct firmware *fw);
-int qm357xx_rom_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *fw);
-
-int qm357xx_rom_write_cmd(struct qmrom_handle *handle, uint8_t cmd);
-int qm357xx_rom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd);
-int qm357xx_rom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
- uint16_t data_size, const char *data);
-int qm357xx_rom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
- uint16_t data_size, const char *data);
-
-#endif /* __QM357XX_ROM_H__ */
diff --git a/libqmrom/include/qmrom.h b/libqmrom/include/qmrom.h
index 226b7f4..c403ed1 100644
--- a/libqmrom/include/qmrom.h
+++ b/libqmrom/include/qmrom.h
@@ -28,19 +28,54 @@
#undef CHECK_STCS
+#define PEG_ERR_TIMEOUT PEG_ERR_BASE - 1
+#define PEG_ERR_ROM_NOT_READY PEG_ERR_BASE - 2
+#define PEG_ERR_SEND_CERT_WRITE PEG_ERR_BASE - 3
+#define PEG_ERR_WRONG_REVISION PEG_ERR_BASE - 4
+#define PEG_ERR_FIRST_KEY_CERT_OR_FW_VER PEG_ERR_BASE - 5
+
enum chip_revision_e {
CHIP_REVISION_A0 = 0xA0,
CHIP_REVISION_B0 = 0xB0,
CHIP_REVISION_C0 = 0xC0,
- CHIP_REVISION_C2 = 0xC2,
CHIP_REVISION_UNKNOWN = 0xFF
};
-enum device_generation_e { DEVICE_GEN_QM357XX, DEVICE_GEN_UNKNOWN = 0xFF };
+#define HBK_LOC 12
+typedef enum {
+ HBK_2E_ICV = 0,
+ HBK_2E_OEM = 1,
+ HBK_1E_ICV_OEM = 2,
+} hbk_t;
+
+#define ROM_VERSION_A0 0x01a0
+#define ROM_VERSION_B0 0xb000
+
+#define ROM_SOC_ID_LEN 0x20
+#define ROM_UUID_LEN 0x10
+
+/* Life cycle state definitions. */
+
+/*! Defines the CM life-cycle state value. */
+#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0
+/*! Defines the DM life-cycle state value. */
+#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1
+/*! Defines the Secure life-cycle state value. */
+#define CC_BSV_SECURE_LCS 0x5
+/*! Defines the RMA life-cycle state value. */
+#define CC_BSV_RMA_LCS 0x7
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
struct qmrom_handle;
-#include <qm357xx_rom.h>
+struct unstitched_firmware {
+ struct firmware *fw_img;
+ struct firmware *fw_crt;
+ struct firmware *key1_crt;
+ struct firmware *key2_crt;
+};
#define SSTC2UINT32(handle, offset) \
({ \
@@ -61,6 +96,24 @@ struct qmrom_handle;
})
/* Those functions allow the libqmrom to call
+ * revision specific functions
+ */
+typedef int (*flash_fw_fn)(struct qmrom_handle *handle,
+ const struct firmware *fw);
+typedef int (*flash_unstitched_fw_fn)(struct qmrom_handle *handle,
+ const struct unstitched_firmware *fw);
+typedef int (*flash_debug_cert_fn)(struct qmrom_handle *handle,
+ struct firmware *dbg_cert);
+typedef int (*erase_debug_cert_fn)(struct qmrom_handle *handle);
+
+struct rom_code_ops {
+ flash_fw_fn flash_fw;
+ flash_unstitched_fw_fn flash_unstitched_fw;
+ flash_debug_cert_fn flash_debug_cert;
+ erase_debug_cert_fn erase_debug_cert;
+};
+
+/* Those functions allow the libqmrom to call
* device specific functions
*/
typedef int (*reset_device_fn)(void *handle);
@@ -73,30 +126,42 @@ struct qmrom_handle {
void *spi_handle;
void *reset_handle;
void *ss_rdy_handle;
- void *ss_irq_handle;
int comms_retries;
- enum device_generation_e dev_gen;
enum chip_revision_e chip_rev;
uint16_t device_version;
struct device_ops dev_ops;
- int spi_speed;
- struct qm357xx_rom_code_ops qm357xx_rom_ops;
+ struct rom_code_ops rom_ops;
+ uint32_t lcs_state;
struct stc *hstc;
struct stc *sstc;
- struct qm357xx_soc_infos qm357xx_soc_info;
+ uint8_t soc_id[ROM_SOC_ID_LEN];
+ uint8_t uuid[ROM_UUID_LEN];
bool is_be;
};
+int qmrom_unstitch_fw(const struct firmware *fw,
+ struct unstitched_firmware *unstitched_fw,
+ enum chip_revision_e revision);
struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
- void *ss_rdy_handle, void *ss_irq_handle,
- int spi_speed, int comms_retries,
- reset_device_fn reset,
- enum device_generation_e dev_gen_hint);
+ void *ss_rdy_handle, int comms_retries,
+ reset_device_fn reset);
void qmrom_deinit(struct qmrom_handle *handle);
int qmrom_reboot_bootloader(struct qmrom_handle *handle);
+int qmrom_flash_dbg_cert(struct qmrom_handle *handle,
+ struct firmware *dbg_cert);
+int qmrom_erase_dbg_cert(struct qmrom_handle *handle);
+int qmrom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw);
+int qmrom_flash_unstitched_fw(struct qmrom_handle *handle,
+ const struct unstitched_firmware *fw);
int qmrom_pre_read(struct qmrom_handle *handle);
int qmrom_read(struct qmrom_handle *handle);
+int qmrom_write_cmd(struct qmrom_handle *handle, uint8_t cmd);
+int qmrom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd);
+int qmrom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
+ uint16_t data_size, const char *data);
+int qmrom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
+ uint16_t data_size, const char *data);
#ifdef CHECK_STCS
void check_stcs(const char *func, int line, struct qmrom_handle *h);
diff --git a/libqmrom/include/qmrom_spi.h b/libqmrom/include/qmrom_spi.h
index c94e544..c3d8c92 100644
--- a/libqmrom/include/qmrom_spi.h
+++ b/libqmrom/include/qmrom_spi.h
@@ -50,13 +50,9 @@ int qmrom_spi_set_cs_level(void *handle, int level);
int qmrom_spi_reset_device(void *reset_handle);
const struct firmware *qmrom_spi_get_firmware(void *handle,
struct qmrom_handle *qmrom_h,
- bool *is_fw_updater,
bool use_prod_fw);
-const struct firmware *qmrom_spi_get_firmware_package(void *handle,
- int lcs_state);
void qmrom_spi_release_firmware(const struct firmware *fw);
int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms);
-int qmrom_spi_read_irq_line(void *handle);
void qmrom_spi_set_freq(unsigned int freq);
unsigned int qmrom_spi_get_freq(void);
diff --git a/libqmrom/include/qmrom_utils.h b/libqmrom/include/qmrom_utils.h
index 7533194..06ece2a 100644
--- a/libqmrom/include/qmrom_utils.h
+++ b/libqmrom/include/qmrom_utils.h
@@ -31,26 +31,21 @@ extern void usleep(unsigned int us);
} while (0)
#define qmrom_free free
-
-#define qmrom_data_dma_able(d) true
#else
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/mm.h>
#define qmrom_msleep(ms) \
do { \
usleep_range(ms * 1000, ms * 1000); \
} while (0)
-#define qmrom_alloc(ptr, size) \
- do { \
- ptr = kzalloc(size, GFP_KERNEL | GFP_DMA); \
+#define qmrom_alloc(ptr, size) \
+ do { \
+ ptr = kzalloc(size, GFP_KERNEL); \
} while (0)
#define qmrom_free kfree
-
-#define qmrom_data_dma_able(d) !is_vmalloc_addr(d)
#endif
#endif /* __QMROM_UTILS_H__ */
diff --git a/libqmrom/src/qm357xx_rom_common.c b/libqmrom/src/qm357xx_rom_common.c
deleted file mode 100644
index 051cc3d..0000000
--- a/libqmrom/src/qm357xx_rom_common.c
+++ /dev/null
@@ -1,414 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2022 Qorvo US, Inc.
- *
- */
-
-#include <qmrom_utils.h>
-#include <qmrom_log.h>
-#include <qmrom_spi.h>
-#include <qmrom.h>
-#include <spi_rom_protocol.h>
-
-#include <qm357xx_fwpkg.h>
-
-int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle);
-int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle);
-
-int qm357xx_rom_write_cmd(struct qmrom_handle *handle, uint8_t cmd)
-{
- handle->hstc->all = 0;
- handle->hstc->host_flags.write = 1;
- handle->hstc->ul = 1;
- handle->hstc->len = 1;
- handle->hstc->payload[0] = cmd;
-
- return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
- (const char *)handle->hstc,
- sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd)
-{
- handle->hstc->all = 0;
- handle->hstc->host_flags.write = 1;
- handle->hstc->ul = 1;
- handle->hstc->len = sizeof(cmd);
- memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
-
- return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
- (const char *)handle->hstc,
- sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
- uint16_t data_size, const char *data)
-{
- handle->hstc->all = 0;
- handle->hstc->host_flags.write = 1;
- handle->hstc->ul = 1;
- handle->hstc->len = data_size + 1;
- handle->hstc->payload[0] = cmd;
- memcpy(&handle->hstc->payload[1], data, data_size);
-
- return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
- (const char *)handle->hstc,
- sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
- uint16_t data_size, const char *data)
-{
- handle->hstc->all = 0;
- handle->hstc->host_flags.write = 1;
- handle->hstc->ul = 1;
- handle->hstc->len = data_size + sizeof(cmd);
- memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
- memcpy(&handle->hstc->payload[sizeof(cmd)], data, data_size);
-
- return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
- (const char *)handle->hstc,
- sizeof(struct stc) + handle->hstc->len);
-}
-
-/*
- * Unfortunately, B0 and C0 have different
- * APIs to get the chip version...
- *
- */
-int qm357xx_rom_probe_device(struct qmrom_handle *handle)
-{
- int rc;
-
- /* Test C0 first */
- rc = qm357xx_rom_c0_probe_device(handle);
- if (!rc)
- return rc;
-
- /* Test B0 next */
- rc = qm357xx_rom_b0_probe_device(handle);
- if (!rc)
- return rc;
-
- /* None matched!!! */
- return -1;
-}
-
-int qm357xx_rom_flash_dbg_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert)
-{
- if (!handle->qm357xx_rom_ops.flash_debug_cert) {
- LOG_ERR("%s: flash debug certificate not support on this device\n",
- __func__);
- return -EINVAL;
- }
- return handle->qm357xx_rom_ops.flash_debug_cert(handle, dbg_cert);
-}
-
-int qm357xx_rom_erase_dbg_cert(struct qmrom_handle *handle)
-{
- if (!handle->qm357xx_rom_ops.erase_debug_cert) {
- LOG_ERR("%s: erase debug certificate not support on this device\n",
- __func__);
- return -EINVAL;
- }
- return handle->qm357xx_rom_ops.erase_debug_cert(handle);
-}
-
-int qm357xx_rom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw)
-{
- int rc = 0;
- struct unstitched_firmware all_fws = { 0 };
-
- if (*(uint32_t *)&fw->data[0] ==
- CRYPTO_MACRO_FIRMWARE_PACK_MAGIC_VALUE) {
- //macro package detected
- //write the FW UPDATER
- rc = qm357xx_rom_unpack_fw_macro_pkg(fw, &all_fws);
- if (rc) {
- LOG_ERR("%s: Unpack macro FW package unsuccessful!\n",
- __func__);
- return rc;
- }
- } else {
- rc = qm357xx_rom_unstitch_fw(fw, &all_fws, handle->chip_rev);
- if (rc) {
- LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
- __func__);
- return rc;
- }
- }
- rc = qm357xx_rom_flash_unstitched_fw(handle, &all_fws);
- return rc;
-}
-
-int qm357xx_rom_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *fw)
-{
- if (!handle->qm357xx_rom_ops.flash_unstitched_fw) {
- LOG_ERR("%s: flash un-stitched firmware not supported on this device\n",
- __func__);
- return -EINVAL;
- }
- return handle->qm357xx_rom_ops.flash_unstitched_fw(handle, fw);
-}
-
-int qm357xx_rom_unstitch_fw(const struct firmware *fw,
- struct unstitched_firmware *unstitched_fw,
- enum chip_revision_e revision)
-{
- uint32_t tot_len = 0;
- uint32_t fw_img_sz = 0;
- uint32_t fw_crt_sz = 0;
- uint32_t key1_crt_sz = 0;
- uint32_t key2_crt_sz = 0;
- uint8_t *p_key1;
- uint8_t *p_key2;
- uint8_t *p_crt;
- uint8_t *p_fw;
- int ret = 0;
-
- if (fw->size < 2 * sizeof(key1_crt_sz)) {
- LOG_ERR("%s: Not enough data (%zu) to unstitch\n", __func__,
- fw->size);
- return -EINVAL;
- }
- LOG_INFO("%s: Unstitching %zu bytes\n", __func__, fw->size);
-
- /* key1 */
- key1_crt_sz = *(uint32_t *)&fw->data[tot_len];
- if (tot_len + key1_crt_sz + sizeof(key1_crt_sz) + sizeof(key2_crt_sz) >
- fw->size) {
- LOG_ERR("%s: Invalid or corrupted stitched file at offset \
- %" PRIu32 " (key1)\n",
- __func__, tot_len);
- ret = -EINVAL;
- goto out;
- }
- tot_len += sizeof(key1_crt_sz);
- p_key1 = (uint8_t *)&fw->data[tot_len];
- tot_len += key1_crt_sz;
-
- /* key2 */
- key2_crt_sz = *(uint32_t *)&fw->data[tot_len];
- if (tot_len + key2_crt_sz + sizeof(key2_crt_sz) + sizeof(fw_crt_sz) >
- fw->size) {
- LOG_ERR("%s: Invalid or corrupted stitched file at offset \
- %" PRIu32 " (key2)\n",
- __func__, tot_len);
- ret = -EINVAL;
- goto out;
- }
- tot_len += sizeof(key2_crt_sz);
- p_key2 = (uint8_t *)&fw->data[tot_len];
- tot_len += key2_crt_sz;
-
- /* cert */
- fw_crt_sz = *(uint32_t *)&fw->data[tot_len];
- if (tot_len + fw_crt_sz + sizeof(fw_crt_sz) + sizeof(fw_img_sz) >
- fw->size) {
- LOG_ERR("%s: Invalid or corrupted stitched file at offset \
- %" PRIu32 " (content cert)\n",
- __func__, tot_len);
- ret = -EINVAL;
- goto out;
- }
- tot_len += sizeof(fw_crt_sz);
- p_crt = (uint8_t *)&fw->data[tot_len];
- tot_len += fw_crt_sz;
-
- /* fw */
- fw_img_sz = *(uint32_t *)&fw->data[tot_len];
- if (tot_len + fw_img_sz + sizeof(fw_img_sz) != fw->size) {
- LOG_ERR("%s: Invalid or corrupted stitched file at offset \
- %" PRIu32 " (firmware)\n",
- __func__, tot_len);
- ret = -EINVAL;
- goto out;
- }
- tot_len += sizeof(fw_img_sz);
- p_fw = (uint8_t *)&fw->data[tot_len];
-
- qmrom_alloc(unstitched_fw->fw_img, fw_img_sz + sizeof(struct firmware));
- if (unstitched_fw->fw_img == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- qmrom_alloc(unstitched_fw->fw_crt, fw_crt_sz + sizeof(struct firmware));
- if (unstitched_fw->fw_crt == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- qmrom_alloc(unstitched_fw->key1_crt,
- key1_crt_sz + sizeof(struct firmware));
- if (unstitched_fw->key1_crt == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- qmrom_alloc(unstitched_fw->key2_crt,
- key2_crt_sz + sizeof(struct firmware));
- if (unstitched_fw->key2_crt == NULL) {
- ret = -ENOMEM;
- goto err;
- }
-
- unstitched_fw->key1_crt->data =
- (const uint8_t *)(unstitched_fw->key1_crt + 1);
- unstitched_fw->key2_crt->data =
- (const uint8_t *)(unstitched_fw->key2_crt + 1);
- unstitched_fw->fw_crt->data =
- (const uint8_t *)(unstitched_fw->fw_crt + 1);
- unstitched_fw->fw_img->data =
- (const uint8_t *)(unstitched_fw->fw_img + 1);
- unstitched_fw->key1_crt->size = key1_crt_sz;
- unstitched_fw->key2_crt->size = key2_crt_sz;
- unstitched_fw->fw_crt->size = fw_crt_sz;
- unstitched_fw->fw_img->size = fw_img_sz;
-
- memcpy((void *)unstitched_fw->key1_crt->data, p_key1, key1_crt_sz);
- memcpy((void *)unstitched_fw->key2_crt->data, p_key2, key2_crt_sz);
- memcpy((void *)unstitched_fw->fw_crt->data, p_crt, fw_crt_sz);
- memcpy((void *)unstitched_fw->fw_img->data, p_fw, fw_img_sz);
- return 0;
-
-err:
- if (unstitched_fw->fw_img)
- qmrom_free(unstitched_fw->fw_img);
- if (unstitched_fw->fw_crt)
- qmrom_free(unstitched_fw->fw_crt);
- if (unstitched_fw->key1_crt)
- qmrom_free(unstitched_fw->key1_crt);
- if (unstitched_fw->key2_crt)
- qmrom_free(unstitched_fw->key2_crt);
-
-out:
- return ret;
-}
-
-int qm357xx_rom_fw_macro_pkg_get_fw_idx(const struct firmware *fw, int idx,
- uint32_t *fw_size, char **fw_data)
-{
- struct fw_macro_pkg_hdr_t *fw_macro_pkg_hdr =
- (struct fw_macro_pkg_hdr_t *)fw->data;
- struct fw_img_desc_t *fw_pkg;
-
- if (fw_macro_pkg_hdr->nb_descriptors >= 1 &&
- idx < fw_macro_pkg_hdr->nb_descriptors) {
- fw_pkg = &fw_macro_pkg_hdr->img_desc[idx];
- if (fw_pkg->offset + fw_pkg->length > fw->size) {
- LOG_ERR("Wrong FW PKG offset = %04x; len = %04x; idx = %d!\n",
- fw_pkg->offset, fw_pkg->length, idx);
- return -EINVAL;
- }
- } else {
- LOG_ERR("%s: No FW pkg found in macro package! nb_descriptors = %d\n",
- __func__, fw_macro_pkg_hdr->nb_descriptors);
- return -EINVAL;
- }
- *fw_size = fw_pkg->length;
- *fw_data = (char *)&fw->data[fw_pkg->offset];
- return 0;
-}
-
-int qm357xx_rom_unpack_fw_macro_pkg(const struct firmware *fw,
- struct unstitched_firmware *all_fws)
-{
- int rc = 0;
- char *fw_data;
- uint32_t fw_size;
- struct firmware fw_pkg;
-
- rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 0, &fw_size, &fw_data);
- if (rc) {
- LOG_ERR("%s: FW MACRO PACKAGE corrupted = %d\n", __func__, rc);
- return rc;
- }
-
- fw_pkg.data = (const uint8_t *)fw_data;
- fw_pkg.size = fw_size;
- return qm357xx_rom_unpack_fw_pkg(&fw_pkg, all_fws);
-}
-
-int qm357xx_rom_unpack_fw_pkg(const struct firmware *fw_pkg,
- struct unstitched_firmware *all_fws)
-{
- int rc = 0;
- uint8_t *p_key1;
- uint8_t *p_key2;
- uint8_t *p_crt;
- uint8_t *p_fw;
- struct fw_pkg_img_hdr_t *fw_pkg_img_hdr;
-
- fw_pkg_img_hdr =
- (struct fw_pkg_img_hdr_t *)(fw_pkg->data +
- sizeof(struct fw_pkg_hdr_t));
-
- if (fw_pkg_img_hdr->magic != CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE) {
- LOG_ERR("%s: Invalid or corrupted file! magic = %04x\n",
- __func__, fw_pkg_img_hdr->magic);
- return -EINVAL;
- }
- qmrom_alloc(all_fws->fw_img,
- fw_pkg_img_hdr->descs[0].length + sizeof(struct firmware));
- if (all_fws->fw_img == NULL) {
- rc = -ENOMEM;
- goto err;
- }
- qmrom_alloc(all_fws->key1_crt,
- CRYPTO_IMAGES_CERT_KEY_SIZE + sizeof(struct firmware));
- if (all_fws->key1_crt == NULL) {
- rc = -ENOMEM;
- goto err;
- }
-
- qmrom_alloc(all_fws->key2_crt,
- CRYPTO_IMAGES_CERT_KEY_SIZE + sizeof(struct firmware));
- if (all_fws->key2_crt == NULL) {
- rc = -ENOMEM;
- goto err;
- }
-
- qmrom_alloc(all_fws->fw_crt,
- CRYPTO_IMAGES_CERT_CONTENT_SIZE + sizeof(struct firmware));
- if (all_fws->fw_crt == NULL) {
- rc = -ENOMEM;
- goto err;
- }
-
- all_fws->key1_crt->data = (const uint8_t *)(all_fws->key1_crt + 1);
- all_fws->key2_crt->data = (const uint8_t *)(all_fws->key2_crt + 1);
- all_fws->fw_crt->data = (const uint8_t *)(all_fws->fw_crt + 1);
- all_fws->fw_img->data = (const uint8_t *)(all_fws->fw_img + 1);
- all_fws->key1_crt->size = CRYPTO_IMAGES_CERT_KEY_SIZE;
- all_fws->key2_crt->size = CRYPTO_IMAGES_CERT_KEY_SIZE;
- all_fws->fw_crt->size = CRYPTO_IMAGES_CERT_CONTENT_SIZE;
- all_fws->fw_img->size = fw_pkg_img_hdr->descs[0].length;
-
- p_key1 = (uint8_t *)fw_pkg_img_hdr + fw_pkg_img_hdr->cert_chain_offset;
- p_key2 = p_key1 + CRYPTO_IMAGES_CERT_KEY_SIZE;
- p_crt = p_key2 + CRYPTO_IMAGES_CERT_KEY_SIZE;
- p_fw = (uint8_t *)fw_pkg_img_hdr + fw_pkg_img_hdr->descs[0].offset;
-
- memcpy((void *)all_fws->key1_crt->data, p_key1,
- all_fws->key1_crt->size);
- memcpy((void *)all_fws->key2_crt->data, p_key2,
- all_fws->key2_crt->size);
- memcpy((void *)all_fws->fw_crt->data, p_crt, all_fws->fw_crt->size);
- memcpy((void *)all_fws->fw_img->data, p_fw, all_fws->fw_img->size);
- return 0;
-
-err:
- if (all_fws->fw_img)
- qmrom_free(all_fws->fw_img);
- if (all_fws->fw_crt)
- qmrom_free(all_fws->fw_crt);
- if (all_fws->key1_crt)
- qmrom_free(all_fws->key1_crt);
- if (all_fws->key2_crt)
- qmrom_free(all_fws->key2_crt);
-
- return rc;
-}
diff --git a/libqmrom/src/qmrom_a0.c b/libqmrom/src/qmrom_a0.c
new file mode 100644
index 0000000..ce75612
--- /dev/null
+++ b/libqmrom/src/qmrom_a0.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
+/*
+ * Copyright 2022 Qorvo US, Inc.
+ *
+ */
+
+#include <qmrom.h>
+#include <qmrom_spi.h>
+#include <qmrom_log.h>
+#include <qmrom_utils.h>
+#include <spi_rom_protocol.h>
+
+#define DEFAULT_SPI_CLOCKRATE 750000
+#define CHIP_VERSION_CHIP_REV_PAYLOAD_OFFSET 1
+#define CHUNK_SIZE_A0 1016
+
+enum A0_CMD {
+ ROM_CMD_A0_GET_CHIP_VER = 0x0,
+ ROM_CMD_A0_DOWNLOAD_RRAM_CMD = 0x40,
+};
+
+enum A0_RESP {
+ /* Waiting for download command */
+ SPI_RSP_WAIT_DOWNLOAD_MODE = 1,
+ SPI_RSP_WAIT_FOR_KEY1_CERT,
+ SPI_RSP_WAIT_FOR_KEY2_CERT,
+ SPI_RSP_WAIT_FOR_IMAGE_CERT,
+ SPI_RSP_WAIT_IMAGE_SIZE,
+ SPI_RSP_WAIT_FOR_IMAGE,
+ SPI_RSP_DOWNLOAD_OK,
+ SPI_RSP_BOOT_OK,
+ /* Checksum/CRC error */
+ SPI_RSP_ERROR_CS,
+ /* Got error certificate RSA/FW ver. Didn't get
+ * all the data before switching to image...
+ */
+ SPI_RSP_ERROR_CERTIFICATE,
+ /* Got command smaller than SPI_HEADER_SIZE.
+ * Each command must be at least this size.
+ */
+ SPI_RSP_CMD_TOO_SHORT,
+ /* Error checking certificates or image, going
+ * to download mode.
+ */
+ SPI_RSP_ERROR_LOADING_IN_DOWNLOAD,
+};
+
+static int qmrom_a0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw);
+
+void qmrom_a0_poll_soc(struct qmrom_handle *handle)
+{
+ int retries = handle->comms_retries;
+ handle->hstc->all = 0;
+ qmrom_msleep(SPI_READY_TIMEOUT_MS);
+ do {
+ qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc, 1);
+ } while (retries-- && handle->sstc->raw_flags == 0);
+}
+
+int qmrom_a0_wait_ready(struct qmrom_handle *handle)
+{
+ int retries = handle->comms_retries;
+ qmrom_a0_poll_soc(handle);
+
+ while (retries-- && !handle->sstc->soc_flags.out_waiting) {
+ qmrom_a0_poll_soc(handle);
+ }
+ return handle->sstc->soc_flags.out_waiting ? 0 :
+ SPI_ERR_WAIT_READY_TIMEOUT;
+}
+
+int qmrom_a0_probe_device(struct qmrom_handle *handle)
+{
+ int rc;
+ LOG_DBG("%s: enters...\n", __func__);
+ handle->is_be = true;
+
+ qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
+
+ rc = qmrom_reboot_bootloader(handle);
+ if (rc) {
+ LOG_ERR("%s: cannot reset the device...\n", __func__);
+ return rc;
+ }
+
+ rc = qmrom_a0_wait_ready(handle);
+ if (rc) {
+ LOG_INFO("%s: maybe not a A0 device\n", __func__);
+ return rc;
+ }
+ qmrom_pre_read(handle);
+ handle->sstc->len = bswap_16(handle->sstc->len);
+ if (handle->sstc->len > 0xff) {
+ /* likely the wrong endianness, B0 or C0? */
+ return -1;
+ }
+ qmrom_read(handle);
+
+ LOG_DBG("%s: Set the chip_rev/device_version\n", __func__);
+ handle->chip_rev =
+ bswap_16(SSTC2UINT16(handle,
+ CHIP_VERSION_CHIP_REV_PAYLOAD_OFFSET)) &
+ 0xFF;
+
+ if (handle->chip_rev != CHIP_REVISION_A0) {
+ LOG_ERR("%s: wrong chip revision %#x\n", __func__,
+ handle->chip_rev);
+ handle->chip_rev = -1;
+ return -1;
+ }
+
+ /* Set rom ops */
+ handle->rom_ops.flash_fw = qmrom_a0_flash_fw;
+ handle->rom_ops.flash_debug_cert = NULL;
+ handle->rom_ops.erase_debug_cert = NULL;
+ return 0;
+}
+
+int qmrom_a0_write_data(struct qmrom_handle *handle, uint16_t data_size,
+ const char *data)
+{
+ handle->hstc->all = 0;
+ handle->hstc->host_flags.write = 1;
+ handle->hstc->ul = 1;
+ handle->hstc->len = data_size;
+ memcpy(handle->hstc->payload, data, data_size);
+
+ return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc,
+ sizeof(struct stc) + data_size);
+}
+
+static int qmrom_a0_write_chunks(struct qmrom_handle *handle,
+ const struct firmware *fw)
+{
+ int rc, sent = 0;
+ const char *bin_data = (const char *)fw->data;
+
+ check_stcs(__func__, __LINE__, handle);
+ while (sent < fw->size) {
+ uint32_t tx_bytes = fw->size - sent;
+ if (tx_bytes > CHUNK_SIZE_A0)
+ tx_bytes = CHUNK_SIZE_A0;
+
+ LOG_DBG("%s: poll soc...\n", __func__);
+ check_stcs(__func__, __LINE__, handle);
+ qmrom_a0_poll_soc(handle);
+ qmrom_pre_read(handle);
+ handle->sstc->len = bswap_16(handle->sstc->len);
+ qmrom_read(handle);
+ if (handle->sstc->payload[0] != SPI_RSP_WAIT_FOR_IMAGE) {
+ LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n",
+ __func__, handle->sstc->payload[0] & 0xff,
+ SPI_RSP_WAIT_FOR_IMAGE);
+ return SPI_PROTO_WRONG_RESP;
+ }
+
+ LOG_DBG("%s: sending %" PRIu32 " bytes of data\n", __func__,
+ tx_bytes);
+ rc = qmrom_a0_write_data(handle, tx_bytes, bin_data);
+ if (rc)
+ return rc;
+ sent += tx_bytes;
+ bin_data += tx_bytes;
+ check_stcs(__func__, __LINE__, handle);
+ }
+ return 0;
+}
+
+static int qmrom_a0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw)
+{
+ int rc = 0, resp;
+
+ LOG_DBG("%s: starting...\n", __func__);
+
+ /* Reboot since the rom code on A0 seems
+ * to have issues when starting flashing
+ * after some prior interaction (like GET_CHIP_VERSION)
+ */
+ rc = qmrom_reboot_bootloader(handle);
+ if (rc) {
+ LOG_ERR("%s: cannot reset the device...\n", __func__);
+ return rc;
+ }
+
+ rc = qmrom_a0_wait_ready(handle);
+ if (rc) {
+ LOG_ERR("%s: timedout waiting for the device to be ready\n",
+ __func__);
+ return rc;
+ }
+ qmrom_pre_read(handle);
+ handle->sstc->len = bswap_16(handle->sstc->len);
+ qmrom_read(handle);
+ if (handle->sstc->payload[0] != SPI_RSP_WAIT_DOWNLOAD_MODE) {
+ LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n", __func__,
+ handle->sstc->payload[0] & 0xff,
+ SPI_RSP_WAIT_DOWNLOAD_MODE);
+ return SPI_PROTO_WRONG_RESP;
+ }
+
+ check_stcs(__func__, __LINE__, handle);
+ LOG_DBG("%s: sending ROM_CMD_A0_DOWNLOAD_RRAM_CMD command\n", __func__);
+ rc = qmrom_write_cmd(handle, ROM_CMD_A0_DOWNLOAD_RRAM_CMD);
+ if (rc)
+ return rc;
+
+ for (resp = SPI_RSP_WAIT_FOR_KEY1_CERT; resp < SPI_RSP_WAIT_FOR_IMAGE;
+ resp++) {
+ qmrom_a0_poll_soc(handle);
+ qmrom_pre_read(handle);
+ handle->sstc->len = bswap_16(handle->sstc->len);
+ qmrom_read(handle);
+ if (handle->sstc->payload[0] != resp) {
+ LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n",
+ __func__, handle->sstc->payload[0] & 0xff,
+ resp);
+ return SPI_PROTO_WRONG_RESP;
+ }
+ if (resp < SPI_RSP_WAIT_IMAGE_SIZE) {
+ rc = qmrom_write_cmd(handle, 0);
+ if (rc)
+ return rc;
+ }
+ }
+
+ LOG_DBG("%s: sending fw size\n", __func__);
+ rc = qmrom_a0_write_data(handle, sizeof(uint32_t),
+ (const char *)&fw->size);
+ if (rc)
+ return rc;
+
+ check_stcs(__func__, __LINE__, handle);
+ rc = qmrom_a0_write_chunks(handle, fw);
+ check_stcs(__func__, __LINE__, handle);
+ return rc;
+}
diff --git a/libqmrom/src/qm357xx_rom_b0.c b/libqmrom/src/qmrom_b0.c
index fe2c637..9b23cff 100644
--- a/libqmrom/src/qm357xx_rom_b0.c
+++ b/libqmrom/src/qmrom_b0.c
@@ -67,14 +67,16 @@ enum B0_RESP {
ERR_DEBUG_CERT_SIZE = 0x1F,
};
-static int qm357xx_rom_b0_flash_debug_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert);
-static int qm357xx_rom_b0_erase_debug_cert(struct qmrom_handle *handle);
+static int qmrom_b0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw);
+static int qmrom_b0_flash_debug_cert(struct qmrom_handle *handle,
+ struct firmware *dbg_cert);
+static int qmrom_b0_erase_debug_cert(struct qmrom_handle *handle);
static int
-qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *all_fws);
+qmrom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
+ const struct unstitched_firmware *all_fws);
-static void qm357xx_rom_b0_poll_soc(struct qmrom_handle *handle)
+static void qmrom_b0_poll_soc(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
memset(handle->hstc, 0, sizeof(struct stc));
@@ -86,12 +88,12 @@ static void qm357xx_rom_b0_poll_soc(struct qmrom_handle *handle)
} while (retries-- && handle->sstc->raw_flags == 0);
}
-static int qm357xx_rom_b0_wait_ready(struct qmrom_handle *handle)
+static int qmrom_b0_wait_ready(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
int rc;
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
/* handle->sstc has been updated */
while (retries-- &&
@@ -104,7 +106,7 @@ static int qm357xx_rom_b0_wait_ready(struct qmrom_handle *handle)
return rc;
} else {
/* error? */
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
}
}
@@ -113,11 +115,11 @@ static int qm357xx_rom_b0_wait_ready(struct qmrom_handle *handle)
SPI_ERR_WAIT_READY_TIMEOUT;
}
-static int qm357xx_rom_b0_poll_cmd_resp(struct qmrom_handle *handle)
+static int qmrom_b0_poll_cmd_resp(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
do {
if (handle->sstc->soc_flags.out_waiting) {
qmrom_pre_read(handle);
@@ -128,23 +130,20 @@ static int qm357xx_rom_b0_poll_cmd_resp(struct qmrom_handle *handle)
qmrom_read(handle);
break;
} else
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
} while (retries--);
return retries > 0 ? 0 : -1;
}
-int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle)
+int qmrom_b0_probe_device(struct qmrom_handle *handle)
{
int rc, i;
uint8_t *soc_lcs_uuid;
handle->is_be = false;
check_stcs(__func__, __LINE__, handle);
- if (handle->spi_speed == 0)
- qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
- else
- qmrom_spi_set_freq(handle->spi_speed);
+ qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
rc = qmrom_reboot_bootloader(handle);
if (rc) {
@@ -152,17 +151,17 @@ int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle)
return rc;
}
- rc = qm357xx_rom_b0_wait_ready(handle);
+ rc = qmrom_b0_wait_ready(handle);
if (rc) {
LOG_INFO("%s: maybe not a B0 device\n", __func__);
return rc;
}
- rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_GET_CHIP_VER);
+ rc = qmrom_write_cmd(handle, ROM_CMD_B0_GET_CHIP_VER);
if (rc)
return rc;
- rc = qm357xx_rom_b0_poll_cmd_resp(handle);
+ rc = qmrom_b0_poll_cmd_resp(handle);
if (rc)
return rc;
@@ -178,49 +177,42 @@ int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle)
return -1;
}
- rc = qm357xx_rom_b0_wait_ready(handle);
+ rc = qmrom_b0_wait_ready(handle);
if (rc) {
LOG_ERR("%s: hmm something went wrong!!!\n", __func__);
return rc;
}
- rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_GET_SOC_INFO);
+ rc = qmrom_write_cmd(handle, ROM_CMD_B0_GET_SOC_INFO);
if (rc)
return rc;
- rc = qm357xx_rom_b0_poll_cmd_resp(handle);
+ rc = qmrom_b0_poll_cmd_resp(handle);
if (rc)
return rc;
/* skip the first byte */
soc_lcs_uuid = &(handle->sstc->payload[1]);
- for (i = 0; i < QM357XX_ROM_SOC_ID_LEN; i++)
- handle->qm357xx_soc_info.soc_id[i] =
- soc_lcs_uuid[QM357XX_ROM_SOC_ID_LEN - i - 1];
- soc_lcs_uuid += QM357XX_ROM_SOC_ID_LEN;
- handle->qm357xx_soc_info.lcs_state = soc_lcs_uuid[0];
+ for (i = 0; i < ROM_SOC_ID_LEN; i++)
+ handle->soc_id[i] = soc_lcs_uuid[ROM_SOC_ID_LEN - i - 1];
+ soc_lcs_uuid += ROM_SOC_ID_LEN;
+ handle->lcs_state = soc_lcs_uuid[0];
soc_lcs_uuid += 1;
- for (i = 0; i < QM357XX_ROM_UUID_LEN; i++)
- handle->qm357xx_soc_info.uuid[i] =
- soc_lcs_uuid[QM357XX_ROM_UUID_LEN - i - 1];
+ for (i = 0; i < ROM_UUID_LEN; i++)
+ handle->uuid[i] = soc_lcs_uuid[ROM_UUID_LEN - i - 1];
- /* Set device type */
- handle->dev_gen = DEVICE_GEN_QM357XX;
/* Set rom ops */
- handle->qm357xx_rom_ops.flash_unstitched_fw =
- qm357xx_rom_b0_flash_unstitched_fw;
- handle->qm357xx_rom_ops.flash_debug_cert =
- qm357xx_rom_b0_flash_debug_cert;
- handle->qm357xx_rom_ops.erase_debug_cert =
- qm357xx_rom_b0_erase_debug_cert;
+ handle->rom_ops.flash_fw = qmrom_b0_flash_fw;
+ handle->rom_ops.flash_unstitched_fw = qmrom_b0_flash_unstitched_fw;
+ handle->rom_ops.flash_debug_cert = qmrom_b0_flash_debug_cert;
+ handle->rom_ops.erase_debug_cert = qmrom_b0_erase_debug_cert;
check_stcs(__func__, __LINE__, handle);
return 0;
}
-static int qm357xx_rom_b0_flash_data(struct qmrom_handle *handle,
- struct firmware *fw, uint8_t cmd,
- uint8_t exp)
+static int qmrom_b0_flash_data(struct qmrom_handle *handle, struct firmware *fw,
+ uint8_t cmd, uint8_t exp)
{
int rc, sent = 0;
const char *bin_data = (const char *)fw->data;
@@ -233,7 +225,7 @@ static int qm357xx_rom_b0_flash_data(struct qmrom_handle *handle,
LOG_DBG("%s: poll soc...\n", __func__);
check_stcs(__func__, __LINE__, handle);
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
qmrom_pre_read(handle);
qmrom_read(handle);
if (handle->sstc->payload[0] != exp) {
@@ -248,8 +240,7 @@ static int qm357xx_rom_b0_flash_data(struct qmrom_handle *handle,
LOG_DBG("%s: sending %d command with %" PRIu32 " bytes\n",
__func__, cmd, tx_bytes);
- rc = qm357xx_rom_write_size_cmd(handle, cmd, tx_bytes,
- bin_data);
+ rc = qmrom_write_size_cmd(handle, cmd, tx_bytes, bin_data);
if (rc)
return rc;
sent += tx_bytes;
@@ -259,18 +250,33 @@ static int qm357xx_rom_b0_flash_data(struct qmrom_handle *handle,
return 0;
}
+static int qmrom_b0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw)
+{
+ int rc = 0;
+ struct unstitched_firmware all_fws = { 0 };
+
+ rc = qmrom_unstitch_fw(fw, &all_fws, handle->chip_rev);
+ if (rc) {
+ LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
+ __func__);
+ return rc;
+ }
+ rc = qmrom_b0_flash_unstitched_fw(handle, &all_fws);
+ return rc;
+}
+
static int
-qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *all_fws)
+qmrom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
+ const struct unstitched_firmware *all_fws)
{
int rc = 0;
- uint8_t flash_cmd = handle->qm357xx_soc_info.lcs_state ==
- CC_BSV_SECURE_LCS ?
+ uint8_t flash_cmd = handle->lcs_state == CC_BSV_SECURE_LCS ?
ROM_CMD_B0_SEC_LOAD_OEM_IMG_TO_RRAM :
ROM_CMD_B0_SEC_LOAD_ICV_IMG_TO_RRAM;
if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
- handle->qm357xx_soc_info.lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
+ handle->lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
LOG_ERR("%s: Trying to flash an ICV fw on a non ICV platform\n",
__func__);
rc = -EINVAL;
@@ -278,7 +284,7 @@ qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
}
if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
- handle->qm357xx_soc_info.lcs_state != CC_BSV_SECURE_LCS) {
+ handle->lcs_state != CC_BSV_SECURE_LCS) {
LOG_ERR("%s: Trying to flash an OEM fw on a non OEM platform\n",
__func__);
rc = -EINVAL;
@@ -288,41 +294,40 @@ qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
LOG_DBG("%s: starting...\n", __func__);
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_wait_ready(handle);
+ rc = qmrom_b0_wait_ready(handle);
if (rc)
goto end;
check_stcs(__func__, __LINE__, handle);
LOG_DBG("%s: sending flash_cmd %u command\n", __func__, flash_cmd);
- rc = qm357xx_rom_write_cmd(handle, flash_cmd);
+ rc = qmrom_write_cmd(handle, flash_cmd);
if (rc)
goto end;
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_flash_data(handle, all_fws->key1_crt,
- ROM_CMD_B0_CERT_DATA,
- WAITING_FOR_FIRST_KEY_CERT);
+ rc = qmrom_b0_flash_data(handle, all_fws->key1_crt,
+ ROM_CMD_B0_CERT_DATA,
+ WAITING_FOR_FIRST_KEY_CERT);
if (rc)
goto end;
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_flash_data(handle, all_fws->key2_crt,
- ROM_CMD_B0_CERT_DATA,
- WAITING_FOR_SECOND_KEY_CERT);
+ rc = qmrom_b0_flash_data(handle, all_fws->key2_crt,
+ ROM_CMD_B0_CERT_DATA,
+ WAITING_FOR_SECOND_KEY_CERT);
if (rc)
goto end;
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_flash_data(handle, all_fws->fw_crt,
- ROM_CMD_B0_CERT_DATA,
- WAITING_FOR_CONTENT_CERT);
+ rc = qmrom_b0_flash_data(handle, all_fws->fw_crt, ROM_CMD_B0_CERT_DATA,
+ WAITING_FOR_CONTENT_CERT);
if (rc)
goto end;
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_flash_data(handle, all_fws->fw_img,
- ROM_CMD_B0_SEC_IMAGE_DATA,
- WAITING_FOR_SEC_FILE_DATA);
+ rc = qmrom_b0_flash_data(handle, all_fws->fw_img,
+ ROM_CMD_B0_SEC_IMAGE_DATA,
+ WAITING_FOR_SEC_FILE_DATA);
if (!rc)
qmrom_msleep(SPI_READY_TIMEOUT_MS);
@@ -336,35 +341,35 @@ end:
return rc;
}
-static int qm357xx_rom_b0_flash_debug_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert)
+static int qmrom_b0_flash_debug_cert(struct qmrom_handle *handle,
+ struct firmware *dbg_cert)
{
int rc;
LOG_DBG("%s: starting...\n", __func__);
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_wait_ready(handle);
+ rc = qmrom_b0_wait_ready(handle);
if (rc)
return rc;
check_stcs(__func__, __LINE__, handle);
LOG_DBG("%s: sending ROM_CMD_B0_WRITE_DBG_CERT command\n", __func__);
- rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_WRITE_DBG_CERT);
+ rc = qmrom_write_cmd(handle, ROM_CMD_B0_WRITE_DBG_CERT);
if (rc)
return rc;
check_stcs(__func__, __LINE__, handle);
LOG_DBG("%s: poll soc...\n", __func__);
- qm357xx_rom_b0_poll_soc(handle);
+ qmrom_b0_poll_soc(handle);
qmrom_pre_read(handle);
qmrom_read(handle);
check_stcs(__func__, __LINE__, handle);
LOG_DBG("%s: sending ROM_CMD_B0_DEBUG_CERT_SIZE command\n", __func__);
- rc = qm357xx_rom_write_size_cmd(handle, ROM_CMD_B0_DEBUG_CERT_SIZE,
- sizeof(uint32_t),
- (const char *)&dbg_cert->size);
+ rc = qmrom_write_size_cmd(handle, ROM_CMD_B0_DEBUG_CERT_SIZE,
+ sizeof(uint32_t),
+ (const char *)&dbg_cert->size);
if (handle->sstc->payload[0] != WAITING_TO_DEBUG_CERTIFICATE_SIZE) {
LOG_ERR("%s: wrong debug cert size result (0x%x vs 0x%x)!!!\n",
__func__, handle->sstc->payload[0] & 0xff,
@@ -374,26 +379,25 @@ static int qm357xx_rom_b0_flash_debug_cert(struct qmrom_handle *handle,
if (rc)
return rc;
- rc = qm357xx_rom_b0_flash_data(handle, dbg_cert, ROM_CMD_B0_CERT_DATA,
- WAITING_FOR_DEBUG_CERT_DATA);
+ rc = qmrom_b0_flash_data(handle, dbg_cert, ROM_CMD_B0_CERT_DATA,
+ WAITING_FOR_DEBUG_CERT_DATA);
check_stcs(__func__, __LINE__, handle);
- qmrom_msleep(SPI_READY_TIMEOUT_MS);
return 0;
}
-static int qm357xx_rom_b0_erase_debug_cert(struct qmrom_handle *handle)
+static int qmrom_b0_erase_debug_cert(struct qmrom_handle *handle)
{
int rc;
LOG_INFO("%s: starting...\n", __func__);
check_stcs(__func__, __LINE__, handle);
- rc = qm357xx_rom_b0_wait_ready(handle);
+ rc = qmrom_b0_wait_ready(handle);
if (!rc)
return rc;
LOG_DBG("%s: sending ROM_CMD_B0_ERASE_DBG_CERT command\n", __func__);
- rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_ERASE_DBG_CERT);
+ rc = qmrom_write_cmd(handle, ROM_CMD_B0_ERASE_DBG_CERT);
if (rc)
return rc;
diff --git a/libqmrom/src/qm357xx_rom_c0.c b/libqmrom/src/qmrom_c0.c
index acd4d31..76a04f3 100644
--- a/libqmrom/src/qm357xx_rom_c0.c
+++ b/libqmrom/src/qmrom_c0.c
@@ -77,12 +77,11 @@ enum C0_RESP {
ERR_DEBUG_CERT_SIZE = 0x1F,
};
-static int
-qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *all_fws);
-static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert);
-static int qm357xx_rom_c0_erase_debug_cert(struct qmrom_handle *handle);
+static int qmrom_c0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw);
+static int qmrom_c0_flash_debug_cert(struct qmrom_handle *handle,
+ struct firmware *dbg_cert);
+static int qmrom_c0_erase_debug_cert(struct qmrom_handle *handle);
#define qmrom_pre_read_c0(h) \
({ \
@@ -100,40 +99,40 @@ static int qm357xx_rom_c0_erase_debug_cert(struct qmrom_handle *handle);
rc = qmrom_read((h)); \
rc; \
})
-#define qm357xx_rom_write_cmd_c0(h, cmd) \
+#define qmrom_write_cmd_c0(h, cmd) \
({ \
int rc; \
qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle, \
SPI_READY_TIMEOUT_MS_C0); \
- rc = qm357xx_rom_write_cmd((h), (cmd)); \
+ rc = qmrom_write_cmd((h), (cmd)); \
rc; \
})
-#define qm357xx_rom_write_cmd32_c0(h, cmd) \
+#define qmrom_write_cmd32_c0(h, cmd) \
({ \
int rc; \
qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle, \
SPI_READY_TIMEOUT_MS_C0); \
- rc = qm357xx_rom_write_cmd32((h), (cmd)); \
+ rc = qmrom_write_cmd32((h), (cmd)); \
rc; \
})
-#define qm357xx_rom_write_size_cmd_c0(h, cmd, ds, d) \
+#define qmrom_write_size_cmd_c0(h, cmd, ds, d) \
({ \
int rc; \
qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle, \
SPI_READY_TIMEOUT_MS_C0); \
- rc = qm357xx_rom_write_size_cmd((h), (cmd), (ds), (d)); \
+ rc = qmrom_write_size_cmd((h), (cmd), (ds), (d)); \
rc; \
})
-#define qm357xx_rom_write_size_cmd32_c0(h, cmd, ds, d) \
- ({ \
- int rc; \
- qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle, \
- SPI_READY_TIMEOUT_MS_C0); \
- rc = qm357xx_rom_write_size_cmd32((h), (cmd), (ds), (d)); \
- rc; \
+#define qmrom_write_size_cmd32_c0(h, cmd, ds, d) \
+ ({ \
+ int rc; \
+ qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle, \
+ SPI_READY_TIMEOUT_MS_C0); \
+ rc = qmrom_write_size_cmd32((h), (cmd), (ds), (d)); \
+ rc; \
})
-static void qm357xx_rom_c0_poll_soc(struct qmrom_handle *handle)
+static void qmrom_c0_poll_soc(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
memset(handle->hstc, 0, sizeof(struct stc));
@@ -152,11 +151,11 @@ static void qm357xx_rom_c0_poll_soc(struct qmrom_handle *handle)
} while (retries-- && handle->sstc->raw_flags == 0);
}
-static int qm357xx_rom_c0_wait_ready(struct qmrom_handle *handle)
+static int qmrom_c0_wait_ready(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
/* handle->sstc has been updated */
while (retries-- &&
@@ -167,7 +166,7 @@ static int qm357xx_rom_c0_wait_ready(struct qmrom_handle *handle)
} else if (handle->sstc->soc_flags.out_active) {
return qmrom_read_c0(handle);
} else
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
}
return handle->sstc->raw_flags == SPI_SH_READY_CMD_BIT_MASK_C0 ?
@@ -175,17 +174,17 @@ static int qm357xx_rom_c0_wait_ready(struct qmrom_handle *handle)
SPI_ERR_WAIT_READY_TIMEOUT;
}
-static int qm357xx_rom_c0_poll_cmd_resp(struct qmrom_handle *handle)
+static int qmrom_c0_poll_cmd_resp(struct qmrom_handle *handle)
{
int retries = handle->comms_retries;
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
do {
if (handle->sstc->soc_flags.out_waiting) {
qmrom_pre_read_c0(handle);
return qmrom_read_c0(handle);
} else
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
} while (retries--);
if (retries <= 0)
LOG_ERR("%s failed after %d replies\n", __func__,
@@ -194,17 +193,14 @@ static int qm357xx_rom_c0_poll_cmd_resp(struct qmrom_handle *handle)
return retries > 0 ? 0 : -1;
}
-int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle)
+int qmrom_c0_probe_device(struct qmrom_handle *handle)
{
int rc, i;
uint8_t *soc_lcs_uuid;
handle->is_be = false;
- if (handle->spi_speed == 0)
- qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
- else
- qmrom_spi_set_freq(handle->spi_speed);
+ qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
rc = qmrom_reboot_bootloader(handle);
if (rc) {
@@ -212,17 +208,17 @@ int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle)
return rc;
}
- rc = qm357xx_rom_c0_wait_ready(handle);
+ rc = qmrom_c0_wait_ready(handle);
if (rc) {
LOG_INFO("%s: maybe not a C0 device\n", __func__);
return rc;
}
- rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_GET_CHIP_VER);
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_GET_CHIP_VER);
if (rc)
return rc;
- rc = qm357xx_rom_c0_poll_cmd_resp(handle);
+ rc = qmrom_c0_poll_cmd_resp(handle);
if (rc)
return rc;
@@ -231,50 +227,41 @@ int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle)
0xFF;
handle->device_version = bswap_16(
SSTC2UINT16(handle, CHIP_VERSION_DEV_REV_PAYLOAD_OFFSET));
- if ((handle->chip_rev != CHIP_REVISION_C0) &&
- ((handle->chip_rev != CHIP_REVISION_C2))) {
+ if (handle->chip_rev != CHIP_REVISION_C0) {
LOG_ERR("%s: wrong chip revision %#x\n", __func__,
handle->chip_rev);
handle->chip_rev = -1;
return -1;
}
- rc = qm357xx_rom_c0_wait_ready(handle);
+ rc = qmrom_c0_wait_ready(handle);
if (rc) {
LOG_ERR("%s: hmm something went wrong!!!\n", __func__);
return rc;
}
- rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_GET_SOC_INFO);
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_GET_SOC_INFO);
if (rc)
return rc;
- rc = qm357xx_rom_c0_poll_cmd_resp(handle);
+ rc = qmrom_c0_poll_cmd_resp(handle);
if (rc)
return rc;
/* skip the first 4 bytes */
soc_lcs_uuid = &(handle->sstc->payload[4]);
- for (i = 0; i < QM357XX_ROM_SOC_ID_LEN; i++)
- handle->qm357xx_soc_info.soc_id[i] =
- soc_lcs_uuid[QM357XX_ROM_SOC_ID_LEN - i - 1];
- soc_lcs_uuid += QM357XX_ROM_SOC_ID_LEN;
- memcpy(&handle->qm357xx_soc_info.lcs_state, soc_lcs_uuid,
- sizeof(uint32_t));
+ for (i = 0; i < ROM_SOC_ID_LEN; i++)
+ handle->soc_id[i] = soc_lcs_uuid[ROM_SOC_ID_LEN - i - 1];
+ soc_lcs_uuid += ROM_SOC_ID_LEN;
+ memcpy(&handle->lcs_state, soc_lcs_uuid, sizeof(uint32_t));
soc_lcs_uuid += 4;
- for (i = 0; i < QM357XX_ROM_UUID_LEN; i++)
- handle->qm357xx_soc_info.uuid[i] =
- soc_lcs_uuid[QM357XX_ROM_UUID_LEN - i - 1];
+ for (i = 0; i < ROM_UUID_LEN; i++)
+ handle->uuid[i] = soc_lcs_uuid[ROM_UUID_LEN - i - 1];
- /* Set device type */
- handle->dev_gen = DEVICE_GEN_QM357XX;
/* Set rom ops */
- handle->qm357xx_rom_ops.flash_unstitched_fw =
- qm357xx_rom_c0_flash_unstitched_fw;
- handle->qm357xx_rom_ops.flash_debug_cert =
- qm357xx_rom_c0_flash_debug_cert;
- handle->qm357xx_rom_ops.erase_debug_cert =
- qm357xx_rom_c0_erase_debug_cert;
+ handle->rom_ops.flash_fw = qmrom_c0_flash_fw;
+ handle->rom_ops.flash_debug_cert = qmrom_c0_flash_debug_cert;
+ handle->rom_ops.erase_debug_cert = qmrom_c0_erase_debug_cert;
return 0;
}
@@ -298,18 +285,17 @@ static void update_write_max_chunk_stats(ktime_t start_time)
static void dump_stats(void)
{
- uint32_t nb_chunks = div_u64(total_bytes, CHUNK_SIZE_C0);
+ uint32_t nb_chunks = total_bytes / CHUNK_SIZE_C0;
LOG_WARN(
"C0 flashing time stats: %llu bytes over %llu us (chunk size %u, write timings: mean %u us, min %u us, max %u us)\n",
- total_bytes, div_u64(total_time_ns, 1000), CHUNK_SIZE_C0,
- (uint32_t)(div_u64((div_u64(total_time_ns, nb_chunks)), 1000)),
+ total_bytes, total_time_ns / 1000, CHUNK_SIZE_C0,
+ (uint32_t)((total_time_ns / nb_chunks) / 1000),
min_write_time_ns / 1000, max_write_time_ns / 1000);
}
#endif
-static int qm357xx_rom_c0_flash_data(struct qmrom_handle *handle,
- struct firmware *fw, uint8_t cmd,
- uint8_t resp, bool skip_last_check)
+static int qmrom_c0_flash_data(struct qmrom_handle *handle, struct firmware *fw,
+ uint8_t cmd, uint8_t resp, bool skip_last_check)
{
int rc, sent = 0;
const char *bin_data = (const char *)fw->data;
@@ -327,8 +313,7 @@ static int qm357xx_rom_c0_flash_data(struct qmrom_handle *handle,
#ifdef C0_WRITE_STATS
start_time = ktime_get();
#endif
- rc = qm357xx_rom_write_size_cmd32_c0(handle, cmd, tx_bytes,
- bin_data);
+ rc = qmrom_write_size_cmd32_c0(handle, cmd, tx_bytes, bin_data);
if (rc)
return rc;
sent += tx_bytes;
@@ -337,7 +322,7 @@ static int qm357xx_rom_c0_flash_data(struct qmrom_handle *handle,
LOG_INFO("%s: flashing done, quitting now\n", __func__);
break;
}
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
#ifdef C0_WRITE_STATS
if (tx_bytes == CHUNK_SIZE_C0)
update_write_max_chunk_stats(start_time);
@@ -359,26 +344,34 @@ static int qm357xx_rom_c0_flash_data(struct qmrom_handle *handle,
return 0;
}
-static int
-qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
- const struct unstitched_firmware *all_fws)
+static int qmrom_c0_flash_fw(struct qmrom_handle *handle,
+ const struct firmware *fw)
{
int rc = 0;
- uint8_t flash_cmd = handle->qm357xx_soc_info.lcs_state ==
- CC_BSV_SECURE_LCS ?
+ struct unstitched_firmware all_fws = { 0 };
+ uint8_t flash_cmd = handle->lcs_state == CC_BSV_SECURE_LCS ?
ROM_CMD_C0_SEC_LOAD_OEM_IMG_TO_RRAM :
ROM_CMD_C0_SEC_LOAD_ICV_IMG_TO_RRAM;
- if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
- handle->qm357xx_soc_info.lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
+ LOG_INFO("Unstitching the fw %p->data %p\n", (void *)fw,
+ (void *)fw->data);
+ rc = qmrom_unstitch_fw(fw, &all_fws, handle->chip_rev);
+ if (rc) {
+ LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
+ __func__);
+ return rc;
+ }
+
+ if (all_fws.key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
+ handle->lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
LOG_ERR("%s: Trying to flash an ICV fw on a non ICV platform\n",
__func__);
rc = -EINVAL;
goto end;
}
- if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
- handle->qm357xx_soc_info.lcs_state != CC_BSV_SECURE_LCS) {
+ if (all_fws.key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
+ handle->lcs_state != CC_BSV_SECURE_LCS) {
LOG_ERR("%s: Trying to flash an OEM fw on a non OEM platform\n",
__func__);
rc = -EINVAL;
@@ -388,30 +381,25 @@ qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
LOG_DBG("%s: starting...\n", __func__);
/* Set RRAM write mode */
- rc = qm357xx_rom_c0_wait_ready(handle);
+ rc = qmrom_c0_wait_ready(handle);
if (rc)
goto end;
- if (handle->chip_rev != CHIP_REVISION_C2) {
- LOG_DBG("%s: sending ROM_CMD_C0_USE_INDIRECT_RRAM_WR command (chip_rev %x)\n",
- __func__, handle->chip_rev);
- rc = qm357xx_rom_write_cmd32_c0(
- handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
- if (rc)
- goto end;
- }
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
+ if (rc)
+ goto end;
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
qmrom_pre_read_c0(handle);
qmrom_read_c0(handle);
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
LOG_DBG("%s: sending flash_cmd %u command\n", __func__, flash_cmd);
- rc = qm357xx_rom_write_cmd32_c0(handle, flash_cmd);
+ rc = qmrom_write_cmd32_c0(handle, flash_cmd);
if (rc)
goto end;
- qm357xx_rom_c0_poll_cmd_resp(handle);
+ qmrom_c0_poll_cmd_resp(handle);
if (handle->sstc->payload[0] != WAITING_FOR_FIRST_KEY_CERT) {
LOG_ERR("%s: Waiting for WAITING_FOR_FIRST_KEY_CERT(%#x) but got %#x\n",
__func__, WAITING_FOR_FIRST_KEY_CERT,
@@ -419,93 +407,65 @@ qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
goto end;
}
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
- rc = qm357xx_rom_c0_flash_data(handle, all_fws->key1_crt,
- ROM_CMD_C0_CERT_DATA,
- WAITING_FOR_SECOND_KEY_CERT, false);
+ rc = qmrom_c0_flash_data(handle, all_fws.key1_crt, ROM_CMD_C0_CERT_DATA,
+ WAITING_FOR_SECOND_KEY_CERT, false);
if (rc)
goto end;
- rc = qm357xx_rom_c0_flash_data(handle, all_fws->key2_crt,
- ROM_CMD_C0_CERT_DATA,
- WAITING_FOR_CONTENT_CERT, false);
+ rc = qmrom_c0_flash_data(handle, all_fws.key2_crt, ROM_CMD_C0_CERT_DATA,
+ WAITING_FOR_CONTENT_CERT, false);
if (rc)
goto end;
- rc = qm357xx_rom_c0_flash_data(handle, all_fws->fw_crt,
- ROM_CMD_C0_CERT_DATA,
- WAITING_FOR_SEC_FILE_DATA, false);
+ rc = qmrom_c0_flash_data(handle, all_fws.fw_crt, ROM_CMD_C0_CERT_DATA,
+ WAITING_FOR_SEC_FILE_DATA, false);
if (rc)
goto end;
- rc = qm357xx_rom_c0_flash_data(handle, all_fws->fw_img,
- ROM_CMD_C0_SEC_IMAGE_DATA,
- WAITING_FOR_SEC_FILE_DATA, true);
+ rc = qmrom_c0_flash_data(handle, all_fws.fw_img,
+ ROM_CMD_C0_SEC_IMAGE_DATA,
+ WAITING_FOR_SEC_FILE_DATA, true);
#ifdef C0_WRITE_STATS
dump_stats();
#endif
- if (qmrom_spi_read_irq_line(handle->ss_irq_handle)) {
- int retries = handle->comms_retries;
-
- do {
- /* A final product id error likely occurred */
- qmrom_pre_read_c0(handle);
- qmrom_read_c0(handle);
- rc = handle->sstc->payload[0];
- if (rc) {
- LOG_ERR("%s: flashing error %d (0x%x) detected\n",
- __func__, rc, rc);
- break;
- }
- } while (--retries);
-
- if (retries <= 0) {
- LOG_ERR("%s: flashing error detected but couldn't be fetched\n",
- __func__);
- rc = -1;
- }
- }
-
end:
- qmrom_free(all_fws->fw_img);
- qmrom_free(all_fws->fw_crt);
- qmrom_free(all_fws->key1_crt);
- qmrom_free(all_fws->key2_crt);
+ qmrom_free(all_fws.fw_img);
+ qmrom_free(all_fws.fw_crt);
+ qmrom_free(all_fws.key1_crt);
+ qmrom_free(all_fws.key2_crt);
return rc;
}
-static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
- struct firmware *dbg_cert)
+static int qmrom_c0_flash_debug_cert(struct qmrom_handle *handle,
+ struct firmware *dbg_cert)
{
int rc;
LOG_DBG("%s: starting...\n", __func__);
- rc = qm357xx_rom_c0_wait_ready(handle);
+ rc = qmrom_c0_wait_ready(handle);
if (rc)
return rc;
- if (handle->chip_rev != CHIP_REVISION_C2) {
- LOG_DBG("%s: using ROM_CMD_C0_USE_INDIRECT_RRAM_WR command\n",
- __func__);
- rc = qm357xx_rom_write_cmd32_c0(
- handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
- if (rc)
- return rc;
- }
+ LOG_DBG("%s: sending ROM_CMD_C0_USE_DIRECT_RRAM_WR command\n",
+ __func__);
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
+ if (rc)
+ return rc;
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
qmrom_pre_read_c0(handle);
qmrom_read_c0(handle);
- qm357xx_rom_c0_poll_soc(handle);
+ qmrom_c0_poll_soc(handle);
LOG_DBG("%s: sending ROM_CMD_C0_WRITE_DBG_CERT command\n", __func__);
- rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_WRITE_DBG_CERT);
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_WRITE_DBG_CERT);
if (rc)
return rc;
- qm357xx_rom_c0_poll_cmd_resp(handle);
+ qmrom_c0_poll_cmd_resp(handle);
if (handle->sstc->payload[0] != WAITING_TO_DEBUG_CERTIFICATE_SIZE) {
LOG_ERR("%s: Waiting for WAITING_TO_DEBUG_CERTIFICATE_SIZE(%#x) but got %#x\n",
__func__, WAITING_TO_DEBUG_CERTIFICATE_SIZE,
@@ -514,10 +474,10 @@ static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
}
LOG_DBG("%s: sending ROM_CMD_C0_DEBUG_CERT_SIZE command\n", __func__);
- rc = qm357xx_rom_write_size_cmd32_c0(handle, ROM_CMD_C0_DEBUG_CERT_SIZE,
- sizeof(uint32_t),
- (const char *)&dbg_cert->size);
- qm357xx_rom_c0_poll_cmd_resp(handle);
+ rc = qmrom_write_size_cmd32_c0(handle, ROM_CMD_C0_DEBUG_CERT_SIZE,
+ sizeof(uint32_t),
+ (const char *)&dbg_cert->size);
+ qmrom_c0_poll_cmd_resp(handle);
if (handle->sstc->payload[0] != WAITING_FOR_DEBUG_CERT_DATA) {
LOG_ERR("%s: Waiting for WAITING_FOR_DEBUG_CERT_DATA(%#x) but got %#x\n",
__func__, WAITING_FOR_DEBUG_CERT_DATA,
@@ -525,23 +485,23 @@ static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
return rc;
}
- rc = qm357xx_rom_c0_flash_data(handle, dbg_cert, ROM_CMD_C0_CERT_DATA,
- WAITING_FOR_DEBUG_CERT_DATA, true);
+ rc = qmrom_c0_flash_data(handle, dbg_cert, ROM_CMD_C0_CERT_DATA,
+ WAITING_FOR_DEBUG_CERT_DATA, true);
return 0;
}
-static int qm357xx_rom_c0_erase_debug_cert(struct qmrom_handle *handle)
+static int qmrom_c0_erase_debug_cert(struct qmrom_handle *handle)
{
int rc;
LOG_DBG("%s: starting...\n", __func__);
- rc = qm357xx_rom_c0_wait_ready(handle);
+ rc = qmrom_c0_wait_ready(handle);
if (rc)
return rc;
LOG_DBG("%s: sending ROM_CMD_C0_ERASE_DBG_CERT command\n", __func__);
- rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_ERASE_DBG_CERT);
+ rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_ERASE_DBG_CERT);
if (rc)
return rc;
diff --git a/libqmrom/src/qmrom_common.c b/libqmrom/src/qmrom_common.c
index 017b346..58ca662 100644
--- a/libqmrom/src/qmrom_common.c
+++ b/libqmrom/src/qmrom_common.c
@@ -10,7 +10,9 @@
#include <qmrom.h>
#include <spi_rom_protocol.h>
-int qm357xx_rom_probe_device(struct qmrom_handle *handle);
+int qmrom_a0_probe_device(struct qmrom_handle *handle);
+int qmrom_b0_probe_device(struct qmrom_handle *handle);
+int qmrom_c0_probe_device(struct qmrom_handle *handle);
static void qmrom_free_stcs(struct qmrom_handle *h)
{
@@ -98,28 +100,93 @@ int qmrom_read(struct qmrom_handle *handle)
sizeof(struct stc) + rd_size);
}
+int qmrom_write_cmd(struct qmrom_handle *handle, uint8_t cmd)
+{
+ handle->hstc->all = 0;
+ handle->hstc->host_flags.write = 1;
+ handle->hstc->ul = 1;
+ handle->hstc->len = 1;
+ handle->hstc->payload[0] = cmd;
+
+ return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc,
+ sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd)
+{
+ handle->hstc->all = 0;
+ handle->hstc->host_flags.write = 1;
+ handle->hstc->ul = 1;
+ handle->hstc->len = sizeof(cmd);
+ memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
+
+ return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc,
+ sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
+ uint16_t data_size, const char *data)
+{
+ handle->hstc->all = 0;
+ handle->hstc->host_flags.write = 1;
+ handle->hstc->ul = 1;
+ handle->hstc->len = data_size + 1;
+ handle->hstc->payload[0] = cmd;
+ memcpy(&handle->hstc->payload[1], data, data_size);
+
+ return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc,
+ sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
+ uint16_t data_size, const char *data)
+{
+ handle->hstc->all = 0;
+ handle->hstc->host_flags.write = 1;
+ handle->hstc->ul = 1;
+ handle->hstc->len = data_size + sizeof(cmd);
+ memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
+ memcpy(&handle->hstc->payload[sizeof(cmd)], data, data_size);
+
+ return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+ (const char *)handle->hstc,
+ sizeof(struct stc) + handle->hstc->len);
+}
+
/*
* Unfortunately, A0, B0 and C0 have different
* APIs to get the chip version...
*
*/
-int qmrom_probe_device(struct qmrom_handle *handle,
- enum device_generation_e dev_gen_hint)
+int qmrom_probe_device(struct qmrom_handle *handle)
{
- int rc = -1;
+ int rc;
- if (dev_gen_hint == DEVICE_GEN_QM357XX ||
- dev_gen_hint == DEVICE_GEN_UNKNOWN)
- rc = qm357xx_rom_probe_device(handle);
+ /* Test B0 first */
+ rc = qmrom_b0_probe_device(handle);
+ if (!rc)
+ return rc;
- return rc;
+ /* Test C0 next */
+ rc = qmrom_c0_probe_device(handle);
+ if (!rc)
+ return rc;
+
+ /* Finally try A0 */
+ rc = qmrom_a0_probe_device(handle);
+ if (!rc)
+ return rc;
+
+ /* None matched!!! */
+ return -1;
}
struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
- void *ss_rdy_handle, void *ss_irq_handle,
- int spi_speed, int comms_retries,
- reset_device_fn reset,
- enum device_generation_e dev_gen_hint)
+ void *ss_rdy_handle, int comms_retries,
+ reset_device_fn reset)
{
struct qmrom_handle *handle;
int rc;
@@ -140,15 +207,14 @@ struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
handle->spi_handle = spi_handle;
handle->reset_handle = reset_handle;
handle->ss_rdy_handle = ss_rdy_handle;
- handle->ss_irq_handle = ss_irq_handle;
handle->comms_retries = comms_retries;
handle->chip_rev = CHIP_REVISION_UNKNOWN;
handle->device_version = -1;
- handle->spi_speed = spi_speed;
+ handle->lcs_state = -1;
handle->dev_ops.reset = reset;
- rc = qmrom_probe_device(handle, dev_gen_hint);
+ rc = qmrom_probe_device(handle);
if (rc) {
LOG_ERR("%s: qmrom_probe_device returned %d!\n", __func__, rc);
qmrom_free_stcs(handle);
@@ -167,6 +233,173 @@ void qmrom_deinit(struct qmrom_handle *handle)
qmrom_free(handle);
}
+int qmrom_flash_dbg_cert(struct qmrom_handle *handle, struct firmware *dbg_cert)
+{
+ if (!handle->rom_ops.flash_debug_cert) {
+ LOG_ERR("%s: flash debug certificate not support on this device\n",
+ __func__);
+ return -EINVAL;
+ }
+ return handle->rom_ops.flash_debug_cert(handle, dbg_cert);
+}
+
+int qmrom_erase_dbg_cert(struct qmrom_handle *handle)
+{
+ if (!handle->rom_ops.erase_debug_cert) {
+ LOG_ERR("%s: erase debug certificate not support on this device\n",
+ __func__);
+ return -EINVAL;
+ }
+ return handle->rom_ops.erase_debug_cert(handle);
+}
+
+int qmrom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw)
+{
+ return handle->rom_ops.flash_fw(handle, fw);
+}
+
+int qmrom_flash_unstitched_fw(struct qmrom_handle *handle,
+ const struct unstitched_firmware *fw)
+{
+ return handle->rom_ops.flash_unstitched_fw(handle, fw);
+}
+
+int qmrom_unstitch_fw(const struct firmware *fw,
+ struct unstitched_firmware *unstitched_fw,
+ enum chip_revision_e revision)
+{
+ uint32_t tot_len = 0;
+ uint32_t fw_img_sz = 0;
+ uint32_t fw_crt_sz = 0;
+ uint32_t key1_crt_sz = 0;
+ uint32_t key2_crt_sz = 0;
+ uint8_t *p_key1;
+ uint8_t *p_key2;
+ uint8_t *p_crt;
+ uint8_t *p_fw;
+ int ret = 0;
+
+ if (revision == CHIP_REVISION_A0) {
+ LOG_ERR("%s: A0, no unstitching!!!\n", __func__);
+ return -EINVAL;
+ }
+ if (fw->size < 2 * sizeof(key1_crt_sz)) {
+ LOG_ERR("%s: Not enough data (%zu) to unstitch\n", __func__,
+ fw->size);
+ return -EINVAL;
+ }
+ LOG_INFO("%s: Unstitching %zu bytes\n", __func__, fw->size);
+
+ /* key1 */
+ key1_crt_sz = *(uint32_t *)&fw->data[tot_len];
+ if (tot_len + key1_crt_sz + sizeof(key1_crt_sz) > fw->size) {
+ LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+ %" PRIu32 " (key1)\n",
+ __func__, tot_len);
+ ret = -EINVAL;
+ goto out;
+ }
+ tot_len += sizeof(key1_crt_sz);
+ p_key1 = (uint8_t *)&fw->data[tot_len];
+ tot_len += key1_crt_sz;
+
+ /* key2 */
+ key2_crt_sz = *(uint32_t *)&fw->data[tot_len];
+ if (tot_len + key2_crt_sz + sizeof(key2_crt_sz) > fw->size) {
+ LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+ %" PRIu32 " (key2)\n",
+ __func__, tot_len);
+ ret = -EINVAL;
+ goto out;
+ }
+ tot_len += sizeof(key2_crt_sz);
+ p_key2 = (uint8_t *)&fw->data[tot_len];
+ tot_len += key2_crt_sz;
+
+ /* cert */
+ fw_crt_sz = *(uint32_t *)&fw->data[tot_len];
+ if (tot_len + fw_crt_sz + sizeof(fw_crt_sz) > fw->size) {
+ LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+ %" PRIu32 " (content cert)\n",
+ __func__, tot_len);
+ ret = -EINVAL;
+ goto out;
+ }
+ tot_len += sizeof(fw_crt_sz);
+ p_crt = (uint8_t *)&fw->data[tot_len];
+ tot_len += fw_crt_sz;
+
+ /* fw */
+ fw_img_sz = *(uint32_t *)&fw->data[tot_len];
+ if (tot_len + fw_img_sz + sizeof(fw_img_sz) != fw->size) {
+ LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+ %" PRIu32 " (firmnware)\n",
+ __func__, tot_len);
+ ret = -EINVAL;
+ goto out;
+ }
+ tot_len += sizeof(fw_img_sz);
+ p_fw = (uint8_t *)&fw->data[tot_len];
+
+ qmrom_alloc(unstitched_fw->fw_img, fw_img_sz + sizeof(struct firmware));
+ if (unstitched_fw->fw_img == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ qmrom_alloc(unstitched_fw->fw_crt, fw_crt_sz + sizeof(struct firmware));
+ if (unstitched_fw->fw_crt == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ qmrom_alloc(unstitched_fw->key1_crt,
+ key1_crt_sz + sizeof(struct firmware));
+ if (unstitched_fw->key1_crt == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ qmrom_alloc(unstitched_fw->key2_crt,
+ key2_crt_sz + sizeof(struct firmware));
+ if (unstitched_fw->key2_crt == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ unstitched_fw->key1_crt->data =
+ (const uint8_t *)(unstitched_fw->key1_crt + 1);
+ unstitched_fw->key2_crt->data =
+ (const uint8_t *)(unstitched_fw->key2_crt + 1);
+ unstitched_fw->fw_crt->data =
+ (const uint8_t *)(unstitched_fw->fw_crt + 1);
+ unstitched_fw->fw_img->data =
+ (const uint8_t *)(unstitched_fw->fw_img + 1);
+ unstitched_fw->key1_crt->size = key1_crt_sz;
+ unstitched_fw->key2_crt->size = key2_crt_sz;
+ unstitched_fw->fw_crt->size = fw_crt_sz;
+ unstitched_fw->fw_img->size = fw_img_sz;
+
+ memcpy((void *)unstitched_fw->key1_crt->data, p_key1, key1_crt_sz);
+ memcpy((void *)unstitched_fw->key2_crt->data, p_key2, key2_crt_sz);
+ memcpy((void *)unstitched_fw->fw_crt->data, p_crt, fw_crt_sz);
+ memcpy((void *)unstitched_fw->fw_img->data, p_fw, fw_img_sz);
+ return 0;
+
+err:
+ if (unstitched_fw->fw_img)
+ qmrom_free(unstitched_fw->fw_img);
+ if (unstitched_fw->fw_crt)
+ qmrom_free(unstitched_fw->fw_crt);
+ if (unstitched_fw->key1_crt)
+ qmrom_free(unstitched_fw->key1_crt);
+ if (unstitched_fw->key2_crt)
+ qmrom_free(unstitched_fw->key2_crt);
+
+out:
+ return ret;
+}
+
int qmrom_reboot_bootloader(struct qmrom_handle *handle)
{
int rc;
diff --git a/qm35-spi.c b/qm35-spi.c
index c39f944..054518f 100644
--- a/qm35-spi.c
+++ b/qm35-spi.c
@@ -26,7 +26,6 @@
* QM35 UCI over HSSPI protocol
*/
-#include <linux/version.h>
#include <linux/bitfield.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
@@ -50,8 +49,6 @@
#include <qmrom_log.h>
#include <spi_rom_protocol.h>
-#include <fwupdater.h>
-
#include "qm35.h"
#include "uci_ioctls.h"
#include "hsspi.h"
@@ -60,8 +57,6 @@
#define QM35_REGULATOR_DELAY_US 1000
#define QMROM_RETRIES 10
-#define FLASHING_RETRIES 10 /* Intentionaly high value */
-/* Redefine certificate error here since original definitions are separate */
#define REGULATORS_ENABLED(x) (x->vdd1 || x->vdd2 || x->vdd3 || x->vdd4)
#ifndef NO_UWB_HAL
@@ -83,8 +78,8 @@ static bool flash_on_probe = false;
module_param(flash_on_probe, bool, 0444);
MODULE_PARM_DESC(flash_on_probe, "Flash during the module probe");
-int spi_speed_hz;
-module_param(spi_speed_hz, int, 0644);
+static int spi_speed_hz;
+module_param(spi_speed_hz, int, 0444);
MODULE_PARM_DESC(spi_speed_hz, "SPI speed (if not set use DTS's one)");
static char *fwname = NULL;
@@ -92,11 +87,11 @@ module_param(fwname, charp, 0444);
MODULE_PARM_DESC(fwname, "Use fwname as firmware binary to flash QM35");
static bool wake_use_wakeup = true;
-module_param(wake_use_wakeup, bool, 0644);
+module_param(wake_use_wakeup, bool, 0444);
MODULE_PARM_DESC(wake_use_wakeup, "Use wakeup pin to wake up QM35");
static bool wake_use_csn = false;
-module_param(wake_use_csn, bool, 0644);
+module_param(wake_use_csn, bool, 0444);
MODULE_PARM_DESC(wake_use_csn, "Use HSSPI CSn pin to wake up QM35");
static bool wake_on_ssirq = true;
@@ -105,34 +100,22 @@ MODULE_PARM_DESC(wake_on_ssirq,
"Allow QM35 to wakeup the platform using ss_irq");
int trace_spi_xfers;
-module_param(trace_spi_xfers, int, 0644);
+module_param(trace_spi_xfers, int, 0444);
MODULE_PARM_DESC(trace_spi_xfers, "Trace all the SPI transfers");
int qmrom_retries = QMROM_RETRIES;
-module_param(qmrom_retries, int, 0644);
+module_param(qmrom_retries, int, 0444);
MODULE_PARM_DESC(qmrom_retries, "QMROM retries");
-int flashing_retries = FLASHING_RETRIES;
-module_param(flashing_retries, int, 0644);
-MODULE_PARM_DESC(flashing_retries, "Flashing retries");
-
int reset_on_error = 1;
-module_param(reset_on_error, int, 0644);
+module_param(reset_on_error, int, 0444);
MODULE_PARM_DESC(reset_on_error, "Reset the QM35 on successive errors");
int log_qm_traces = 1;
module_param(log_qm_traces, int, 0444);
MODULE_PARM_DESC(log_qm_traces, "Logs the QM35 traces in the kernel messages");
-int fu_spi_speed_hz;
-module_param(fu_spi_speed_hz, int, 0644);
-MODULE_PARM_DESC(fu_spi_speed_hz, "FW updater SPI speed");
-
-int qmrom_spi_speed_hz;
-module_param(qmrom_spi_speed_hz, int, 0644);
-MODULE_PARM_DESC(qmrom_spi_speed_hz, "FW updater SPI speed");
-
-static uint8_t qm_soc_id[QM357XX_ROM_SOC_ID_LEN];
+static uint8_t qm_soc_id[ROM_SOC_ID_LEN];
static uint16_t qm_dev_id;
/*
@@ -374,13 +357,8 @@ static irqreturn_t qm35_ss_rdy_handler(int irq, void *data)
if (wake_use_wakeup)
gpiod_set_value(qm35_hdl->gpio_wakeup, 0);
- if (!qm35_hdl->flashing) {
- hsspi_clear_spi_slave_busy(&qm35_hdl->hsspi);
- hsspi_set_spi_slave_ready(&qm35_hdl->hsspi);
- } else {
- qm35_hdl->qmrom_qm_ready = true;
- wake_up_interruptible(&qm35_hdl->qmrom_wq_ready);
- }
+ hsspi_clear_spi_slave_busy(&qm35_hdl->hsspi);
+ hsspi_set_spi_slave_ready(&qm35_hdl->hsspi);
return IRQ_HANDLED;
}
@@ -478,133 +456,25 @@ int qm35_reset_sync(struct qm35_ctx *qm35_hdl)
return ret;
}
-static int qm_firmware_flash_fw(struct qm35_ctx *qm35_hdl,
- struct qmrom_handle *h,
- const struct firmware *fw)
-{
- int rc = 0, nb_retries = FLASHING_RETRIES;
- do {
- /* If the previous flashing failed, re-enter the QM
- * rom code so it will be in the same initial state
- */
- if (rc)
- qmrom_reboot_bootloader(h);
-
- rc = qm357xx_rom_flash_fw(h, fw);
- if (rc)
- dev_err(&qm35_hdl->spi->dev,
- "Attempt %d: flashing failed with %d!\n",
- FLASHING_RETRIES - nb_retries, rc);
- if (rc == PEG_ERR_FIRST_KEY_CERT_OR_FW_VER)
- break;
- } while (rc && --nb_retries > 0);
- return rc;
-}
-
-static int qm_firmware_flash_macro_pkg(struct qm35_ctx *qm35_hdl,
- struct qmrom_handle *h,
- const struct firmware *fw)
-{
- int rc, nb_retries = FLASHING_RETRIES;
- char *fw_data;
- uint32_t fw_size;
-
- rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 1, &fw_size, &fw_data);
- if (rc) {
- dev_err(&qm35_hdl->spi->dev,
- "FW MACRO PACKAGE corrupted = %d\n", rc);
- return rc;
- }
- if (*(uint32_t *)fw_data != CRYPTO_FIRMWARE_PACK_MAGIC_VALUE) {
- rc = -EINVAL;
- dev_err(&qm35_hdl->spi->dev,
- "FW PACKAGE not found - magic is %04x, size is %d\n",
- *(uint32_t *)fw_data, fw_size);
- return rc;
- }
-
- do {
- /* If the previous flashing failed, re-enter the QM
- * rom code so it will be in the same initial state
- */
- if (spi_speed_hz)
- qmrom_spi_set_freq(spi_speed_hz);
- else
- qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
-
- if (rc)
- qmrom_reboot_bootloader(h);
-
- /* The Macro Package contain the fw updater and the package
- * simply flash the first and provide the second to
- * the updater lib
- */
- rc = qm357xx_rom_flash_fw(h, fw);
- if (rc) {
- dev_err(&qm35_hdl->spi->dev,
- "Attempt %d: fw updater flashing failed with %d!\n",
- FLASHING_RETRIES - nb_retries, rc);
- if (rc == PEG_ERR_FIRST_KEY_CERT_OR_FW_VER)
- break;
- continue;
- }
-
- /* Now flash the firmware proper */
- if (fu_spi_speed_hz)
- qmrom_spi_set_freq(fu_spi_speed_hz);
- else
- qmrom_spi_set_freq(FWUPDATER_SPI_SPEED_HZ);
- rc = run_fwupdater(h, fw_data, fw_size);
- if (rc) {
- dev_err(&qm35_hdl->spi->dev,
- "Attempt %d: fw app flashing failed with %d!\n",
- FLASHING_RETRIES - nb_retries, rc);
- }
- } while (rc && --nb_retries > 0);
- return rc;
-}
-
static int qm_firmware_flashing(void *handle, struct qmrom_handle *h,
- bool *is_macro_pkg, bool use_prod_fw)
+ bool use_prod_fw)
{
struct qm35_ctx *qm35_hdl = (struct qm35_ctx *)handle;
struct spi_device *spi = qm35_hdl->spi;
- int rc = 0;
const struct firmware *fw;
-#ifdef C0_WRITE_STATS
- uint64_t elapsed_time_ns;
- ktime_t start_time;
-#endif
+ int ret = 0;
- fw = qmrom_spi_get_firmware(&spi->dev, h, is_macro_pkg, use_prod_fw);
+ fw = qmrom_spi_get_firmware(&spi->dev, h, use_prod_fw);
if (fw == NULL) {
dev_err(&spi->dev, "Firmware file not present!\n");
return -1;
}
-#ifdef C0_WRITE_STATS
- start_time = ktime_get();
-#endif
-
- qm35_hdl->flashing = true;
- if (!*is_macro_pkg)
- rc = qm_firmware_flash_fw(qm35_hdl, h, fw);
- else
- rc = qm_firmware_flash_macro_pkg(qm35_hdl, h, fw);
-
-#ifdef C0_WRITE_STATS
- elapsed_time_ns = ktime_to_ns(ktime_sub(ktime_get(), start_time));
- if (!rc)
- dev_warn(&spi->dev, "Fw_updater flashed in %llu us\n",
- div_u64(elapsed_time_ns, 1000));
-#endif
+ ret = qmrom_flash_fw(h, fw);
+ dev_dbg(&spi->dev, "Return qmrom_flash_fw = %d!\n", ret);
qmrom_spi_release_firmware(fw);
- qm35_hdl->flashing = false;
-
- /* Reset the device anyway */
- qmrom_spi_reset_device(qm35_hdl);
- return rc;
+ return ret;
}
static int qm_firmware_load(struct qm35_ctx *qm35_hdl)
@@ -612,19 +482,14 @@ static int qm_firmware_load(struct qm35_ctx *qm35_hdl)
struct spi_device *spi = qm35_hdl->spi;
unsigned int state = qm35_get_state(qm35_hdl);
struct qmrom_handle *h;
- bool is_macro_pkg = false;
- int ret, irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
+ int ret;
qm35_set_state(qm35_hdl, QM35_CTRL_STATE_FW_DOWNLOADING);
qmrom_set_log_device(&spi->dev, LOG_WARN);
- if (irq >= 0)
- enable_irq(irq);
-
- h = qmrom_init(&spi->dev, qm35_hdl, qm35_hdl, qm35_hdl->gpio_ss_irq,
- qmrom_spi_speed_hz, qmrom_retries,
- qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+ h = qmrom_init(&spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+ qmrom_retries, qmrom_spi_reset_device);
if (!h) {
pr_err("qmrom_init failed\n");
ret = -1;
@@ -635,16 +500,14 @@ static int qm_firmware_load(struct qm35_ctx *qm35_hdl)
dev_info(&spi->dev, " dev_id: deca%04x\n", h->device_version);
if (h->chip_rev != CHIP_REVISION_A0) {
- dev_info(&spi->dev, " soc_id: %*phN\n",
- QM357XX_ROM_SOC_ID_LEN, h->qm357xx_soc_info.soc_id);
- dev_info(&spi->dev, " uuid: %*phN\n",
- QM357XX_ROM_UUID_LEN, h->qm357xx_soc_info.uuid);
- dev_info(&spi->dev, " lcs_state: %u\n",
- h->qm357xx_soc_info.lcs_state);
+ dev_info(&spi->dev, " soc_id: %*phN\n", ROM_SOC_ID_LEN,
+ h->soc_id);
+ dev_info(&spi->dev, " uuid: %*phN\n", ROM_UUID_LEN,
+ h->uuid);
+ dev_info(&spi->dev, " lcs_state: %u\n", h->lcs_state);
memcpy(&qm_dev_id, &h->device_version, sizeof(qm_dev_id));
- memcpy(qm_soc_id, h->qm357xx_soc_info.soc_id,
- QM357XX_ROM_SOC_ID_LEN);
+ memcpy(qm_soc_id, h->soc_id, ROM_SOC_ID_LEN);
debug_soc_info_available(&qm35_hdl->debug);
} else {
@@ -653,21 +516,18 @@ static int qm_firmware_load(struct qm35_ctx *qm35_hdl)
}
dev_dbg(&spi->dev, "Starting device flashing!\n");
- ret = qm_firmware_flashing(qm35_hdl, h, &is_macro_pkg, true);
+ ret = qm_firmware_flashing(qm35_hdl, h, true);
if (ret) {
qmrom_reboot_bootloader(h);
- ret = qm_firmware_flashing(qm35_hdl, h, &is_macro_pkg, false);
+ ret = qm_firmware_flashing(qm35_hdl, h, false);
}
if (ret)
dev_err(&spi->dev, "Firmware download failed with %d!\n", ret);
else
- dev_info(&spi->dev, "Device flashing succeeded!\n");
+ dev_info(&spi->dev, "Device flashing completed!\n");
out:
- if (irq >= 0)
- disable_irq_nosync(irq);
-
qm35_set_state(qm35_hdl, state);
return ret;
@@ -682,7 +542,7 @@ int qm_get_dev_id(struct qm35_ctx *qm35_hdl, uint16_t *dev_id)
int qm_get_soc_id(struct qm35_ctx *qm35_hdl, uint8_t *soc_id)
{
- memcpy(soc_id, qm_soc_id, QM357XX_ROM_SOC_ID_LEN);
+ memcpy(soc_id, qm_soc_id, ROM_SOC_ID_LEN);
return 0;
}
@@ -707,7 +567,8 @@ int qm_get_soc_id(struct qm35_ctx *qm35_hdl, uint8_t *soc_id)
*/
static int hsspi_irqs_setup(struct qm35_ctx *qm35_ctx)
{
- int ret, irq;
+ int ret;
+ unsigned long ss_irqflags;
/* Get READY GPIO */
qm35_ctx->gpio_ss_rdy =
@@ -715,47 +576,25 @@ static int hsspi_irqs_setup(struct qm35_ctx *qm35_ctx)
if (IS_ERR(qm35_ctx->gpio_ss_rdy))
return PTR_ERR(qm35_ctx->gpio_ss_rdy);
- irq = gpiod_to_irq(qm35_ctx->gpio_ss_rdy);
- if (irq < 0) {
- dev_err(&qm35_ctx->spi->dev,
- "%s: gpiod_to_irq(ss-ready) returns %d", __func__, irq);
- return irq;
- }
- ret = devm_request_irq(&qm35_ctx->spi->dev, irq, &qm35_ss_rdy_handler,
- IRQF_TRIGGER_RISING, "hsspi-ss-rdy", qm35_ctx);
- if (ret) {
- dev_err(&qm35_ctx->spi->dev, "%s: devm_request_irq returned %d",
- __func__, ret);
+ ret = devm_request_irq(&qm35_ctx->spi->dev,
+ gpiod_to_irq(qm35_ctx->gpio_ss_rdy),
+ &qm35_ss_rdy_handler, IRQF_TRIGGER_RISING,
+ "hsspi-ss-rdy", qm35_ctx);
+ if (ret)
return ret;
- }
- /* devm_request_irq enables the interrupt. On probe, the hsspi is in
- * HSSPI_STOPPED state by default. In this state, the interrupt is
- * expected to be disabled. */
- disable_irq(irq);
/* get SS_IRQ GPIO */
- qm35_ctx->gpio_ss_irq =
- devm_gpiod_get(&qm35_ctx->spi->dev, "ss-irq", GPIOD_IN);
- if (IS_ERR(qm35_ctx->gpio_ss_irq)) {
- dev_err(&qm35_ctx->spi->dev,
- "%s: gpiod_get_index(ss-irq) returned %pK", __func__,
- qm35_ctx->gpio_ss_irq);
- }
+ qm35_ctx->gpio_ss_irq = devm_gpiod_get_optional(&qm35_ctx->spi->dev,
+ "ss-irq", GPIOD_IN);
- qm35_ctx->spi->irq = gpiod_to_irq(qm35_ctx->gpio_ss_irq);
- if (qm35_ctx->spi->irq < 0) {
- dev_err(&qm35_ctx->spi->dev,
- "%s: gpiod_to_irq(ss-irq) returned %d", __func__,
- qm35_ctx->spi->irq);
- return qm35_ctx->spi->irq;
- }
- ret = devm_request_irq(&qm35_ctx->spi->dev, qm35_ctx->spi->irq,
- &qm35_irq_handler, IRQF_TRIGGER_HIGH,
- "hsspi-ss-irq", qm35_ctx);
- if (ret) {
- dev_err(&qm35_ctx->spi->dev, "%s: devm_request_irq returned %d",
- __func__, ret);
- return ret;
+ if (qm35_ctx->gpio_ss_irq) {
+ if (IS_ERR(qm35_ctx->gpio_ss_irq))
+ return PTR_ERR(qm35_ctx->gpio_ss_irq);
+
+ qm35_ctx->spi->irq = gpiod_to_irq(qm35_ctx->gpio_ss_irq);
+ ss_irqflags = IRQF_TRIGGER_HIGH;
+ } else {
+ ss_irqflags = irq_get_trigger_type(qm35_ctx->spi->irq);
}
if (wake_on_ssirq) {
@@ -769,6 +608,12 @@ static int hsspi_irqs_setup(struct qm35_ctx *qm35_ctx)
qm35_ctx->hsspi.wakeup = qm35_wakeup;
qm35_ctx->hsspi.reset_qm35 = qm35_reset_hook;
+ ret = devm_request_irq(&qm35_ctx->spi->dev, qm35_ctx->spi->irq,
+ &qm35_irq_handler, ss_irqflags, "hsspi-ss-irq",
+ qm35_ctx);
+ if (ret)
+ return ret;
+
/* Get exton */
qm35_ctx->gpio_exton =
devm_gpiod_get_optional(&qm35_ctx->spi->dev, "exton", GPIOD_IN);
@@ -916,7 +761,6 @@ static int qm35_probe(struct spi_device *spi)
qm35_ctx->spi = spi;
qm35_ctx->log_qm_traces = log_qm_traces;
spin_lock_init(&qm35_ctx->lock);
- init_waitqueue_head(&qm35_ctx->qmrom_wq_ready);
spi_set_drvdata(spi, qm35_ctx);
@@ -998,11 +842,11 @@ static int qm35_probe(struct spi_device *spi)
if (!NO_UWB_HAL) {
/* If regulators not available, QM is powered on */
if (!REGULATORS_ENABLED(qm35_ctx))
- qm35_hsspi_start(qm35_ctx);
+ hsspi_start(&qm35_ctx->hsspi);
} else {
qm35_regulators_set(qm35_ctx, true);
usleep_range(100000, 100000);
- qm35_hsspi_start(qm35_ctx);
+ hsspi_start(&qm35_ctx->hsspi);
}
ret = misc_register(&qm35_ctx->uci_dev);
@@ -1043,7 +887,7 @@ static int qm35_remove(struct spi_device *spi)
misc_deregister(&qm35_hdl->uci_dev);
- qm35_hsspi_stop(qm35_hdl);
+ hsspi_stop(&qm35_hdl->hsspi);
hsspi_unregister(&qm35_hdl->hsspi, &qm35_hdl->log_layer.hlayer);
hsspi_unregister(&qm35_hdl->hsspi, &qm35_hdl->coredump_layer.hlayer);
diff --git a/qm35.h b/qm35.h
index 7bc3d70..59cf825 100644
--- a/qm35.h
+++ b/qm35.h
@@ -4,7 +4,6 @@
#define __QM35_H___
#include <linux/gpio.h>
-#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/spinlock.h>
@@ -17,9 +16,6 @@
#include "hsspi_log.h"
#include "debug.h"
-#define FWUPDATER_SPI_SPEED_HZ 20000000
-#define DEFAULT_SPI_CLOCKRATE 3000000
-
#define DEBUG_CERTIFICATE_SIZE 2560
#define QM_RESET_LOW_MS 2
/*
@@ -28,7 +24,7 @@
#define QM_BOOT_MS 450
#define QM_BEFORE_RESET_MS 450
-#define DRV_VERSION "7.2.0-rc6"
+#define DRV_VERSION "6.3.8-rc1"
struct regulator;
@@ -61,11 +57,6 @@ struct qm35_ctx {
struct regulator *vdd4;
bool regulators_enabled;
bool log_qm_traces;
-
- /* qmrom support */
- struct wait_queue_head qmrom_wq_ready;
- bool qmrom_qm_ready;
- bool flashing;
};
static inline unsigned int qm35_get_state(struct qm35_ctx *qm35_hdl)
diff --git a/qmrom_spi.c b/qmrom_spi.c
index 76ce52e..0592d2f 100644
--- a/qmrom_spi.c
+++ b/qmrom_spi.c
@@ -26,7 +26,6 @@
* QM35 FW ROM protocol SPI ops
*/
-#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <qmrom_spi.h>
@@ -34,12 +33,6 @@
#include "qm35.h"
-/* TODO Compile QM358XX code */
-int qm358xx_rom_probe_device(struct qmrom_handle *handle)
-{
- return -1;
-}
-
static const char *fwname = NULL;
static unsigned int speed_hz;
extern int trace_spi_xfers;
@@ -52,7 +45,6 @@ void qmrom_set_fwname(const char *name)
int qmrom_spi_transfer(void *handle, char *rbuf, const char *wbuf, size_t size)
{
struct spi_device *spi = (struct spi_device *)handle;
- struct qm35_ctx *qm35_ctx = spi_get_drvdata(spi);
int rc;
struct spi_transfer xfer[] = {
@@ -64,14 +56,13 @@ int qmrom_spi_transfer(void *handle, char *rbuf, const char *wbuf, size_t size)
},
};
- qm35_ctx->qmrom_qm_ready = false;
rc = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
if (trace_spi_xfers) {
- print_hex_dump(KERN_DEBUG, "qm35 tx:", DUMP_PREFIX_NONE, 16, 1,
- wbuf, size, false);
- print_hex_dump(KERN_DEBUG, "qm35 rx:", DUMP_PREFIX_NONE, 16, 1,
- rbuf, size, false);
+ print_hex_dump(KERN_DEBUG, "tx:", DUMP_PREFIX_NONE, 16, 1, wbuf,
+ size, false);
+ print_hex_dump(KERN_DEBUG, "rx:", DUMP_PREFIX_NONE, 16, 1, rbuf,
+ size, false);
}
return rc;
@@ -103,25 +94,26 @@ int qmrom_spi_reset_device(void *reset_handle)
const struct firmware *qmrom_spi_get_firmware(void *handle,
struct qmrom_handle *qmrom_h,
- bool *is_macro_pkg,
bool use_prod_fw)
{
const struct firmware *fw;
struct spi_device *spi = handle;
- const char *fw_name;
+ char _fw_name[16]; /* enough room to store "qm35_xx_xxx.bin" */
+ const char *fw_name = _fw_name;
int ret;
- uint32_t lcs_state = qmrom_h->qm357xx_soc_info.lcs_state;
+ enum chip_revision_e revision = qmrom_h->chip_rev;
+ int lcs_state = qmrom_h->lcs_state;
if (!fwname) {
- if (lcs_state != CC_BSV_SECURE_LCS) {
- dev_warn(&spi->dev, "LCS state is not secure.");
- }
-
- if (use_prod_fw)
- fw_name = "qm35_fw_pkg_prod.bin";
- else
- fw_name = "qm35_fw_pkg.bin";
- *is_macro_pkg = true;
+ if (revision == CHIP_REVISION_A0)
+ fw_name = "qm35_a0.bin";
+ else if (lcs_state == CC_BSV_SECURE_LCS) {
+ if (use_prod_fw)
+ fw_name = "qm35_b0_oem_prod.bin";
+ else
+ fw_name = "qm35_b0_oem.bin";
+ } else
+ fw_name = "qm35_b0_icv.bin";
} else {
fw_name = fwname;
}
@@ -129,24 +121,6 @@ const struct firmware *qmrom_spi_get_firmware(void *handle,
ret = request_firmware(&fw, fw_name, &spi->dev);
if (ret) {
- if (lcs_state != CC_BSV_SECURE_LCS) {
- dev_warn(&spi->dev, "LCS state is not secure.");
- }
-
- /* Didn't get the macro package, try the stitched image */
- *is_macro_pkg = false;
- if (use_prod_fw)
- fw_name = "qm35_oem_prod.bin";
- else
- fw_name = "qm35_oem.bin";
- dev_info(&spi->dev, "Requesting fw %s!\n", fw_name);
- ret = request_firmware(&fw, fw_name, &spi->dev);
- if (!ret) {
- dev_info(&spi->dev, "Firmware size is %zu!\n",
- fw->size);
- return fw;
- }
-
release_firmware(fw);
dev_err(&spi->dev,
"request_firmware failed (ret=%d) for '%s'\n", ret,
@@ -166,17 +140,11 @@ void qmrom_spi_release_firmware(const struct firmware *fw)
int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms)
{
- struct qm35_ctx *qm35_ctx = (struct qm35_ctx *)handle;
-
- wait_event_interruptible_timeout(qm35_ctx->qmrom_wq_ready,
- qm35_ctx->qmrom_qm_ready,
- msecs_to_jiffies(timeout_ms));
- return gpiod_get_value(qm35_ctx->gpio_ss_rdy) > 0 ? 0 : -1;
-}
-
-int qmrom_spi_read_irq_line(void *handle)
-{
- return gpiod_get_value(handle);
+ int count_down = (int)timeout_ms;
+ while (!gpiod_get_value(handle) && (--count_down >= 0)) {
+ usleep_range(1000, 1100);
+ }
+ return gpiod_get_value(handle) ? 0 : -1;
}
void qmrom_spi_set_freq(unsigned int freq)
@@ -184,7 +152,7 @@ void qmrom_spi_set_freq(unsigned int freq)
speed_hz = freq;
}
-unsigned int qmrom_spi_get_freq(void)
+unsigned int qmrom_spi_get_freq()
{
return speed_hz;
}