qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-arm] [Qemu-devel] Problems adding TMS570LC43 - Cortex-R5f


From: Philippe Mathieu-Daudé
Subject: Re: [Qemu-arm] [Qemu-devel] Problems adding TMS570LC43 - Cortex-R5f
Date: Fri, 18 Jan 2019 12:05:39 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0

On 1/18/19 11:14 AM, KONRAD Frederic wrote:
> Le 1/17/19 à 7:00 PM, Philippe Mathieu-Daudé a écrit :
>> On 1/17/19 5:54 PM, João Gaspar wrote:
>>> Hi!
>>> I'm new at QEMU so I have some questions.
>>>
>>> I'm trying to create a new support machine to QEMU, the TMS570LC43
>>> board, this board use the Cortex-R5f microcontroller.
>>> At this moment when I do the "qemu-system-arm -M help" my machine is
>>> showed with the name "cortex-r5".
>>
>> OMG why on Earth do you want to model a Hercules SoC? Speaking of
>> experience, I used to work with those and spend some time tring to model
>> them, I don't recommend this to you to start modelling an ARM SoC with
>> QEMU. So I'm curious to understand your goal here, is it for hobby or
>> univ/job assignment?
>> Do you plan to run real world firmwares or simple/generic programs?
>> Designed for Safety critical/Real-Time embedded world, it has plenty of
>> very specific features that a safe firmware should be using, thus making
>> the work of modelling very teddious.
>> Any unmodified firmware require you to implement the Clock Monitoring,
>> PBIST, and part of the ESM.
>> Also, you might be limited to run from SRAM then EMIF, because the flash
>> registers (F021) aren't public.
>> Also the CPU boots in Big Endian, and while QEMU backend support both
>> endianess, there are no ARM system booting BE, and you might encounter
>> weird bugs has it happened to me.
> 
> We have a TMS570 platform as well (very minimal though to boot our
> runtimes) and
> I can confirm that there are some endianness pain with this platform.

There also used to be GCC (now fixed) and newlib (in specs) bugs...
I.E. https://answers.launchpad.net/gcc-arm-embedded/+question/189066
'Support for Cortex-R4F Big-Endian' asked on 2012-02-28, last comment on
2018-06-11: "the tool chain does not support big-endian out of the box".

Frederic, one of my BE issues was fixed by this commit:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=98f52cdbb5c
"Fix access_with_adjusted_size(small size) on big-endian memory regions"

Also the Thumb code is now readable since this commit:
https://git.qemu.org/?p=qemu.git;a=commitdiff;h=f7478a92dd9
"Fix Thumb-1 BE32 execution and disassembly"

João, something that helped me quite a lot (I guess Peter Maydell
suggested it to me once at Connect) is to switch the CPU in
little-endian, then modelling on QEMU is somehow easier.
However at the time of my efforts, firmwares were only
TÜV/SÜD/SIL3/MISRA certifiable for BE, and the F021 libs were only
available for BE. At the time the LE series went out (RM48) I lost
interest and moved on.

An useful example of endianess switch is this test from Peter Crosthwaite:
https://github.com/pcrost/arm-be-test/blob/master/main.c#L36

Regards,

Phil.

