diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index aebc5afaeb..22d0bf39cd 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -16,7 +16,8 @@ ifeq ($(BOARD),netduino2) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_STM32 LDSCRIPT = stm32.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),microbit) @@ -24,14 +25,26 @@ CFLAGS += -mthumb -mcpu=cortex-m0 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_NRF51 LDSCRIPT = nrf51.ld QEMU_EXTRA = -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144 -SRC_BOARD_O = lib/utils/gchelper_m0.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m0.o +MPY_CROSS_FLAGS += -march=armv7m endif ifeq ($(BOARD),mps2-an385) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_MPS2 LDSCRIPT = mps2.ld -SRC_BOARD_O = lib/utils/gchelper_m3.o +SRC_BOARD_O = lib/utils/gchelper_native.o lib/utils/gchelper_m3.o +MPY_CROSS_FLAGS += -march=armv7m +endif + +ifeq ($(BOARD),sabrelite) +CFLAGS += -mcpu=cortex-a9 +CFLAGS += -DQEMU_SOC_IMX6 +LDSCRIPT = imx6.ld +QEMU_EXTRA = -m 128M +SRC_BOARD_O = lib/utils/gchelper_generic.o +# It's really armv7a but closest supported value is armv6. +MPY_CROSS_FLAGS += -march=armv6 endif CROSS_COMPILE ?= arm-none-eabi- @@ -95,7 +108,6 @@ LIB_SRC_C += $(addprefix lib/,\ libm/atanf.c \ libm/atan2f.c \ libm/roundf.c \ - utils/gchelper_native.c \ utils/sys_stdio_mphal.c \ ) @@ -125,7 +137,6 @@ ifneq ($(FROZEN_MANIFEST),) CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMICROPY_MODULE_FROZEN_MPY CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool -MPY_CROSS_FLAGS += -march=armv7m endif all: run diff --git a/ports/qemu-arm/Makefile.test b/ports/qemu-arm/Makefile.test index 6b7f1dc7ab..b4ad6114b8 100644 --- a/ports/qemu-arm/Makefile.test +++ b/ports/qemu-arm/Makefile.test @@ -4,6 +4,11 @@ FROZEN_MANIFEST ?= "freeze('test-frzmpy')" include Makefile +ifeq ($(BOARD),sabrelite) +# These don't work on Cortex-A9. +TESTS_EXCLUDE = inlineasm/asmdiv.py inlineasm/asmspecialregs.py +endif + CFLAGS += -DTEST .PHONY: $(BUILD)/genhdr/tests.h @@ -11,7 +16,7 @@ CFLAGS += -DTEST $(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h $(BUILD)/genhdr/tests.h: (cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp) - $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py) > $@ + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ $(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING diff --git a/ports/qemu-arm/imx6.ld b/ports/qemu-arm/imx6.ld new file mode 100644 index 0000000000..7155956f15 --- /dev/null +++ b/ports/qemu-arm/imx6.ld @@ -0,0 +1,47 @@ +/* Vector table is at 0x00000000, entry point is 0x10000000. */ + +MEMORY +{ + ROM : ORIGIN = 0x00000000, LENGTH = 96K + RAM : ORIGIN = 0x10000000, LENGTH = 128M +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); + +SECTIONS +{ + .rom : { + . = ALIGN(4); + KEEP(*(.isr_vector)) + . = ALIGN(4); + } > ROM + + .text : { + . = ALIGN(4); + *(.text.Reset_Handler) + *(.text*) + *(.rodata*) + . = ALIGN(4); + _etext = .; + _sidata = _etext; + } > RAM + + .data : AT ( _sidata ) + { + . = ALIGN(4); + _sdata = .; + *(.data*) + . = ALIGN(4); + _edata = .; + } > RAM + + .bss : + { + . = ALIGN(4); + _sbss = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + } > RAM +} diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index 498ab3ed2c..1f05719caa 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -3,9 +3,16 @@ // options to control how MicroPython is built #define MICROPY_ALLOC_PATH_MAX (512) -#define MICROPY_EMIT_X64 (0) + +#if defined(__ARM_ARCH_ISA_ARM) +#define MICROPY_EMIT_ARM (1) +#define MICROPY_EMIT_INLINE_THUMB (1) +#elif defined(__ARM_ARCH_ISA_THUMB) #define MICROPY_EMIT_THUMB (1) #define MICROPY_EMIT_INLINE_THUMB (1) +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) +#endif + #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (0) @@ -43,8 +50,6 @@ // type definitions for the specific machine -#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) - #define MP_SSIZE_MAX (0x7fffffff) #define UINT_FMT "%lu" diff --git a/ports/qemu-arm/startup.c b/ports/qemu-arm/startup.c index 58bdf7af9e..a52b068c33 100644 --- a/ports/qemu-arm/startup.c +++ b/ports/qemu-arm/startup.c @@ -28,6 +28,27 @@ void Default_Handler(void) { } } +#if defined(__ARM_ARCH_ISA_ARM) + +// ARM architecture with standard ARM ISA. + +__attribute__((naked, section(".isr_vector"))) void isr_vector(void) { + __asm volatile ( + "b Reset_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "b Default_Handler\n" + "nop\n" + "b Default_Handler\n" + "b Default_Handler\n" + ); +} + +#elif defined(__ARM_ARCH_ISA_THUMB) + +// ARM architecture with Thumb-only ISA. + const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&_estack, (uint32_t)&Reset_Handler, @@ -47,6 +68,8 @@ const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { (uint32_t)&Default_Handler, // SysTick_Handler }; +#endif + void _start(void) { // Enable the UART uart_init(); @@ -68,7 +91,11 @@ __attribute__((naked)) void exit(int status) { "ldr r1, =0x20026\n" // ADP_Stopped_ApplicationExit, a clean exit ".notclean:\n" "movs r0, #0x18\n" // SYS_EXIT + #if defined(__ARM_ARCH_ISA_ARM) + "svc 0x00123456\n" + #elif defined(__ARM_ARCH_ISA_THUMB) "bkpt 0xab\n" + #endif ); for (;;) { } diff --git a/ports/qemu-arm/uart.c b/ports/qemu-arm/uart.c index 8710e9e9f6..828398cd17 100644 --- a/ports/qemu-arm/uart.c +++ b/ports/qemu-arm/uart.c @@ -75,4 +75,31 @@ void uart_tx_strn(const char *buf, size_t len) { } } +#elif defined(QEMU_SOC_IMX6) + +#define UART_UCR1_UARTEN (1 << 0) +#define UART_UCR2_TXEN (1 << 2) + +typedef struct _UART_t { + volatile uint32_t URXD; // 0x00 + volatile uint32_t r0[15]; + volatile uint32_t UTXD; // 0x40 + volatile uint32_t r1[15]; + volatile uint32_t UCR1; // 0x80 + volatile uint32_t UCR2; // 0x84 +} UART_t; + +#define UART1 ((UART_t *)(0x02020000)) + +void uart_init(void) { + UART1->UCR1 = UART_UCR1_UARTEN; + UART1->UCR2 = UART_UCR2_TXEN; +} + +void uart_tx_strn(const char *buf, size_t len) { + for (size_t i = 0; i < len; ++i) { + UART1->UTXD = buf[i]; + } +} + #endif