Compare commits

...

6 Commits
fdma ... master

Author SHA1 Message Date
imi415 bc18798dbc
Updated startup compatible with SPL.
Signed-off-by: imi415 <imi415.public@gmail.com>
2022-09-07 23:48:27 +08:00
imi415 85ce765a43
Additional exception handlers.
Signed-off-by: imi415 <imi415.public@gmail.com>
2022-09-07 23:11:11 +08:00
imi415 886fc31ff0
Remove return values of handlers.
Signed-off-by: imi415 <imi415.public@gmail.com>
2022-09-07 22:27:21 +08:00
imi415 d8e7b24931
Refactored exception routine, working trapa handler.
Signed-off-by: imi415 <imi415.public@gmail.com>
2022-09-07 22:12:54 +08:00
imi415 782308d696
Updated struct names. 2022-09-04 19:47:08 +08:00
imi415 2c021cbf5f
Removed STM License as vendor files are moved to a seperate repo. 2022-08-12 00:16:45 +08:00
11 changed files with 257 additions and 92 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: AcrossEmptyLines
AlignConsecutiveDeclarations: Consecutive
AlignConsecutiveAssignments: Consecutive
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
ColumnLimit: 120

View File

@ -1,3 +0,0 @@
This project uses some initialization code from STLinux U-Boot,
the license header is kept in the corresponding files.
Check these files for license.

9
include/sh4_core.h Normal file
View File

@ -0,0 +1,9 @@
#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

View File

