1 /* 2 * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net> 3 * 4 * i.MX31 SOC emulation. 5 * 6 * Based on hw/arm/fsl-imx31.c 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "hw/arm/fsl-imx31.h" 23 #include "sysemu/sysemu.h" 24 #include "exec/address-spaces.h" 25 #include "hw/boards.h" 26 #include "sysemu/char.h" 27 28 static void fsl_imx31_init(Object *obj) 29 { 30 FslIMX31State *s = FSL_IMX31(obj); 31 int i; 32 33 object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" TYPE_ARM_CPU); 34 35 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC); 36 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default()); 37 38 object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM); 39 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default()); 40 41 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) { 42 object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL); 43 qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default()); 44 } 45 46 object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT); 47 qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default()); 48 49 for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) { 50 object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT); 51 qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default()); 52 } 53 54 for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) { 55 object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C); 56 qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default()); 57 } 58 } 59 60 static void fsl_imx31_realize(DeviceState *dev, Error **errp) 61 { 62 FslIMX31State *s = FSL_IMX31(dev); 63 uint16_t i; 64 Error *err = NULL; 65 66 object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); 67 if (err) { 68 error_propagate(errp, err); 69 return; 70 } 71 72 object_property_set_bool(OBJECT(&s->avic), true, "realized", &err); 73 if (err) { 74 error_propagate(errp, err); 75 return; 76 } 77 sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX31_AVIC_ADDR); 78 sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0, 79 qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); 80 sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1, 81 qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); 82 83 object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err); 84 if (err) { 85 error_propagate(errp, err); 86 return; 87 } 88 sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX31_CCM_ADDR); 89 90 /* Initialize all UARTS */ 91 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) { 92 static const struct { 93 hwaddr addr; 94 unsigned int irq; 95 } serial_table[FSL_IMX31_NUM_UARTS] = { 96 { FSL_IMX31_UART1_ADDR, FSL_IMX31_UART1_IRQ }, 97 { FSL_IMX31_UART2_ADDR, FSL_IMX31_UART2_IRQ }, 98 }; 99 100 if (i < MAX_SERIAL_PORTS) { 101 CharDriverState *chr; 102 103 chr = serial_hds[i]; 104 105 if (!chr) { 106 char label[20]; 107 snprintf(label, sizeof(label), "imx31.uart%d", i); 108 chr = qemu_chr_new(label, "null", NULL); 109 } 110 111 qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr); 112 } 113 114 object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err); 115 if (err) { 116 error_propagate(errp, err); 117 return; 118 } 119 120 sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); 121 sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, 122 qdev_get_gpio_in(DEVICE(&s->avic), 123 serial_table[i].irq)); 124 } 125 126 s->gpt.ccm = DEVICE(&s->ccm); 127 128 object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err); 129 if (err) { 130 error_propagate(errp, err); 131 return; 132 } 133 134 sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX31_GPT_ADDR); 135 sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0, 136 qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX31_GPT_IRQ)); 137 138 /* Initialize all EPIT timers */ 139 for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) { 140 static const struct { 141 hwaddr addr; 142 unsigned int irq; 143 } epit_table[FSL_IMX31_NUM_EPITS] = { 144 { FSL_IMX31_EPIT1_ADDR, FSL_IMX31_EPIT1_IRQ }, 145 { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ }, 146 }; 147 148 s->epit[i].ccm = DEVICE(&s->ccm); 149 150 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err); 151 if (err) { 152 error_propagate(errp, err); 153 return; 154 } 155 156 sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr); 157 sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0, 158 qdev_get_gpio_in(DEVICE(&s->avic), 159 epit_table[i].irq)); 160 } 161 162 /* Initialize all I2C */ 163 for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) { 164 static const struct { 165 hwaddr addr; 166 unsigned int irq; 167 } i2c_table[FSL_IMX31_NUM_I2CS] = { 168 { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ }, 169 { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ }, 170 { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ } 171 }; 172 173 /* Initialize the I2C */ 174 object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err); 175 if (err) { 176 error_propagate(errp, err); 177 return; 178 } 179 /* Map I2C memory */ 180 sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); 181 /* Connect I2C IRQ to PIC */ 182 sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, 183 qdev_get_gpio_in(DEVICE(&s->avic), 184 i2c_table[i].irq)); 185 } 186 187 /* On a real system, the first 16k is a `secure boot rom' */ 188 memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL, 189 "imx31.secure_rom", 190 FSL_IMX31_SECURE_ROM_SIZE, &err); 191 if (err) { 192 error_propagate(errp, err); 193 return; 194 } 195 memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR, 196 &s->secure_rom); 197 198 /* There is also a 16k ROM */ 199 memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx31.rom", 200 FSL_IMX31_ROM_SIZE, &err); 201 if (err) { 202 error_propagate(errp, err); 203 return; 204 } 205 memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR, 206 &s->rom); 207 208 /* initialize internal RAM (16 KB) */ 209 memory_region_init_ram(&s->iram, NULL, "imx31.iram", FSL_IMX31_IRAM_SIZE, 210 &err); 211 if (err) { 212 error_propagate(errp, err); 213 return; 214 } 215 memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR, 216 &s->iram); 217 vmstate_register_ram_global(&s->iram); 218 219 /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */ 220 memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias", 221 &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE); 222 memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR, 223 &s->iram_alias); 224 } 225 226 static void fsl_imx31_class_init(ObjectClass *oc, void *data) 227 { 228 DeviceClass *dc = DEVICE_CLASS(oc); 229 230 dc->realize = fsl_imx31_realize; 231 } 232 233 static const TypeInfo fsl_imx31_type_info = { 234 .name = TYPE_FSL_IMX31, 235 .parent = TYPE_DEVICE, 236 .instance_size = sizeof(FslIMX31State), 237 .instance_init = fsl_imx31_init, 238 .class_init = fsl_imx31_class_init, 239 }; 240 241 static void fsl_imx31_register_types(void) 242 { 243 type_register_static(&fsl_imx31_type_info); 244 } 245 246 type_init(fsl_imx31_register_types) 247