18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * ARMV7M System emulation. 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2006-2007 CodeSourcery. 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Written by Paul Brook 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This code is licenced under the GPL. 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1026b47fe632cf0de7962e79a1113d8a5d93459262David 'Digit' Turner#include "hw/sysbus.h" 1162fba4882dbb1bea4f69e0b543cb90acee84742fDavid 'Digit' Turner#include "hw/arm/arm.h" 1234c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h" 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Bitbanded IO. Each word corresponds to a single bit. */ 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Get the byte address of the real memory for a bitband acess. */ 175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline uint32_t bitband_addr(void * opaque, uint32_t addr) 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t res; 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner res = *(uint32_t *)opaque; 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project res |= (addr & 0x1ffffff) >> 5; 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return res; 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 27bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t bitband_readb(void *opaque, hwaddr offset) 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t v; 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_physical_memory_read(bitband_addr(opaque, offset), &v, 1); 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (v & (1 << ((offset >> 2) & 7))) != 0; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 34bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void bitband_writeb(void *opaque, hwaddr offset, 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t value) 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t mask; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t v; 405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = bitband_addr(opaque, offset); 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (1 << ((offset >> 2) & 7)); 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_read(addr, &v, 1); 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (value & 1) 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v |= mask; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v &= ~mask; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_write(addr, &v, 1); 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 50bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t bitband_readw(void *opaque, hwaddr offset) 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t mask; 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t v; 555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = bitband_addr(opaque, offset) & ~1; 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (1 << ((offset >> 2) & 15)); 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = tswap16(mask); 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_read(addr, (uint8_t *)&v, 2); 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (v & mask) != 0; 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 62bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void bitband_writew(void *opaque, hwaddr offset, 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t value) 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t mask; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t v; 685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = bitband_addr(opaque, offset) & ~1; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (1 << ((offset >> 2) & 15)); 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = tswap16(mask); 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_read(addr, (uint8_t *)&v, 2); 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (value & 1) 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v |= mask; 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v &= ~mask; 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_write(addr, (uint8_t *)&v, 2); 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 79bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t bitband_readl(void *opaque, hwaddr offset) 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t v; 845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = bitband_addr(opaque, offset) & ~3; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (1 << ((offset >> 2) & 31)); 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = tswap32(mask); 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_read(addr, (uint8_t *)&v, 4); 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (v & mask) != 0; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 91bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void bitband_writel(void *opaque, hwaddr offset, 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t value) 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t addr; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t mask; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t v; 975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = bitband_addr(opaque, offset) & ~3; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = (1 << ((offset >> 2) & 31)); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mask = tswap32(mask); 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_read(addr, (uint8_t *)&v, 4); 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (value & 1) 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v |= mask; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project v &= ~mask; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_physical_memory_write(addr, (uint8_t *)&v, 4); 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 108280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerstatic CPUReadMemoryFunc * const bitband_readfn[] = { 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_readb, 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_readw, 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_readl 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 114280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnerstatic CPUWriteMemoryFunc * const bitband_writefn[] = { 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_writeb, 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_writew, 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bitband_writel 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct { 1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner SysBusDevice busdev; 1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner uint32_t base; 1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} BitBandState; 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void bitband_init(SysBusDevice *dev) 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner BitBandState *s = FROM_SYSBUS(BitBandState, dev); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int iomemtype; 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s->base = qdev_get_prop_int(&dev->qdev, "base", 0); 1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn, 1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner &s->base); 1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sysbus_init_mmio(dev, 0x02000000, iomemtype); 1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void armv7m_bitband_init(void) 1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DeviceState *dev; 1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dev = qdev_create(NULL, "ARM,bitband-memory"); 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qdev_set_prop_int(dev, "base", 0x20000000); 1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qdev_init(dev); 1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000); 1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dev = qdev_create(NULL, "ARM,bitband-memory"); 1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qdev_set_prop_int(dev, "base", 0x40000000); 1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qdev_init(dev); 1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000); 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Board init. */ 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Init CPU and memory for a v7-M based board. 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flash_size and sram_size are in kb. 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Returns the NVIC array. */ 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectqemu_irq *armv7m_init(int flash_size, int sram_size, 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char *kernel_filename, const char *cpu_model) 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 159e2678e116c8cdb0f36b247a5bd9cfacc849362fcDavid 'Digit' Turner CPUOldState *env; 1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DeviceState *nvic; 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* FIXME: make this local state. */ 1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner static qemu_irq pic[64]; 1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_irq *cpu_pic; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t pc; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int image_size; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t entry; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t lowaddr; 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i; 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project flash_size *= 1024; 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sram_size *= 1024; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!cpu_model) 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_model = "cortex-m3"; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env = cpu_init(cpu_model); 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!env) { 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "Unable to find CPU definition\n"); 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* > 32Mb SRAM gets complicated because it overlaps the bitband area. 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project We don't have proper commandline options, so allocate half of memory 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project as SRAM, up to a maximum of 32Mb, and the rest as code. */ 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ram_size > (512 + 32) * 1024 * 1024) 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ram_size = (512 + 32) * 1024 * 1024; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sram_size = (ram_size / 2) & TARGET_PAGE_MASK; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sram_size > 32 * 1024 * 1024) 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sram_size = 32 * 1024 * 1024; 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code_size = ram_size - sram_size; 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Flash programming is done via the SCU, so pretend it is ROM. */ 1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_register_physical_memory(0, flash_size, 195280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner qemu_ram_alloc(NULL, "armv7m.flash", 196280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner flash_size) | IO_MEM_ROM); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project cpu_register_physical_memory(0x20000000, sram_size, 198280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner qemu_ram_alloc(NULL, "armv7m.sram", 199280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner sram_size) | IO_MEM_RAM); 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project armv7m_bitband_init(); 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner nvic = qdev_create(NULL, "armv7m_nvic"); 2035285864985be9077e58e42235af6582dee72e841David 'Digit' Turner env->nvic = nvic; 2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qdev_init(nvic); 2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_pic = arm_pic_init_cpu(env); 2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]); 2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i = 0; i < 64; i++) { 2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner pic[i] = qdev_get_gpio_in(nvic, i); 2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL); 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (image_size < 0) { 2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner image_size = load_image_targphys(kernel_filename, 0, flash_size); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lowaddr = 0; 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (image_size < 0) { 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "qemu: could not load kernel '%s'\n", 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kernel_filename); 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* If the image was loaded at address zero then assume it is a 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project regular ROM image and perform the normal CPU reset sequence. 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Otherwise jump directly to the entry point. */ 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (lowaddr == 0) { 2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner env->regs[13] = ldl_phys(0); 2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner pc = ldl_phys(4); 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pc = entry; 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->thumb = pc & 1; 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project env->regs[15] = pc & ~1; 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Hack to map an additional page of ram at the top of the address 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project space. This stops qemu complaining about executing code outside RAM 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project when returning from an exception. */ 2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner cpu_register_physical_memory(0xfffff000, 0x1000, 238c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner qemu_ram_alloc(NULL, "armv7m.hack", 239280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner 0x1000) | IO_MEM_RAM); 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return pic; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void armv7m_register_devices(void) 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState), 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bitband_init); 2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerdevice_init(armv7m_register_devices) 250