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 | |
| 25 | #include "sysbus.h" |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 26 | #include "net.h" |
| 27 | #include "flash.h" |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 28 | #include "boards.h" |
Edgar E. Iglesias | 4b81698 | 2009-05-16 01:40:46 +0200 | [diff] [blame] | 29 | #include "sysemu.h" |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 30 | #include "etraxfs.h" |
Blue Swirl | ca20cf3 | 2009-09-20 14:58:02 +0000 | [diff] [blame] | 31 | #include "loader.h" |
| 32 | #include "elf.h" |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 33 | #include "cris-boot.h" |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 34 | |
| 35 | #define D(x) |
| 36 | #define DNAND(x) |
| 37 | |
| 38 | struct nand_state_t |
| 39 | { |
Paul Brook | bc24a22 | 2009-05-10 01:44:56 +0100 | [diff] [blame] | 40 | NANDFlashState *nand; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 41 | unsigned int rdy:1; |
| 42 | unsigned int ale:1; |
| 43 | unsigned int cle:1; |
| 44 | unsigned int ce:1; |
| 45 | }; |
| 46 | |
| 47 | static struct nand_state_t nand_state; |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 48 | static uint32_t nand_readl (void *opaque, target_phys_addr_t addr) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 49 | { |
| 50 | struct nand_state_t *s = opaque; |
| 51 | uint32_t r; |
| 52 | int rdy; |
| 53 | |
| 54 | r = nand_getio(s->nand); |
| 55 | nand_getpins(s->nand, &rdy); |
| 56 | s->rdy = rdy; |
| 57 | |
| 58 | DNAND(printf("%s addr=%x r=%x\n", __func__, addr, r)); |
| 59 | return r; |
| 60 | } |
| 61 | |
| 62 | static void |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 63 | nand_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 64 | { |
| 65 | struct nand_state_t *s = opaque; |
| 66 | int rdy; |
| 67 | |
| 68 | DNAND(printf("%s addr=%x v=%x\n", __func__, addr, value)); |
| 69 | nand_setpins(s->nand, s->cle, s->ale, s->ce, 1, 0); |
| 70 | nand_setio(s->nand, value); |
| 71 | nand_getpins(s->nand, &rdy); |
| 72 | s->rdy = rdy; |
| 73 | } |
| 74 | |
Blue Swirl | d60efc6 | 2009-08-25 18:29:31 +0000 | [diff] [blame] | 75 | static CPUReadMemoryFunc * const nand_read[] = { |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 76 | &nand_readl, |
| 77 | &nand_readl, |
| 78 | &nand_readl, |
| 79 | }; |
| 80 | |
Blue Swirl | d60efc6 | 2009-08-25 18:29:31 +0000 | [diff] [blame] | 81 | static CPUWriteMemoryFunc * const nand_write[] = { |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 82 | &nand_writel, |
| 83 | &nand_writel, |
| 84 | &nand_writel, |
| 85 | }; |
| 86 | |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 87 | |
| 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) { |
| 144 | /* 25 degrees celcius. */ |
| 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 | { |
| 167 | struct nand_state_t *nand; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 168 | struct tempsensor_t tempsensor; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 169 | uint32_t regs[0x5c / 4]; |
| 170 | } gpio_state; |
| 171 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 172 | static uint32_t gpio_readl (void *opaque, target_phys_addr_t addr) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 173 | { |
| 174 | struct gpio_state_t *s = opaque; |
| 175 | uint32_t r = 0; |
| 176 | |
| 177 | addr >>= 2; |
| 178 | switch (addr) |
| 179 | { |
| 180 | case R_PA_DIN: |
| 181 | r = s->regs[RW_PA_DOUT] & s->regs[RW_PA_OE]; |
| 182 | |
| 183 | /* Encode pins from the nand. */ |
| 184 | r |= s->nand->rdy << 7; |
| 185 | break; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 186 | case R_PD_DIN: |
| 187 | r = s->regs[RW_PD_DOUT] & s->regs[RW_PD_OE]; |
| 188 | |
| 189 | /* Encode temp sensor pins. */ |
| 190 | r |= (!!(s->tempsensor.shiftreg & 0x10000)) << 4; |
| 191 | break; |
| 192 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 193 | default: |
| 194 | r = s->regs[addr]; |
| 195 | break; |
| 196 | } |
| 197 | return r; |
| 198 | D(printf("%s %x=%x\n", __func__, addr, r)); |
| 199 | } |
| 200 | |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 201 | static void gpio_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 202 | { |
| 203 | struct gpio_state_t *s = opaque; |
| 204 | D(printf("%s %x=%x\n", __func__, addr, value)); |
| 205 | |
| 206 | addr >>= 2; |
| 207 | switch (addr) |
| 208 | { |
| 209 | case RW_PA_DOUT: |
| 210 | /* Decode nand pins. */ |
| 211 | s->nand->ale = !!(value & (1 << 6)); |
| 212 | s->nand->cle = !!(value & (1 << 5)); |
| 213 | s->nand->ce = !!(value & (1 << 4)); |
| 214 | |
| 215 | s->regs[addr] = value; |
| 216 | break; |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 217 | |
| 218 | case RW_PD_DOUT: |
| 219 | /* Temp sensor clk. */ |
| 220 | if ((s->regs[addr] ^ value) & 2) |
| 221 | tempsensor_clkedge(&s->tempsensor, !!(value & 2), |
| 222 | !!(value & 16)); |
| 223 | s->regs[addr] = value; |
| 224 | break; |
| 225 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 226 | default: |
| 227 | s->regs[addr] = value; |
| 228 | break; |
| 229 | } |
| 230 | } |
| 231 | |
Blue Swirl | d60efc6 | 2009-08-25 18:29:31 +0000 | [diff] [blame] | 232 | static CPUReadMemoryFunc * const gpio_read[] = { |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 233 | NULL, NULL, |
| 234 | &gpio_readl, |
| 235 | }; |
| 236 | |
Blue Swirl | d60efc6 | 2009-08-25 18:29:31 +0000 | [diff] [blame] | 237 | static CPUWriteMemoryFunc * const gpio_write[] = { |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 238 | NULL, NULL, |
| 239 | &gpio_writel, |
| 240 | }; |
| 241 | |
| 242 | #define INTMEM_SIZE (128 * 1024) |
| 243 | |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 244 | static struct cris_load_info li; |
Aurelien Jarno | 409dbce | 2010-03-14 21:20:59 +0100 | [diff] [blame] | 245 | |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 246 | static |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 247 | void axisdev88_init (ram_addr_t ram_size, |
edgar_igl | ef99823 | 2009-01-26 21:47:27 +0000 | [diff] [blame] | 248 | const char *boot_device, |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 249 | const char *kernel_filename, const char *kernel_cmdline, |
| 250 | const char *initrd_filename, const char *cpu_model) |
| 251 | { |
| 252 | CPUState *env; |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 253 | DeviceState *dev; |
| 254 | SysBusDevice *s; |
| 255 | qemu_irq irq[30], nmi[2], *cpu_irq; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 256 | void *etraxfs_dmac; |
| 257 | struct etraxfs_dma_client *eth[2] = {NULL, NULL}; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 258 | int i; |
| 259 | int nand_regs; |
| 260 | int gpio_regs; |
Anthony Liguori | c227f09 | 2009-10-01 16:12:16 -0500 | [diff] [blame] | 261 | ram_addr_t phys_ram; |
| 262 | ram_addr_t phys_intmem; |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 263 | |
| 264 | /* init CPUs */ |
| 265 | if (cpu_model == NULL) { |
| 266 | cpu_model = "crisv32"; |
| 267 | } |
| 268 | env = cpu_init(cpu_model); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 269 | |
| 270 | /* allocate RAM */ |
Alex Williamson | 1724f04 | 2010-06-25 11:09:35 -0600 | [diff] [blame] | 271 | phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 272 | cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); |
| 273 | |
| 274 | /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the |
| 275 | internal memory. */ |
Alex Williamson | 1724f04 | 2010-06-25 11:09:35 -0600 | [diff] [blame] | 276 | phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 277 | cpu_register_physical_memory(0x38000000, INTMEM_SIZE, |
| 278 | phys_intmem | IO_MEM_RAM); |
| 279 | |
| 280 | |
| 281 | /* Attach a NAND flash to CS1. */ |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 282 | nand_state.nand = nand_init(NAND_MFR_STMICRO, 0x39); |
Avi Kivity | 1eed09c | 2009-06-14 11:38:51 +0300 | [diff] [blame] | 283 | nand_regs = cpu_register_io_memory(nand_read, nand_write, &nand_state); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 284 | cpu_register_physical_memory(0x10000000, 0x05000000, nand_regs); |
| 285 | |
| 286 | gpio_state.nand = &nand_state; |
Avi Kivity | 1eed09c | 2009-06-14 11:38:51 +0300 | [diff] [blame] | 287 | gpio_regs = cpu_register_io_memory(gpio_read, gpio_write, &gpio_state); |
edgar_igl | 4a1e6be | 2009-01-07 13:05:58 +0000 | [diff] [blame] | 288 | cpu_register_physical_memory(0x3001a000, 0x5c, gpio_regs); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 289 | |
| 290 | |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 291 | cpu_irq = cris_pic_init_cpu(env); |
| 292 | dev = qdev_create(NULL, "etraxfs,pic"); |
| 293 | /* FIXME: Is there a proper way to signal vectors to the CPU core? */ |
Gerd Hoffmann | ee6847d | 2009-07-15 13:43:31 +0200 | [diff] [blame] | 294 | qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector); |
Markus Armbruster | e23a1b3 | 2009-10-07 01:15:58 +0200 | [diff] [blame] | 295 | qdev_init_nofail(dev); |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 296 | s = sysbus_from_qdev(dev); |
| 297 | sysbus_mmio_map(s, 0, 0x3001c000); |
| 298 | sysbus_connect_irq(s, 0, cpu_irq[0]); |
| 299 | sysbus_connect_irq(s, 1, cpu_irq[1]); |
| 300 | for (i = 0; i < 30; i++) { |
Paul Brook | 067a3dd | 2009-05-26 14:56:11 +0100 | [diff] [blame] | 301 | irq[i] = qdev_get_gpio_in(dev, i); |
Edgar E. Iglesias | fd6dc90 | 2009-05-18 22:24:22 +0200 | [diff] [blame] | 302 | } |
Paul Brook | 067a3dd | 2009-05-26 14:56:11 +0100 | [diff] [blame] | 303 | nmi[0] = qdev_get_gpio_in(dev, 30); |
| 304 | nmi[1] = qdev_get_gpio_in(dev, 31); |
Edgar E. Iglesias | 73cfd29 | 2009-05-16 00:23:15 +0200 | [diff] [blame] | 305 | |
Edgar E. Iglesias | ba49431 | 2009-06-15 21:00:50 +0200 | [diff] [blame] | 306 | etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 307 | for (i = 0; i < 10; i++) { |
| 308 | /* On ETRAX, odd numbered channels are inputs. */ |
Edgar E. Iglesias | 73cfd29 | 2009-05-16 00:23:15 +0200 | [diff] [blame] | 309 | etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 310 | } |
| 311 | |
| 312 | /* Add the two ethernet blocks. */ |
Edgar E. Iglesias | ba49431 | 2009-06-15 21:00:50 +0200 | [diff] [blame] | 313 | eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1); |
aliguori | 0ae18ce | 2009-01-13 19:39:36 +0000 | [diff] [blame] | 314 | if (nb_nics > 1) |
Edgar E. Iglesias | ba49431 | 2009-06-15 21:00:50 +0200 | [diff] [blame] | 315 | eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 316 | |
| 317 | /* The DMA Connector block is missing, hardwire things for now. */ |
| 318 | etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); |
| 319 | etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); |
| 320 | if (eth[1]) { |
| 321 | etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); |
| 322 | etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); |
| 323 | } |
| 324 | |
| 325 | /* 2 timers. */ |
Edgar E. Iglesias | 3b1fd90 | 2009-05-16 02:08:16 +0200 | [diff] [blame] | 326 | sysbus_create_varargs("etraxfs,timer", 0x3001e000, irq[0x1b], nmi[1], NULL); |
| 327 | sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 328 | |
| 329 | for (i = 0; i < 4; i++) { |
Edgar E. Iglesias | 4b81698 | 2009-05-16 01:40:46 +0200 | [diff] [blame] | 330 | sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000, |
Edgar E. Iglesias | 3b1fd90 | 2009-05-16 02:08:16 +0200 | [diff] [blame] | 331 | irq[0x14 + i]); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 332 | } |
| 333 | |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 334 | if (!kernel_filename) { |
| 335 | fprintf(stderr, "Kernel image must be specified\n"); |
| 336 | exit(1); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 337 | } |
Edgar E. Iglesias | 77d4f95 | 2010-06-10 14:45:46 +0200 | [diff] [blame] | 338 | |
| 339 | li.image_filename = kernel_filename; |
| 340 | li.cmdline = kernel_cmdline; |
| 341 | cris_load_image(env, &li); |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 342 | } |
| 343 | |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 344 | static QEMUMachine axisdev88_machine = { |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 345 | .name = "axis-dev88", |
| 346 | .desc = "AXIS devboard 88", |
| 347 | .init = axisdev88_init, |
edgar_igl | 10c144e | 2009-01-07 12:19:50 +0000 | [diff] [blame] | 348 | }; |
Anthony Liguori | f80f9ec | 2009-05-20 18:38:09 -0500 | [diff] [blame] | 349 | |
| 350 | static void axisdev88_machine_init(void) |
| 351 | { |
| 352 | qemu_register_machine(&axisdev88_machine); |
| 353 | } |
| 354 | |
| 355 | machine_init(axisdev88_machine_init); |