Skip to content

Commit

Permalink
Add Frame Manager microcode upload.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske committed Nov 14, 2023
1 parent 0f0f8ca commit aace337
Showing 1 changed file with 117 additions and 38 deletions.
155 changes: 117 additions & 38 deletions hal/nxp_t1024.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#define ENABLE_PCIE
#define ENABLE_CPLD
#define ENABLE_QE /* QUICC Engine */
//#define ENABLE_FMAN /* not complete */
#define ENABLE_FMAN
#define ENABLE_MP /* multi-core support */
#if defined(WOLFBOOT_TPM) || defined(TEST_TPM)
#define ENABLE_ESPI /* SPI for TPM */
Expand Down Expand Up @@ -238,8 +238,25 @@ static void hal_flash_unlock_sector(uint32_t sector);
#endif

#define FMAN_BASE (CCSRBAR + 0x400000)
#define FMAN_MURAM (FMAN_BASE)
#define FMAN_MURAM_SIZE (512 * 1024)

/* Hardware Ports (0-63) 4KB each (256KB total) */
#define FMAN_BMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000))

#define FMAN_QMI(n) ((FMAN_BASE + 0x80000) + ((n) * 0x1000) + 0x400)

#define FMAN_DMA (FMAN_BASE + 0xC2000UL) /* FMan DMA */

#define FMAN_FPM (FMAN_BASE + 0xC3000UL) /* Frame processing manager (FPM) */

#define FMAN_IRAM (FMAN_BASE + 0xC4000UL) /* FMan Controller Configuration Data */
#define FMAN_IRAM_IADD ((volatile uint32_t*)(FMAN_IRAM + 0x000UL)) /* Address Register (FMCDADDR) */
#define FMAN_IRAM_IDATA ((volatile uint32_t*)(FMAN_IRAM + 0x004UL)) /* Register (FMCDDATA) */
#define FMAN_IRAM_IREADY ((volatile uint32_t*)(FMAN_IRAM + 0x00CUL)) /* Ready Register (FMCDREADY) */

#define FMAN_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */
#define FMAN_IRAM_READY 0x80000000


/* T1024 PC16552D Dual UART */
Expand Down Expand Up @@ -1144,7 +1161,7 @@ static void hal_cpld_init(void)
}


/* QE Microcode */
/* QE Microcode Loading */
#if defined(ENABLE_QE) || defined(ENABLE_FMAN)

/* Structure packing */
Expand All @@ -1156,7 +1173,6 @@ static void hal_cpld_init(void)
#endif

/* QE based on work from Shlomi Gridish and Dave Liu at Freescale/NXP */

struct qe_header {
uint32_t length; /* Length of the entire structure, in bytes */
uint8_t magic[3]; /* Set to { 'Q', 'E', 'F' } */
Expand Down Expand Up @@ -1198,27 +1214,9 @@ struct qe_firmware {
/* CRC32 should be located here, after the microcode binaries */
} QE_PACKED;

static void qe_upload_microcode(const struct qe_firmware *firmware,
const struct qe_microcode *ucode)
{
const uint32_t *code = (uint32_t*)((uint8_t *)firmware + ucode->code_offset);
unsigned int i;

wolfBoot_printf("QE: uploading '%s' version %u.%u.%u\n",
ucode->id, ucode->major, ucode->minor, ucode->revision);

/* Use auto-increment */
set32(QE_IRAM_IADD, ucode->iram_offset |
QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);

/* Copy 32-bits at a time to iRAM */
for (i = 0; i < ucode->count; i++) {
set32(QE_IRAM_IDATA, code[i]);
}
}

/* Upload a microcode to the I-RAM at a specific address */
static int qe_upload_firmware(const struct qe_firmware *firmware)
/* Checks for valid QE firmware */
static int qe_check_firmware(const struct qe_firmware *firmware, const char* t)
{
unsigned int i, j;
uint32_t crc;
Expand All @@ -1232,19 +1230,19 @@ static int qe_upload_firmware(const struct qe_firmware *firmware)
/* Check the magic */
if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
(hdr->magic[2] != 'F')) {
wolfBoot_printf("QE firmware header invalid!\n");
wolfBoot_printf("%s: firmware header invalid!\n", t);
return -1;
}

/* Check the version */
if (hdr->version != 1) {
wolfBoot_printf("QE version %d unsupported!\n", hdr->version);
wolfBoot_printf("%s: version %d unsupported!\n", t, hdr->version);
return -1;
}

/* Validate some of the fields */
if ((firmware->count < 1) || (firmware->count > QE_MAX_RISC)) {
wolfBoot_printf("QE count %d invalid!\n", firmware->count);
wolfBoot_printf("%s: count %d invalid!\n", t, firmware->count);
return -1;
}

Expand All @@ -1259,26 +1257,59 @@ static int qe_upload_firmware(const struct qe_firmware *firmware)

/* Validate the length */
if (length != calc_size + sizeof(uint32_t)) {
wolfBoot_printf("QE length %d invalid!\n", length);
wolfBoot_printf("%s: length %d invalid!\n", t, length);
return -1;
}

#ifdef ENABLE_QE_CRC32
/* Validate the CRC */
crc = *(uint32_t *)((void *)firmware + calc_size);
if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) {
wolfBoot_printf("QE firmware CRC is invalid\n");
wolfBoot_printf("%s: firmware CRC is invalid\n", t);
return -1;
}
#endif

