diff --git a/hal/nxp_t1024.c b/hal/nxp_t1024.c index 1472bf35f..3e8b46d39 100644 --- a/hal/nxp_t1024.c +++ b/hal/nxp_t1024.c @@ -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 */ @@ -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 */ @@ -1144,7 +1161,7 @@ static void hal_cpld_init(void) } -/* QE Microcode */ +/* QE Microcode Loading */ #if defined(ENABLE_QE) || defined(ENABLE_FMAN) /* Structure packing */ @@ -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' } */ @@ -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; @@ -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; } @@ -1259,7 +1257,7 @@ 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; } @@ -1267,18 +1265,51 @@ static int qe_upload_firmware(const struct qe_firmware *firmware) /* 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]; @@ -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) { @@ -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); @@ -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) { }