blob: d656b81e33ec2fa964cc1e403d86d7caba1e68a3 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/* Copyright (C) 2007-2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10** GNU General Public License for more details.
11*/
12#include "hw.h"
13#include "boards.h"
14#include "devices.h"
15#include "net.h"
16#include "arm_pic.h"
17#include "sysemu.h"
18#include "goldfish_device.h"
19#include "android/globals.h"
20#include "audio/audio.h"
21#include "arm-misc.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070022#include "console.h"
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080023#ifdef CONFIG_MEMCHECK
24#include "memcheck/memcheck_api.h"
25#endif // CONFIG_MEMCHECK
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080026
27#define ARM_CPU_SAVE_VERSION 1
28
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080029char* audio_input_source = NULL;
30
31void goldfish_memlog_init(uint32_t base);
32
33static struct goldfish_device event0_device = {
34 .name = "goldfish_events",
35 .id = 0,
36 .size = 0x1000,
37 .irq_count = 1
38};
39
40static struct goldfish_device nand_device = {
41 .name = "goldfish_nand",
42 .id = 0,
43 .size = 0x1000
44};
45
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080046/* Board init. */
47
San Mehat68a8f7b2009-12-05 09:54:44 -080048static void goldfish_sdcard_init(int n, unsigned base)
49{
50 int idx = drive_get_index( IF_IDE, 0, n );
51
52 goldfish_mmc_init(base, n);
53
54 if (idx >= 0) {
55 goldfish_mmc_insert(n, drives_table[idx].bdrv);
56 }
57}
58
59// #define TEST_SWITCH 1
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080060#if TEST_SWITCH
61uint32_t switch_test_write(void *opaque, uint32_t state)
62{
63 goldfish_switch_set_state(opaque, state);
64 return state;
65}
66#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070067static void android_arm_init_(ram_addr_t ram_size,
68 const char *boot_device,
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -080069 const char *kernel_filename,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080070 const char *kernel_cmdline,
71 const char *initrd_filename,
72 const char *cpu_model)
73{
74 CPUState *env;
75 qemu_irq *cpu_pic;
76 qemu_irq *goldfish_pic;
77 int i;
78 struct arm_boot_info info;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070079 ram_addr_t ram_offset;
80 DisplayState* ds = get_displaystate();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080081
82 if (!cpu_model)
83 cpu_model = "arm926";
84
85 env = cpu_init(cpu_model);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080086 register_savevm( "cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, env );
87
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070088 ram_offset = qemu_ram_alloc(ram_size);
89 cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080090
91 cpu_pic = arm_pic_init_cpu(env);
92 goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]);
93 goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22);
94
95 goldfish_device_bus_init(0xff001000, 1);
96
97 goldfish_timer_and_rtc_init(0xff003000, 3);
98
99 goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4);
100 for(i = 1; i < MAX_SERIAL_PORTS; i++) {
101 //printf("android_arm_init serial %d %x\n", i, serial_hds[i]);
102 if(serial_hds[i]) {
103 goldfish_tty_add(serial_hds[i], i, 0, 0);
104 }
105 }
106
107 for(i = 0; i < MAX_NICS; i++) {
108 if (nd_table[i].vlan) {
109 if (nd_table[i].model == NULL
110 || strcmp(nd_table[i].model, "smc91c111") == 0) {
111 struct goldfish_device *smc_device;
112 smc_device = qemu_mallocz(sizeof(*smc_device));
113 smc_device->name = "smc91x";
114 smc_device->id = i;
115 smc_device->size = 0x1000;
116 smc_device->irq_count = 1;
117 goldfish_add_device_no_io(smc_device);
118 smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]);
119 } else {
120 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
121 exit (1);
122 }
123 }
124 }
125
126 goldfish_fb_init(ds, 0);
127#ifdef HAS_AUDIO
The Android Open Source Project92c73112009-03-05 14:34:31 -0800128 goldfish_audio_init(0xff004000, 0, audio_input_source);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800129#endif
San Mehat68a8f7b2009-12-05 09:54:44 -0800130
131 goldfish_sdcard_init(0, 0xff005000);
132 goldfish_sdcard_init(1, 0xff007000);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800133
134 goldfish_memlog_init(0xff006000);
135
136 if (android_hw->hw_battery)
137 goldfish_battery_init();
138
139 goldfish_add_device_no_io(&event0_device);
140 events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]);
141
142#ifdef CONFIG_NAND
143 goldfish_add_device_no_io(&nand_device);
144 nand_dev_init(nand_device.base);
145#endif
146#ifdef CONFIG_TRACE
147 extern const char *trace_filename;
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800148 /* Init trace device if either tracing, or memory checking is enabled. */
149 if (trace_filename != NULL
150#ifdef CONFIG_MEMCHECK
151 || memcheck_enabled
152#endif // CONFIG_MEMCHECK
153 ) {
Jack Veenstra9980bbb2009-05-05 10:35:03 -0700154 trace_dev_init();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800155 }
Vladimir Chtchetkine5389aa12010-02-16 10:38:35 -0800156 if (trace_filename != NULL) {
157 dprint( "Trace file name is set to %s\n", trace_filename );
158 } else {
159 dprint("Trace file name is not set\n");
160 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800161#endif
162
163#if TEST_SWITCH
164 {
165 void *sw;
166 sw = goldfish_switch_add("test", NULL, NULL, 0);
167 goldfish_switch_set_state(sw, 1);
168 goldfish_switch_add("test2", switch_test_write, sw, 1);
169 }
170#endif
171
172 memset(&info, 0, sizeof info);
173 info.ram_size = ram_size;
174 info.kernel_filename = kernel_filename;
175 info.kernel_cmdline = kernel_cmdline;
176 info.initrd_filename = initrd_filename;
177 info.nb_cpus = 1;
178 info.board_id = 1441;
179
180 arm_load_kernel(env, &info);
181}
182
183QEMUMachine android_arm_machine = {
184 "android_arm",
185 "ARM Android Emulator",
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700186 android_arm_init_,
The Android Open Source Project92c73112009-03-05 14:34:31 -0800187 0,
188 0,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700189 1,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800190 NULL
191};
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700192
193static void android_arm_init(void)
194{
195 qemu_register_machine(&android_arm_machine);
196}
197
198machine_init(android_arm_init);