[MINI2440] Clean the demo start script
[qemu/mini2440.git] / hw / mini2440.c
blob0ba91a94ce56745cbd730d2a98e36401703a59ef
1 /*
2 * Neo1973 mobile telephone platforms emulation.
3 * Detailed information at openmoko.org.
5 * Copyright (c) 2007 OpenMoko, Inc.
6 * Author: Andrzej Zaborowski <andrew@openedhand.com>
8 * This code is licensed under the GNU GPL v2.
9 */
11 #include "hw.h"
12 #include "s3c.h"
13 #include "arm-misc.h"
14 #include "sysemu.h"
15 #include "i2c.h"
16 #include "qemu-timer.h"
17 #include "devices.h"
18 #include "audio/audio.h"
19 #include "boards.h"
20 #include "console.h"
21 #include "usb.h"
22 #include "net.h"
23 #include "sd.h"
24 #include "dm9000.h"
25 #include "eeprom24c0x.h"
27 #define mini2440_printf(format, ...) \
28 fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
30 /* Wiring common to all revisions */
31 #define MINI2440_GPIO_BACKLIGHT S3C_GPB(1)
32 #define MINI2440_GPIO_LCD_RESET S3C_GPC(6)
33 #define MINI2440_GPIO_nSD_DETECT S3C_GPG(8)
34 #define MINI2440_IRQ_nSD_DETECT S3C_EINT(16)
35 #define MINI2440_IRQ_DM9000 S3C_EINT(7)
36 #define MINI2440_GPIO_DM9000 S3C_GPF(7)
38 #define MINI2440_GPIO_SDMMC_ON S3C_GPB(2)
39 #define MINI2440_GPIO_USB_PULLUP S3C_GPB(9)
40 #define MINI2440_GPIO_USB_ATTACH S3C_GPB(10)
42 struct mini2440_board_s {
43 struct s3c_state_s *cpu;
44 unsigned int ram;
45 i2c_slave * eeprom;
46 const char * kernel;
47 SDState * mmc;
48 struct nand_flash_s *nand;
49 int bl_level;
53 /* Handlers for output ports */
54 static void mini2440_bl_switch(void *opaque, int line, int level)
56 printf("%s: LCD Backlight now %s.\n", __FUNCTION__, level ? "on" : "off");
59 static void mini2440_bl_intensity(int line, int level, void *opaque)
61 struct mini2440_board_s *s = (struct mini2440_board_s *) opaque;
63 if ((level >> 8) != s->bl_level) {
64 s->bl_level = level >> 8;
65 // printf("%s: LCD Backlight now at %i/64.\n", __FUNCTION__, s->bl_level);
69 static void mini2440_gpio_setup(struct mini2440_board_s *s)
71 s3c_gpio_out_set(s->cpu->io, MINI2440_GPIO_BACKLIGHT,
72 *qemu_allocate_irqs(mini2440_bl_switch, s, 1));
74 s3c_timers_cmp_handler_set(s->cpu->timers, 1, mini2440_bl_intensity, s);
76 // this confuses the kernel, we will need a way to bridge this IRQ to the SD system
77 // right now without this, qemu will not know how to pass the SD card insert/remove
78 // properly to the kernel
79 // sd_set_cb(s->mmc, 0, s3c_gpio_in_get(s->cpu->io)[MINI2440_IRQ_nSD_DETECT]);
82 #if 0
83 static void hexdump(const void* address, uint32_t len)
85 const unsigned char* p = address;
86 int i, j;
88 for (i = 0; i < len; i += 16) {
89 for (j = 0; j < 16 && i + j < len; j++)
90 fprintf(stderr, "%02x ", p[i + j]);
91 for (; j < 16; j++)
92 fprintf(stderr, " ");
93 fprintf(stderr, " ");
94 for (j = 0; j < 16 && i + j < len; j++)
95 fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
96 fprintf(stderr, "\n");
99 #endif
101 static void mini2440_reset(void *opaque)
103 struct mini2440_board_s *s = (struct mini2440_board_s *) opaque;
104 uint32_t image_size;
106 if (1) {
107 image_size = load_image("mini2440/u-boot.bin", phys_ram_base + 0x03f80000);
108 if (!image_size)
109 image_size = load_image("u-boot.bin", phys_ram_base + 0x03f80000);
110 if (image_size) {
111 if (image_size & (512 -1)) /* round size to a NAND block size */
112 image_size = (image_size + 512) & ~(512-1);
113 fprintf(stderr, "%s: loaded default u-boot (size %x)\n", __FUNCTION__, image_size);
114 s->cpu->env->regs[15] = S3C_RAM_BASE | 0x03f80000; // start address, u-boot already relocated
117 #if 0
119 * Performs Samsung S3C2440 bootup, but loading 4KB of the nand at the base of the RAM
120 * and jumping there
122 if (s->nand) {
123 uint32_t src = 0;
124 int page = 0;
125 uint8_t stone[S3C_SRAM_SIZE];
126 uint8_t * dst = stone;
128 fprintf(stderr, "%s: attempting boot from NAND\n", __FUNCTION__);
130 for (page = 0; page < (S3C_SRAM_SIZE / 512); page++, src += 512+16, dst += 512)
131 if (nand_readraw(s->nand, src, dst, 512) == 0) {
132 fprintf(stderr, "%s: failed to load nand %d:%d\n", __FUNCTION__, src, 512+16);
134 cpu_physical_memory_write(S3C_SRAM_BASE_NANDBOOT, stone, S3C_SRAM_SIZE);
135 s->cpu->env->regs[15] = S3C_SRAM_BASE_NANDBOOT; // start address, u-boot relocating code
136 fprintf(stderr, "%s: 4KB SteppingStone loaded from NAND\n", __FUNCTION__);
138 #endif
139 if (1) {
140 image_size = load_image(s->kernel, phys_ram_base + 0x02000000);
141 if (image_size) {
142 if (image_size & (512 -1)) /* round size to a NAND block size */
143 image_size = (image_size + 512) & ~(512-1);
144 fprintf(stderr, "%s: loaded %s (size %x)\n", __FUNCTION__, s->kernel, image_size);
147 if (0) {
148 image_size = load_image("/tftpboot/minimalist-image-mini2440.jffs2", phys_ram_base);
149 if (image_size) {
150 if (image_size & (512 -1)) /* round size to a NAND block size */
151 image_size = (image_size + 512) & ~(512-1);
152 fprintf(stderr, "%s: loaded jffs2 (size %x)\n", __FUNCTION__, image_size);
158 /* Typical touchscreen calibration values */
159 static const int mini2440_ts_scale[6] = {
160 0, (90 - 960) * 256 / 1021, -90 * 256 * 32,
161 (940 - 75) * 256 / 1021, 0, 75 * 256 * 32,
164 /* Board init. */
165 static struct mini2440_board_s *mini2440_init_common(int ram_size,
166 const char *kernel_filename, const char *cpu_model,
167 SDState *mmc)
169 struct mini2440_board_s *s = (struct mini2440_board_s *)
170 qemu_mallocz(sizeof(struct mini2440_board_s));
172 s->ram = 0x04000000;
173 s->kernel = kernel_filename;
174 s->mmc = mmc;
176 /* Setup CPU & memory */
177 if (ram_size < s->ram + S3C_SRAM_SIZE) {
178 fprintf(stderr, "This platform requires %i bytes of memory (not %d)\n",
179 s->ram + S3C_SRAM_SIZE, ram_size);
180 exit(1);
182 if (cpu_model && strcmp(cpu_model, "arm920t")) {
183 fprintf(stderr, "This platform requires an ARM920T core\n");
184 exit(2);
186 s->cpu = s3c24xx_init(S3C_CPU_2440, s->ram, S3C_SRAM_BASE_NANDBOOT, s->mmc);
188 /* Setup peripherals */
189 mini2440_gpio_setup(s);
191 // s->eeprom = eeprom24c0x_new(EE_24C08);
193 // if (usb_enabled)
194 // usb_device_attach(usb_bt_init(local_piconet));
197 NICInfo* nd;
198 nd = &nd_table[0];
199 if (!nd->model)
200 nd->model = "dm9000";
201 if (strcmp(nd->model, "dm9000") == 0) {
202 dm9000_init(nd, 0x20000000, 0x300, 0x304, s3c_gpio_in_get(s->cpu->io)[MINI2440_IRQ_DM9000]);
206 s3c_adc_setscale(s->cpu->adc, mini2440_ts_scale);
208 /* Setup initial (reset) machine state */
209 qemu_register_reset(mini2440_reset, s);
210 #if 0
211 arm_load_kernel(s->ram, kernel_filename, kernel_cmdline,
212 initrd_filename, 0x49e, S3C_RAM_BASE);
213 #endif
215 return s;
218 static void mini2440_init(ram_addr_t ram_size, int vga_ram_size,
219 const char *boot_device,
220 const char *kernel_filename, const char *kernel_cmdline,
221 const char *initrd_filename, const char *cpu_model)
223 struct mini2440_board_s *mini;
224 int sd_idx = drive_get_index(IF_SD, 0, 0);
225 SDState *sd = 0;
227 if (sd_idx >= 0)
228 sd = sd_init(drives_table[sd_idx].bdrv, 0);
230 mini = mini2440_init_common(ram_size,
231 kernel_filename, cpu_model, sd);
233 mini->nand = nand_init(NAND_MFR_SAMSUNG, 0x36);
234 mini->cpu->nand->reg(mini->cpu->nand, mini->nand);
236 mini2440_reset(mini);
239 QEMUMachine mini2440_machine = {
240 "mini2440",
241 "MINI2440 Chinese Samsung SoC dev board (S3C2440A)",
242 .init = mini2440_init,
243 .ram_require = (0x04000000 + S3C_SRAM_SIZE) | RAMSIZE_FIXED