Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
imi415 | 650049d060 | |
imi415 | 029f336438 | |
imi415 | d82bb3fb7e | |
imi415 | 3d407c43f2 |
|
@ -1,9 +1,9 @@
|
|||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
AlignConsecutiveMacros: AcrossEmptyLines
|
||||
AlignConsecutiveDeclarations: Consecutive
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignConsecutiveAssignments: true
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterEnum: false
|
||||
|
|
|
@ -10,6 +10,7 @@ set(TARGET_SOURCES
|
|||
"src/main.c"
|
||||
"src/stx7105_exc.c"
|
||||
"src/stx7105_utils.c"
|
||||
"src/stx7105_fdma_fw.c"
|
||||
"src/syscalls.c"
|
||||
"startup_stx7105.S"
|
||||
)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
This project uses some initialization code from STLinux U-Boot,
|
||||
the license header is kept in the corresponding files.
|
||||
Check these files for license.
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef SH4_CORE_H
|
||||
#define SH4_CORE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define __trapa(code) asm volatile("trapa %0" ::"i"(code))
|
||||
#define __sleep() asm volatile("sleep")
|
||||
|
||||
#endif // SH4_CORE_H
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sh4_core.h"
|
||||
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#define __IO volatile
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef STX7105_FDMA_H
|
||||
#define STX7105_FDMA_H
|
||||
|
||||
#include "stx7105.h"
|
||||
|
||||
typedef enum {
|
||||
FDMA_CMD_START_CHANNEL = 1U,
|
||||
FDMA_CMD_PAUSE_CHANNEL = 2U,
|
||||
FDMA_CMD_FLUSH_CHANNEL = 3U,
|
||||
} FDMA_Command_TypeDef;
|
||||
|
||||
typedef enum {
|
||||
FDMA_STAT_CHANNEL_IDLE = 0U,
|
||||
FDMA_STAT_CHANNEL_RUNNING = 2U,
|
||||
FDMA_STAT_CHANNEL_PAUSED = 3U,
|
||||
} FDMA_Status_TypeDef;
|
||||
|
||||
typedef enum {
|
||||
FDMA_REQ_CTL_OP_LDST1 = 0U,
|
||||
FDMA_REQ_CTL_OP_LDST2 = 1U,
|
||||
FDMA_REQ_CTL_OP_LDST4 = 2U,
|
||||
FDMA_REQ_CTL_OP_LDST8 = 3U,
|
||||
FDMA_REQ_CTL_OP_LDST16 = 4U,
|
||||
FDMA_REQ_CTL_OP_LDST32 = 5U,
|
||||
} FDMA_ReqCtl_Opcode_TypeDef;
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t NEXT; /* Offset: 0x0000, Next node in the list */
|
||||
__IO uint32_t CTRL; /* Offset: 0x0004, Control register */
|
||||
__IO uint32_t NBYTES; /* Offset: 0x0008, Number of bytes */
|
||||
__IO uint32_t SADDR; /* Offset: 0x000C, Source address */
|
||||
__IO uint32_t DADDR; /* Offset: 0x0010, Destination address */
|
||||
__IO uint32_t LENGTH; /* Offset: 0x0014, Burst length */
|
||||
__IO uint32_t S_STRIDE; /* Offset: 0x0018, Source stride */
|
||||
__IO uint32_t D_STRIDE; /* Offset: 0x001C, Destination stride */
|
||||
} FDMA_FwRegs_Channel_TypeDef;
|
||||
|
||||
/* Firmware regs, implemented on the base of DMEM */
|
||||
typedef struct {
|
||||
__IO uint32_t REVID; /* Offset: 0x8000 */
|
||||
uint32_t UNUSED0[1103]; /* Offset: 0x8004 */
|
||||
__IO uint32_t CMD_STAT[16]; /* Offset: 0x9140 */
|
||||
__IO uint32_t REQ_CTRL[16]; /* Offset: 0x9180 */
|
||||
uint32_t UNUSED1[240]; /* Offset: 0x91C0 */
|
||||
FDMA_FwRegs_Channel_TypeDef CHANNEL[16]; /* Offset: 0x9580 */
|
||||
} FDMA_FWRegs_TypeDef;
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_HOLDOFF_Pos 0U
|
||||
#define FDMA_FwRegs_REQ_CTLN_HOLDOFF_
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_OPCODE_Pos 4U
|
||||
#define FDMA_FwRegs_REQ_CTLN_OPCODE_Msk (0x0FU << FDMA_FwRegs_REQ_CTLN_OPCODE_Pos)
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_WNR_Pos 14U
|
||||
#define FDMA_FwRegs_REQ_CTLN_WNR_Msk (1U << FDMA_FwRegs_REQ_CTLN_INC_ADDR_Pos)
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_DATA_SWAP_Pos 17U
|
||||
#define FDMA_FwRegs_REQ_CTLN_DATA_SWAP_Msk (1U << FDMA_FwRegs_REQ_CTLN_INC_ADDR_Pos)
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_INC_ADDR_Pos 21U
|
||||
#define FDMA_FwRegs_REQ_CTLN_INC_ADDR_Msk (1U << FDMA_FwRegs_REQ_CTLN_INC_ADDR_Pos)
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_INITIATOR_Pos 22U
|
||||
#define FDMA_FwRegs_REQ_CTLN_INITIATOR_Msk (1U << FDMA_FwRegs_REQ_CTLN_INITIATOR_Pos)
|
||||
|
||||
#define FDMA_FwRegs_REQ_CTLN_NUM_OPS_Pos 24U
|
||||
#define FDMA_FwRegs_REQ_CTLN_NUM_OPS_Msk (0xFFU << FDMA_FwRegs_REQ_CTLN_INC_ADDR_Pos)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef STX7105_FDMA_FW_H
|
||||
#define STX7105_FDMA_FW_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t entry_point;
|
||||
uint32_t text_size;
|
||||
uint32_t data_size;
|
||||
uint8_t *text;
|
||||
uint8_t *data;
|
||||
} stx7105_fdma_fw_t;
|
||||
|
||||
extern stx7105_fdma_fw_t stx7105_fdma0_fw;
|
||||
extern stx7105_fdma_fw_t stx7105_fdma1_fw;
|
||||
|
||||
#endif
|
99
src/main.c
99
src/main.c
|
@ -1,22 +1,28 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stx7105.h"
|
||||
#include "stx7105_fdma.h"
|
||||
#include "stx7105_fdma_fw.h"
|
||||
#include "stx7105_utils.h"
|
||||
|
||||
#define LED_RED_GPIO PIO0
|
||||
#define LED_RED_PIN 5U
|
||||
#define LED_RED_GPIO PIO0
|
||||
#define LED_RED_PIN 5U
|
||||
|
||||
#define LED_BLUE_GPIO PIO0
|
||||
#define LED_BLUE_PIN 4U
|
||||
#define LED_BLUE_GPIO PIO0
|
||||
#define LED_BLUE_PIN 4U
|
||||
|
||||
#define CONSOLE_ASC ASC2
|
||||
#define SYSTEM_DEVID (0xFE001000U) /* DEVID */
|
||||
#define SYSTEM_CONFIG34 (0xFE001188U) /* PIO4 */
|
||||
#define SYSTEM_CONFIG7 (0xFE00111CU) /* RXSEL */
|
||||
|
||||
#define MEMTEST_START 0x82000000
|
||||
#define MEMTEST_END 0x8F000000
|
||||
#define MEMTEST_START 0x82000000
|
||||
#define MEMTEST_END 0x8F000000
|
||||
|
||||
#define DMA_BUFFER_SIZE 16
|
||||
uint8_t src_buffer[DMA_BUFFER_SIZE];
|
||||
|
||||
void uart_init(void) {
|
||||
PIO4->CLR_PC0 = 1U; /* PC = 110, AFOUT, PP */
|
||||
|
@ -33,30 +39,48 @@ void uart_init(void) {
|
|||
CONSOLE_ASC->CTRL = 0x1589UL; /* 8N1, RX enable, FIFO enable, Baud mode 1 */
|
||||
}
|
||||
|
||||
static void memory_test(void) {
|
||||
printf("Begin memory test from 0x%08x to 0x%08x\r\n", MEMTEST_START, MEMTEST_END);
|
||||
static void configure_fdma0(void) {
|
||||
FDMA0->SLIM_CLK_GATE |= (FDMA_SLIM_CLK_GATE_DIS_Msk | FDMA_SLIM_CLK_GATE_RESET_Msk);
|
||||
FDMA0->PERIPH_STBUS_SYNC |= FDMA_PERIPH_STBUS_SYNC_DIS_Msk;
|
||||
|
||||
for (uint32_t i = MEMTEST_START; i < MEMTEST_END; i += 4) {
|
||||
*(uint32_t *)i = i;
|
||||
|
||||
if (i % 0x100000 == 0U) {
|
||||
printf("Write to 0x%08lx...\r\n", i);
|
||||
}
|
||||
for (uint32_t i = 0; i < stx7105_fdma0_fw.text_size; i++) {
|
||||
FDMA0->SLIM_IMEM[i] = stx7105_fdma0_fw.text[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = MEMTEST_START; i < MEMTEST_END; i += 4) {
|
||||
if (*(uint32_t *)i != i) {
|
||||
printf("Read back error at 0x%08lx\r\n", i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (i % 0x100000 == 0U) {
|
||||
printf("Read from 0x%08lx...\r\n", i);
|
||||
}
|
||||
for (uint32_t i = 0; i < stx7105_fdma0_fw.data_size; i++) {
|
||||
FDMA0->SLIM_DMEM[i] = stx7105_fdma0_fw.data[i];
|
||||
}
|
||||
|
||||
printf("Memory test finished.\r\n");
|
||||
FDMA0->SLIM_CLK_GATE &= ~FDMA_SLIM_CLK_GATE_DIS_Msk;
|
||||
FDMA0->PERIPH_INT_CLR = 0xFFFFFFFFU;
|
||||
FDMA0->PERIPH_CMD_CLR = 0xFFFFFFFFU;
|
||||
|
||||
FDMA0->SLIM_EN |= FDMA_SLIM_EN_RUN_Msk;
|
||||
|
||||
printf("FDMA0 SLIM ID: 0x%08lx\r\n", FDMA0->SLIM_ID);
|
||||
printf("FDMA0 SLIM Version: 0x%08lx\r\n", FDMA0->SLIM_VER);
|
||||
}
|
||||
|
||||
static void configure_fdma1(void) {
|
||||
FDMA1->SLIM_CLK_GATE |= (FDMA_SLIM_CLK_GATE_DIS_Msk | FDMA_SLIM_CLK_GATE_RESET_Msk);
|
||||
FDMA1->PERIPH_STBUS_SYNC |= FDMA_PERIPH_STBUS_SYNC_DIS_Msk;
|
||||
|
||||
for (uint32_t i = 0; i < stx7105_fdma1_fw.text_size; i++) {
|
||||
FDMA1->SLIM_IMEM[i] = stx7105_fdma1_fw.text[i];
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < stx7105_fdma1_fw.data_size; i++) {
|
||||
FDMA1->SLIM_DMEM[i] = stx7105_fdma1_fw.data[i];
|
||||
}
|
||||
|
||||
FDMA1->SLIM_CLK_GATE &= ~FDMA_SLIM_CLK_GATE_DIS_Msk;
|
||||
FDMA1->PERIPH_INT_CLR = 0xFFFFFFFFU;
|
||||
FDMA1->PERIPH_CMD_CLR = 0xFFFFFFFFU;
|
||||
|
||||
FDMA1->SLIM_EN |= FDMA_SLIM_EN_RUN_Msk;
|
||||
|
||||
printf("FDMA1 SLIM ID: 0x%08lx\r\n", FDMA1->SLIM_ID);
|
||||
printf("FDMA1 SLIM Version: 0x%08lx\r\n", FDMA1->SLIM_VER);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
@ -70,9 +94,24 @@ int main(void) {
|
|||
|
||||
printf("Hello world\r\n");
|
||||
|
||||
__trapa(34); /* TRAPA test code.. */
|
||||
printf("CKGA Opts 1: 0x%08lx\r\n", CKGA->CLKOPSRC_SWITCH_CFG);
|
||||
printf("CKGA Opts 2: 0x%08lx\r\n", CKGA->CLKOPSRC_SWITCH_CFG2);
|
||||
|
||||
memory_test();
|
||||
configure_fdma0();
|
||||
configure_fdma1();
|
||||
|
||||
FDMA_FWRegs_TypeDef *fdma0_fwregs = (FDMA_FWRegs_TypeDef *)(FDMA0->SLIM_DMEM);
|
||||
|
||||
fdma0_fwregs->CHANNEL[0].NEXT = (uint32_t)NULL;
|
||||
fdma0_fwregs->CHANNEL[0].NBYTES = DMA_BUFFER_SIZE;
|
||||
fdma0_fwregs->CHANNEL[0].LENGTH = DMA_BUFFER_SIZE;
|
||||
fdma0_fwregs->CHANNEL[0].SADDR = (uint32_t)src_buffer;
|
||||
fdma0_fwregs->CHANNEL[0].DADDR = CONSOLE_ASC->TX_BUF;
|
||||
fdma0_fwregs->CHANNEL[0].S_STRIDE = 0U;
|
||||
fdma0_fwregs->CHANNEL[0].D_STRIDE = 0U;
|
||||
fdma0_fwregs->REQ_CTRL[0] = (1U << FDMA_FwRegs_REQ_CTLN_NUM_OPS_Pos) | FDMA_FwRegs_REQ_CTLN_INC_ADDR_Msk;
|
||||
|
||||
delay_ms(5000);
|
||||
|
||||
for (;;) {
|
||||
set_led(LED_BLUE_GPIO, LED_BLUE_PIN, 1U);
|
||||
|
@ -83,9 +122,3 @@ int main(void) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tra #34 is SysCall.. */
|
||||
int syscall_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
set_led(LED_RED_GPIO, LED_RED_PIN, 1U);
|
||||
return 0;
|
||||
}
|
|
@ -1,153 +1,86 @@
|
|||
#include "stx7105.h"
|
||||
|
||||
#define WEAK_ATTR __attribute__((weak))
|
||||
#define IRQ_ATTR __attribute__((interrupt_handler))
|
||||
#define WEAK_IRQ_ATTR __attribute__((weak, interrupt_handler))
|
||||
#define __WEAK __attribute__((weak))
|
||||
#define __IRQ __attribute__((interrupt_handler))
|
||||
#define __WEAK_IRQ __attribute__((weak, interrupt_handler))
|
||||
|
||||
typedef enum {
|
||||
EXP_TYPE_RADDERR = 0x0E0,
|
||||
EXP_TYPE_WADDERR = 0x100,
|
||||
EXP_TYPE_TRAP = 0x160,
|
||||
EXP_TYPE_TRAP = 0x160,
|
||||
} expevt_type_t;
|
||||
|
||||
typedef enum {
|
||||
INT_TYPE_TMU_TNUI0 = 0x400,
|
||||
INT_TYPE_TMU_TNUI1 = 0x420,
|
||||
INT_TYPE_TMU_TNUI2 = 0x440,
|
||||
INT_TYPE_TMU_TICPI2 = 0x460,
|
||||
INT_TYPE_ASC_UART0 = 0x1160,
|
||||
INT_TYPE_ASC_UART1 = 0x1140,
|
||||
INT_TYPE_ASC_UART2 = 0x1120,
|
||||
INT_TYPE_ASC_UART3 = 0x1100,
|
||||
INT_TYPE_TMU_TNUI0 = 0x400,
|
||||
INT_TYPE_TMU_TNUI1 = 0x420,
|
||||
INT_TYPE_TMU_TNUI2 = 0x440,
|
||||
INT_TYPE_TMU_TICPI2 = 0x460,
|
||||
INT_TYPE_FDMA_0_MBOX = 0x1380,
|
||||
INT_TYPE_FDMA_1_MBOX = 0x13A0,
|
||||
} intevt_type_t;
|
||||
|
||||
typedef enum {
|
||||
TRA_TYPE_START_SCHEDULER = 32,
|
||||
TRA_TYPE_YIELD = 33,
|
||||
TRA_TYPE_SYSCALL = 34,
|
||||
TRA_TYPE_SYSCALL = 34,
|
||||
} tra_type_t;
|
||||
|
||||
/* ========================= TMU 0/1/2 Underrun Interrupt Handlers ================================= */
|
||||
|
||||
WEAK_ATTR void tuni0_handler(void) {
|
||||
__WEAK int tuni0_handler(void) {
|
||||
/* Does nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEAK_ATTR void tuni1_handler(void) {
|
||||
__WEAK int fdma0_mbox_handler(void) {
|
||||
/* Does nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEAK_ATTR void tuni2_handler(void) {
|
||||
__WEAK int fdma1_mbox_handler(void) {
|
||||
/* Does nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================= ASC(UART) 0/1/2 Interrupt Handlers ================================= */
|
||||
|
||||
WEAK_ATTR void asc0_handler(void) {
|
||||
/* Does nothing */
|
||||
__WEAK int syscall_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEAK_ATTR void asc1_handler(void) {
|
||||
/* Does nothing */
|
||||
}
|
||||
|
||||
WEAK_ATTR void asc2_handler(void) {
|
||||
/* Does nothing */
|
||||
}
|
||||
|
||||
WEAK_ATTR void asc3_handler(void) {
|
||||
/* Does nothing */
|
||||
}
|
||||
|
||||
/* ========================= Different Trap Code Handlers ================================= */
|
||||
|
||||
WEAK_ATTR void syscall_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
/* Does nothing */
|
||||
}
|
||||
|
||||
WEAK_ATTR void yield_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
/* Does nothing */
|
||||
}
|
||||
|
||||
/* ========================= TRAPA(Trap) Exception Handlers ================================= */
|
||||
|
||||
WEAK_ATTR void trap_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
tra_type_t tra = (CSP->TRA >> 2U) & 0xFFU; /* TRA[9:2] */
|
||||
__WEAK int trap_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
tra_type_t tra = CSP->TRA;
|
||||
|
||||
switch (tra) {
|
||||
case TRA_TYPE_SYSCALL:
|
||||
syscall_handler(p1, p2, p3, p4);
|
||||
break;
|
||||
case TRA_TYPE_YIELD:
|
||||
yield_handler(p1, p2, p3, p4);
|
||||
return syscall_handler(p1, p2, p3, p4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================= Address Error Exception Handlers ================================= */
|
||||
|
||||
WEAK_ATTR void radderr_handler(void) {
|
||||
/* Dead... */
|
||||
for (;;) {
|
||||
/* Loop... */
|
||||
}
|
||||
}
|
||||
|
||||
WEAK_ATTR void wadderr_handler(void) {
|
||||
/* Dead... */
|
||||
for (;;) {
|
||||
/* Loop... */
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= System Exception Handlers ================================= */
|
||||
|
||||
WEAK_IRQ_ATTR void general_exc_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
__WEAK_IRQ int general_exc_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
expevt_type_t expevt = CSP->EXPEVT;
|
||||
switch (expevt) {
|
||||
case EXP_TYPE_TRAP:
|
||||
trap_handler(p1, p2, p3, p4);
|
||||
break;
|
||||
case EXP_TYPE_RADDERR:
|
||||
radderr_handler();
|
||||
break;
|
||||
case EXP_TYPE_WADDERR:
|
||||
wadderr_handler();
|
||||
return trap_handler(p1, p2, p3, p4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================= System Interrupt Handlers ================================= */
|
||||
|
||||
WEAK_IRQ_ATTR void general_int_handler(void) {
|
||||
__WEAK_IRQ int general_int_handler(void) {
|
||||
intevt_type_t intevt = CSP->INTEVT;
|
||||
switch (intevt) {
|
||||
case INT_TYPE_TMU_TNUI0:
|
||||
tuni0_handler();
|
||||
return tuni0_handler();
|
||||
break;
|
||||
case INT_TYPE_TMU_TNUI1:
|
||||
tuni1_handler();
|
||||
case INT_TYPE_FDMA_0_MBOX:
|
||||
return fdma0_mbox_handler();
|
||||
break;
|
||||
case INT_TYPE_TMU_TNUI2:
|
||||
tuni2_handler();
|
||||
break;
|
||||
case INT_TYPE_ASC_UART0:
|
||||
asc0_handler();
|
||||
break;
|
||||
case INT_TYPE_ASC_UART1:
|
||||
asc1_handler();
|
||||
break;
|
||||
case INT_TYPE_ASC_UART2:
|
||||
asc2_handler();
|
||||
break;
|
||||
case INT_TYPE_ASC_UART3:
|
||||
asc3_handler();
|
||||
case INT_TYPE_FDMA_1_MBOX:
|
||||
return fdma1_mbox_handler();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -39,8 +39,8 @@ void delay_ms(uint32_t msec) {
|
|||
INTC->IPRA |= (1U << INTC_IPRA_IPR_TMU0_Pos); /* Interrupt priority 1 */
|
||||
|
||||
/* Wait until underflow occurs */
|
||||
while (s_tmu_flag != 1) {
|
||||
__sleep();
|
||||
while(s_tmu_flag != 1) {
|
||||
asm("sleep");
|
||||
}
|
||||
|
||||
s_tmu_flag = 0U;
|
||||
|
@ -48,7 +48,9 @@ void delay_ms(uint32_t msec) {
|
|||
TMU->TSTR &= ~TMU_TSTR_STR0_Msk; /* Stop counter */
|
||||
}
|
||||
|
||||
void tuni0_handler(void) {
|
||||
int tuni0_handler(void) {
|
||||
s_tmu_flag = 1U;
|
||||
TMU->TCR0 &= ~(TMU_TCR_UNF_Msk);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#define CONSOLE_ASC ASC2
|
||||
|
||||
#define HEAP_SIZE 0x10000
|
||||
#define HEAP_SIZE 0x10000
|
||||
|
||||
extern char _end;
|
||||
static uint32_t s_heap_size = 0U;
|
||||
|
@ -35,9 +35,10 @@ int _write(int file, char *ptr, int len) {
|
|||
}
|
||||
|
||||
int _open(const char *name, int flags, int mode) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _read(int file, char *ptr, int len) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
.section .text.vtors, "ax"
|
||||
_vtors:
|
||||
.long _stext
|
||||
.long _eidata
|
||||
.long _start
|
||||
|
||||
|
|
|
@ -7,17 +7,13 @@ ENTRY(_start)
|
|||
/* We don't use 29-bit mode since PMB and LMI initialization has to be done anyway. */
|
||||
|
||||
MEMORY {
|
||||
EMI (rx) : ORIGIN = 0x80000000, LENGTH = 0x01000000 /* EMI copied to Non-cached LMI virtual address: 0x8000_0000 */
|
||||
LMI (rwx) : ORIGIN = 0x81000000, LENGTH = 0x0F000000 /* Non-cached LMI virtual address: 0x8100_0000 */
|
||||
EMI_CACHED (rx) : ORIGIN = 0x90000000, LENGTH = 0x01000000 /* EMI copied to cached LMI virtual address: 0x9000_0000 */
|
||||
LMI_CACHED (rwx) : ORIGIN = 0x91000000, LENGTH = 0x0F000000 /* Cached LMI virtual address: 0x9100_0000 */
|
||||
|
||||
EMI (rx) : ORIGIN = 0x80000000, LENGTH = 0x01000000 /* LMI virtual address: 0x8000_0000 */
|
||||
LMI (rwx) : ORIGIN = 0x81000000, LENGTH = 0x0F000000 /* LMI virtual address: 0x8100_0000 */
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.text : {
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.text.vtors))
|
||||
*(.text.init)
|
||||
*(.text.exc)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# FDMAFWExtract
|
||||
|
||||
This tool can be used to extract firmware data from ELF files.
|
|
@ -0,0 +1,164 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <libelf.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void print_usage(void) {
|
||||
fprintf(stderr, "Usage: fdmafwextract ELF_FILENAME\n");
|
||||
}
|
||||
|
||||
static int get_section_idx_by_name(Elf *handle, char *name) {
|
||||
/* Get total section counts. */
|
||||
size_t e_nsections;
|
||||
if (elf_getshdrnum(handle, &e_nsections) < 0) {
|
||||
int errsv = elf_errno();
|
||||
fprintf(stderr, "Failed to retrieve section counts, %s\n", elf_errmsg(errsv));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get string table index. */
|
||||
size_t e_stridx;
|
||||
if (elf_getshdrstrndx(handle, &e_stridx) < 0) {
|
||||
int errsv = elf_errno();
|
||||
fprintf(stderr, "Failed to get string table index, %s\n", elf_errmsg(errsv));
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Search sections for specific name */
|
||||
for (size_t i = 0; i < e_nsections; i++) {
|
||||
Elf_Scn *scn = elf_getscn(handle, i);
|
||||
if (scn == NULL) {
|
||||
int errsv = elf_errno();
|
||||
fprintf(stderr, "Failed to get section ID: %d, %s\n", i, elf_errmsg(errsv));
|
||||
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Get section header */
|
||||
GElf_Shdr shdr_mem;
|
||||
GElf_Shdr *shdr = gelf_getshdr(scn, &shdr_mem);
|
||||
if (shdr == NULL) {
|
||||
int errsv = elf_errno();
|
||||
fprintf(stderr, "Failed to get section header ID: %d, %s\n", i, elf_errmsg(errsv));
|
||||
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* Get section name string from table */
|
||||
const char *s_name = elf_strptr(handle, e_stridx, shdr->sh_name);
|
||||
if (s_name == NULL) {
|
||||
int errsv = elf_errno();
|
||||
fprintf(stderr, "Failed to get section name for ID: %d, %s\n", i, elf_errmsg(errsv));
|
||||
|
||||
return -5;
|
||||
}
|
||||
|
||||
/* Found a match */
|
||||
if (strcmp(s_name, name) == 0) {
|
||||
fprintf(stderr, "Found a match for section %s at ID: %d\n", s_name, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop completed with no matching sections found. */
|
||||
fprintf(stderr, "No section named %s found.\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dump_section_as_c_array(Elf *handle, int idx, bool pad_32) {
|
||||
Elf_Scn *scn = elf_getscn(handle, idx);
|
||||
if (scn == NULL) {
|
||||
int es = elf_errno();
|
||||
fprintf(stderr, "Failed to get section %d: %s\n", idx, elf_errmsg(es));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Elf_Data *data = elf_rawdata(scn, NULL);
|
||||
if (data == NULL) {
|
||||
int es = elf_errno();
|
||||
fprintf(stderr, "Failed to get section data %d: %s\n", idx, elf_errmsg(es));
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Section %d size: 0x%x, offset: 0x%x\n", idx, data->d_size, data->d_off);
|
||||
|
||||
fprintf(stdout, "\n{\n");
|
||||
for(int i = 0; i < data->d_size; i++) {
|
||||
fprintf(stdout, "0x%02x, ", ((uint8_t *)data->d_buf)[i]);
|
||||
|
||||
if(i % 16 == 15) {
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
int ret = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
print_usage();
|
||||
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int elf_fd = open(argv[1], O_RDONLY);
|
||||
if (elf_fd < 0) {
|
||||
int es = errno;
|
||||
fprintf(stderr, "Failed to open ELF file: %s\n", strerror(es));
|
||||
|
||||
ret = -2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
elf_version(EV_CURRENT);
|
||||
|
||||
Elf *e_handle = elf_begin(elf_fd, ELF_C_READ, NULL);
|
||||
if (e_handle == NULL) {
|
||||
int es = elf_errno();
|
||||
fprintf(stderr, "ELF begin failed: %s\n", elf_errmsg(es));
|
||||
|
||||
ret = -3;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
ret = get_section_idx_by_name(e_handle, ".text");
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to find text section.\n");
|
||||
|
||||
ret = -4;
|
||||
goto elf_out;
|
||||
}
|
||||
|
||||
ret = dump_section_as_c_array(e_handle, ret, true);
|
||||
|
||||
ret = get_section_idx_by_name(e_handle, ".data");
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to find data section.\n");
|
||||
|
||||
ret = -5;
|
||||
goto elf_out;
|
||||
}
|
||||
|
||||
ret = dump_section_as_c_array(e_handle, ret, false);
|
||||
|
||||
elf_out:
|
||||
elf_end(e_handle);
|
||||
|
||||
err_out:
|
||||
close(elf_fd);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
FLASH_SIZE=1015808 # 1048576 - 32768
|
||||
FLASH_SIZE=1048576
|
||||
|
||||
INPUT_IMAGE="$1"
|
||||
BINARY_NAME="$2"
|
||||
|
@ -30,4 +30,4 @@ PAD_SIZE=$((${FLASH_SIZE} - ${BINARY_SIZE}))
|
|||
echo "Output binary size: ${BINARY_SIZE}, additional padding: ${PAD_SIZE}."
|
||||
|
||||
# Pad output file using `dd`
|
||||
tr '\0' '\377' < /dev/zero | dd bs=1 count=${PAD_SIZE} of=${BINARY_NAME} conv=notrunc seek=${BINARY_SIZE}
|
||||
tr '\0' '\377' < /dev/zero | dd bs=1 count=${PAD_SIZE} of=${BINARY_NAME} conv=notrunc seek=${BINARY_SIZE}
|
Loading…
Reference in New Issue