Added basic exception handler.

This commit is contained in:
imi415 2022-06-27 00:18:19 +08:00
parent f28dda7542
commit 2de08ba3ee
Signed by: imi415
GPG Key ID: 885EC2B5A8A6F8A7
8 changed files with 317 additions and 67 deletions

View File

@ -8,6 +8,7 @@ set(TARGET_LDSCRIPT "${CMAKE_SOURCE_DIR}/stx7105.ld")
set(TARGET_SOURCES
"src/main.c"
"src/stx7105_exc.c"
"startup_stx7105.S"
"startup_stx7105_init_ram.S"
)
@ -16,7 +17,7 @@ set(TARGET_INCLUDES
"include"
)
set(TARGET_FLAGS_HARDWARE "-m4-300 -ml")
set(TARGET_FLAGS_HARDWARE "-m4a -ml")
set(CMAKE_C_FLAGS_DEBUG "-DDEBUG -g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -g -O0")
@ -26,12 +27,12 @@ set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2 -flto")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2 -flto")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-flto")
set(CMAKE_C_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall")
set(CMAKE_CXX_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall")
set(CMAKE_EXE_LINKER_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall -lc -lm -nostartfiles -Wl,--print-memory-usage")
set(CMAKE_C_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall -ffunction-sections -fdata-sections")
set(CMAKE_CXX_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall -ffunction-sections -fdata-sections")
set(CMAKE_EXE_LINKER_FLAGS "${TARGET_FLAGS_HARDWARE} -Wall -lc -lm -nostartfiles -Wl,--print-memory-usage -Wl,--gc-sections")
add_compile_definitions(TARGET_DEFS)
include_directories(TARGET_INCLUDES)
add_compile_definitions(${TARGET_DEFS})
include_directories(${TARGET_INCLUDES})
add_executable(${CMAKE_PROJECT_NAME}.elf ${TARGET_SOURCES})
target_link_options(${CMAKE_PROJECT_NAME}.elf

99
include/stx7105.h Normal file
View File

@ -0,0 +1,99 @@
#ifndef STX7105_H
#define STX7105_H
#include <stdint.h>
#define __PACKED __attribute__((packed, aligned(1)))
#define __IO volatile
typedef struct __PACKED {
__IO uint8_t POUT; /* Offset: 0x00, GPIO pin output register */
__IO uint8_t UNUSED0[3]; /* Offset: 0x01 */
__IO uint8_t SET_POUT; /* Offset: 0x04, GPIO pin output set register */
__IO uint8_t UNUSED1[3]; /* Offset: 0x05 */
__IO uint8_t CLR_POUT; /* Offset: 0x08, GPIO pin output clear register */
__IO uint8_t UNUSED2[7]; /* Offset: 0x09 */
__IO uint8_t PIN; /* Offset: 0x10, GPIO pin input register */
__IO uint8_t UNUSED3[15]; /* Offset: 0x11 */
__IO uint8_t PC0; /* Offset: 0x20, GPIO pin config register 0 */
__IO uint8_t UNUSED4[3]; /* Offset: 0x21 */
__IO uint8_t SET_PC0; /* Offset: 0x24, GPIO pin config set register 0 */
__IO uint8_t UNUSED5[3]; /* Offset: 0x25 */
__IO uint8_t CLR_PC0; /* Offset: 0x28, GPIO pin config clear register 0 */
__IO uint8_t UNUSED6[7]; /* Offset: 0x29 */
__IO uint8_t PC1; /* Offset: 0x30, GPIO pin config register 1 */
__IO uint8_t UNUSED7[3]; /* Offset: 0x31 */
__IO uint8_t SET_PC1; /* Offset: 0x34, GPIO pin config set register 1 */
__IO uint8_t UNUSED8[3]; /* Offset: 0x35 */
__IO uint8_t CLR_PC1; /* Offset: 0x38, GPIO pin config clear register 1 */
__IO uint8_t UNUSED9[7]; /* Offset: 0x39 */
__IO uint8_t PC2; /* Offset: 0x40, GPIO pin config register 2 */
__IO uint8_t UNUSED10[3]; /* Offset: 0x41 */
__IO uint8_t SET_PC2; /* Offset: 0x44, GPIO pin config set register 2 */
__IO uint8_t UNUSED11[3]; /* Offset: 0x45 */
__IO uint8_t CLR_PC2; /* Offset: 0x48, GPIO pin config clear register 2 */
__IO uint8_t UNUSED12[7]; /* Offset: 0x49 */
__IO uint8_t PCOMP; /* Offset: 0x50, GPIO pin input comparison register */
__IO uint8_t UNUSED13[3]; /* Offset: 0x51 */
__IO uint8_t SET_PCOMP; /* Offset: 0x54, GPIO pin input comparison set regiser */
__IO uint8_t UNUSED14[3]; /* Offset: 0x55 */
__IO uint8_t CLR_PCOMP; /* Offset: 0x58, GPIO pin input comparison clear regiser */
__IO uint8_t UNUSED15[7]; /* Offset: 0x59 */
__IO uint8_t PMASK; /* Offset: 0x60, GPIO pin input comparison mask register */
__IO uint8_t UNUSED16[3]; /* Offset: 0x61 */
__IO uint8_t SET_PMASK; /* Offset: 0x64, GPIO pin input comparison mask set regiser */
__IO uint8_t UNUSED17[3]; /* Offset: 0x65 */
__IO uint8_t CLR_PMASK; /* Offset: 0x68, GPIO pin input comparison mask clear regiser */
} PIO_TypeDef;
typedef struct __PACKED {
__IO uint32_t BAUDRATE; /* Offset: 0x00, ASCn baud rate generator register */
__IO uint32_t TX_BUF; /* Offset: 0x04, ASCn transmit buffer register */
__IO uint32_t RX_BUF; /* Offset: 0x08, ASCn receive buffer register */
__IO uint32_t CTRL; /* Offset: 0x0C, ASCn control register */
__IO uint32_t INT_EN; /* Offset: 0x10, ASCn interrupt enable register */
__IO uint32_t STA; /* Offset: 0x14, ASCn interrupt status register */
__IO uint32_t GUARDTIME; /* Offset: 0x18, ASCn guard time register */
__IO uint32_t TIMEOUT; /* Offset: 0x1C, ASCn time out register */
__IO uint32_t TX_RST; /* Offset: 0x20, ASCn transmit FIFO reset register */
__IO uint32_t RX_RST; /* Offset: 0x24, ASCn receive FIFO reset register */
__IO uint32_t RETRIES; /* Offset: 0x28, ASCn number of retries on transmission register */
} ASC_TypeDef;
typedef struct __PACKED {
__IO uint8_t TOCR; /* Offset: 0x00, Timer output control register */
__IO uint8_t UNUSED0[3]; /* Offset: 0x01 */
__IO uint8_t TSTR; /* Offset: 0x04, Timer start register */
__IO uint8_t UNUSED1[3]; /* Offset: 0x05 */
__IO uint32_t TCOR0; /* Offset: 0x08, Timer constant register 0 */
__IO uint32_t TCNT0; /* Offset: 0x0C, Timer counter 0 */
__IO uint16_t TCR0; /* Offset: 0x10, Timer control register 0 */
__IO uint8_t UNUSED2[2]; /* Offset: 0x11 */
__IO uint32_t TCOR1; /* Offset: 0x14, Timer constant register 1 */
__IO uint32_t TCNT1; /* Offset: 0x18, Timer counter 1 */
__IO uint16_t TCR1; /* Offset: 0x1C, Timer control register 1 */
__IO uint8_t UNUSED3[2]; /* Offset: 0x1D */
__IO uint32_t TCOR2; /* Offset: 0x20, Timer constant register 2 */
__IO uint32_t TCNT2; /* Offset: 0x24, Timer counter 2 */
__IO uint16_t TCR2; /* Offset: 0x28, Timer control register 2 */
__IO uint8_t UNUSED4[2]; /* Offset: 0x29 */
__IO uint32_t TCPR2; /* Offset: 0x2C */
} TMU_TypeDef;
#define PIO0_BASE (0xFD020000U)
#define PIO4_BASE (0xFD024000U)
#define ASC0_BASE (0xFD030000U)
#define ASC1_BASE (0xFD031000U)
#define ASC2_BASE (0xFD032000U)
#define ASC3_BASE (0xFD033000U)
#define TMU_BASE (0xFFD80000U)
#define PIO0 ((PIO_TypeDef *)PIO0_BASE)
#define PIO4 ((PIO_TypeDef *)PIO4_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 TMU ((TMU_TypeDef *)TMU_BASE)
#endif

View File

@ -1,82 +1,101 @@
#include <stdint.h>
#include <stdio.h>
#define ST_GPIO0_BASE_ADDR (0xFD020000)
#define ST_GPIO0_OFFSET_POUT 0x00U
#define ST_GPIO0_OFFSET_SET_POUT 0x04U
#define ST_GPIO0_OFFSET_CLR_POUT 0x08U
#define ST_GPIO0_OFFSET_PC0 0x20U
#define ST_GPIO0_OFFSET_SET_PC0 0x24U
#define ST_GPIO0_OFFSET_CLR_PC0 0x28U
#define ST_GPIO0_OFFSET_PC1 0x30U
#define ST_GPIO0_OFFSET_SET_PC1 0x34U
#define ST_GPIO0_OFFSET_CLR_PC1 0x38U
#define ST_GPIO0_OFFSET_PC2 0x40U
#define ST_GPIO0_OFFSET_SET_PC2 0x44U
#define ST_GPIO0_OFFSET_CLR_PC2 0x48U
#define SH_TMU_BASE_ADDR (0xFFD80000)
#define SH_TMU_OFFSET_TOCR 0x00U
#define SH_TMU_OFFSET_TSTR 0x04U
#define SH_TMU_OFFSET_TCOR0 0x08U
#define SH_TMU_OFFSET_TCNT0 0x0CU
#define SH_TMU_OFFSET_TCR0 0x10U
#define SH_TMU_OFFSET_TCOR1 0x14U
#define SH_TMU_OFFSET_TCNT1 0x18U
#define SH_TMU_OFFSET_TCR1 0x1CU
#define SH_TMU_OFFSET_TCOR2 0x20U
#define SH_TMU_OFFSET_TCNT2 0x24U
#define SH_TMU_OFFSET_TCR2 0x28U
#define SH_TMU_OFFSET_TCPR2 0x2CU
#include "stx7105.h"
#define LED_RED_GPIO PIO0
#define LED_RED_PIN 5U
#define LED_BLUE_PIN 4U
static void init_led(uint8_t pin) {
*(uint32_t *)(ST_GPIO0_BASE_ADDR + ST_GPIO0_OFFSET_CLR_PC0) = (1 << pin);
*(uint32_t *)(ST_GPIO0_BASE_ADDR + ST_GPIO0_OFFSET_SET_PC1) = (1 << pin);
*(uint32_t *)(ST_GPIO0_BASE_ADDR + ST_GPIO0_OFFSET_CLR_PC2) = (1 << pin);
#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 */
static void set_led(PIO_TypeDef *gpiox, uint8_t pin, uint8_t val);
static void init_led(PIO_TypeDef *gpiox, uint8_t pin, uint8_t init_value) {
gpiox->CLR_PC0 = 1 << pin;
gpiox->SET_PC1 = 1 << pin;
gpiox->CLR_PC2 = 1 << pin;
set_led(gpiox, pin, init_value);
}
static void set_led(uint8_t pin, uint8_t val) {
static void set_led(PIO_TypeDef *gpiox, uint8_t pin, uint8_t val) {
if (val) {
*(uint32_t *)(ST_GPIO0_BASE_ADDR + ST_GPIO0_OFFSET_SET_POUT) = (1 << pin);
gpiox->SET_POUT = (1 << pin);
} else {
*(uint32_t *)(ST_GPIO0_BASE_ADDR + ST_GPIO0_OFFSET_CLR_POUT) = (1 << pin);
gpiox->CLR_POUT = (1 << pin);
}
}
static void delay_ms(uint32_t msec) {
/* Initialize TMU and count to zero */
/* TMU clock is from Peripheral clock, approx. 66MHz */
/* Prescale to 450kHz for convenience (TMUs can only divide by max. 1024) */
/* Prescale to 66kHz for convenience (TMUs can only divide by max. 1024) */
*(uint8_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TSTR) &= ~1U; /* Stop counter */
*(uint16_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TCR0) = 0x04U; /* 1024 prescale */
*(uint32_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TCNT0) = (msec * 66); /* 66kHz */
*(uint8_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TSTR) |= 1U; /* Start counter */
uint32_t reload_value = msec * 66 - 1;
TMU->TSTR &= ~1U; /* Stop counter */
TMU->TCR0 = 0x04U; /* 1024 prescale */
TMU->TCNT0 = reload_value; /* 66kHz */
TMU->TCOR0 = reload_value; /* Reload register */
TMU->TSTR |= 1U; /* Start counter */
/* Wait until underflow occurs */
uint16_t tcr0 = 0U;
do {
tcr0 = *(uint16_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TCR0);
tcr0 = TMU->TCR0;
} while ((tcr0 & 0x100) == 0);
*(uint8_t *)(SH_TMU_BASE_ADDR + SH_TMU_OFFSET_TSTR) &= ~1U; /* Stop counter */
TMU->TSTR &= ~1U; /* Stop counter */
}
static void uart_init(void) {
PIO4->CLR_PC0 = 1U; /* PC = 110, AFOUT, PP */
PIO4->SET_PC1 = 1U;
PIO4->SET_PC2 = 1U;
// *(uint32_t *)SYSTEM_CONFIG34 = 0x00000100UL; /* BIT[8,0] = 10, AF 3 */
// *(uint32_t *)SYSTEM_CONFIG7 &= ~(0x00000006UL); /* BIT[2:1], UART2 RX SEL */
// CONSOLE_ASC->CTRL = 0x1509UL; /* 8N1, RX enable, FIFO enable, Baud mode 1 */
// CONSOLE_ASC->BAUDRATE = 0x04B8UL; /* 115200 in baud mode 1, assuming Fcomm=100MHz */
// CONSOLE_ASC->TX_RST = 0x01UL; /* Reset TX FIFO, any value OK */
// CONSOLE_ASC->RX_RST = 0x01UL; /* Reset RX FIFO, any value OK */
// CONSOLE_ASC->CTRL = 0x1589UL; /* 8N1, RX enable, FIFO enable, Baud mode 1 */
}
int main(void) {
init_led(LED_RED_PIN);
init_led(LED_BLUE_PIN);
// init_led(LED_RED_GPIO, LED_RED_PIN, 0U);
// init_led(LED_BLUE_GPIO, LED_BLUE_PIN, 0U);
set_led(LED_RED_PIN, 0);
set_led(LED_BLUE_PIN, 0);
// if(*(uint32_t *)SYSTEM_DEVID != 0x2D43E041UL) {
// set_led(LED_RED_GPIO, LED_RED_PIN, 1U);
// }
*(uint32_t *)SYSTEM_CONFIG34 = 0x00000100UL; /* BIT[8,0] = 10, AF 3 */
uart_init();
// for (uint16_t i = 0; i < 65534; i++) {
// CONSOLE_ASC->TX_BUF = i;
// while (CONSOLE_ASC->STA & 0x200) {
// /**/
// }
// }
// printf("Hello world\r\n");
for (;;) {
/* Dead loop */
set_led(LED_BLUE_PIN, 1);
delay_ms(1);
set_led(LED_BLUE_PIN, 0);
delay_ms(1);
// set_led(LED_BLUE_GPIO, LED_BLUE_PIN, 1);
// delay_ms(1000);
// set_led(LED_BLUE_GPIO, LED_BLUE_PIN, 0);
// delay_ms(1000);
}
}

61
src/stx7105_exc.c Normal file
View File

@ -0,0 +1,61 @@
#include "stx7105.h"
#define EXPEVT_BASE 0xFF000024
#define TRA_BASE 0xFF000020
typedef enum {
EXP_TYPE_TRAP = 0x160,
} expevt_type_t;
typedef enum {
TRA_TYPE_SYSCALL = 34,
} tra_type_t;
static int uart_write(char *ptr, int len) {
for (int i = 0; i < len; i++) {
while (ASC2->STA & 0x200) {
/* TX FIFO full... */
}
ASC2->TX_BUF = (uint8_t)ptr[i];
}
return len;
}
static int syscall_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
if (p1 == 4) {
return uart_write((char *)p3, (int)p4);
}
return 0;
}
static int trap_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
tra_type_t tra = *(uint32_t *)TRA_BASE;
switch (tra) {
case TRA_TYPE_SYSCALL:
return syscall_handler(p1, p2, p3, p4);
break;
default:
break;
}
return 0;
}
__attribute__((interrupt_handler)) int general_exc_handler(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
expevt_type_t expevt = *(uint32_t *)EXPEVT_BASE;
PIO0->SET_POUT = (1 << 5);
switch (expevt) {
case EXP_TYPE_TRAP:
trap_handler(p1, p2, p3, p4);
break;
default:
break;
}
return 0;
}

View File

@ -30,6 +30,7 @@ _start:
mov.l r0, @r1
mov.l _gpio_clr_pc2_k, r1
mov.l r0, @r1
mov.l _sr_k, r0
ldc r0, sr
mov.l _stack_k, sp /* Setup R15(SP) */
@ -144,7 +145,12 @@ _enable_se_mode:
mov.l _ccn_pascr_value_k, r1
mov.l r1, @r0
mova _copy_data, r0
_setup_irq:
mov.l _exc_base_k, r0
ldc r0, vbr
_go_non_privileged:
mov.l _crt0_entry, r0
ldc r0, spc
stc sr, r0
ldc r0, ssr
@ -162,7 +168,7 @@ _loop_copy_data:
mov.l @r0+, r3 /* Load a word to r3 from [sidata], with post-increment of 4 */
mov.l r3, @r1 /* Store the word in r3 to [sdata] */
add #4, r1 /* Increment sdata pointer */
cmp/ge r1, r2
cmp/gt r1, r2 /* r2 greater or equal than r1? */
bt _loop_copy_data
_zero_bss:
@ -173,7 +179,7 @@ _zero_bss:
_loop_zero_bss:
mov.l r2, @r0
add #4, r0
cmp/ge r0, r1
cmp/gt r0, r1
bt _loop_zero_bss
/* Turn on Blue LED */
@ -187,11 +193,6 @@ _setup_fpu:
mov #0, r4
lds r3, fpscr
/* Turn on Red LED */
mov #32, r7
mov.l _gpio_set_k, r8
mov.l r7, @r8
_main_entry:
mov.l _main_k, r0
jsr @r0
@ -284,6 +285,9 @@ _gpio_set_pc1_k:
_gpio_clr_pc2_k:
.long 0xFD020048
_crt0_entry:
.long _copy_data
/* libc FPU routine */
_set_fpscr_k:
.long ___set_fpscr
@ -307,3 +311,19 @@ _main_k:
.long _main /* Same address as main */
_exit_k:
.long _exit
_exc_base_k:
.long _exc_base
.section .text.exc, "ax"
.align 4
_exc_base:
.org 0x100, 0x00
_exc_grnl_vector:
mov.l _exc_grnl_entry, r0
jmp @r0
nop
.align 4
_exc_grnl_entry:
.long _general_exc_handler

View File

@ -15,6 +15,7 @@ SECTIONS {
.text : {
. = ALIGN(4);
*(.text.init)
*(.text.exc)
*(.text)
*(.text*)
*(.rodata)
@ -22,23 +23,25 @@ SECTIONS {
. = ALIGN(4);
} >EMI
_sidata = LOADADDR(.data);
.data : {
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} >LMI AT >EMI
_sidata = LOADADDR(.data);
.bss : {
. = ALIGN(4);
__bss_start = .;
*(.bss)
*(.bss*)
*(COMMON)
_end = ALIGN(8);
. = ALIGN(8);
_end = .;
__end = _end;
} >LMI

14
tools/flash_image.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
IMAGE_NAME=$1
if [ -z "${IMAGE_NAME}" ] ; then
IMAGE_NAME=image.bin
fi
if [ ! -f "${IMAGE_NAME}" ] ; then
echo "binary not exist."
exit -1
fi
flashrom --programmer ch341a_spi -w "${IMAGE_NAME}"

33
tools/pad_image.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
FLASH_SIZE=1048576
INPUT_IMAGE="$1"
BINARY_NAME="$2"
# ELF name not a valid name.
if [ ! -f "${INPUT_IMAGE}" ] ; then
echo "No such file."
exit -1
fi
# Output name not set..
if [ -z "${BINARY_NAME}" ] ; then
echo "Binary name not set, using default"
BINARY_NAME="image.bin"
fi
# Create binary file from ELF
sh-unknown-elf-objcopy -O binary ${INPUT_IMAGE} ${BINARY_NAME}
if [ "$?" -lt "0" ] ; then
exit -2
fi
# Calculate size and padding length
BINARY_SIZE=`stat --format "%s" ${BINARY_NAME}`
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}