* [Qemu-devel] Cortex-M development progress
@ 2014-11-25 19:58 Liviu Ionescu
2014-11-25 20:37 ` Peter Maydell
0 siblings, 1 reply; 3+ messages in thread
From: Liviu Ionescu @ 2014-11-25 19:58 UTC (permalink / raw)
To: QEMU Developers
As mentioned in a previous message, I started work on a more detailed implementation for the M profile.
At first I defined in target-arm/cpu.c the cpu-s for all variants (M0/M0+/M1/M3/M4/M7).
/* Cortex-M cores. Currently only M3 is tested and fully functional. */
{ .name = "cortex-m0", .initfn = cortex_m0_initfn,
.class_init = arm_v6m_class_init },
{ .name = "cortex-m0p", .initfn = cortex_m0p_initfn,
.class_init = arm_v6m_class_init },
{ .name = "cortex-m1", .initfn = cortex_m1_initfn,
.class_init = arm_v6m_class_init },
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
.class_init = arm_v7m_class_init },
{ .name = "cortex-m7", .initfn = cortex_m7_initfn,
.class_init = arm_v7m_class_init },
The proper flags might still need adjustments, but at least we have a starting point.
Same for functionality, I did not add any SIMD & FPU instructions, these will come later, on an as-needed basis.
Then I defined (in a new file named hw/arm/cortexm.c) initialisation functions for all cores:
qemu_irq *cortex_m0_core_init(cortex_m_core_info *cm_info, MachineState *machine);
qemu_irq *cortex_m0p_core_init(cortex_m_core_info *cm_info, MachineState *machine);
qemu_irq *cortex_m3_core_init(cortex_m_core_info *cm_info, MachineState *machine);
qemu_irq *cortex_m4_core_init(cortex_m_core_info *cm_info, MachineState *machine);
qemu_irq *cortex_m7_core_init(cortex_m_core_info *cm_info, MachineState *machine);
Based on the ARM cores I defined, in separate files for each MCU family, initialisation functions for many MCUs:
qemu_irq *stm32f407vg_mcu_init(MachineState *machine);
qemu_irq *stm32f407zg_mcu_init(MachineState *machine);
qemu_irq *stm32f405rg_mcu_init(MachineState *machine);
qemu_irq *stm32f411re_mcu_init(MachineState *machine);
qemu_irq *stm32f429zi_mcu_init(MachineState *machine);
qemu_irq *stm32f334r8_mcu_init(MachineState *machine);
qemu_irq *stm32f303vc_mcu_init(MachineState *machine);
qemu_irq *stm32f205rf_mcu_init(MachineState *machine);
qemu_irq *stm32f107vc_mcu_init(MachineState *machine);
qemu_irq *stm32f103rb_mcu_init(MachineState *machine);
qemu_irq *stm32f100rb_mcu_init(MachineState *machine);
qemu_irq *stm32f051r8_mcu_init(MachineState *machine);
qemu_irq *stm32l152re_mcu_init(MachineState *machine);
qemu_irq *mk20dx128vlh5_mcu_init(MachineState *machine);
qemu_irq *mk64fn1m0vll12_mcu_init(MachineState *machine);
qemu_irq *mkl25z128vlk4_mcu_init(MachineState *machine);
qemu_irq *mk60fn1m0vlq12_mcu_init(MachineState *machine);
qemu_irq *mkl25z128vlk4_mcu_init(MachineState *machine);
qemu_irq *mkl26z128vlh4_mcu_init(MachineState *machine);
qemu_irq *mkl46z256vll4_mcu_init(MachineState *machine);
qemu_irq *mk22fn512vlh12_mcu_init(MachineState *machine);
qemu_irq *mkl43z256vlh4_mcu_init(MachineState *machine);
qemu_irq *lpc1769fbd100_mcu_init(MachineState *machine);
qemu_irq *tm4c123gh6pm_mcu_init(MachineState *machine);
qemu_irq *sam3s4b_mcu_init(MachineState *machine);
qemu_irq *xmc4500_f100k1024_mcu_init(MachineState *machine);
qemu_irq *xmc4500_f100f1024_mcu_init(MachineState *machine);
qemu_irq *xmc4500_f144k1024_mcu_init(MachineState *machine);
qemu_irq *xmc4400_f100k512_mcu_init(MachineState *machine);
qemu_irq *xmc4200_q48k256_mcu_init(MachineState *machine);
qemu_irq *xmc1300_t038x200_mcu_init(MachineState *machine);
qemu_irq *xmc1302_t038x200_mcu_init(MachineState *machine);
qemu_irq *xmc1201_t038x200_mcu_init(MachineState *machine);
qemu_irq *xmc1100_t038x064_mcu_init(MachineState *machine);
qemu_irq *xmc1100_q024f0064_mcu_init(MachineState *machine);
Then I defined several boards, grouped in separate files:
qemu_register_machine(&stm32f429i_discovery_machine);
qemu_register_machine(&stm32f4_discovery_machine);
qemu_register_machine(&stm32f3_discovery_machine);
qemu_register_machine(&stm32f0_discovery_machine);
qemu_register_machine(&stm32vl_discovery_machine);
qemu_register_machine(&netduino2_machine);
qemu_register_machine(&netduinoplus2_machine);
qemu_register_machine(&netduinogo_machine);
qemu_register_machine(&mapple_machine);
qemu_register_machine(&nucleo_f411re_machine);
qemu_register_machine(&nucleo_f334r8_machine);
qemu_register_machine(&nucleo_f103rb_machine);
qemu_register_machine(&nucleo_l152re_machine);
qemu_register_machine(&stm32_e407_machine);
qemu_register_machine(&stm32_p107_machine);
qemu_register_machine(&stm32_p103_machine);
qemu_register_machine(&stm32_h103_machine);
qemu_register_machine(&olimexino_stm32_machine);
qemu_register_machine(&frdm_k20d50m_machine);
qemu_register_machine(&frdm_k64f_machine);
qemu_register_machine(&frdm_k22f_machine);
qemu_register_machine(&twr_k60f120m_machine);
qemu_register_machine(&frdm_kl25z_machine);
qemu_register_machine(&frdm_kl26z_machine);
qemu_register_machine(&frdm_kl46z_machine);
qemu_register_machine(&frdm_kl43z_machine);
qemu_register_machine(&lpcxpresso_lpc1769_machine);
qemu_register_machine(&ek_tm4c123gxl_machine);
qemu_register_machine(&sam3_h256_machine);
qemu_register_machine(&xmc4500_enterprise_kit_machine);
qemu_register_machine(&xmc4400_enterprise_kit_machine);
qemu_register_machine(&xmc4200_enterprise_kit_machine);
qemu_register_machine(&xmc4500_relax_kit_machine);
qemu_register_machine(&xmc4500_relax_lite_kit_machine);
qemu_register_machine(&xmc1300_boot_kit_machine);
qemu_register_machine(&xmc1200_boot_kit_machine);
qemu_register_machine(&xmc1100_boot_kit_machine);
qemu_register_machine(&xmc2go_machine);
The result looks like:
GNU ARM Eclipse QEMU v2.1.92 (qemu-system-gnuarmeclipse).
Supported machines are:
EK-TM4C123GXL TI Tiva C Series TM4C123GXL LaunchPad Evaluation Kit (Experimental)
FRDM-K20D50M Freescale Freedom Development Platform for Kinetis K20 USB MCUs (Experimental)
FRDM-K22F Freescale Freedom Development Platform for Kinetis K22 MCUs (Experimental)
FRDM-K64F Freescale Freedom Development Platform for Kinetis K6[34] and K24 MCUs (Experimental)
FRDM-KL25Z Freescale Freedom Development Platform for Kinetis KL[12][45] MCUs (Experimental)
FRDM-KL26Z Freescale Freedom Development Platform for Kinetis KL[12]6 MCUs (Experimental)
FRDM-KL43Z Freescale Freedom Development Platform for Kinetis KL[34]3, KL[12]7 MCUs (Experimental)
FRDM-KL46Z Freescale Freedom Development Platform for Kinetis KL[34]x MCUs (Experimental)
LPCXpresso-LPC1769 Embedded Artists LPCXpresso LPC1769 Development Board (Experimental)
Mapple LeafLab Arduino-style STM32 microcontroller board (Experimental)
NUCLEO-F103RB ST Nucleo Development Board for STM32 F1 series (Experimental)
NUCLEO-F334R8 ST Nucleo Development Board for STM32 F3 series (Experimental)
NUCLEO-F411RE ST Nucleo Development Board for STM32 F4 series (Experimental)
NUCLEO-L152RE ST Nucleo Development Board with STM32L152RET6 (Experimental)
Netduino2 Netduino Development Board with STM32F2 (Experimental)
NetduinoGo Netduino GoBus Development Board with STM32F4 (Experimental)
NetduinoPlus2 Netduino Development Board with STM32F4 (Experimental)
OLIMEXINO-STM32 Olimex Mapple (Arduino-like) Development Board (Experimental)
SAM3-H256 Olimex Header Board for ATSAM3S4BA (Experimental)
STM32-E407 Olimex Development Board for STM32F407ZGT6 (Experimental)
STM32-H103 Olimex Header Board for STM32F103RBT6 (Experimental)
STM32-P103 Olimex Prototype Board for STM32F103RBT6 (Experimental)
STM32-P107 Olimex Prototype Board for STM32F107VCT6 (Experimental)
STM32F0-Discovery ST Discovery kit for STM32F051 line (Experimental)
STM32F3-Discovery ST Discovery kit for STM32F303 line (Experimental)
STM32F4-Discovery ST Discovery kit for STM32F407/417 lines (Experimental)
STM32F429I-Discovery ST Discovery kit for STM32F429/439 lines (Experimental)
STM32VL-Discovery ST Discovery kit for STM32F100 Value Line (Experimental)
TWR-K60F120M Freescale Kinetis K60 120 MHz Tower System Module (Experimental)
XMC 2Go Infineon XMC 2Go Kit with XMC1100 (Experimental)
XMC1100 Boot Kit Infineon CPU Card XMC1100 Boot Kit Entry Series (Experimental)
XMC1200 Boot Kit Infineon CPU Card XMC1200 Boot Kit Feature Series (Experimental)
XMC1300 Boot Kit Infineon CPU Card XMC1300 Boot Kit Control Series (Experimental)
XMC4200 Enterprise Kit Infineon CPU Board XMC4200 Actuator (Experimental)
XMC4400 Enterprise Kit Infineon CPU Board XMC4400 General Purpose (Experimental)
XMC4500 Enterprise Kit Infineon CPU Board XMC4500 General Purpose (Experimental)
XMC4500 Relax Kit Infineon CPU Board XMC4500 Relax Kit (Experimental)
XMC4500 Relax Lite Kit Infineon CPU Board XMC4500 Relax Lite Kit (Experimental)
akita Akita PDA (PXA270)
borzoi Borzoi PDA (PXA270)
...
xilinx-zynq-a9 Xilinx Zynq Platform Baseboard for Cortex-A9
z2 Zipit Z2 (PXA27x)
According to my tests, the core initialisations are enough to run a simple SysTick timer application.
ilg-mbp:build ilg$ /Users/ilg/Work/qemu/gnuarmeclipse-qemu.git/gnuarmeclipse-softmmu/qemu-system-gnuarmeclipse -machine STM32F0-Discovery -verbose -semihosting-config target=native,cmdline="1 2 3" -kernel /Users/ilg/My\ Files/MacBookPro\ Projects/GNU\ ARM\ Eclipse/Eclipse\ Workspaces/runtime-EclipseGNUARMPlug-ins/cm0/Debug/cm0.elf
GNU ARM Eclipse QEMU v2.1.92 (qemu-system-gnuarmeclipse).
Board: 'STM32F0-Discovery' (ST Discovery kit for STM32F051 line (Experimental)).
Device: 'STM32F051R8' (cortex-m0), Flash: 64 KB, RAM: 8 KB.
Image: '/Users/ilg/My Files/MacBookPro Projects/GNU ARM Eclipse/Eclipse Workspaces/runtime-EclipseGNUARMPlug-ins/cm0/Debug/cm0.elf'.
Command line: '1 2 3' (5 bytes).
main(argc=3, argv=["1", "2", "3"]);
Hello ARM World!
Standard output message.
Standard error message.
System clock: 8000000Hz
Second 1
Second 2
Second 3
Second 4
Second 5
Done.
ilg-mbp:build ilg$
In the next step I plan to add support for Clock & PLL inits for the ST families, so that the CMSIS SysInit() to pass.
---
The sources are pushed on my GNU ARM Eclipse site (git://git.code.sf.net/p/gnuarmeclipse/qemu), the gnuarmeclipse-cortexm branch, available for browsing at
https://sourceforge.net/p/gnuarmeclipse/qemu/ci/gnuarmeclipse-cortexm/tree/
I would appreciate any comments, suggestions.
After implementing some peripherals I'll have a better understanding on the entire Cortex-M emulation.
If this is of use for the project, we can certainly find solutions for integrating it, and possibly use as a base for Alistair Francis & Andre Bechus work.
Regards,
Liviu
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] Cortex-M development progress
2014-11-25 19:58 [Qemu-devel] Cortex-M development progress Liviu Ionescu
@ 2014-11-25 20:37 ` Peter Maydell
2014-11-25 21:37 ` Liviu Ionescu
0 siblings, 1 reply; 3+ messages in thread
From: Peter Maydell @ 2014-11-25 20:37 UTC (permalink / raw)
To: Liviu Ionescu; +Cc: QEMU Developers
On 25 November 2014 at 19:58, Liviu Ionescu <ilg@livius.net> wrote:
> As mentioned in a previous message, I started work on a more detailed implementation for the M profile.
>
> At first I defined in target-arm/cpu.c the cpu-s for all variants (M0/M0+/M1/M3/M4/M7).
>
> /* Cortex-M cores. Currently only M3 is tested and fully functional. */
> { .name = "cortex-m0", .initfn = cortex_m0_initfn,
> .class_init = arm_v6m_class_init },
> { .name = "cortex-m0p", .initfn = cortex_m0p_initfn,
> .class_init = arm_v6m_class_init },
> { .name = "cortex-m1", .initfn = cortex_m1_initfn,
> .class_init = arm_v6m_class_init },
> { .name = "cortex-m3", .initfn = cortex_m3_initfn,
> .class_init = arm_v7m_class_init },
> { .name = "cortex-m4", .initfn = cortex_m4_initfn,
> .class_init = arm_v7m_class_init },
> { .name = "cortex-m7", .initfn = cortex_m7_initfn,
> .class_init = arm_v7m_class_init },
>
> The proper flags might still need adjustments, but at least we have a starting point.
I would recommend concentrating on one of these and getting
it right, rather than defining five new cores and dozens
of MCUs none of which are actually implemented to their
specifications.
> According to my tests, the core initialisations are enough
> to run a simple SysTick timer application.
This just means that code that doesn't really care what
CPU it runs on will run on a CPU that claims to be an
M0/M4/M7 but is actually more or less an M3. If your
code really doesn't care then just run it on our
existing Cortex-M3 CPU.
Patches which can be integrated into mainline will need
to make a reasonable attempt at implementing the actual
correct functionality of whichever CPU you pick (either
adding the extra features in an M4 or cutting out
the features which don't exist in v6M).
I'd also strongly prefer not to implement three dozen
boards unless we really need them all. Again, start
with one and implement a decent subset of the devices
it has on it.
thanks
-- PMM
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] Cortex-M development progress
2014-11-25 20:37 ` Peter Maydell
@ 2014-11-25 21:37 ` Liviu Ionescu
0 siblings, 0 replies; 3+ messages in thread
From: Liviu Ionescu @ 2014-11-25 21:37 UTC (permalink / raw)
To: Peter Maydell; +Cc: QEMU Developers
On 25 Nov 2014, at 22:37, Peter Maydell <peter.maydell@linaro.org> wrote:
> I'd also strongly prefer not to implement three dozen
> boards unless we really need them all. Again, start
> with one and implement a decent subset of the devices
> it has on it.
we probably have different goals.
I don't need three dozen boards either, but I need most common CMSIS devices implemented, and since the current QEMU structure requires boards, I had to define boards to use them.
> M0/M4/M7 but is actually more or less an M3. If your
> code really doesn't care then just run it on our
> existing Cortex-M3 CPU.
this is not exactly what I need.
now the current workflow in GNU ARM Eclipse is to create a project from a template, build it, create a debug configuration using the J-Link plug-in, and start the debug session.
the planned use of QEMU is together with a QEMU plug-in, similar to the J-Link plug-in. exactly the same executable should run with the QEMU plug-in, configured for the same device as the J-Link plug-in.
it is not reasonable to expect the program to be rebuild for a different processor or memory map.
> I would recommend concentrating on one of these and getting
> it right, rather than defining five new cores and dozens
> of MCUs none of which are actually implemented to their
> specifications.
the main purpose of this exercise was to define a framework for adding MCUs/boards.
it is much structured than the existing implementations that mix mcus and boards, and provides a better starting point for future additions.
but if you are not interested, no problem, I'll keep everything local in my branch.
regards,
Liviu
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-11-25 21:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-25 19:58 [Qemu-devel] Cortex-M development progress Liviu Ionescu
2014-11-25 20:37 ` Peter Maydell
2014-11-25 21:37 ` Liviu Ionescu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).