1 /* 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/hw.h" 13 #include "hw/boards.h" 14 #include "hw/devices.h" 15 #include "net/net.h" 16 #include "hw/arm/pic.h" 17 #include "sysemu/sysemu.h" 18 #include "hw/android/goldfish/device.h" 19 #include "android/globals.h" 20 #include "audio/audio.h" 21 #include "hw/arm/arm.h" 22 #include "ui/console.h" 23 #include "sysemu/blockdev.h" 24 #include "hw/android/goldfish/pipe.h" 25 26 #include "android/utils/debug.h" 27 28 #define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 29 30 #define ARM_CPU_SAVE_VERSION 1 31 32 char* audio_input_source = NULL; 33 34 static struct goldfish_device event0_device = { 35 .name = "goldfish_events", 36 .id = 0, 37 .size = 0x1000, 38 .irq_count = 1 39 }; 40 41 static struct goldfish_device nand_device = { 42 .name = "goldfish_nand", 43 .id = 0, 44 .size = 0x1000 45 }; 46 47 /* Board init. */ 48 49 static void android_arm_init_(ram_addr_t ram_size, 50 const char *boot_device, 51 const char *kernel_filename, 52 const char *kernel_cmdline, 53 const char *initrd_filename, 54 const char *cpu_model) 55 { 56 CPUARMState *env; 57 qemu_irq *cpu_pic; 58 qemu_irq *goldfish_pic; 59 int i; 60 struct arm_boot_info info; 61 ram_addr_t ram_offset; 62 63 if (!cpu_model) 64 cpu_model = "arm926"; 65 66 env = cpu_init(cpu_model); 67 68 ram_offset = qemu_ram_alloc(NULL,"android_arm",ram_size); 69 cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); 70 71 cpu_pic = arm_pic_init_cpu(env); 72 goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]); 73 goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22); 74 75 goldfish_device_bus_init(0xff001000, 1); 76 77 goldfish_timer_and_rtc_init(0xff003000, 3); 78 79 goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4); 80 for(i = 1; i < MAX_SERIAL_PORTS; i++) { 81 //printf("android_arm_init serial %d %x\n", i, serial_hds[i]); 82 if(serial_hds[i]) { 83 goldfish_tty_add(serial_hds[i], i, 0, 0); 84 } 85 } 86 87 for(i = 0; i < MAX_NICS; i++) { 88 if (nd_table[i].vlan) { 89 if (nd_table[i].model == NULL 90 || strcmp(nd_table[i].model, "smc91c111") == 0) { 91 struct goldfish_device *smc_device; 92 smc_device = g_malloc0(sizeof(*smc_device)); 93 smc_device->name = "smc91x"; 94 smc_device->id = i; 95 smc_device->size = 0x1000; 96 smc_device->irq_count = 1; 97 goldfish_add_device_no_io(smc_device); 98 smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]); 99 } else { 100 fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); 101 exit (1); 102 } 103 } 104 } 105 106 goldfish_fb_init(0); 107 #ifdef HAS_AUDIO 108 goldfish_audio_init(0xff004000, 0, audio_input_source); 109 #endif 110 { 111 DriveInfo* info = drive_get( IF_IDE, 0, 0 ); 112 if (info != NULL) { 113 goldfish_mmc_init(0xff005000, 0, info->bdrv); 114 } 115 } 116 117 goldfish_battery_init(android_hw->hw_battery); 118 119 goldfish_add_device_no_io(&event0_device); 120 events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]); 121 122 #ifdef CONFIG_NAND 123 goldfish_add_device_no_io(&nand_device); 124 nand_dev_init(nand_device.base); 125 #endif 126 127 bool newDeviceNaming = 128 (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1); 129 pipe_dev_init(newDeviceNaming); 130 131 memset(&info, 0, sizeof info); 132 info.ram_size = ram_size; 133 info.kernel_filename = kernel_filename; 134 info.kernel_cmdline = kernel_cmdline; 135 info.initrd_filename = initrd_filename; 136 info.nb_cpus = 1; 137 info.is_linux = 1; 138 info.board_id = 1441; 139 140 arm_load_kernel(env, &info); 141 } 142 143 QEMUMachine android_arm_machine = { 144 "android_arm", 145 "ARM Android Emulator", 146 android_arm_init_, 147 0, 148 0, 149 1, 150 NULL 151 }; 152 153 static void android_arm_init(void) 154 { 155 qemu_register_machine(&android_arm_machine); 156 } 157 158 machine_init(android_arm_init); 159