Diff for /qemu/hw/armv7m.c between versions 1.1.1.1 and 1.1.1.8

version 1.1.1.1, 2018/04/24 16:48:33 version 1.1.1.8, 2018/04/24 19:27:49
Line 4 Line 4
  * Copyright (c) 2006-2007 CodeSourcery.   * Copyright (c) 2006-2007 CodeSourcery.
  * Written by Paul Brook   * Written by Paul Brook
  *   *
  * This code is licenced under the GPL.   * This code is licensed under the GPL.
  */   */
   
 #include "hw.h"  #include "sysbus.h"
 #include "arm-misc.h"  #include "arm-misc.h"
 #include "sysemu.h"  #include "loader.h"
   #include "elf.h"
   
 /* Bitbanded IO.  Each word corresponds to a single bit.  */  /* Bitbanded IO.  Each word corresponds to a single bit.  */
   
 /* Get the byte address of the real memory for a bitband acess.  */  /* Get the byte address of the real memory for a bitband access.  */
 static inline uint32_t bitband_addr(uint32_t addr)  static inline uint32_t bitband_addr(void * opaque, uint32_t addr)
 {  {
     uint32_t res;      uint32_t res;
   
     res = addr & 0xe0000000;      res = *(uint32_t *)opaque;
     res |= (addr & 0x1ffffff) >> 5;      res |= (addr & 0x1ffffff) >> 5;
     return res;      return res;
   
Line 27  static inline uint32_t bitband_addr(uint Line 28  static inline uint32_t bitband_addr(uint
 static uint32_t bitband_readb(void *opaque, target_phys_addr_t offset)  static uint32_t bitband_readb(void *opaque, target_phys_addr_t offset)
 {  {
     uint8_t v;      uint8_t v;
     cpu_physical_memory_read(bitband_addr(offset), &v, 1);      cpu_physical_memory_read(bitband_addr(opaque, offset), &v, 1);
     return (v & (1 << ((offset >> 2) & 7))) != 0;      return (v & (1 << ((offset >> 2) & 7))) != 0;
 }  }
   
Line 37  static void bitband_writeb(void *opaque, Line 38  static void bitband_writeb(void *opaque,
     uint32_t addr;      uint32_t addr;
     uint8_t mask;      uint8_t mask;
     uint8_t v;      uint8_t v;
     addr = bitband_addr(offset);      addr = bitband_addr(opaque, offset);
     mask = (1 << ((offset >> 2) & 7));      mask = (1 << ((offset >> 2) & 7));
     cpu_physical_memory_read(addr, &v, 1);      cpu_physical_memory_read(addr, &v, 1);
     if (value & 1)      if (value & 1)
Line 52  static uint32_t bitband_readw(void *opaq Line 53  static uint32_t bitband_readw(void *opaq
     uint32_t addr;      uint32_t addr;
     uint16_t mask;      uint16_t mask;
     uint16_t v;      uint16_t v;
     addr = bitband_addr(offset) & ~1;      addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));      mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);      mask = tswap16(mask);
     cpu_physical_memory_read(addr, (uint8_t *)&v, 2);      cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
Line 65  static void bitband_writew(void *opaque, Line 66  static void bitband_writew(void *opaque,
     uint32_t addr;      uint32_t addr;
     uint16_t mask;      uint16_t mask;
     uint16_t v;      uint16_t v;
     addr = bitband_addr(offset) & ~1;      addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));      mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);      mask = tswap16(mask);
     cpu_physical_memory_read(addr, (uint8_t *)&v, 2);      cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
Line 81  static uint32_t bitband_readl(void *opaq Line 82  static uint32_t bitband_readl(void *opaq
     uint32_t addr;      uint32_t addr;
     uint32_t mask;      uint32_t mask;
     uint32_t v;      uint32_t v;
     addr = bitband_addr(offset) & ~3;      addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));      mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);      mask = tswap32(mask);
     cpu_physical_memory_read(addr, (uint8_t *)&v, 4);      cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
Line 94  static void bitband_writel(void *opaque, Line 95  static void bitband_writel(void *opaque,
     uint32_t addr;      uint32_t addr;
     uint32_t mask;      uint32_t mask;
     uint32_t v;      uint32_t v;
     addr = bitband_addr(offset) & ~3;      addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));      mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);      mask = tswap32(mask);
     cpu_physical_memory_read(addr, (uint8_t *)&v, 4);      cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
Line 105  static void bitband_writel(void *opaque, Line 106  static void bitband_writel(void *opaque,
     cpu_physical_memory_write(addr, (uint8_t *)&v, 4);      cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
 }  }
   
 static CPUReadMemoryFunc *bitband_readfn[] = {  static const MemoryRegionOps bitband_ops = {
    bitband_readb,      .old_mmio = {
    bitband_readw,          .read = { bitband_readb, bitband_readw, bitband_readl, },
    bitband_readl          .write = { bitband_writeb, bitband_writew, bitband_writel, },
       },
       .endianness = DEVICE_NATIVE_ENDIAN,
 };  };
   
 static CPUWriteMemoryFunc *bitband_writefn[] = {  typedef struct {
    bitband_writeb,      SysBusDevice busdev;
    bitband_writew,      MemoryRegion iomem;
    bitband_writel      uint32_t base;
 };  } BitBandState;
   
   static int bitband_init(SysBusDevice *dev)
   {
       BitBandState *s = FROM_SYSBUS(BitBandState, dev);
   
       memory_region_init_io(&s->iomem, &bitband_ops, &s->base, "bitband",
                             0x02000000);
       sysbus_init_mmio_region(dev, &s->iomem);
       return 0;
   }
   
 static void armv7m_bitband_init(void)  static void armv7m_bitband_init(void)
 {  {
     int iomemtype;      DeviceState *dev;
   
     iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn,      dev = qdev_create(NULL, "ARM,bitband-memory");
                                        NULL);      qdev_prop_set_uint32(dev, "base", 0x20000000);
     cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype);      qdev_init_nofail(dev);
     cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype);      sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000);
   
       dev = qdev_create(NULL, "ARM,bitband-memory");
       qdev_prop_set_uint32(dev, "base", 0x40000000);
       qdev_init_nofail(dev);
       sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000);
 }  }
   
 /* Board init.  */  /* Board init.  */
   
   static void armv7m_reset(void *opaque)
   {
       cpu_reset((CPUState *)opaque);
   }
   
 /* Init CPU and memory for a v7-M based board.  /* Init CPU and memory for a v7-M based board.
    flash_size and sram_size are in kb.     flash_size and sram_size are in kb.
    Returns the NVIC array.  */     Returns the NVIC array.  */
   
 qemu_irq *armv7m_init(int flash_size, int sram_size,  qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
                         int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)                        const char *kernel_filename, const char *cpu_model)
 {  {
     CPUState *env;      CPUState *env;
     qemu_irq *pic;      DeviceState *nvic;
     uint32_t pc;      /* FIXME: make this local state.  */
       static qemu_irq pic[64];
       qemu_irq *cpu_pic;
     int image_size;      int image_size;
     uint64_t entry;      uint64_t entry;
     uint64_t lowaddr;      uint64_t lowaddr;
       int i;
       int big_endian;
       MemoryRegion *sram = g_new(MemoryRegion, 1);
       MemoryRegion *flash = g_new(MemoryRegion, 1);
       MemoryRegion *hack = g_new(MemoryRegion, 1);
   
     flash_size *= 1024;      flash_size *= 1024;
     sram_size *= 1024;      sram_size *= 1024;
Line 166  qemu_irq *armv7m_init(int flash_size, in Line 198  qemu_irq *armv7m_init(int flash_size, in
 #endif  #endif
   
     /* Flash programming is done via the SCU, so pretend it is ROM.  */      /* Flash programming is done via the SCU, so pretend it is ROM.  */
     cpu_register_physical_memory(0, flash_size, IO_MEM_ROM);      memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
     cpu_register_physical_memory(0x20000000, sram_size,      memory_region_set_readonly(flash, true);
                                  flash_size + IO_MEM_RAM);      memory_region_add_subregion(address_space_mem, 0, flash);
       memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
       memory_region_add_subregion(address_space_mem, 0x20000000, sram);
     armv7m_bitband_init();      armv7m_bitband_init();
   
     pic = armv7m_nvic_init(env);      nvic = qdev_create(NULL, "armv7m_nvic");
       env->nvic = nvic;
       qdev_init_nofail(nvic);
       cpu_pic = arm_pic_init_cpu(env);
       sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
       for (i = 0; i < 64; i++) {
           pic[i] = qdev_get_gpio_in(nvic, i);
       }
   
   #ifdef TARGET_WORDS_BIGENDIAN
       big_endian = 1;
   #else
       big_endian = 0;
   #endif
   
     image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);      image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
                             NULL, big_endian, ELF_MACHINE, 1);
     if (image_size < 0) {      if (image_size < 0) {
         image_size = load_image(kernel_filename, phys_ram_base);          image_size = load_image_targphys(kernel_filename, 0, flash_size);
         lowaddr = 0;          lowaddr = 0;
     }      }
     if (image_size < 0) {      if (image_size < 0) {
Line 184  qemu_irq *armv7m_init(int flash_size, in Line 232  qemu_irq *armv7m_init(int flash_size, in
         exit(1);          exit(1);
     }      }
   
     /* If the image was loaded at address zero then assume it is a  
        regular ROM image and perform the normal CPU reset sequence.  
        Otherwise jump directly to the entry point.  */  
     if (lowaddr == 0) {  
         env->regs[13] = tswap32(*(uint32_t *)phys_ram_base);  
         pc = tswap32(*(uint32_t *)(phys_ram_base + 4));  
     } else {  
         pc = entry;  
     }  
     env->thumb = pc & 1;  
     env->regs[15] = pc & ~1;  
   
     /* Hack to map an additional page of ram at the top of the address      /* Hack to map an additional page of ram at the top of the address
        space.  This stops qemu complaining about executing code outside RAM         space.  This stops qemu complaining about executing code outside RAM
        when returning from an exception.  */         when returning from an exception.  */
     cpu_register_physical_memory(0xfffff000, 0x1000, IO_MEM_RAM + ram_size);      memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
       memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
   
       qemu_register_reset(armv7m_reset, env);
     return pic;      return pic;
 }  }
   
   static SysBusDeviceInfo bitband_info = {
       .init = bitband_init,
       .qdev.name  = "ARM,bitband-memory",
       .qdev.size  = sizeof(BitBandState),
       .qdev.props = (Property[]) {
           DEFINE_PROP_UINT32("base", BitBandState, base, 0),
           DEFINE_PROP_END_OF_LIST(),
       }
   };
   
   static void armv7m_register_devices(void)
   {
       sysbus_register_withprop(&bitband_info);
   }
   
   device_init(armv7m_register_devices)

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.8


unix.superglobalmegacorp.com