3 * Samsung S3C2410X emulation
5 * Copyright 2009 Daniel Silverstone and Vincent Sanders
7 * Copyright 2010, 2013, 2019 Stefan Weil
9 * This file is under the terms of the GNU General Public License Version 2.
12 #include "qemu/osdep.h"
14 #include "hw/qdev-properties.h"
15 #include "hw/sysbus.h"
16 #include "qapi/error.h" /* error_abort */
17 #include "sysemu/sysemu.h"
18 #include "exec/address-spaces.h" /* get_system_memory */
22 #define logout(fmt, ...) \
23 fprintf(stderr, "S3C24xx\t%-24s" fmt, __func__, ##__VA_ARGS__)
25 #define TODO() logout("%s:%u: missing\n", __FILE__, __LINE__)
28 #define CPU_S3C2410X_IDENT_S3C2410X 0x32410000
29 #define CPU_S3C2410X_IDENT_S3C2410A 0x32410002
31 /* Integrated peripherals */
34 #define CPU_S3C2410X_SRAM_BASE (CPU_S3C2410X_PERIPHERAL + 0x00000000)
35 #define CPU_S3C2410X_SRAM_SIZE 4096
38 #define CPU_S3C2410X_MEMC_BASE (CPU_S3C2410X_PERIPHERAL + 0x8000000)
41 #define CPU_S3C2410X_OHCI_BASE (CPU_S3C2410X_PERIPHERAL + 0x9000000)
43 /* Interrupt controller */
44 #define CPU_S3C2410X_IRQ_BASE (CPU_S3C2410X_PERIPHERAL + 0xA000000)
47 #define CPU_S3C2410X_CLKCON_BASE (CPU_S3C2410X_PERIPHERAL + 0xC000000)
50 #define CPU_S3C2410X_LCD_BASE (CPU_S3C2410X_PERIPHERAL + 0xD000000)
53 #define CPU_S3C2410X_NAND_BASE (CPU_S3C2410X_PERIPHERAL + 0xE000000)
55 /* serial port bases */
56 #define CPU_S3C2410X_SERIAL0_BASE (CPU_S3C2410X_PERIPHERAL + 0x10000000)
57 #define CPU_S3C2410X_SERIAL1_BASE (CPU_S3C2410X_PERIPHERAL + 0x10004000)
58 #define CPU_S3C2410X_SERIAL2_BASE (CPU_S3C2410X_PERIPHERAL + 0x10008000)
60 /* Timer controller */
61 #define CPU_S3C2410X_TIMERS_BASE (CPU_S3C2410X_PERIPHERAL + 0x11000000)
62 #define CPU_S3C24XX_WDG_BASE (CPU_S3C2410X_PERIPHERAL + 0x13000000)
65 #define CPU_S3C2410X_IIC_BASE (CPU_S3C2410X_PERIPHERAL + 0x14000000)
68 #define CPU_S3C2410X_GPIO_BASE (CPU_S3C2410X_PERIPHERAL + 0x16000000)
71 #define CPU_S3C2410X_RTC_BASE (CPU_S3C2410X_PERIPHERAL + 0x17000000)
72 #define CPU_S3C24XX_ADC_BASE (CPU_S3C2410X_PERIPHERAL + 0x18000000)
74 /*----------------------------------------------------------------------------*/
76 /* Initialise a Samsung S3C2410X SOC ARM core and internal peripherals. */
78 s3c2410x_init(int sdram_size
)
81 MemoryRegion
*sysmem
= get_system_memory();
82 S3CState
*s
= g_new0(S3CState
, 1);
84 /* Prepare the ARM 920T core. */
85 s
->cpu
= ARM_CPU(cpu_create(ARM_CPU_TYPE_NAME("arm920t")));
87 /* S3C2410X SDRAM memory is always at the same physical location. */
88 memory_region_init_ram(&s
->sdram0
, OBJECT(s
),
89 "s3c2410x.sdram0", sdram_size
, &error_abort
);
90 memory_region_init_alias(&s
->sdram1
, NULL
, "s3c2410x.sdram1",
91 &s
->sdram0
, 0, sdram_size
);
92 memory_region_init_alias(&s
->sdram2
, NULL
, "s3c2410x.sdram2",
93 &s
->sdram0
, 0, sdram_size
);
94 memory_region_add_subregion(sysmem
, CPU_S3C2410X_DRAM
, &s
->sdram0
);
95 memory_region_add_subregion(sysmem
,
96 CPU_S3C2410X_DRAM
+ 0x80000000, &s
->sdram1
);
97 memory_region_add_subregion(sysmem
,
98 CPU_S3C2410X_DRAM
+ 0x90000000, &s
->sdram2
);
101 memory_region_init_ram(&s
->sram
, OBJECT(s
), "s3c2410x.sram",
102 CPU_S3C2410X_SRAM_SIZE
, &error_abort
);
103 memory_region_add_subregion(sysmem
, CPU_S3C2410X_SRAM_BASE
, &s
->sram
);
105 /* SDRAM memory controller */
106 s
->memc
= s3c24xx_memc_init(CPU_S3C2410X_MEMC_BASE
);
108 /* Interrupt controller */
109 s
->irq
= s3c24xx_irq_init(s
, CPU_S3C2410X_IRQ_BASE
);
111 /* Clock and power control */
112 s
->clkcon
= s3c24xx_clkcon_init(s
, CPU_S3C2410X_CLKCON_BASE
, 12000000);
114 /* Timer controller */
115 s
->timers
= s3c24xx_timers_init(s
, CPU_S3C2410X_TIMERS_BASE
, 0, 12000000);
117 /* Serial port controllers */
118 s
->uart
[0] = s3c24xx_serial_init(s
, serial_hd(0), CPU_S3C2410X_SERIAL0_BASE
, 32);
119 s
->uart
[1] = s3c24xx_serial_init(s
, serial_hd(1), CPU_S3C2410X_SERIAL1_BASE
, 35);
120 s
->uart
[2] = s3c24xx_serial_init(s
, serial_hd(2), CPU_S3C2410X_SERIAL2_BASE
, 38);
122 /* Real time clock */
123 s
->rtc
= s3c24xx_rtc_init(CPU_S3C2410X_RTC_BASE
);
126 dev
= sysbus_create_simple("s3c24xx_gpio", CPU_S3C2410X_GPIO_BASE
, NULL
);
127 s
->gpio
= s3c24xx_gpio_init(s
, CPU_S3C2410X_GPIO_BASE
, CPU_S3C2410X_IDENT_S3C2410A
);
130 s
->iic
= s3c24xx_iic_init(s3c24xx_get_irq(s
->irq
, 27),
131 CPU_S3C2410X_IIC_BASE
);
134 dev
= sysbus_create_simple("s3c24xx_lcd", CPU_S3C2410X_LCD_BASE
,
135 s3c24xx_get_irq(s
->irq
, 16));
137 /* NAND controller */
138 s
->nand
= s3c24xx_nand_init(CPU_S3C2410X_NAND_BASE
);
140 /* A two port OHCI controller */
141 dev
= qdev_create(NULL
, "sysbus-ohci");
142 qdev_prop_set_uint32(dev
, "num-ports", 2);
143 //~ qdev_prop_set_taddr(dev, "dma-offset", base);
144 qdev_init_nofail(dev
);
145 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 0, CPU_S3C2410X_OHCI_BASE
);
146 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 0, s3c24xx_get_irq(s
->irq
, 26));
148 dev
= sysbus_create_simple("s3c24xx_wdg", CPU_S3C24XX_WDG_BASE
, NULL
);
149 dev
= sysbus_create_simple("s3c24xx_adc", CPU_S3C24XX_ADC_BASE
, NULL
);