> For the initial question it seems that you used "cortex-r5" in:
> 
>>>      DEFINE_MACHINE("cortex-r5", cortexR5_machine_init)
> 
> So expect the machine to be called like that.
> 
> Cheers,
> Fred
> 
>>
>> So if you don't have a strong reason, I'd redirect you to use another
>> ARM SoC.
>>
>>> The probleme start when I try to instaciate the machine with the comand
>>> "qemu-system-arm --machine cortex-r5 -cpu cortex-r5f", after that I
>>> received the message "segmentation fault (core dump)".
>>>
>>> Does anyone have an possible cause to my problem or an tip?
>>
>> Since this question isn't ARM specific but generic about QEMU machines,
>> I recommend you to also post to the address@hidden list (now
>> copied).
>>
>> You can have a more verbose debug output configuring QEMU as:
>>
>> ./configure ... --extra-cflags=--ggdb --enable-debug
>>
>> Regards,
>>
>> Phil.
>>
>>>
>>> I'm gonna let the code too, because probably I'm doing aniything wrong!
>>>
>>>      #include "qemu/osdep.h"
>>>      #include "qapi/error.h"
>>>      #include "qemu-common.h"
>>>      #include "hw/arm/arm.h"
>>>      #include "exec/address-spaces.h"
>>>      #include "qemu/error-report.h"
>>>      #include "qom/object.h"
>>>      #include "cpu.h"
>>>      #include "hw/sysbus.h"
>>>      #include "hw/arm/cortex-R5.h"
>>>
>>>      //RTI -> Real Time Interruption
>>>      //static const uint32_t RTI_addr = 0xFFFFFC00;
>>>
>>>      //SPI
>>>      static const uint32_t spi_addr[CR5_NUM_SPI] = {0xFFF7F400,
>>>      0xFFF7F600, 0xFFF7F800, 0xFFF7FA00, 0xFFF7FC00};
>>>      //I2C
>>>      static const uint32_t i2c_addr[CR5_NUM_I2C] = {0xFFF7D400,
>>> 0xFFF7D500};
>>>      //CAN
>>>      static const uint32_t can_addr[CR5_NUM_CAN] = {0XFFF7DC00,
>>>      0XFFF7DE00, 0X0FFF7E00, 0X0FFF7E200};
>>>      //ADC
>>>      static const uint32_t adc_addr[CR5_NUM_ADC] = {0xFFF7C000,
>>> 0xFFF7C200};
>>>      //GIO
>>>      static const uint32_t gio_addr[CR5_NUM_GIO] = {0xFFF7BC00};
>>>
>>>      /*IRQ
>>>      Interrupt Request Assignement
>>>      http://www.ti.com/lit/ds/spns195c/spns195c.pdf
>>>      Page: 118
>>>      */
>>>      //irq RTI
>>>      /* static const int rti_cmp_irq0 = 2;
>>>      static const int rti_cmp_irq1 = 3;
>>>      static const int rti_cmp_irq2 = 4;
>>>      static const int rti_cmp_irq3 = 5;
>>>      static const int rti_oflw_irq0 = 6;
>>>      static const int rti_oflw_irq1 = 7;
>>>      static const int rti_timebase_irq = 8; */
>>>      //irq SPI
>>>      static const int spi_l0_irq[CR5_NUM_SPI] = {12, 17, 37, 49, 53};
>>>      static const int spi_l1_irq[CR5_NUM_SPI] = {26, 30, 38, 54, 56};
>>>      //irq I2C
>>>      static const int i2c_irq[CR5_NUM_I2C] = {66, 114};
>>>      //irc CAN
>>>      static const int can_l0_irq[CR5_NUM_CAN] = {16, 35, 45, 113};
>>>      static const int can_l1_irq[CR5_NUM_CAN] = {29, 42, 55, 117};
>>>      static const int can_if3_irq[CR5_NUM_CAN] = {44, 46, 60, 120};
>>>      //irq ADC
>>>      static const int adc_swgroup1_irq[CR5_NUM_ADC] = {15, 51};
>>>      static const int adc_swgroup2_irq[CR5_NUM_ADC] = {28, 57};
>>>      static const int adc_eventgroup_irq[CR5_NUM_ADC] = {14, 50};
>>>      static const int adc_magnitudecmp_irq[CR5_NUM_ADC] = {31, 59};
>>>      //irq GIO
>>>      static const int gio_high_irq[CR5_NUM_GIO] = {9};
>>>      static const int gio_low_irq[CR5_NUM_GIO] = {23};
>>>
>>>
>>>      static void cortexR5_initf(MachineState *mc)
>>>      {
>>>          CORTEXR5State *s = g_new0(CORTEXR5State, 1);
>>>
>>>          DeviceState *dev;
>>>          SysBusDevice *busdev;
>>>          Error *err = NULL;
>>>
>>>          int i;
>>>          ARMCPU *cpu;
>>>
>>>
>>>          MemoryRegion *system_memory = get_system_memory();
>>>          MemoryRegion *ram = g_new(MemoryRegion, 1);
>>>          MemoryRegion *flash = g_new(MemoryRegion, 1);
>>>          MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
>>>
>>>        
>>>          //s->cr5_cpu = ARM_CPU(object_new(mc->cpu_type));
>>>          cpu = ARM_CPU(object_new(mc->cpu_type));
>>>
>>>          //object_initialize_child(obj, "cpu", &s->cr5_cpu,
>>>      sizeof(s->cr5_cpu), ARM_CPU_TYPE_NAME("cortex-r5f"), &error_abort,
>>>      NULL);
>>>          object_property_set_bool(OBJECT(cpu), true, "realized",
>>>      &error_fatal);
>>>
>>>          memory_region_init_ram(flash, NULL, "CORTEXR5.flash",
>>>      FLASH_SIZE, &error_fatal);
>>>
>>>          memory_region_init_alias(flash_alias, NULL,
>>>      "CORTEXR5.flash.alias", flash, 0, FLASH_SIZE);
>>>
>>>          memory_region_set_readonly(flash, true);
>>>          memory_region_set_readonly(flash_alias, true);
>>>
>>>          memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS,
>>>      flash);
>>>          memory_region_add_subregion(system_memory, 0, flash_alias);
>>>
>>>          memory_region_init_ram(ram, NULL, "CORTEXR5.ram", SRAM_SIZE,
>>>      &error_fatal);
>>>          memory_region_add_subregion(system_memory, RAM_BASE_ADDRESS,
>>> ram);
>>>
>>>          //SPI
>>>          for (i = 0; i < CR5_NUM_SPI; i++)
>>>          {
>>>              dev = DEVICE(&(s->spi[i]));
>>>              object_property_set_bool(OBJECT(&s->spi[i]), true,
>>>      "realized", &err);
>>>              if (err != NULL)
>>>              {
>>>                  //error_propagate(errp, err);
>>>                  return;
>>>              }
>>>              busdev = SYS_BUS_DEVICE(dev);
>>>              sysbus_mmio_map(busdev, 0, spi_addr[i]);
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      spi_l0_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      spi_l1_irq[i]));
>>>          }
>>>
>>>          //I2C
>>>          for (i = 0; i < CR5_NUM_I2C; i++)
>>>          {
>>>              dev = DEVICE(&(s->i2c[i]));
>>>              object_property_set_bool(OBJECT(&s->i2c[i]), true,
>>>      "realized", &err);
>>>              if (err != NULL)
>>>              {
>>>                  //error_propagate(errp, err);
>>>                  return;
>>>              }
>>>              busdev = SYS_BUS_DEVICE(dev);
>>>              sysbus_mmio_map(busdev, 0, i2c_addr[i]);
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      i2c_irq[i]));
>>>          }
>>>
>>>          //CAN
>>>          for (i = 0; i < CR5_NUM_CAN; i++)
>>>          {
>>>              dev = DEVICE(&(s->can[i]));
>>>              object_property_set_bool(OBJECT(&s->can[i]), true,
>>>      "realized", &err);
>>>              if (err != NULL)
>>>              {
>>>                  //error_propagate(errp, err);
>>>                  return;
>>>              }
>>>              busdev = SYS_BUS_DEVICE(dev);
>>>              sysbus_mmio_map(busdev, 0, can_addr[i]);
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      can_l0_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      can_l1_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      can_if3_irq[i]));
>>>          }
>>>
>>>          //ADC
>>>          object_property_set_int(OBJECT(s->adc_irqs), CR5_NUM_ADC,
>>>      "num-lines", &err);
>>>          object_property_set_bool(OBJECT(s->adc_irqs), true, "realized",
>>>      &err);
>>>          if (err != NULL)
>>>          {
>>>              //error_propagate(errp, err);
>>>              return;
>>>          }
>>>         // qdev_connect_gpio_out(DEVICE(s->adc_irq), 0,
>>>      qdev_get_gpio_in(dev));
>>>
>>>          for (i = 0; i < CR5_NUM_ADC; i++)
>>>          {
>>>              dev = DEVICE(&(s->adc[i]));
>>>              object_property_set_bool(OBJECT(&s->adc[i]), true,
>>>      "realized", &err);
>>>              if (err != NULL)
>>>              {
>>>                  //error_propagate(errp, err);
>>>                  return;
>>>              }
>>>              busdev = SYS_BUS_DEVICE(dev);
>>>              sysbus_mmio_map(busdev, 0, adc_addr[i]);
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      adc_swgroup1_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      adc_swgroup2_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      adc_eventgroup_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      adc_magnitudecmp_irq[i]));
>>>          }
>>>
>>>          //GIO
>>>          for (i = 0; i < CR5_NUM_GIO; i++)
>>>          {
>>>              dev = DEVICE(&(s->gio[i]));
>>>              object_property_set_bool(OBJECT(&s->gio[i]), true,
>>>      "realized", &err);
>>>              if (err != NULL)
>>>              {
>>>                  //error_propagate(errp, err);
>>>                  return;
>>>              }
>>>              busdev = SYS_BUS_DEVICE(dev);
>>>              sysbus_mmio_map(busdev, 0, gio_addr[i]);
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      gio_high_irq[i]));
>>>              sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(dev),
>>>      gio_low_irq[i]));
>>>          }
>>>      }
>>>
>>>
>>>
>>>      static void cortexR5_machine_init(MachineClass *mc){
>>>         //mc->name = "Cortex-R5f";
>>>          mc->desc = "Based on TMS570LC43x";
>>>          mc->init =  cortexR5_initf;
>>>          mc->max_cpus = 1;
>>>          mc->ignore_memory_transaction_failures = true;
>>>          mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r5f");
>>>      }
>>>
>>>
>>>
>>>      DEFINE_MACHINE("cortex-r5", cortexR5_machine_init)
>>>
>>>
>>>
>>>
>>> Thanks in advanced,
>>>
>>> João Gaspar
>>>
>>> Enviado do Outlook <http://aka.ms/weboutlook>
>>
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]