|
|
1.1 ! root 1: /* ! 2: * ARMV7M System emulation. ! 3: * ! 4: * Copyright (c) 2006-2007 CodeSourcery. ! 5: * Written by Paul Brook ! 6: * ! 7: * This code is licenced under the GPL. ! 8: */ ! 9: ! 10: #include "hw.h" ! 11: #include "arm-misc.h" ! 12: #include "sysemu.h" ! 13: ! 14: /* Bitbanded IO. Each word corresponds to a single bit. */ ! 15: ! 16: /* Get the byte address of the real memory for a bitband acess. */ ! 17: static inline uint32_t bitband_addr(uint32_t addr) ! 18: { ! 19: uint32_t res; ! 20: ! 21: res = addr & 0xe0000000; ! 22: res |= (addr & 0x1ffffff) >> 5; ! 23: return res; ! 24: ! 25: } ! 26: ! 27: static uint32_t bitband_readb(void *opaque, target_phys_addr_t offset) ! 28: { ! 29: uint8_t v; ! 30: cpu_physical_memory_read(bitband_addr(offset), &v, 1); ! 31: return (v & (1 << ((offset >> 2) & 7))) != 0; ! 32: } ! 33: ! 34: static void bitband_writeb(void *opaque, target_phys_addr_t offset, ! 35: uint32_t value) ! 36: { ! 37: uint32_t addr; ! 38: uint8_t mask; ! 39: uint8_t v; ! 40: addr = bitband_addr(offset); ! 41: mask = (1 << ((offset >> 2) & 7)); ! 42: cpu_physical_memory_read(addr, &v, 1); ! 43: if (value & 1) ! 44: v |= mask; ! 45: else ! 46: v &= ~mask; ! 47: cpu_physical_memory_write(addr, &v, 1); ! 48: } ! 49: ! 50: static uint32_t bitband_readw(void *opaque, target_phys_addr_t offset) ! 51: { ! 52: uint32_t addr; ! 53: uint16_t mask; ! 54: uint16_t v; ! 55: addr = bitband_addr(offset) & ~1; ! 56: mask = (1 << ((offset >> 2) & 15)); ! 57: mask = tswap16(mask); ! 58: cpu_physical_memory_read(addr, (uint8_t *)&v, 2); ! 59: return (v & mask) != 0; ! 60: } ! 61: ! 62: static void bitband_writew(void *opaque, target_phys_addr_t offset, ! 63: uint32_t value) ! 64: { ! 65: uint32_t addr; ! 66: uint16_t mask; ! 67: uint16_t v; ! 68: addr = bitband_addr(offset) & ~1; ! 69: mask = (1 << ((offset >> 2) & 15)); ! 70: mask = tswap16(mask); ! 71: cpu_physical_memory_read(addr, (uint8_t *)&v, 2); ! 72: if (value & 1) ! 73: v |= mask; ! 74: else ! 75: v &= ~mask; ! 76: cpu_physical_memory_write(addr, (uint8_t *)&v, 2); ! 77: } ! 78: ! 79: static uint32_t bitband_readl(void *opaque, target_phys_addr_t offset) ! 80: { ! 81: uint32_t addr; ! 82: uint32_t mask; ! 83: uint32_t v; ! 84: addr = bitband_addr(offset) & ~3; ! 85: mask = (1 << ((offset >> 2) & 31)); ! 86: mask = tswap32(mask); ! 87: cpu_physical_memory_read(addr, (uint8_t *)&v, 4); ! 88: return (v & mask) != 0; ! 89: } ! 90: ! 91: static void bitband_writel(void *opaque, target_phys_addr_t offset, ! 92: uint32_t value) ! 93: { ! 94: uint32_t addr; ! 95: uint32_t mask; ! 96: uint32_t v; ! 97: addr = bitband_addr(offset) & ~3; ! 98: mask = (1 << ((offset >> 2) & 31)); ! 99: mask = tswap32(mask); ! 100: cpu_physical_memory_read(addr, (uint8_t *)&v, 4); ! 101: if (value & 1) ! 102: v |= mask; ! 103: else ! 104: v &= ~mask; ! 105: cpu_physical_memory_write(addr, (uint8_t *)&v, 4); ! 106: } ! 107: ! 108: static CPUReadMemoryFunc *bitband_readfn[] = { ! 109: bitband_readb, ! 110: bitband_readw, ! 111: bitband_readl ! 112: }; ! 113: ! 114: static CPUWriteMemoryFunc *bitband_writefn[] = { ! 115: bitband_writeb, ! 116: bitband_writew, ! 117: bitband_writel ! 118: }; ! 119: ! 120: static void armv7m_bitband_init(void) ! 121: { ! 122: int iomemtype; ! 123: ! 124: iomemtype = cpu_register_io_memory(0, bitband_readfn, bitband_writefn, ! 125: NULL); ! 126: cpu_register_physical_memory(0x22000000, 0x02000000, iomemtype); ! 127: cpu_register_physical_memory(0x42000000, 0x02000000, iomemtype); ! 128: } ! 129: ! 130: /* Board init. */ ! 131: /* Init CPU and memory for a v7-M based board. ! 132: flash_size and sram_size are in kb. ! 133: Returns the NVIC array. */ ! 134: ! 135: qemu_irq *armv7m_init(int flash_size, int sram_size, ! 136: const char *kernel_filename, const char *cpu_model) ! 137: { ! 138: CPUState *env; ! 139: qemu_irq *pic; ! 140: uint32_t pc; ! 141: int image_size; ! 142: uint64_t entry; ! 143: uint64_t lowaddr; ! 144: ! 145: flash_size *= 1024; ! 146: sram_size *= 1024; ! 147: ! 148: if (!cpu_model) ! 149: cpu_model = "cortex-m3"; ! 150: env = cpu_init(cpu_model); ! 151: if (!env) { ! 152: fprintf(stderr, "Unable to find CPU definition\n"); ! 153: exit(1); ! 154: } ! 155: ! 156: #if 0 ! 157: /* > 32Mb SRAM gets complicated because it overlaps the bitband area. ! 158: We don't have proper commandline options, so allocate half of memory ! 159: as SRAM, up to a maximum of 32Mb, and the rest as code. */ ! 160: if (ram_size > (512 + 32) * 1024 * 1024) ! 161: ram_size = (512 + 32) * 1024 * 1024; ! 162: sram_size = (ram_size / 2) & TARGET_PAGE_MASK; ! 163: if (sram_size > 32 * 1024 * 1024) ! 164: sram_size = 32 * 1024 * 1024; ! 165: code_size = ram_size - sram_size; ! 166: #endif ! 167: ! 168: /* Flash programming is done via the SCU, so pretend it is ROM. */ ! 169: cpu_register_physical_memory(0, flash_size, IO_MEM_ROM); ! 170: cpu_register_physical_memory(0x20000000, sram_size, ! 171: flash_size + IO_MEM_RAM); ! 172: armv7m_bitband_init(); ! 173: ! 174: pic = armv7m_nvic_init(env); ! 175: ! 176: image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL); ! 177: if (image_size < 0) { ! 178: image_size = load_image(kernel_filename, phys_ram_base); ! 179: lowaddr = 0; ! 180: } ! 181: if (image_size < 0) { ! 182: fprintf(stderr, "qemu: could not load kernel '%s'\n", ! 183: kernel_filename); ! 184: exit(1); ! 185: } ! 186: ! 187: /* If the image was loaded at address zero then assume it is a ! 188: regular ROM image and perform the normal CPU reset sequence. ! 189: Otherwise jump directly to the entry point. */ ! 190: if (lowaddr == 0) { ! 191: env->regs[13] = tswap32(*(uint32_t *)phys_ram_base); ! 192: pc = tswap32(*(uint32_t *)(phys_ram_base + 4)); ! 193: } else { ! 194: pc = entry; ! 195: } ! 196: env->thumb = pc & 1; ! 197: env->regs[15] = pc & ~1; ! 198: ! 199: /* Hack to map an additional page of ram at the top of the address ! 200: space. This stops qemu complaining about executing code outside RAM ! 201: when returning from an exception. */ ! 202: cpu_register_physical_memory(0xfffff000, 0x1000, IO_MEM_RAM + ram_size); ! 203: ! 204: return pic; ! 205: } ! 206:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.