android_arm.c revision 1ca833c1638c8b48a1f373abbcbb88bc8bf8aed9
1bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro/* Copyright (C) 2007-2008 The Android Open Source Project
2bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro**
3bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** This software is licensed under the terms of the GNU General Public
4bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** License version 2, as published by the Free Software Foundation, and
5bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** may be copied, distributed, and modified under those terms.
6bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro**
7bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** This program is distributed in the hope that it will be useful,
8bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** but WITHOUT ANY WARRANTY; without even the implied warranty of
9bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro** GNU General Public License for more details.
11bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro*/
12bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "hw.h"
13bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "boards.h"
14bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "devices.h"
15bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "net.h"
16bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "arm_pic.h"
17bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "sysemu.h"
18bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "goldfish_device.h"
19bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "android/globals.h"
20bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "audio/audio.h"
21bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "arm-misc.h"
22bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#include "console.h"
233edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#include "blockdev.h"
2464c6c367497c7fcf88e7527022234043e4460758Jesse Wilson#include "goldfish_pipe.h"
2564c6c367497c7fcf88e7527022234043e4460758Jesse Wilson#ifdef CONFIG_MEMCHECK
263edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#include "memcheck/memcheck_api.h"
273edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#endif  // CONFIG_MEMCHECK
28bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro
293edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#include "android/utils/debug.h"
303edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#include "android/hw-qemud-pipe.h"
312680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes
3255d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro#define  D(...)  VERBOSE_PRINT(init,__VA_ARGS__)
333edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
342680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes#define ARM_CPU_SAVE_VERSION  1
352680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes
36bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapirochar* audio_input_source = NULL;
373edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
383edd28a92fc86a1260347d0995e65a815d73bbbeMattias Peterssonvoid goldfish_memlog_init(uint32_t base);
393edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
403edd28a92fc86a1260347d0995e65a815d73bbbeMattias Peterssonstatic struct goldfish_device event0_device = {
41bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    .name = "goldfish_events",
42bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    .id = 0,
43bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    .size = 0x1000,
44bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    .irq_count = 1
453edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson};
4655d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro
47bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapirostatic struct goldfish_device nand_device = {
48bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    .name = "goldfish_nand",
493edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    .id = 0,
5055d86d85b3cd11461ba793cdc8ed74c87311a447Carl Shapiro    .size = 0x1000
51bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro};
52bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro
532680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes/* Board init.  */
546a22fa91a64739523c1344023f6dfde57e53110eJesse Wilson
553edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#define TEST_SWITCH 1
56bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#if TEST_SWITCH
57bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapirouint32_t switch_test_write(void *opaque, uint32_t state)
58bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro{
59bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    goldfish_switch_set_state(opaque, state);
60bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    return state;
61bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro}
62bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro#endif
63bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapirostatic void android_arm_init_(ram_addr_t ram_size,
64bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    const char *boot_device,
652680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes    const char *kernel_filename,
663edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    const char *kernel_cmdline,
672680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes    const char *initrd_filename,
682680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes    const char *cpu_model)
69bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro{
70bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    CPUState *env;
71bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    qemu_irq *cpu_pic;
72bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    qemu_irq *goldfish_pic;
73bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    int i;
747796ec1e199a9d4f791ae206a60e35fd82d2b462Jeff Brown    struct arm_boot_info  info;
75bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    ram_addr_t ram_offset;
76bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro
77bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    if (!cpu_model)
78bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro        cpu_model = "arm926";
79bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro
80bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro    env = cpu_init(cpu_model);
819429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    register_savevm( "cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, env );
829429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson
833edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    ram_offset = qemu_ram_alloc(ram_size);
849429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
859429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson
869429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    cpu_pic = arm_pic_init_cpu(env);
873edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]);
889429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22);
899429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson
909429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    goldfish_device_bus_init(0xff001000, 1);
913edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
923edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    goldfish_timer_and_rtc_init(0xff003000, 3);
933edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
943edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4);
953edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    for(i = 1; i < MAX_SERIAL_PORTS; i++) {
962680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes        //printf("android_arm_init serial %d %x\n", i, serial_hds[i]);
973edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson        if(serial_hds[i]) {
982680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes            goldfish_tty_add(serial_hds[i], i, 0, 0);
992680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes        }
1002680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes    }
1012680db46e43b69cc1c49429d371cd1c7512d6f2cElliott Hughes
1023edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    for(i = 0; i < MAX_NICS; i++) {
1033edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson        if (nd_table[i].vlan) {
1043edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson            if (nd_table[i].model == NULL
1053edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                || strcmp(nd_table[i].model, "smc91c111") == 0) {
1063edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                struct goldfish_device *smc_device;
1073edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                smc_device = qemu_mallocz(sizeof(*smc_device));
1083edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                smc_device->name = "smc91x";
1093edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                smc_device->id = i;
1103edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson                smc_device->size = 0x1000;
1119429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson                smc_device->irq_count = 1;
1129429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson                goldfish_add_device_no_io(smc_device);
1139429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson                smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]);
1149429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson            } else {
1159429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson                fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
1169429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson                exit (1);
1179429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson            }
1183edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson        }
1199429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    }
1203edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson
1213edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson    goldfish_fb_init(0);
1223edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson#ifdef HAS_AUDIO
1239429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    goldfish_audio_init(0xff004000, 0, audio_input_source);
1249429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson#endif
1259429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    {
1263edd28a92fc86a1260347d0995e65a815d73bbbeMattias Petersson        DriveInfo* info = drive_get( IF_IDE, 0, 0 );
1279429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson        if (info != NULL) {
1289429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson            goldfish_mmc_init(0xff005000, 0, info->bdrv);
1299429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson        }
1309429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    }
1319429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson
1329429d06c5427a6cac499ba90f138afac006135a2Jesse Wilson    goldfish_memlog_init(0xff006000);
133bbfadc8ae01454abba5335fccceaa1c80123ae49Carl Shapiro
134    if (android_hw->hw_battery)
135        goldfish_battery_init();
136
137    goldfish_add_device_no_io(&event0_device);
138    events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]);
139
140#ifdef CONFIG_NAND
141    goldfish_add_device_no_io(&nand_device);
142    nand_dev_init(nand_device.base);
143#endif
144#ifdef CONFIG_TRACE
145    extern const char *trace_filename;
146    /* Init trace device if either tracing, or memory checking is enabled. */
147    if (trace_filename != NULL
148#ifdef CONFIG_MEMCHECK
149        || memcheck_enabled
150#endif  // CONFIG_MEMCHECK
151        || 1  /* XXX: ALWAYS AVAILABLE FOR QEMUD PIPES */
152       ) {
153        trace_dev_init();
154    }
155    if (trace_filename != NULL) {
156        D( "Trace file name is set to %s\n", trace_filename );
157    } else  {
158        D("Trace file name is not set\n");
159    }
160#endif
161
162    init_qemud_pipes();
163
164#if TEST_SWITCH
165    {
166        void *sw;
167        sw = goldfish_switch_add("test", NULL, NULL, 0);
168        goldfish_switch_set_state(sw, 1);
169        goldfish_switch_add("test2", switch_test_write, sw, 1);
170    }
171#endif
172
173    memset(&info, 0, sizeof info);
174    info.ram_size        = ram_size;
175    info.kernel_filename = kernel_filename;
176    info.kernel_cmdline  = kernel_cmdline;
177    info.initrd_filename = initrd_filename;
178    info.nb_cpus         = 1;
179    info.board_id        = 1441;
180
181    arm_load_kernel(env, &info);
182}
183
184QEMUMachine android_arm_machine = {
185    "android_arm",
186    "ARM Android Emulator",
187    android_arm_init_,
188    0,
189    0,
190    1,
191    NULL
192};
193
194static void android_arm_init(void)
195{
196    qemu_register_machine(&android_arm_machine);
197}
198
199machine_init(android_arm_init);
200