hw/xtensa: extract xtensa_create_memory_regions

XTFPGA boards should populate core memory regions the same way sim
machine does. Move xtensa_create_memory_regions implementation to a
separate file and use it to create instruction and data memory regions
on XTFPGA boards.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2017-12-22 13:53:36 -08:00
parent 29b39bc712
commit e53fa62c17
5 changed files with 148 additions and 42 deletions

View File

@ -1,3 +1,4 @@
obj-y += pic_cpu.o
obj-y += sim.o
obj-y += xtensa_memory.o
obj-y += xtfpga.o

View File

@ -36,25 +36,7 @@
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
static void xtensa_create_memory_regions(const XtensaMemory *memory,
const char *name)
{
unsigned i;
GString *num_name = g_string_new(NULL);
for (i = 0; i < memory->num; ++i) {
MemoryRegion *m;
g_string_printf(num_name, "%s%u", name, i);
m = g_new(MemoryRegion, 1);
memory_region_init_ram(m, NULL, num_name->str,
memory->location[i].size, &error_fatal);
memory_region_add_subregion(get_system_memory(),
memory->location[i].addr, m);
}
g_string_free(num_name, true);
}
#include "xtensa_memory.h"
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
{
@ -94,12 +76,18 @@ static void xtensa_sim_init(MachineState *machine)
XtensaMemory sysram = env->config->sysram;
sysram.location[0].size = ram_size;
xtensa_create_memory_regions(&env->config->instrom, "xtensa.instrom");
xtensa_create_memory_regions(&env->config->instram, "xtensa.instram");
xtensa_create_memory_regions(&env->config->datarom, "xtensa.datarom");
xtensa_create_memory_regions(&env->config->dataram, "xtensa.dataram");
xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom");
xtensa_create_memory_regions(&sysram, "xtensa.sysram");
xtensa_create_memory_regions(&env->config->instrom, "xtensa.instrom",
get_system_memory());
xtensa_create_memory_regions(&env->config->instram, "xtensa.instram",
get_system_memory());
xtensa_create_memory_regions(&env->config->datarom, "xtensa.datarom",
get_system_memory());
xtensa_create_memory_regions(&env->config->dataram, "xtensa.dataram",
get_system_memory());
xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom",
get_system_memory());
xtensa_create_memory_regions(&sysram, "xtensa.sysram",
get_system_memory());
}
if (serial_hds[0]) {

55
hw/xtensa/xtensa_memory.c Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2017, Max Filippov, Open Source and Linux Lab.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Open Source and Linux Lab nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "exec/memory.h"
#include "qemu/error-report.h"
#include "xtensa_memory.h"
void xtensa_create_memory_regions(const XtensaMemory *memory,
const char *name,
MemoryRegion *super)
{
unsigned i;
GString *num_name = g_string_new(NULL);
for (i = 0; i < memory->num; ++i) {
MemoryRegion *m;
g_string_printf(num_name, "%s%u", name, i);
m = g_new(MemoryRegion, 1);
memory_region_init_ram(m, NULL, num_name->str,
memory->location[i].size, &error_fatal);
memory_region_add_subregion(super, memory->location[i].addr, m);
}
g_string_free(num_name, true);
}

40
hw/xtensa/xtensa_memory.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2017, Max Filippov, Open Source and Linux Lab.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Open Source and Linux Lab nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _XTENSA_MEMORY_H
#define _XTENSA_MEMORY_H
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "cpu.h"
#include "exec/memory.h"
void xtensa_create_memory_regions(const XtensaMemory *memory,
const char *name,
MemoryRegion *super);
#endif

View File

@ -44,6 +44,7 @@
#include "sysemu/device_tree.h"
#include "qemu/error-report.h"
#include "bootparam.h"
#include "xtensa_memory.h"
typedef struct XtfpgaBoardDesc {
hwaddr flash_base;
@ -216,7 +217,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
MemoryRegion *system_memory = get_system_memory();
XtensaCPU *cpu = NULL;
CPUXtensaState *env = NULL;
MemoryRegion *ram, *rom, *system_io;
MemoryRegion *system_io;
DriveInfo *dinfo;
pflash_t *flash = NULL;
QemuOpts *machine_opts = qemu_get_machine_opts();
@ -238,10 +239,21 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
cpu_reset(CPU(cpu));
}
ram = g_malloc(sizeof(*ram));
memory_region_init_ram(ram, NULL, "xtfpga.dram", machine->ram_size,
&error_fatal);
memory_region_add_subregion(system_memory, 0, ram);
if (env) {
XtensaMemory sysram = env->config->sysram;
sysram.location[0].size = machine->ram_size;
xtensa_create_memory_regions(&env->config->instrom, "xtensa.instrom",
system_memory);
xtensa_create_memory_regions(&env->config->instram, "xtensa.instram",
system_memory);
xtensa_create_memory_regions(&env->config->datarom, "xtensa.datarom",
system_memory);
xtensa_create_memory_regions(&env->config->dataram, "xtensa.dataram",
system_memory);
xtensa_create_memory_regions(&sysram, "xtensa.sysram",
system_memory);
}
system_io = g_malloc(sizeof(*system_io));
memory_region_init_io(system_io, NULL, &xtfpga_io_ops, NULL, "xtfpga.io",
@ -269,21 +281,24 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
if (kernel_filename) {
uint32_t entry_point = env->pc;
size_t bp_size = 3 * get_tag_size(0); /* first/last and memory tags */
uint32_t tagptr = 0xfe000000 + board->sram_size;
uint32_t tagptr = env->config->sysrom.location[0].addr +
board->sram_size;
uint32_t cur_tagptr;
BpMemInfo memory_location = {
.type = tswap32(MEMORY_TYPE_CONVENTIONAL),
.start = tswap32(0),
.end = tswap32(machine->ram_size),
.start = tswap32(env->config->sysram.location[0].addr),
.end = tswap32(env->config->sysram.location[0].addr +
machine->ram_size),
};
uint32_t lowmem_end = machine->ram_size < 0x08000000 ?
machine->ram_size : 0x08000000;
uint32_t cur_lowmem = QEMU_ALIGN_UP(lowmem_end / 2, 4096);
rom = g_malloc(sizeof(*rom));
memory_region_init_ram(rom, NULL, "xtfpga.sram", board->sram_size,
&error_fatal);
memory_region_add_subregion(system_memory, 0xfe000000, rom);
lowmem_end += env->config->sysram.location[0].addr;
cur_lowmem += env->config->sysram.location[0].addr;
xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom",
system_memory);
if (kernel_cmdline) {
bp_size += get_tag_size(strlen(kernel_cmdline) + 1);
@ -404,13 +419,20 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
if (flash) {
MemoryRegion *flash_mr = pflash_cfi01_get_memory(flash);
MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));
uint32_t size = env->config->sysrom.location[0].size;
if (board->flash_size - board->flash_boot_base < size) {
size = board->flash_size - board->flash_boot_base;
}
memory_region_init_alias(flash_io, NULL, "xtfpga.flash",
flash_mr, board->flash_boot_base,
board->flash_size - board->flash_boot_base < 0x02000000 ?
board->flash_size - board->flash_boot_base : 0x02000000);
memory_region_add_subregion(system_memory, 0xfe000000,
flash_io);
flash_mr, board->flash_boot_base, size);
memory_region_add_subregion(system_memory,
env->config->sysrom.location[0].addr,
flash_io);
} else {
xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom",
system_memory);
}
}
}