Commit d9e8553b authored by Max Filippov's avatar Max Filippov
Browse files

hw/xtensa: add virt machine



virt machine is a sim machine with generic PCI host controller.
Make common parts of sim machine initialization reusable.
Add PCI controller at 0xf0000000 with PIO space at its base address,
ECAM space at base address + 1M and MMIO space at base address + 64M.
Connect IRQ lines to consecutive CPU external IRQ pins starting from 0.
Instantiate network interfaces on virt machine.

Xtensa linux kernel configuration virt_defconfig can successfully boot
on this machine.

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent d5eaec84
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1302,6 +1302,11 @@ M: Max Filippov <jcmvbkbc@gmail.com>
S: Maintained
F: hw/xtensa/sim.c

virt
M: Max Filippov <jcmvbkbc@gmail.com>
S: Maintained
F: hw/xtensa/virt.c

XTFPGA (LX60, LX200, ML605, KC705)
M: Max Filippov <jcmvbkbc@gmail.com>
S: Maintained
+1 −0
Original line number Diff line number Diff line
@@ -5,4 +5,5 @@ CONFIG_SEMIHOSTING=y
# Boards:
#
CONFIG_XTENSA_SIM=y
CONFIG_XTENSA_VIRT=y
CONFIG_XTENSA_XTFPGA=y
+6 −0
Original line number Diff line number Diff line
config XTENSA_SIM
    bool

config XTENSA_VIRT
    bool
    select XTENSA_SIM
    select PCI_EXPRESS_GENERIC_BRIDGE
    select PCI_DEVICES

config XTENSA_XTFPGA
    bool
    select OPENCORES_ETH
+1 −0
Original line number Diff line number Diff line
@@ -2,4 +2,5 @@ obj-y += mx_pic.o
obj-y += pic_cpu.o
obj-y += xtensa_memory.o
obj-$(CONFIG_XTENSA_SIM) += sim.o
obj-$(CONFIG_XTENSA_VIRT) += virt.o
obj-$(CONFIG_XTENSA_XTFPGA) += xtfpga.o
+26 −15
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
#include "xtensa_memory.h"
#include "xtensa_sim.h"

static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
{
@@ -52,12 +53,11 @@ static void sim_reset(void *opaque)
    cpu_reset(CPU(cpu));
}

static void xtensa_sim_init(MachineState *machine)
XtensaCPU *xtensa_sim_common_init(MachineState *machine)
{
    XtensaCPU *cpu = NULL;
    CPUXtensaState *env = NULL;
    ram_addr_t ram_size = machine->ram_size;
    const char *kernel_filename = machine->kernel_filename;
    int n;

    for (n = 0; n < machine->smp.cpus; n++) {
@@ -89,30 +89,41 @@ static void xtensa_sim_init(MachineState *machine)
        xtensa_create_memory_regions(&sysram, "xtensa.sysram",
                                     get_system_memory());
    }

    if (serial_hd(0)) {
        xtensa_sim_open_console(serial_hd(0));
    }
    if (kernel_filename) {
        uint64_t elf_entry;
        uint64_t elf_lowaddr;
    return cpu;
}

void xtensa_sim_load_kernel(XtensaCPU *cpu, MachineState *machine)
{
    const char *kernel_filename = machine->kernel_filename;
#ifdef TARGET_WORDS_BIGENDIAN
        int success = load_elf(kernel_filename, NULL,
                               translate_phys_addr, cpu,
                               &elf_entry, &elf_lowaddr,
                               NULL, 1, EM_XTENSA, 0, 0);
    int big_endian = true;
#else
        int success = load_elf(kernel_filename, NULL,
                               translate_phys_addr, cpu,
                               &elf_entry, &elf_lowaddr,
                               NULL, 0, EM_XTENSA, 0, 0);
    int big_endian = false;
#endif

    if (kernel_filename) {
        uint64_t elf_entry;
        uint64_t elf_lowaddr;
        int success = load_elf(kernel_filename, NULL, translate_phys_addr, cpu,
                               &elf_entry, &elf_lowaddr, NULL, big_endian,
                               EM_XTENSA, 0, 0);

        if (success > 0) {
            env->pc = elf_entry;
            cpu->env.pc = elf_entry;
        }
    }
}

static void xtensa_sim_init(MachineState *machine)
{
    XtensaCPU *cpu = xtensa_sim_common_init(machine);

    xtensa_sim_load_kernel(cpu, machine);
}

static void xtensa_sim_machine_init(MachineClass *mc)
{
    mc->desc = "sim machine (" XTENSA_DEFAULT_CPU_MODEL ")";
Loading