edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 1 | /* |
| 2 | * QEMU model for the AXIS devboard 88. |
| 3 | * |
| 4 | * Copyright (c) 2009 Edgar E. Iglesias, Axis Communications AB. |
| 5 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| 7 | * of this software and associated documentation files (the "Software"), to deal |
| 8 | * in the Software without restriction, including without limitation the rights |
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 10 | * copies of the Software, and to permit persons to whom the Software is |
| 11 | * furnished to do so, subject to the following conditions: |
| 12 | * |
| 13 | * The above copyright notice and this permission notice shall be included in |
| 14 | * all copies or substantial portions of the Software. |
| 15 | * |
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 22 | * THE SOFTWARE. |
| 23 | */ |
Edgar E. Iglesias | 4b81698 | 2009-05-16 01:40:46 +0200 | [diff] [blame] | 24 | |
Peter Maydell | 23b0d7d | 2016-01-26 18:17:24 +0000 | [diff] [blame] | 25 | #include "qemu/osdep.h" |
Philippe Mathieu-Daudé | a4ed5a3 | 2018-06-25 09:42:18 -0300 | [diff] [blame] | 26 | #include "qemu/units.h" |
Markus Armbruster | da34e65 | 2016-03-14 09:01:28 +0100 | [diff] [blame] | 27 | #include "qapi/error.h" |
Paolo Bonzini | 4771d75 | 2016-01-19 21:51:44 +0100 | [diff] [blame] | 28 | #include "cpu.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 29 | #include "hw/sysbus.h" |
Paolo Bonzini | 1422e32 | 2012-10-24 08:43:34 +0200 | [diff] [blame] | 30 | #include "net/net.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 31 | #include "hw/block/flash.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 32 | #include "hw/boards.h" |
Paolo Bonzini | 0d09e41 | 2013-02-05 17:06:20 +0100 | [diff] [blame] | 33 | #include "hw/cris/etraxfs.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 34 | #include "hw/loader.h" |
Blue Swirl | ca20cf3 | 2009-09-20 14:58:02 +0000 | [diff] [blame] | 35 | #include "elf.h" |
Paolo Bonzini | 47b43a1 | 2013-03-18 17:36:02 +0100 | [diff] [blame] | 36 | #include "boot.h" |
Andreas Färber | 5efe843 | 2013-07-29 18:40:20 +0200 | [diff] [blame] | 37 | #include "sysemu/qtest.h" |
xiaoqiang zhao | 8290de9 | 2016-05-25 14:39:01 +0800 | [diff] [blame] | 38 | #include "sysemu/sysemu.h" |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 39 | |
| 40 | #define D(x) |
| 41 | #define DNAND(x) |
| 42 | |
| 43 | struct nand_state_t |
| 44 | { |
Juha Riihimäki | d422038 | 2011-07-29 16:35:24 +0100 | [diff] [blame] | 45 | DeviceState *nand; |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 46 | MemoryRegion iomem; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 47 | unsigned int rdy:1; |
| 48 | unsigned int ale:1; |
| 49 | unsigned int cle:1; |
| 50 | unsigned int ce:1; |
| 51 | }; |
| 52 | |
| 53 | static struct nand_state_t nand_state; |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 54 | static uint64_t nand_read(void *opaque, hwaddr addr, unsigned size) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 55 | { |
| 56 | struct nand_state_t *s = opaque; |
| 57 | uint32_t r; |
| 58 | int rdy; |
| 59 | |
| 60 | r = nand_getio(s->nand); |
| 61 | nand_getpins(s->nand, &rdy); |
| 62 | s->rdy = rdy; |
| 63 | |
| 64 | DNAND(printf("%s addr=%x r=%x\n", __func__, addr, r)); |
| 65 | return r; |
| 66 | } |
| 67 | |
| 68 | static void |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 69 | nand_write(void *opaque, hwaddr addr, uint64_t value, |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 70 | unsigned size) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 71 | { |
| 72 | struct nand_state_t *s = opaque; |
| 73 | int rdy; |
| 74 | |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 75 | DNAND(printf("%s addr=%x v=%x\n", __func__, addr, (unsigned)value)); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 76 | nand_setpins(s->nand, s->cle, s->ale, s->ce, 1, 0); |
| 77 | nand_setio(s->nand, value); |
| 78 | nand_getpins(s->nand, &rdy); |
| 79 | s->rdy = rdy; |
| 80 | } |
| 81 | |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 82 | static const MemoryRegionOps nand_ops = { |
| 83 | .read = nand_read, |
| 84 | .write = nand_write, |
| 85 | .endianness = DEVICE_NATIVE_ENDIAN, |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 86 | }; |
| 87 | |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 88 | struct tempsensor_t |
| 89 | { |
| 90 | unsigned int shiftreg; |
| 91 | unsigned int count; |
| 92 | enum { |
| 93 | ST_OUT, ST_IN, ST_Z |
| 94 | } state; |
| 95 | |
| 96 | uint16_t regs[3]; |
| 97 | }; |
| 98 | |
| 99 | static void tempsensor_clkedge(struct tempsensor_t *s, |
| 100 | unsigned int clk, unsigned int data_in) |
| 101 | { |
| 102 | D(printf("%s clk=%d state=%d sr=%x\n", __func__, |
| 103 | clk, s->state, s->shiftreg)); |
| 104 | if (s->count == 0) { |
| 105 | s->count = 16; |
| 106 | s->state = ST_OUT; |
| 107 | } |
| 108 | switch (s->state) { |
| 109 | case ST_OUT: |
| 110 | /* Output reg is clocked at negedge. */ |
| 111 | if (!clk) { |
| 112 | s->count--; |
| 113 | s->shiftreg <<= 1; |
| 114 | if (s->count == 0) { |
| 115 | s->shiftreg = 0; |
| 116 | s->state = ST_IN; |
| 117 | s->count = 16; |
| 118 | } |
| 119 | } |
| 120 | break; |
| 121 | case ST_Z: |
| 122 | if (clk) { |
| 123 | s->count--; |
| 124 | if (s->count == 0) { |
| 125 | s->shiftreg = 0; |
| 126 | s->state = ST_OUT; |
| 127 | s->count = 16; |
| 128 | } |
| 129 | } |
| 130 | break; |
| 131 | case ST_IN: |
| 132 | /* Indata is sampled at posedge. */ |
| 133 | if (clk) { |
| 134 | s->count--; |
| 135 | s->shiftreg <<= 1; |
| 136 | s->shiftreg |= data_in & 1; |
| 137 | if (s->count == 0) { |
| 138 | D(printf("%s cfgreg=%x\n", __func__, s->shiftreg)); |
| 139 | s->regs[0] = s->shiftreg; |
| 140 | s->state = ST_OUT; |
| 141 | s->count = 16; |
| 142 | |
| 143 | if ((s->regs[0] & 0xff) == 0) { |
Veres Lajos | 67cc32e | 2015-09-08 22:45:14 +0100 | [diff] [blame] | 144 | /* 25 degrees celsius. */ |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 145 | s->shiftreg = 0x0b9f; |
| 146 | } else if ((s->regs[0] & 0xff) == 0xff) { |
| 147 | /* Sensor ID, 0x8100 LM70. */ |
| 148 | s->shiftreg = 0x8100; |
| 149 | } else |
| 150 | printf("Invalid tempsens state %x\n", s->regs[0]); |
| 151 | } |
| 152 | } |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | |
| 158 | #define RW_PA_DOUT 0x00 |
| 159 | #define R_PA_DIN 0x01 |
| 160 | #define RW_PA_OE 0x02 |
| 161 | #define RW_PD_DOUT 0x10 |
| 162 | #define R_PD_DIN 0x11 |
| 163 | #define RW_PD_OE 0x12 |
| 164 | |
| 165 | static struct gpio_state_t |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 166 | { |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 167 | MemoryRegion iomem; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 168 | struct nand_state_t *nand; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 169 | struct tempsensor_t tempsensor; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 170 | uint32_t regs[0x5c / 4]; |
| 171 | } gpio_state; |
| 172 | |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 173 | static uint64_t gpio_read(void *opaque, hwaddr addr, unsigned size) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 174 | { |
| 175 | struct gpio_state_t *s = opaque; |
| 176 | uint32_t r = 0; |
| 177 | |
| 178 | addr >>= 2; |
| 179 | switch (addr) |
| 180 | { |
| 181 | case R_PA_DIN: |
| 182 | r = s->regs[RW_PA_DOUT] & s->regs[RW_PA_OE]; |
| 183 | |
| 184 | /* Encode pins from the nand. */ |
| 185 | r |= s->nand->rdy << 7; |
| 186 | break; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 187 | case R_PD_DIN: |
| 188 | r = s->regs[RW_PD_DOUT] & s->regs[RW_PD_OE]; |
| 189 | |
| 190 | /* Encode temp sensor pins. */ |
| 191 | r |= (!!(s->tempsensor.shiftreg & 0x10000)) << 4; |
| 192 | break; |
| 193 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 194 | default: |
| 195 | r = s->regs[addr]; |
| 196 | break; |
| 197 | } |
| 198 | return r; |
| 199 | D(printf("%s %x=%x\n", __func__, addr, r)); |
| 200 | } |
| 201 | |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 202 | static void gpio_write(void *opaque, hwaddr addr, uint64_t value, |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 203 | unsigned size) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 204 | { |
| 205 | struct gpio_state_t *s = opaque; |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 206 | D(printf("%s %x=%x\n", __func__, addr, (unsigned)value)); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 207 | |
| 208 | addr >>= 2; |
| 209 | switch (addr) |
| 210 | { |
| 211 | case RW_PA_DOUT: |
| 212 | /* Decode nand pins. */ |
| 213 | s->nand->ale = !!(value & (1 << 6)); |
| 214 | s->nand->cle = !!(value & (1 << 5)); |
| 215 | s->nand->ce = !!(value & (1 << 4)); |
| 216 | |
| 217 | s->regs[addr] = value; |
| 218 | break; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 219 | |
| 220 | case RW_PD_DOUT: |
| 221 | /* Temp sensor clk. */ |
| 222 | if ((s->regs[addr] ^ value) & 2) |
| 223 | tempsensor_clkedge(&s->tempsensor, !!(value & 2), |
| 224 | !!(value & 16)); |
| 225 | s->regs[addr] = value; |
| 226 | break; |
| 227 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 228 | default: |
| 229 | s->regs[addr] = value; |
| 230 | break; |
| 231 | } |
| 232 | } |
| 233 | |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 234 | static const MemoryRegionOps gpio_ops = { |
| 235 | .read = gpio_read, |
| 236 | .write = gpio_write, |
| 237 | .endianness = DEVICE_NATIVE_ENDIAN, |
| 238 | .valid = { |
| 239 | .min_access_size = 4, |
| 240 | .max_access_size = 4, |
| 241 | }, |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 242 | }; |
| 243 | |
Philippe Mathieu-Daudé | a4ed5a3 | 2018-06-25 09:42:18 -0300 | [diff] [blame] | 244 | #define INTMEM_SIZE (128 * KiB) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 245 | |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 246 | static struct cris_load_info li; |
Aurelien Jarno | 409dbce | 2010-03-14 21:20:59 +0100 | [diff] [blame] | 247 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 248 | static |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 249 | void axisdev88_init(MachineState *machine) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 250 | { |
Marcel Apfelbaum | 3ef9622 | 2014-05-07 17:42:57 +0300 | [diff] [blame] | 251 | const char *kernel_filename = machine->kernel_filename; |
| 252 | const char *kernel_cmdline = machine->kernel_cmdline; |
Andreas Färber | ddeb9ae | 2012-05-05 11:50:35 +0200 | [diff] [blame] | 253 | CRISCPU *cpu; |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 254 | DeviceState *dev; |
| 255 | SysBusDevice *s; |
Peter Maydell | 522f253 | 2011-07-29 16:35:19 +0100 | [diff] [blame] | 256 | DriveInfo *nand; |
Edgar E. Iglesias | 4a6da67 | 2014-01-21 22:45:54 +1000 | [diff] [blame] | 257 | qemu_irq irq[30], nmi[2]; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 258 | void *etraxfs_dmac; |
Edgar E. Iglesias | 1da005b | 2011-08-09 12:13:26 +0200 | [diff] [blame] | 259 | struct etraxfs_dma_client *dma_eth; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 260 | int i; |
Avi Kivity | b0e3d5a | 2011-07-25 14:32:34 +0300 | [diff] [blame] | 261 | MemoryRegion *address_space_mem = get_system_memory(); |
Avi Kivity | b0e3d5a | 2011-07-25 14:32:34 +0300 | [diff] [blame] | 262 | MemoryRegion *phys_intmem = g_new(MemoryRegion, 1); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 263 | |
| 264 | /* init CPUs */ |
Igor Mammedov | 5eab493 | 2017-10-05 15:50:41 +0200 | [diff] [blame] | 265 | cpu = CRIS_CPU(cpu_create(machine->cpu_type)); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 266 | |
Igor Mammedov | 17c38c7 | 2020-02-19 11:09:14 -0500 | [diff] [blame] | 267 | memory_region_add_subregion(address_space_mem, 0x40000000, machine->ram); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 268 | |
| 269 | /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the |
| 270 | internal memory. */ |
Peter Maydell | 98a99ce | 2017-07-07 15:42:53 +0100 | [diff] [blame] | 271 | memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", |
| 272 | INTMEM_SIZE, &error_fatal); |
Avi Kivity | b0e3d5a | 2011-07-25 14:32:34 +0300 | [diff] [blame] | 273 | memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 274 | |
| 275 | /* Attach a NAND flash to CS1. */ |
Peter Maydell | 522f253 | 2011-07-29 16:35:19 +0100 | [diff] [blame] | 276 | nand = drive_get(IF_MTD, 0, 0); |
Markus Armbruster | 4be7463 | 2014-10-07 13:59:18 +0200 | [diff] [blame] | 277 | nand_state.nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL, |
Peter Maydell | 522f253 | 2011-07-29 16:35:19 +0100 | [diff] [blame] | 278 | NAND_MFR_STMICRO, 0x39); |
Paolo Bonzini | 2c9b15c | 2013-06-06 05:41:28 -0400 | [diff] [blame] | 279 | memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state, |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 280 | "nand", 0x05000000); |
| 281 | memory_region_add_subregion(address_space_mem, 0x10000000, |
| 282 | &nand_state.iomem); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 283 | |
| 284 | gpio_state.nand = &nand_state; |
Paolo Bonzini | 2c9b15c | 2013-06-06 05:41:28 -0400 | [diff] [blame] | 285 | memory_region_init_io(&gpio_state.iomem, NULL, &gpio_ops, &gpio_state, |
Avi Kivity | 838335e | 2011-11-14 11:17:21 +0200 | [diff] [blame] | 286 | "gpio", 0x5c); |
| 287 | memory_region_add_subregion(address_space_mem, 0x3001a000, |
| 288 | &gpio_state.iomem); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 289 | |
| 290 | |
Markus Armbruster | e178113 | 2021-03-04 15:02:28 +0100 | [diff] [blame] | 291 | dev = qdev_new("etraxfs-pic"); |
Andreas Färber | 1356b98 | 2013-01-20 02:47:33 +0100 | [diff] [blame] | 292 | s = SYS_BUS_DEVICE(dev); |
Markus Armbruster | 3c6ef47 | 2020-06-10 07:32:34 +0200 | [diff] [blame] | 293 | sysbus_realize_and_unref(s, &error_fatal); |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 294 | sysbus_mmio_map(s, 0, 0x3001c000); |
Edgar E. Iglesias | 4a6da67 | 2014-01-21 22:45:54 +1000 | [diff] [blame] | 295 | sysbus_connect_irq(s, 0, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_IRQ)); |
| 296 | sysbus_connect_irq(s, 1, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_NMI)); |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 297 | for (i = 0; i < 30; i++) { |
Paul Brook | 067a3dd | 2009-05-26 14:56:11 +0100 | [diff] [blame] | 298 | irq[i] = qdev_get_gpio_in(dev, i); |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 299 | } |
Paul Brook | 067a3dd | 2009-05-26 14:56:11 +0100 | [diff] [blame] | 300 | nmi[0] = qdev_get_gpio_in(dev, 30); |
| 301 | nmi[1] = qdev_get_gpio_in(dev, 31); |
Edgar E. Iglesias | 73cfd29 | 2009-05-16 00:23:15 +0200 | [diff] [blame] | 302 | |
Edgar E. Iglesias | ba49431 | 2009-06-15 21:00:50 +0200 | [diff] [blame] | 303 | etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 304 | for (i = 0; i < 10; i++) { |
| 305 | /* On ETRAX, odd numbered channels are inputs. */ |
Edgar E. Iglesias | 73cfd29 | 2009-05-16 00:23:15 +0200 | [diff] [blame] | 306 | etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 307 | } |
| 308 | |
| 309 | /* Add the two ethernet blocks. */ |
Anthony Liguori | 7267c09 | 2011-08-20 22:09:37 -0500 | [diff] [blame] | 310 | dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels. */ |
Edgar E. Iglesias | 1da005b | 2011-08-09 12:13:26 +0200 | [diff] [blame] | 311 | etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]); |
| 312 | if (nb_nics > 1) { |
| 313 | etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]); |
| 314 | } |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 315 | |
| 316 | /* The DMA Connector block is missing, hardwire things for now. */ |
Edgar E. Iglesias | 1da005b | 2011-08-09 12:13:26 +0200 | [diff] [blame] | 317 | etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]); |
| 318 | etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]); |
| 319 | if (nb_nics > 1) { |
| 320 | etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]); |
| 321 | etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | /* 2 timers. */ |
Markus Armbruster | e178113 | 2021-03-04 15:02:28 +0100 | [diff] [blame] | 325 | sysbus_create_varargs("etraxfs-timer", 0x3001e000, irq[0x1b], nmi[1], NULL); |
| 326 | sysbus_create_varargs("etraxfs-timer", 0x3005e000, irq[0x1b], nmi[1], NULL); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 327 | |
| 328 | for (i = 0; i < 4; i++) { |
Peter Maydell | 9bca0ed | 2018-04-20 15:52:43 +0100 | [diff] [blame] | 329 | etraxfs_ser_create(0x30026000 + i * 0x2000, irq[0x14 + i], serial_hd(i)); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 330 | } |
| 331 | |
Andreas Färber | 5efe843 | 2013-07-29 18:40:20 +0200 | [diff] [blame] | 332 | if (kernel_filename) { |
| 333 | li.image_filename = kernel_filename; |
| 334 | li.cmdline = kernel_cmdline; |
Paolo Bonzini | 58a70f1 | 2020-10-28 06:19:42 -0400 | [diff] [blame] | 335 | li.ram_size = machine->ram_size; |
Andreas Färber | 5efe843 | 2013-07-29 18:40:20 +0200 | [diff] [blame] | 336 | cris_load_image(cpu, &li); |
| 337 | } else if (!qtest_enabled()) { |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 338 | fprintf(stderr, "Kernel image must be specified\n"); |
| 339 | exit(1); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 340 | } |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 341 | } |
| 342 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 343 | static void axisdev88_machine_init(MachineClass *mc) |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 344 | { |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 345 | mc->desc = "AXIS devboard 88"; |
| 346 | mc->init = axisdev88_init; |
Philippe Mathieu-Daudé | ea0ac7f | 2020-02-07 17:19:47 +0100 | [diff] [blame] | 347 | mc->is_default = true; |
Igor Mammedov | 5eab493 | 2017-10-05 15:50:41 +0200 | [diff] [blame] | 348 | mc->default_cpu_type = CRIS_CPU_TYPE_NAME("crisv32"); |
Igor Mammedov | 17c38c7 | 2020-02-19 11:09:14 -0500 | [diff] [blame] | 349 | mc->default_ram_id = "axisdev88.ram"; |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 350 | } |
| 351 | |
Eduardo Habkost | e264d29 | 2015-09-04 15:37:08 -0300 | [diff] [blame] | 352 | DEFINE_MACHINE("axis-dev88", axisdev88_machine_init) |