]>
Commit | Line | Data |
---|---|---|
d9e8553b MF |
1 | /* |
2 | * Copyright (c) 2019, Max Filippov, Open Source and Linux Lab. | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are met: | |
7 | * * Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | |
9 | * * Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | |
12 | * * Neither the name of the Open Source and Linux Lab nor the | |
13 | * names of its contributors may be used to endorse or promote products | |
14 | * derived from this software without specific prior written permission. | |
15 | * | |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | |
27 | ||
28 | #include "qemu/osdep.h" | |
29 | #include "qapi/error.h" | |
30 | #include "cpu.h" | |
31 | #include "sysemu/reset.h" | |
32 | #include "sysemu/sysemu.h" | |
33 | #include "hw/boards.h" | |
34 | #include "hw/loader.h" | |
35 | #include "hw/pci-host/gpex.h" | |
36 | #include "net/net.h" | |
37 | #include "elf.h" | |
38 | #include "exec/memory.h" | |
39 | #include "exec/address-spaces.h" | |
40 | #include "qemu/error-report.h" | |
41 | #include "xtensa_memory.h" | |
42 | #include "xtensa_sim.h" | |
43 | ||
44 | static void create_pcie(CPUXtensaState *env, int irq_base, hwaddr addr_base) | |
45 | { | |
46 | hwaddr base_ecam = addr_base + 0x00100000; | |
47 | hwaddr size_ecam = 0x03f00000; | |
48 | hwaddr base_pio = addr_base + 0x00000000; | |
49 | hwaddr size_pio = 0x00010000; | |
50 | hwaddr base_mmio = addr_base + 0x04000000; | |
51 | hwaddr size_mmio = 0x08000000; | |
52 | ||
53 | MemoryRegion *ecam_alias; | |
54 | MemoryRegion *ecam_reg; | |
55 | MemoryRegion *pio_alias; | |
56 | MemoryRegion *pio_reg; | |
57 | MemoryRegion *mmio_alias; | |
58 | MemoryRegion *mmio_reg; | |
59 | ||
60 | DeviceState *dev; | |
61 | PCIHostState *pci; | |
62 | qemu_irq *extints; | |
63 | int i; | |
64 | ||
3e80f690 MA |
65 | dev = qdev_new(TYPE_GPEX_HOST); |
66 | qdev_realize_and_unref(dev, NULL, &error_fatal); | |
d9e8553b MF |
67 | |
68 | /* Map only the first size_ecam bytes of ECAM space. */ | |
69 | ecam_alias = g_new0(MemoryRegion, 1); | |
70 | ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); | |
71 | memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam", | |
72 | ecam_reg, 0, size_ecam); | |
73 | memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias); | |
74 | ||
75 | /* | |
76 | * Map the MMIO window into system address space so as to expose | |
77 | * the section of PCI MMIO space which starts at the same base address | |
78 | * (ie 1:1 mapping for that part of PCI MMIO space visible through | |
79 | * the window). | |
80 | */ | |
81 | mmio_alias = g_new0(MemoryRegion, 1); | |
82 | mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); | |
83 | memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio", | |
84 | mmio_reg, base_mmio, size_mmio); | |
85 | memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias); | |
86 | ||
87 | /* Map IO port space. */ | |
88 | pio_alias = g_new0(MemoryRegion, 1); | |
89 | pio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 2); | |
90 | memory_region_init_alias(pio_alias, OBJECT(dev), "pcie-pio", | |
91 | pio_reg, 0, size_pio); | |
92 | memory_region_add_subregion(get_system_memory(), base_pio, pio_alias); | |
93 | ||
94 | /* Connect IRQ lines. */ | |
95 | extints = xtensa_get_extints(env); | |
96 | ||
97 | for (i = 0; i < GPEX_NUM_IRQS; i++) { | |
98 | void *q = extints[irq_base + i]; | |
99 | ||
100 | sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, q); | |
101 | gpex_set_irq_num(GPEX_HOST(dev), i, irq_base + i); | |
102 | } | |
103 | ||
104 | pci = PCI_HOST_BRIDGE(dev); | |
105 | if (pci->bus) { | |
106 | for (i = 0; i < nb_nics; i++) { | |
107 | NICInfo *nd = &nd_table[i]; | |
108 | ||
109 | if (!nd->model) { | |
110 | nd->model = g_strdup("virtio"); | |
111 | } | |
112 | ||
113 | pci_nic_init_nofail(nd, pci->bus, nd->model, NULL); | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | static void xtensa_virt_init(MachineState *machine) | |
119 | { | |
120 | XtensaCPU *cpu = xtensa_sim_common_init(machine); | |
121 | CPUXtensaState *env = &cpu->env; | |
122 | ||
123 | create_pcie(env, 0, 0xf0000000); | |
124 | xtensa_sim_load_kernel(cpu, machine); | |
125 | } | |
126 | ||
127 | static void xtensa_virt_machine_init(MachineClass *mc) | |
128 | { | |
129 | mc->desc = "virt machine (" XTENSA_DEFAULT_CPU_MODEL ")"; | |
130 | mc->init = xtensa_virt_init; | |
131 | mc->max_cpus = 32; | |
132 | mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE; | |
133 | } | |
134 | ||
135 | DEFINE_MACHINE("virt", xtensa_virt_machine_init) |