xref: /qemu/hw/arm/cubieboard.c (revision 138ca49a82b978f035b709abee45324dd7ab3e68)
1  /*
2   * cubieboard emulation
3   *
4   * Copyright (C) 2013 Li Guang
5   * Written by Li Guang <lig.fnst@cn.fujitsu.com>
6   *
7   * This program is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU General Public License as published by the
9   * Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful, but WITHOUT
13   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15   * for more details.
16   */
17  
18  #include "qemu/osdep.h"
19  #include "exec/address-spaces.h"
20  #include "qapi/error.h"
21  #include "cpu.h"
22  #include "sysemu/sysemu.h"
23  #include "hw/sysbus.h"
24  #include "hw/boards.h"
25  #include "hw/qdev-properties.h"
26  #include "hw/arm/allwinner-a10.h"
27  
28  static struct arm_boot_info cubieboard_binfo = {
29      .loader_start = AW_A10_SDRAM_BASE,
30      .board_id = 0x1008,
31  };
32  
33  static void cubieboard_init(MachineState *machine)
34  {
35      AwA10State *a10;
36      Error *err = NULL;
37      DriveInfo *di;
38      BlockBackend *blk;
39      BusState *bus;
40      DeviceState *carddev;
41  
42      /* BIOS is not supported by this board */
43      if (machine->firmware) {
44          error_report("BIOS not supported for this machine");
45          exit(1);
46      }
47  
48      /* This board has fixed size RAM (512MiB or 1GiB) */
49      if (machine->ram_size != 512 * MiB &&
50          machine->ram_size != 1 * GiB) {
51          error_report("This machine can only be used with 512MiB or 1GiB RAM");
52          exit(1);
53      }
54  
55      /* Only allow Cortex-A8 for this board */
56      if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) {
57          error_report("This board can only be used with cortex-a8 CPU");
58          exit(1);
59      }
60  
61      a10 = AW_A10(object_new(TYPE_AW_A10));
62      object_property_add_child(OBJECT(machine), "soc", OBJECT(a10));
63      object_unref(OBJECT(a10));
64  
65      if (!object_property_set_int(OBJECT(&a10->emac), "phy-addr", 1, &err)) {
66          error_reportf_err(err, "Couldn't set phy address: ");
67          exit(1);
68      }
69  
70      if (!object_property_set_int(OBJECT(&a10->timer), "clk0-freq", 32768,
71                                   &err)) {
72          error_reportf_err(err, "Couldn't set clk0 frequency: ");
73          exit(1);
74      }
75  
76      if (!object_property_set_int(OBJECT(&a10->timer), "clk1-freq", 24000000,
77                                   &err)) {
78          error_reportf_err(err, "Couldn't set clk1 frequency: ");
79          exit(1);
80      }
81  
82      if (!qdev_realize(DEVICE(a10), NULL, &err)) {
83          error_reportf_err(err, "Couldn't realize Allwinner A10: ");
84          exit(1);
85      }
86  
87      /* Retrieve SD bus */
88      di = drive_get_next(IF_SD);
89      blk = di ? blk_by_legacy_dinfo(di) : NULL;
90      bus = qdev_get_child_bus(DEVICE(a10), "sd-bus");
91  
92      /* Plug in SD card */
93      carddev = qdev_new(TYPE_SD_CARD);
94      qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
95      qdev_realize_and_unref(carddev, bus, &error_fatal);
96  
97      memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
98                                  machine->ram);
99  
100      /* TODO create and connect IDE devices for ide_drive_get() */
101  
102      cubieboard_binfo.ram_size = machine->ram_size;
103      arm_load_kernel(&a10->cpu, machine, &cubieboard_binfo);
104  }
105  
106  static void cubieboard_machine_init(MachineClass *mc)
107  {
108      mc->desc = "cubietech cubieboard (Cortex-A8)";
109      mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
110      mc->default_ram_size = 1 * GiB;
111      mc->init = cubieboard_init;
112      mc->block_default_type = IF_IDE;
113      mc->units_per_default_bus = 1;
114      mc->ignore_memory_transaction_failures = true;
115      mc->default_ram_id = "cubieboard.ram";
116  }
117  
118  DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
119