wolfBoot_printf("%s: Firmware: Length %d, Count %d\n",
t, length, firmware->count);

return 0;
}
#endif /* ENABLE_QE || ENABLE_FMAN */


/* ---- QUICC Engine Driver ---- */
#ifdef ENABLE_QE

static void qe_upload_microcode(const struct qe_firmware *firmware,
const struct qe_microcode *ucode)
{
const uint32_t *code = (uint32_t*)((uint8_t *)firmware + ucode->code_offset);
unsigned int i;

wolfBoot_printf("QE: uploading '%s' version %u.%u.%u\n",
ucode->id, ucode->major, ucode->minor, ucode->revision);

/* Use auto-increment */
set32(QE_IRAM_IADD, ucode->iram_offset |
QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);

/* Copy 32-bits at a time to iRAM */
for (i = 0; i < ucode->count; i++) {
set32(QE_IRAM_IDATA, code[i]);
}
}

/* Upload a microcode to the I-RAM at a specific address */
static int qe_upload_firmware(const struct qe_firmware *firmware)
{
unsigned int i, j;

/* Use common instruction RAM if not split (default is split) */
if (!firmware->split) {
set16(QE_CP_CERCR, get16(QE_CP_CERCR) | QE_CP_CERCR_CIR);
}

wolfBoot_printf("QE: Length %d, Count %d\n", length, firmware->count);

/* Loop through each microcode. */
for (i = 0; i < firmware->count; i++) {
const struct qe_microcode *ucode = &firmware->microcode[i];
Expand Down Expand Up @@ -1306,11 +1337,6 @@ static int qe_upload_firmware(const struct qe_firmware *firmware)
return 0;
}

#endif

/* ---- QUICC Engine Driver ---- */
#ifdef ENABLE_QE

static void qe_issue_cmd(uint32_t cmd, uint32_t sbc, uint8_t mcn,
uint32_t cmd_data)
{
Expand All @@ -1330,9 +1356,13 @@ static int hal_qe_init(void)
{
int ret;
uint32_t sdma_base;
const struct qe_firmware* fw = (const struct qe_firmware*)QE_FW_ADDR;

/* Upload microcode to IRAM */
ret = qe_upload_firmware((const struct qe_firmware *)QE_FW_ADDR);
ret = qe_check_firmware(fw, "QE");
if (ret == 0) {
/* Upload microcode to IRAM */
ret = qe_upload_firmware(fw);
}
if (ret == 0) {
/* enable the microcode in IRAM */
set32(QE_IRAM_IREADY, QE_IRAM_READY);
Expand Down Expand Up @@ -1361,12 +1391,61 @@ static int hal_qe_init(void)
#endif /* ENABLE_QUICC */

#ifdef ENABLE_FMAN
static void fman_upload_microcode(const struct qe_firmware *firmware,
const struct qe_microcode *ucode)
{
const uint32_t *code = (uint32_t*)((uint8_t *)firmware + ucode->code_offset);
unsigned int i;

wolfBoot_printf("FMAN: uploading '%s' version %u.%u.%u\n",
ucode->id, ucode->major, ucode->minor, ucode->revision);

/* Use auto-increment */
set32(FMAN_IRAM_IADD, FMAN_IRAM_IADD_AIE);

/* Copy 32-bits at a time to iRAM */
for (i = 0; i < ucode->count; i++) {
set32(FMAN_IRAM_IDATA, code[i]);
}

/* Verify write is done */
set32(FMAN_IRAM_IADD, 0);
while (get32(FMAN_IRAM_IDATA) != code[0]);

/* Enable microcode */
set32(FMAN_IRAM_IREADY, FMAN_IRAM_READY);

}

/* Upload a microcode to the I-RAM at a specific address */
static int fman_upload_firmware(const struct qe_firmware *firmware)
{
unsigned int i;

/* Loop through each microcode. */
for (i = 0; i < firmware->count; i++) {
const struct qe_microcode *ucode = &firmware->microcode[i];
uint32_t trapCount = 0;

/* Upload a microcode if it's present */
if (ucode->code_offset) {
fman_upload_microcode(firmware, ucode);
}
}

return 0;
}

static int hal_fman_init(void)
{
int ret;
const struct qe_firmware* fw = (const struct qe_firmware*)FMAN_FW_ADDR;

/* Upload microcode to IRAM */
ret = qe_upload_firmware((const struct qe_firmware *)FMAN_FW_ADDR);
ret = qe_check_firmware(fw, "FMAN");
if (ret == 0) {
ret = fman_upload_firmware(fw);
}
if (ret == 0) {

}
Expand Down

0 comments on commit aace337

Please sign in to comment.