@ -3,6 +3,8 @@
#include <stdint.h>
#include "sh4_core.h"
#define __PACKED __attribute__((packed, aligned(1)))
#define __IO volatile
@ -129,46 +131,92 @@ typedef struct {
__IO uint32_t BDMRB; /* Offset: 0x2001C, Break data mask register B */
__IO uint16_t BRCR; /* Offset: 0x20020, Break control register */
uint8_t UNUSED9[2]; /* Offset: 0x20022 */
} CSR_TypeDef;
} CSP_TypeDef;
/* drivers/stm/stx7105.c */
typedef struct {
__IO uint32_t SLIM_ID; /* Offset: 0x0000, SLIM CPU ID register */
__IO uint32_t SLIM_VER; /* Offset: 0x0004, SLIM CPU version register */
__IO uint32_t SLIM_EN; /* Offset: 0x0008, SLIM CPU enable control register */
__IO uint32_t SLIM_CLK_GATE; /* Offset: 0x000C, SLIM CPU clock gate register */
__IO uint32_t SLIM_ID; /* Offset: 0x0000, SLIM CPU ID register */
__IO uint32_t SLIM_VER; /* Offset: 0x0004, SLIM CPU version register */
__IO uint32_t SLIM_EN; /* Offset: 0x0008, SLIM CPU enable control register */
__IO uint32_t SLIM_CLK_GATE; /* Offset: 0x000C, SLIM CPU clock gate register */
uint32_t UNUSED0[8188]; /* Offset: 0x0010 */
__IO uint8_t SLIM_DMEM[8192]; /* Offset: 0x8000, SLIM CPU data memory */
uint32_t UNUSED1[2018]; /* Offset: 0xA000 */
__IO uint32_t PERIPH_STBUS_SYNC; /* Offset: 0xBF88, STBus sync control register */
uint32_t UNUSED2[13]; /* Offset: 0xBF8C */
__IO uint32_t PERIPH_CMD_STA; /* Offset: 0xBFC0, Command mailbox */
__IO uint32_t PERIPH_CMD_SET; /* Offset: 0xBFC4, Command mailbox */
__IO uint32_t PERIPH_CMD_CLR; /* Offset: 0xBFC8, Command mailbox */
__IO uint32_t PERIPH_CMD_MASK; /* Offset: 0xBFCC, Command mailbox */
__IO uint32_t PERIPH_INT_STA; /* Offset: 0xBFD0, Interrupt mailbox */
__IO uint32_t PERIPH_INT_SET; /* Offset: 0xBFD4, Interrupt mailbox */
__IO uint32_t PERIPH_INT_CLR; /* Offset: 0xBFD8, Interrupt mailbox */
__IO uint32_t PERIPH_INT_MASK; /* Offset: 0xBFDC, Interrupt mailbox */
uint32_t UNUSED3[8]; /* Offset: 0xBFE0 */
__IO uint8_t SLIM_IMEM[16384]; /* Offset: 0xC000, SLIM CPU instruction memory */
} FDMA_TypeDef;
#define PIO0_BASE (0xFD020000U)
#define PIO1_BASE (0xFD021000U)
#define PIO2_BASE (0xFD022000U)
#define PIO3_BASE (0xFD023000U)
#define PIO4_BASE (0xFD024000U)
#define PIO5_BASE (0xFD025000U)
#define PIO6_BASE (0xFD026000U)
#define ASC0_BASE (0xFD030000U)
#define ASC1_BASE (0xFD031000U)
#define ASC2_BASE (0xFD032000U)
#define ASC3_BASE (0xFD033000U)
#define FDMA0_BASE (0xFE220000U)
#define CSR_BASE (0xFF000000U)
#define INTC_BASE (0xFFD00000U)
#define TMU_BASE (0xFFD80000U)
/* WARNING: THE CLKGENA is different from other ST40s' */
typedef struct {
__IO uint32_t PLL0_CFG; /* Offset: 0x0000 */
__IO uint32_t PLL1_CFG; /* Offset: 0x0004 */
uint32_t UNUSED0[2]; /* Offset: 0x0008 */
__IO uint32_t POWER_CFG; /* Offset: 0x0010 */
__IO uint32_t CLKOPSRC_SWITCH_CFG; /* Offset: 0x0014 */
uint32_t UNUSED1[4]; /* Offset: 0x0018 */
__IO uint32_t CLKOPSRC_SWITCH_CFG2; /* Offset: 0x0024 */
uint32_t UNUSED2[2]; /* Offset: 0x0028 */
__IO uint32_t CLKOBS_MUX1_CFG; /* Offset: 0x0030 */
__IO uint32_t CLKOBS_MASTER_MAXCOUNT; /* Offset: 0x0034 */
__IO uint32_t CLKOBS_CMD; /* Offset: 0x0038 */
__IO uint32_t CLKOBS_STATUS; /* Offset: 0x003C */
__IO uint32_t CLKOBS_SLAVE0_COUNT; /* Offset: 0x0040 */
__IO uint32_t OSCMUX_DEBUG; /* Offset: 0x0044 */
__IO uint32_t CLKOBS_MUX2_CFG; /* Offset: 0x0048 */
__IO uint32_t LOW_POWER_CTRL; /* Offset: 0x004C */
} CKGA_TypeDef;
#define PIO0 ((PIO_TypeDef *)PIO0_BASE)
#define PIO1 ((PIO_TypeDef *)PIO1_BASE)
#define PIO2 ((PIO_TypeDef *)PIO2_BASE)
#define PIO3 ((PIO_TypeDef *)PIO3_BASE)
#define PIO4 ((PIO_TypeDef *)PIO4_BASE)
#define PIO5 ((PIO_TypeDef *)PIO5_BASE)
#define PIO6 ((PIO_TypeDef *)PIO6_BASE)
#define ASC0 ((ASC_TypeDef *)ASC0_BASE)
#define ASC1 ((ASC_TypeDef *)ASC1_BASE)
#define ASC2 ((ASC_TypeDef *)ASC2_BASE)
#define ASC3 ((ASC_TypeDef *)ASC3_BASE)
#define CSR ((CSR_TypeDef *)CSR_BASE)
#define PIO0_BASE (0xFD020000U)
#define PIO1_BASE (0xFD021000U)
#define PIO2_BASE (0xFD022000U)
#define PIO3_BASE (0xFD023000U)
#define PIO4_BASE (0xFD024000U)
#define PIO5_BASE (0xFD025000U)
#define PIO6_BASE (0xFD026000U)
#define ASC0_BASE (0xFD030000U)
#define ASC1_BASE (0xFD031000U)
#define ASC2_BASE (0xFD032000U)
#define ASC3_BASE (0xFD033000U)
#define CKGA_BASE (0xFE213000U)
#define FDMA0_BASE (0xFE220000U)
#define FDMA1_BASE (0xFE410000U)
#define CSP_BASE (0xFF000000U)
#define INTC_BASE (0xFFD00000U)
#define TMU_BASE (0xFFD80000U)
#define PIO0 ((PIO_TypeDef *)PIO0_BASE)
#define PIO1 ((PIO_TypeDef *)PIO1_BASE)
#define PIO2 ((PIO_TypeDef *)PIO2_BASE)
#define PIO3 ((PIO_TypeDef *)PIO3_BASE)
#define PIO4 ((PIO_TypeDef *)PIO4_BASE)
#define PIO5 ((PIO_TypeDef *)PIO5_BASE)
#define PIO6 ((PIO_TypeDef *)PIO6_BASE)
#define ASC0 ((ASC_TypeDef *)ASC0_BASE)
#define ASC1 ((ASC_TypeDef *)ASC1_BASE)
#define ASC2 ((ASC_TypeDef *)ASC2_BASE)
#define ASC3 ((ASC_TypeDef *)ASC3_BASE)
#define CKGA ((CKGA_TypeDef *)CKGA_BASE)
#define FDMA0 ((FDMA_TypeDef *)FDMA0_BASE)
#define INTC ((INTC_TypeDef *)INTC_BASE)
#define TMU ((TMU_TypeDef *)TMU_BASE)
#define FDMA1 ((FDMA_TypeDef *)FDMA1_BASE)
#define CSP ((CSP_TypeDef *)CSP_BASE)
#define INTC ((INTC_TypeDef *)INTC_BASE)
#define TMU ((TMU_TypeDef *)TMU_BASE)
#define TMU_TSTR_STR0_Pos 0
#define TMU_TSTR_STR0_Msk (1U << TMU_TSTR_STR0_Pos)
@ -188,4 +236,16 @@ typedef struct {
#define INTC_IPRA_IPR_TMU0_Pos 12
#define INTC_IPRA_IPR_TMU0_Msk (0x0FU << INTC_IPRA_IPR_TMU0_Pos)
#define FDMA_SLIM_EN_RUN_Pos 0
#define FDMA_SLIM_EN_RUN_Msk (1U << FDMA_SLIM_EN_RUN_Pos)
#define FDMA_SLIM_CLK_GATE_DIS_Pos 0
#define FDMA_SLIM_CLK_GATE_DIS_Msk (1U << FDMA_SLIM_CLK_GATE_DIS_Pos)
#define FDMA_SLIM_CLK_GATE_RESET_Pos 2
#define FDMA_SLIM_CLK_GATE_RESET_Msk (1U << FDMA_SLIM_CLK_GATE_RESET_Pos)
#define FDMA_PERIPH_STBUS_SYNC_DIS_Pos 0
#define FDMA_PERIPH_STBUS_SYNC_DIS_Msk (1U << FDMA_PERIPH_STBUS_SYNC_DIS_Pos)
#endif

View File

@ -4,19 +4,19 @@
#include "stx7105.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
void uart_init(void) {
PIO4->CLR_PC0 = 1U; /* PC = 110, AFOUT, PP */
@ -34,10 +34,12 @@ void uart_init(void) {
}
static void memory_test(void) {
printf("Begin memory test from 0x%08x to 0x%08x\r\n", MEMTEST_START, MEMTEST_END);
for (uint32_t i = MEMTEST_START; i < MEMTEST_END; i += 4) {
*(uint32_t *)i = i;
if (i % 0x10000 == 0U) {
if (i % 0x100000 == 0U) {
printf("Write to 0x%08lx...\r\n", i);
}
}
@ -49,33 +51,26 @@ static void memory_test(void) {
return;
}
if (i % 0x10000 == 0U) {
if (i % 0x100000 == 0U) {
printf("Read from 0x%08lx...\r\n", i);
}
}
printf("Memory test finished.\r\n");
}
int main(void) {
init_led(LED_RED_GPIO, LED_RED_PIN, 0U);
init_led(LED_BLUE_GPIO, LED_BLUE_PIN, 0U);
setbuf(stdout,NULL);
setbuf(stderr,NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
uart_init();
printf("Hello world\r\n");
printf("Size of int: %d\r\n", sizeof(int));
printf("Size of short: %d\r\n", sizeof(short));
printf("Size of char: %d\r\n", sizeof(char));
printf("Size of long: %d\r\n", sizeof(long));
printf("Size of pointer: %d\r\n", sizeof(uint8_t *));
printf("Size of uint8_t: %d\r\n", sizeof(uint8_t));
printf("Size of uint16_t: %d\r\n", sizeof(uint16_t));
printf("Size of uint32_t: %d\r\n", sizeof(uint32_t));
delay_ms(5000);
__trapa(34); /* TRAPA test code.. */
memory_test();
@ -88,3 +83,9 @@ 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;
}

View File

@ -1,11 +1,13 @@
#include "stx7105.h"
#define __WEAK __attribute__((weak))
#define __IRQ __attribute__((interrupt_handler))
#define __WEAK_IRQ __attribute__((weak, interrupt_handler))
#define WEAK_ATTR __attribute__((weak))
#define IRQ_ATTR __attribute__((interrupt_handler))
#define WEAK_IRQ_ATTR __attribute__((weak, interrupt_handler))
typedef enum {
EXP_TYPE_TRAP = 0x160,
EXP_TYPE_RADDERR = 0x0E0,
EXP_TYPE_WADDERR = 0x100,
EXP_TYPE_TRAP = 0x160,
} expevt_type_t;
typedef enum {
@ -13,57 +15,139 @@ typedef enum {
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,
} intevt_type_t;
typedef enum {
TRA_TYPE_SYSCALL = 34,
TRA_TYPE_START_SCHEDULER = 32,
TRA_TYPE_YIELD = 33,
TRA_TYPE_SYSCALL = 34,
} tra_type_t;
/* ========================= TMU 0/1/2 Underrun Interrupt Handlers ================================= */
__WEAK int tuni0_handler(void) {
WEAK_ATTR void tuni0_handler(void) {
/* Does nothing */
return 0;
}
__WEAK int syscall_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
return 0;
WEAK_ATTR void tuni1_handler(void) {
/* Does nothing */
}
__WEAK int trap_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
tra_type_t tra = CSR->TRA;
WEAK_ATTR void tuni2_handler(void) {
/* Does nothing */
}
/* ========================= ASC(UART) 0/1/2 Interrupt Handlers ================================= */
WEAK_ATTR void asc0_handler(void) {
/* Does nothing */
}
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] */
switch (tra) {
case TRA_TYPE_SYSCALL:
return syscall_handler(p1, p2, p3, p4);
syscall_handler(p1, p2, p3, p4);
break;
case TRA_TYPE_YIELD:
yield_handler(p1, p2, p3, p4);
break;
default:
break;
}
return 0;
}
__WEAK_IRQ int general_exc_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
expevt_type_t expevt = CSR->EXPEVT;
/* ========================= 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) {
expevt_type_t expevt = CSP->EXPEVT;
switch (expevt) {
case EXP_TYPE_TRAP:
return trap_handler(p1, p2, p3, p4);
trap_handler(p1, p2, p3, p4);
break;
case EXP_TYPE_RADDERR:
radderr_handler();
break;
case EXP_TYPE_WADDERR:
wadderr_handler();
break;
default:
break;
}
return 0;
}
__WEAK_IRQ int general_int_handler(void) {
intevt_type_t intevt = CSR->INTEVT;
/* ========================= System Interrupt Handlers ================================= */
WEAK_IRQ_ATTR void general_int_handler(void) {
intevt_type_t intevt = CSP->INTEVT;
switch (intevt) {
case INT_TYPE_TMU_TNUI0:
return tuni0_handler();
tuni0_handler();
break;
case INT_TYPE_TMU_TNUI1:
tuni1_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();
break;
default:
break;
}
return 0;
}

View File

@ -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) {
asm("sleep");
while (s_tmu_flag != 1) {
__sleep();
}
s_tmu_flag = 0U;
@ -48,9 +48,7 @@ void delay_ms(uint32_t msec) {
TMU->TSTR &= ~TMU_TSTR_STR0_Msk; /* Stop counter */
}
int tuni0_handler(void) {
void tuni0_handler(void) {
s_tmu_flag = 1U;
TMU->TCR0 &= ~(TMU_TCR_UNF_Msk);
return 0;
}

View File

@ -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,10 +35,9 @@ 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;
}

View File

@ -7,6 +7,7 @@
.section .text.vtors, "ax"
_vtors:
.long _stext
.long _eidata
.long _start

View File

@ -7,13 +7,17 @@ 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 /* LMI virtual address: 0x8000_0000 */
LMI (rwx) : ORIGIN = 0x81000000, LENGTH = 0x0F000000 /* LMI virtual address: 0x8100_0000 */
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 */
}
SECTIONS {
.text : {
. = ALIGN(4);
_stext = .;
KEEP(*(.text.vtors))
*(.text.init)
*(.text.exc)

View File

@ -1,6 +1,6 @@
#!/bin/sh
FLASH_SIZE=1048576
FLASH_SIZE=1015808 # 1048576 - 32768
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}