147 lines
3.2 KiB
C
147 lines
3.2 KiB
C
|
|
#include <bsp/gctl.h>
|
|
#include <bsp/gpio.h>
|
|
#include <bsp/uart.h>
|
|
#include <bsp/usb.h>
|
|
#include <bsp/irq.h>
|
|
#include <bsp/cache.h>
|
|
#include <bsp/util.h>
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
static uint8_t bytecode[] = {
|
|
0x05, // iconst_2
|
|
0x05, // iconst_2
|
|
0x60, // iadd
|
|
0xAC, // ireturn
|
|
};
|
|
|
|
__attribute__((__aligned__(1024)))
|
|
static struct {
|
|
void* handlers[512];
|
|
uint8_t stack[256];
|
|
uint8_t locals[256];
|
|
} jazelle_block;
|
|
|
|
static void handler_ireturn(void) {
|
|
int32_t result;
|
|
asm volatile(
|
|
"ldr %[res], [r6, #-4]!\n"
|
|
"bkpt #1\n"
|
|
:[res]"=r"(result)
|
|
);
|
|
while (true); // a
|
|
}
|
|
|
|
static void jazelle_exec(const uint8_t* bytecode) {
|
|
jazelle_block.handlers[0xAC] = handler_ireturn;
|
|
const void* block = &jazelle_block;
|
|
|
|
asm volatile(
|
|
"push {lr}\n"
|
|
// set configuration valid & jazelle enable bits
|
|
"mov r0, #2\n"
|
|
"mcr p14, 7, r0, c1, c0, 0\n"
|
|
"mov r0, #1\n"
|
|
"mcr p14, 7, r0, c2, c0, 0\n"
|
|
|
|
"mov lr, %[bc]\n"
|
|
|
|
// init handler table pointer and stack pointer
|
|
"mov r5, %[blk]\n"
|
|
"add r6, r5, #0x800\n"
|
|
"add r7, r5, #0x900\n"
|
|
|
|
// switch to jazelle mode
|
|
"adr r12, .Lno_jazelle\n"
|
|
"bxj r12\n"
|
|
"bkpt #0\n"
|
|
"b .Lend\n"
|
|
".Lno_jazelle:\n"
|
|
"mov r0, #0\n"
|
|
"mcr p14, 7, r0, c1, c0, 0\n"
|
|
"mcr p14, 7, r0, c2, c0, 0\n"
|
|
"bkpt #2\n"
|
|
".Lend:\n"
|
|
"pop {lr}\n"
|
|
:
|
|
:[bc]"r"(bytecode),[blk]"r"(block)
|
|
:"r0","r12","r5","r6","r7","memory");
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
Fx3CacheEnableCaches();
|
|
Fx3IrqInit();
|
|
|
|
Fx3GctlInitClock();
|
|
*(volatile uint32_t *)(void *)0x400020e8 = 0;
|
|
Fx3GctlInitIoMatrix(FX3_GCTL_ALTFUNC_GPIF32BIT_UART_I2S);
|
|
/*Fx3UartInit(115200, FX3_UART_NO_PARITY, FX3_UART_1_STOP_BIT);
|
|
Fx3UartTxString("\nhello world\n");
|
|
Fx3UartTxFlush();
|
|
|
|
Fx3GpioInitClock();
|
|
Fx3GpioSetupSimple(45,
|
|
FX3_GPIO_SIMPLE_ENABLE |
|
|
FX3_GPIO_SIMPLE_INPUT_EN);
|
|
Fx3GpioSetupSimple(54,
|
|
FX3_GPIO_SIMPLE_ENABLE |
|
|
FX3_GPIO_SIMPLE_DRIVE_HI_EN |
|
|
FX3_GPIO_SIMPLE_DRIVE_LO_EN);
|
|
Fx3GpioSetupComplex(50,
|
|
FX3_PIN_STATUS_ENABLE |
|
|
(FX3_GPIO_TIMER_MODE_SLOW_CLK << FX3_PIN_STATUS_TIMER_MODE_SHIFT) |
|
|
(FX3_GPIO_PIN_MODE_PWM << FX3_PIN_STATUS_MODE_SHIFT) |
|
|
FX3_PIN_STATUS_DRIVE_HI_EN |
|
|
FX3_PIN_STATUS_DRIVE_LO_EN,
|
|
0, GPIO_SLOW_CLK/1000-1, GPIO_SLOW_CLK/2000);
|
|
|
|
Fx3IrqEnableInterrupts();*/
|
|
|
|
jazelle_exec(bytecode);
|
|
|
|
while (true) ; // a
|
|
}
|
|
|
|
/* Newlib's assert() calls this function if the assertion fails */
|
|
void
|
|
__assert_func (const char *file,
|
|
int line,
|
|
const char *func,
|
|
const char *failedexpr)
|
|
{
|
|
if (file != NULL) {
|
|
char linestrbuf[16], *linestr = &linestrbuf[sizeof(linestrbuf)];
|
|
Fx3UartTxString(file);
|
|
Fx3UartTxChar(':');
|
|
/* Avoid using newlib functions like itoa so as not to trigger
|
|
a recursive assert... */
|
|
*--linestr = '\0';
|
|
while (line >= 10 && linestr != &linestrbuf[1]) {
|
|
*--linestr = '0' + (line % 10);
|
|
line /= 10;
|
|
}
|
|
*--linestr = '0' + line;
|
|
Fx3UartTxString(linestr);
|
|
Fx3UartTxString(": ");
|
|
}
|
|
if (func != NULL) {
|
|
Fx3UartTxString(func);
|
|
Fx3UartTxString(": ");
|
|
}
|
|
Fx3UartTxString("Assertion ");
|
|
if (failedexpr != NULL) {
|
|
Fx3UartTxChar('`');
|
|
Fx3UartTxString(failedexpr);
|
|
Fx3UartTxString("' ");
|
|
}
|
|
Fx3UartTxString("failed.\n");
|
|
for(;;)
|
|
;
|
|
}
|