3 * System emulation for the Simtec Electronics BAST
5 * Copyright 2006, 2008 Daniel Silverstone and Vincent Sanders
7 * Copyright 2010, 2013 Stefan Weil
9 * This file is under the terms of the GNU General Public License Version 2.
12 * * Undefined r/w at address 0x118002f9 (serial i/o?).
13 * * Undefined r/w at address 0x118003f9 (serial i/o?).
14 * * Undefined r/w at address 0x29000000 ff (ax88796).
15 * * Undefined r/w at address 0x4b000000 ff.
16 * * Undefined r/w at address 0x55000000 ff (iis).
17 * * eth1 is 10 Mbps half duplex only.
20 #include "qemu/osdep.h"
22 #include "chardev/char.h" /* qemu_chr_new */
23 #include "exec/address-spaces.h" /* get_system_memory */
24 #include "hw/arm/boot.h"
25 #include "hw/boards.h"
26 #include "hw/char/serial.h" /* serial_isa_init */
28 #include "hw/i2c/i2c.h" /* i2c_create_slave */
29 #include "hw/ide/internal.h" /* ide_cmd_write, ... */
30 #include "hw/loader.h" /* load_image_targphys */
31 #include "hw/qdev-properties.h"
32 #include "hw/sysbus.h" /* SYS_BUS_DEVICE, ... */
33 #include "migration/vmstate.h" /* VMStateDescription */
35 #include "qemu-common.h" /* qemu_find_file */
37 #include "sysemu/blockdev.h" /* drive_get */
38 #include "sysemu/dma.h" /* QEMUSGList (in ide/internal.h) */
39 #include "sysemu/sysemu.h"
41 #define BIOS_FILENAME "able.bin"
43 #define MiB (1024 * 1024)
45 #define S3C24XX_DBF(format, ...) (void)0
56 #define BAST_NOR_RO_BASE CPU_S3C2410X_CS0
57 #define BAST_NOR_RW_BASE (CPU_S3C2410X_CS1 + 0x4000000)
58 #define BAST_NOR_SIZE (2 * MiB)
59 #define BAST_BOARD_ID 331
61 #define BAST_CS1_CPLD_BASE (CPU_S3C2410X_CS1 | (0xc << 23))
62 #define BAST_CS5_CPLD_BASE (CPU_S3C2410X_CS5 | (0xc << 23))
63 #define BAST_CPLD_SIZE (4<<23)
65 static uint64_t cpld_read(void *opaque
, hwaddr address
,
68 STCBState
*stcb
= opaque
;
69 int reg
= (address
>> 23) & 0xf;
71 return stcb
->cpld_ctrl2
;
76 static void cpld_write(void *opaque
, hwaddr address
,
77 uint64_t value
, unsigned size
)
79 STCBState
*stcb
= opaque
;
80 int reg
= (address
>> 23) & 0xf;
82 stcb
->cpld_ctrl2
= value
;
83 s3c24xx_nand_attach(stcb
->soc
->nand
, stcb
->nand
[stcb
->cpld_ctrl2
& 3]);
87 static const MemoryRegionOps cpld_ops
= {
90 .endianness
= DEVICE_NATIVE_ENDIAN
,
97 static void stcb_cpld_register(STCBState
*s
)
99 MemoryRegion
*sysmem
= get_system_memory();
100 memory_region_init_io(&s
->cpld1
, OBJECT(s
),
101 &cpld_ops
, s
, "cpld1", BAST_CPLD_SIZE
);
102 memory_region_init_alias(&s
->cpld5
, NULL
, "cpld5", &s
->cpld1
, 0, BAST_CPLD_SIZE
);
103 memory_region_add_subregion(sysmem
, BAST_CS1_CPLD_BASE
, &s
->cpld1
);
104 memory_region_add_subregion(sysmem
, BAST_CS5_CPLD_BASE
, &s
->cpld5
);
108 #define BAST_IDE_PRI_SLOW (CPU_S3C2410X_CS3 | 0x02000000)
109 #define BAST_IDE_SEC_SLOW (CPU_S3C2410X_CS3 | 0x03000000)
110 #define BAST_IDE_PRI_FAST (CPU_S3C2410X_CS5 | 0x02000000)
111 #define BAST_IDE_SEC_FAST (CPU_S3C2410X_CS5 | 0x03000000)
113 #define BAST_IDE_PRI_SLOW_BYTE (CPU_S3C2410X_CS2 | 0x02000000)
114 #define BAST_IDE_SEC_SLOW_BYTE (CPU_S3C2410X_CS2 | 0x03000000)
115 #define BAST_IDE_PRI_FAST_BYTE (CPU_S3C2410X_CS4 | 0x02000000)
116 #define BAST_IDE_SEC_FAST_BYTE (CPU_S3C2410X_CS4 | 0x03000000)
118 /* MMIO interface to IDE on Simtec's BAST
120 * Copyright Daniel Silverstone and Vincent Sanders
122 * This section of this file is under the terms of
123 * the GNU General Public License Version 2
126 /* Each BAST IDE region is 0x01000000 bytes long,
127 * the second half is the "alternate" register set
139 static void stcb_ide_write(void *opaque
, hwaddr addr
,
140 uint64_t val
, unsigned size
)
142 MMIOState
*s
= opaque
;
143 int reg
= (addr
& 0x3ff) >> 5; /* 0x200 long, 0x20 stride */
144 int alt
= (addr
& 0x800000) != 0;
145 S3C24XX_DBF("IDE write to addr %08x (reg %d) of value %04x\n", (unsigned int)addr
, reg
, val
);
147 ide_cmd_write(&s
->bus
, 0, val
);
151 ide_data_writew(&s
->bus
, 0, val
);
153 /* Everything else */
154 ide_ioport_write(&s
->bus
, reg
, val
);
158 static uint64_t stcb_ide_read(void *opaque
, hwaddr addr
,
161 MMIOState
*s
= opaque
;
162 int reg
= (addr
& 0x3ff) >> 5; /* 0x200 long, 0x20 stride */
163 int alt
= (addr
& 0x800000) != 0;
164 S3C24XX_DBF("IDE read of addr %08x (reg %d)\n", (unsigned int)addr
, reg
);
166 return ide_status_read(&s
->bus
, 0);
169 return ide_data_readw(&s
->bus
, 0);
171 return ide_ioport_read(&s
->bus
, reg
);
175 static const MemoryRegionOps stcb_ide_ops
= {
176 .read
= stcb_ide_read
,
177 .write
= stcb_ide_write
,
178 .endianness
= DEVICE_NATIVE_ENDIAN
,
180 .min_access_size
= 4,
185 /* hd_table must contain 2 block drivers */
186 /* BAST uses memory mapped registers, not I/O. Return the memory
187 * I/O tag to access the ide.
188 * The BAST description will register it into the map in the right place.
190 static MMIOState
*stcb_ide_init(DriveInfo
*dinfo0
, DriveInfo
*dinfo1
, qemu_irq irq
)
192 MMIOState
*s
= g_malloc0(sizeof(MMIOState
));
194 //~ ide_init2_with_non_qdev_drives(&s->bus, dinfo0, dinfo1, irq);
195 memory_region_init_io(&s
->slow
, OBJECT(s
),
196 &stcb_ide_ops
, s
, "stcb-ide", 0x1000000);
197 memory_region_init_alias(&s
->fast
, NULL
, "stcb-ide", &s
->slow
, 0, 0x1000000);
198 memory_region_init_alias(&s
->slowb
, NULL
, "stcb-ide", &s
->slow
, 0, 0x1000000);
199 memory_region_init_alias(&s
->fastb
, NULL
, "stcb-ide", &s
->slow
, 0, 0x1000000);
203 static void stcb_register_ide(STCBState
*stcb
)
208 MemoryRegion
*sysmem
= get_system_memory();
210 if (drive_get_max_bus(IF_IDE
) >= 2) {
211 fprintf(stderr
, "qemu: too many IDE busses\n");
215 dinfo0
= drive_get(IF_IDE
, 0, 0);
216 dinfo1
= drive_get(IF_IDE
, 0, 1);
217 s
= stcb_ide_init(dinfo0
, dinfo1
, s3c24xx_get_eirq(stcb
->soc
->gpio
, 16));
218 memory_region_add_subregion(sysmem
, BAST_IDE_PRI_SLOW
, &s
->slow
);
219 memory_region_add_subregion(sysmem
, BAST_IDE_PRI_FAST
, &s
->fast
);
220 memory_region_add_subregion(sysmem
, BAST_IDE_PRI_SLOW_BYTE
, &s
->slowb
);
221 memory_region_add_subregion(sysmem
, BAST_IDE_PRI_FAST_BYTE
, &s
->fastb
);
223 dinfo0
= drive_get(IF_IDE
, 1, 0);
224 dinfo1
= drive_get(IF_IDE
, 1, 1);
225 s
= stcb_ide_init(dinfo0
, dinfo1
, s3c24xx_get_eirq(stcb
->soc
->gpio
, 17));
226 memory_region_add_subregion(sysmem
, BAST_IDE_SEC_SLOW
, &s
->slow
);
227 memory_region_add_subregion(sysmem
, BAST_IDE_SEC_FAST
, &s
->fast
);
228 memory_region_add_subregion(sysmem
, BAST_IDE_SEC_SLOW_BYTE
, &s
->slowb
);
229 memory_region_add_subregion(sysmem
, BAST_IDE_SEC_FAST_BYTE
, &s
->fastb
);
232 #define BAST_PA_ASIXNET 0x01000000
233 #define BAST_PA_SUPERIO 0x01800000
235 #define SERIAL_BASE (CPU_S3C2410X_CS2 + BAST_PA_SUPERIO)
236 #define SERIAL_CLK 1843200
238 #define ASIXNET_BASE (CPU_S3C2410X_CS5 + BAST_PA_ASIXNET)
239 #define ASIXNET_SIZE (0x400)
240 #define AX88796_BASE (CPU_S3C2410X_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20))
241 #define AX88796_SIZE (3 * 0x20)
243 #define DM9000_BASE (0x2d000000)
244 #define DM9000_IRQ 10
246 #define logout(fmt, ...) \
247 fprintf(stderr, "AX88796\t%-24s" fmt, __func__, ##__VA_ARGS__)
249 #define TYPE_AX88796 "ax88796"
250 #define AX88796(obj) OBJECT_CHECK(AX88796State, (obj), TYPE_AX88796)
259 static uint64_t ax88796_read(void *opaque
, hwaddr offset
,
262 //~ AX88796State *s = opaque;
278 //~ return 0; // FIXME
281 logout("0x" TARGET_FMT_plx
" 0x%08x\n", offset
, value
);
285 static void ax88796_write(void *opaque
, hwaddr offset
,
286 uint64_t value
, unsigned size
)
288 //~ AX88796State *s = opaque;
304 logout("0x" TARGET_FMT_plx
" 0x%08" PRIx64
"\n", offset
, value
);
307 static const MemoryRegionOps ax88796_ops
= {
308 .read
= ax88796_read
,
309 .write
= ax88796_write
,
310 .endianness
= DEVICE_NATIVE_ENDIAN
,
312 .min_access_size
= 4,
317 static void ax88796_realize(DeviceState
*dev
, Error
**errp
)
319 AX88796State
*s
= AX88796(dev
);
320 SysBusDevice
*sbd
= SYS_BUS_DEVICE(dev
);
324 memory_region_init_io(&s
->mmio
, OBJECT(s
),
325 &ax88796_ops
, s
, TYPE_AX88796
, ASIXNET_SIZE
);
326 //~ sysbus_init_mmio(sbd, AX88796_SIZE, iomemtype);
327 sysbus_init_mmio(sbd
, &s
->mmio
);
328 //~ sysbus_init_irq(dev, &s->irq);
329 //~ ax88796_reset(s);
331 isa_ne2000_init(ne2000_io
[i
], ne2000_irq
[i
], &nd_table
[i
]);
332 ISANE2000State
*isa
= DO_UPCAST(ISANE2000State
, dev
, dev
);
333 NE2000State
*s
= &isa
->ne2000
;
335 register_ioport_write(isa
->iobase
, 16, 1, ne2000_ioport_write
, s
);
336 register_ioport_read(isa
->iobase
, 16, 1, ne2000_ioport_read
, s
);
338 register_ioport_write(isa
->iobase
+ 0x10, 1, 1, ne2000_asic_ioport_write
, s
);
339 register_ioport_read(isa
->iobase
+ 0x10, 1, 1, ne2000_asic_ioport_read
, s
);
340 register_ioport_write(isa
->iobase
+ 0x10, 2, 2, ne2000_asic_ioport_write
, s
);
341 register_ioport_read(isa
->iobase
+ 0x10, 2, 2, ne2000_asic_ioport_read
, s
);
343 register_ioport_write(isa
->iobase
+ 0x1f, 1, 1, ne2000_reset_ioport_write
, s
);
344 register_ioport_read(isa
->iobase
+ 0x1f, 1, 1, ne2000_reset_ioport_read
, s
);
346 isa_init_irq(dev
, &s
->irq
, isa
->isairq
);
348 qemu_macaddr_default_if_unset(&s
->c
.macaddr
);
351 s
->nic
= qemu_new_nic(&net_ne2000_isa_info
, &s
->c
,
352 object_get_typename(OBJECT(dev
)), dev
->qdev
.id
, s
);
353 qemu_format_nic_info_str(qemu_get_queue(s
->nic
), s
->c
.macaddr
.a
);
357 static const VMStateDescription ax88796_vmsd
= {
358 .name
= TYPE_AX88796
,
360 .minimum_version_id
= 1,
361 .minimum_version_id_old
= 1,
362 .fields
= (VMStateField
[]) {
363 VMSTATE_END_OF_LIST()
367 static Property ax88796_properties
[] = {
368 DEFINE_NIC_PROPERTIES(AX88796State
, conf
),
369 DEFINE_PROP_END_OF_LIST()
372 static void ax88796_class_init(ObjectClass
*klass
, void *data
)
374 DeviceClass
*dc
= DEVICE_CLASS(klass
);
375 dc
->realize
= ax88796_realize
;
376 dc
->vmsd
= &ax88796_vmsd
;
377 dc
->props
= ax88796_properties
;
380 static const TypeInfo ax88796_info
= {
381 .name
= TYPE_AX88796
,
382 .parent
= TYPE_SYS_BUS_DEVICE
,
383 .instance_size
= sizeof(AX88796State
),
384 .class_init
= ax88796_class_init
387 static void ax88796_register_types(void)
389 type_register_static(&ax88796_info
);
392 type_init(ax88796_register_types
)
395 static void stcb_i2c_setup(STCBState
*stcb
)
397 I2CBus
*bus
= s3c24xx_i2c_bus(stcb
->soc
->iic
);
398 uint8_t *eeprom_buf
= g_malloc0(256);
400 eeprom
= qdev_create((BusState
*)bus
, "smbus-eeprom");
401 qdev_prop_set_uint8(eeprom
, "address", 0x50);
402 qdev_prop_set_ptr(eeprom
, "data", eeprom_buf
);
403 qdev_init_nofail(eeprom
);
405 i2c_create_slave(bus
, "ch7xxx", 0x75);
406 i2c_create_slave(bus
, "stcpmu", 0x6B);
410 static struct arm_boot_info bast_binfo
= {
411 .board_id
= BAST_BOARD_ID
,
412 .ram_size
= 0x10000000, /* 256MB */
415 static void stcb_init(MachineState
*machine
)
417 MemoryRegion
*sysmem
= get_system_memory();
426 BlockBackend
*flash_bds
= NULL
;
429 /* ensure memory is limited to 256MB */
430 if (machine
->ram_size
> (256 * MiB
)) {
431 machine
->ram_size
= 256 * MiB
;
433 ram_size
= machine
->ram_size
;
435 /* initialise board informations */
436 bast_binfo
.ram_size
= ram_size
;
437 bast_binfo
.kernel_filename
= machine
->kernel_filename
;
438 bast_binfo
.kernel_cmdline
= machine
->kernel_cmdline
;
439 bast_binfo
.initrd_filename
= machine
->initrd_filename
;
440 bast_binfo
.nb_cpus
= 1;
441 bast_binfo
.loader_start
= BAST_NOR_RO_BASE
;
443 /* allocate storage for board state */
444 stcb
= g_malloc0(sizeof(STCBState
));
446 /* Make sure all serial ports are associated with a device. */
447 for (i
= 0; i
< serial_max_hds(); i
++) {
449 assert(serial_hd(i
));
451 /* TODO: This code no longer works. Remove or replace. */
454 snprintf(label
, sizeof(label
), "serial%d", i
);
455 serial_hd(i
) = qemu_chr_new(label
, "vc:80Cx24C", NULL
);
461 stcb
->soc
= s3c2410x_init(ram_size
);
463 stcb_register_ide(stcb
);
465 dinfo
= drive_get(IF_PFLASH
, 0, 0);
466 /* Acquire flash contents and register pflash device */
468 /* load from specified flash device */
469 flash_bds
= blk_by_legacy_dinfo(dinfo
);
471 /* Try and load default bootloader image */
472 char *filename
= qemu_find_file(QEMU_FILE_TYPE_BIOS
, BIOS_FILENAME
);
474 ret
= load_image_targphys(filename
,
475 BAST_NOR_RO_BASE
, BAST_NOR_SIZE
);
481 pflash_cfi02_register(BAST_NOR_RW_BASE
, "bast.flash",
482 BAST_NOR_SIZE
, flash_bds
, 0x10000, 1, 2,
483 0x00BF, 0x234B, 0x0000, 0x0000, 0x5555, 0x2AAA,
485 /* TODO: Read only ROM type mapping to address BAST_NOR_RO_BASE. */
487 /* if kernel is given, boot that directly */
488 if (machine
->kernel_filename
!= NULL
) {
489 bast_binfo
.loader_start
= CPU_S3C2410X_DRAM
;
490 //~ bast_binfo.loader_start = 0xc0108000 - 0x00010000;
491 arm_load_kernel(stcb
->soc
->cpu
, machine
, &bast_binfo
);
494 /* Setup initial (reset) program counter */
495 stcb
->soc
->cpu
->env
.regs
[15] = bast_binfo
.loader_start
;
499 qemu_check_nic_model(nd
, "dm9000");
500 dev
= qdev_create(NULL
, "dm9000");
501 qdev_set_nic_properties(dev
, nd
);
502 qdev_init_nofail(dev
);
503 s
= SYS_BUS_DEVICE(dev
);
504 sysbus_mmio_map(s
, 0, DM9000_BASE
);
505 sysbus_connect_irq(s
, 0, s3c24xx_get_eirq(stcb
->soc
->gpio
, DM9000_IRQ
));
510 qemu_check_nic_model(nd
, TYPE_AX88796
);
511 dev
= qdev_create(NULL
, TYPE_AX88796
);
512 qdev_set_nic_properties(dev
, nd
);
513 qdev_init_nofail(dev
);
514 s
= SYS_BUS_DEVICE(dev
);
515 sysbus_mmio_map(s
, 0, ASIXNET_BASE
);
516 logout("ASIXNET_BASE = 0x%08x\n", ASIXNET_BASE
);
517 logout("AX88796_BASE = 0x%08x\n", AX88796_BASE
);
518 //~ sysbus_connect_irq(s, 0, s3c24xx_get_eirq(stcb->soc->gpio, AX88796_IRQ));
521 /* Initialise the BAST CPLD */
522 stcb_cpld_register(stcb
);
524 /* attach i2c devices */
525 stcb_i2c_setup(stcb
);
527 /* Attach some NAND devices */
528 stcb
->nand
[0] = NULL
;
529 stcb
->nand
[1] = NULL
;
530 dinfo
= drive_get(IF_MTD
, 0, 0);
532 stcb
->nand
[2] = NULL
;
534 stcb
->nand
[2] = nand_init(NULL
, 0xEC, 0x79); /* 128MiB small-page */
537 chr
= qemu_chr_new("uart0", "vc:80Cx24C", NULL
);
538 serial_mm_init(sysmem
, SERIAL_BASE
+ 0x2f8, 0,
539 s3c24xx_get_eirq(stcb
->soc
->gpio
, 15),
540 SERIAL_CLK
, chr
, DEVICE_NATIVE_ENDIAN
);
541 chr
= qemu_chr_new("uart1", "vc:80Cx24C", NULL
);
542 serial_mm_init(sysmem
, SERIAL_BASE
+ 0x3f8, 0,
543 s3c24xx_get_eirq(stcb
->soc
->gpio
, 14),
544 SERIAL_CLK
, chr
, DEVICE_NATIVE_ENDIAN
);
548 i8259
= i8259_init(s3c24xx_get_eirq(stcb
->soc
->gpio
, 4));
550 /*isa_dev =*/ isa_create_simple("i8042");
551 serial_isa_init(0, serial_hd(0));
552 serial_isa_init(1, serial_hd(1));
556 static void bast_machine_init(MachineClass
*mc
)
558 mc
->desc
= "Simtec Electronics BAST (S3C2410A, ARM920T)";
559 mc
->init
= stcb_init
;
563 DEFINE_MACHINE("bast", bast_machine_init
)