1110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz/* Copyright (C) 2007-2008 The Android Open Source Project 2110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** 3110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** This software is licensed under the terms of the GNU General Public 4110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** License version 2, as published by the Free Software Foundation, and 5110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** may be copied, distributed, and modified under those terms. 6110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** 7110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** This program is distributed in the hope that it will be useful, 8110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** but WITHOUT ANY WARRANTY; without even the implied warranty of 9110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz** GNU General Public License for more details. 11110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz*/ 12110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/hw.h" 13110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/boards.h" 14110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/devices.h" 15110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "net/net.h" 16110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/arm/pic.h" 17110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "sysemu/sysemu.h" 18110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/android/goldfish/device.h" 19110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "android/globals.h" 20110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "audio/audio.h" 21110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/arm/arm.h" 22110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "ui/console.h" 23110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "sysemu/blockdev.h" 24110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "hw/android/goldfish/pipe.h" 25110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 26110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#include "android/utils/debug.h" 27110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 28110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#define D(...) VERBOSE_PRINT(init,__VA_ARGS__) 29110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 30110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#define ARM_CPU_SAVE_VERSION 1 31110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 32110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantzchar* audio_input_source = NULL; 33f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz 34f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantzstatic struct goldfish_device event0_device = { 35f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz .name = "goldfish_events", 36f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz .id = 0, 37f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz .size = 0x1000, 38f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz .irq_count = 1 39110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz}; 40f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz 41110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantzstatic struct goldfish_device nand_device = { 42110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz .name = "goldfish_nand", 43110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz .id = 0, 44110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz .size = 0x1000 45110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz}; 46110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 47110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz/* Board init. */ 48110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 49f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantzstatic void android_arm_init_(ram_addr_t ram_size, 50110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz const char *boot_device, 51110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz const char *kernel_filename, 52110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz const char *kernel_cmdline, 53110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz const char *initrd_filename, 54110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz const char *cpu_model) 55110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz{ 56f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz CPUARMState *env; 57110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz qemu_irq *cpu_pic; 58110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz qemu_irq *goldfish_pic; 59110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz int i; 60110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz struct arm_boot_info info; 61110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz ram_addr_t ram_offset; 62110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 63f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz if (!cpu_model) 64110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz cpu_model = "arm926"; 65110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 66110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz env = cpu_init(cpu_model); 67110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 68110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz ram_offset = qemu_ram_alloc(NULL,"android_arm",ram_size); 69110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); 70110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 71815b75705f5e3f0f7db025368da37bb14395de9aRoland Scheidegger cpu_pic = arm_pic_init_cpu(env); 72e968975cb57eb854769292f7c6ff773c64a386c3Marek Olšák goldfish_pic = goldfish_interrupt_init(0xff000000, cpu_pic[ARM_PIC_CPU_IRQ], cpu_pic[ARM_PIC_CPU_FIQ]); 73f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz goldfish_device_init(goldfish_pic, 0xff010000, 0x7f0000, 10, 22); 74110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 75110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_device_bus_init(0xff001000, 1); 76f86def5e74566c8db1ced1cddfc1a1f7bee9875dJakob Bornecrantz 77a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri goldfish_timer_and_rtc_init(0xff003000, 3); 78a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri 79a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri goldfish_tty_add(serial_hds[0], 0, 0xff002000, 4); 80a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri for(i = 1; i < MAX_SERIAL_PORTS; i++) { 81a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri //printf("android_arm_init serial %d %x\n", i, serial_hds[i]); 82a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri if(serial_hds[i]) { 83a508d2dddcc67d0f92cc36b9ed6f36a9bbfc579dLuca Barbieri goldfish_tty_add(serial_hds[i], i, 0, 0); 84ccb5e65bc972e0065c0b71cdf0d2feecb6cc95abLuca Barbieri } 85f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz } 86f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz 87f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz for(i = 0; i < MAX_NICS; i++) { 88110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz if (nd_table[i].vlan) { 89110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz if (nd_table[i].model == NULL 90110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz || strcmp(nd_table[i].model, "smc91c111") == 0) { 91110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz struct goldfish_device *smc_device; 92110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz smc_device = g_malloc0(sizeof(*smc_device)); 93f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz smc_device->name = "smc91x"; 94f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz smc_device->id = i; 95110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz smc_device->size = 0x1000; 96110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz smc_device->irq_count = 1; 97110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_add_device_no_io(smc_device); 98f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz smc91c111_init(&nd_table[i], smc_device->base, goldfish_pic[smc_device->irq]); 99f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz } else { 100f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); 101f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz exit (1); 102110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz } 103f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz } 104110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz } 105110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 106110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_fb_init(0); 107110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#ifdef HAS_AUDIO 108110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_audio_init(0xff004000, 0, audio_input_source); 109f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz#endif 110f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz { 111f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz DriveInfo* info = drive_get( IF_IDE, 0, 0 ); 112f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz if (info != NULL) { 113f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz goldfish_mmc_init(0xff005000, 0, info->bdrv); 114f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz } 115f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz } 116f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz 117f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz goldfish_battery_init(android_hw->hw_battery); 118f7cf8b4658aadb0a125f1e1fb9d6cb73d44902b0Jakob Bornecrantz 119110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_add_device_no_io(&event0_device); 120110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz events_dev_init(event0_device.base, goldfish_pic[event0_device.irq]); 121110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 122110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#ifdef CONFIG_NAND 123110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz goldfish_add_device_no_io(&nand_device); 124110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz nand_dev_init(nand_device.base); 125110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz#endif 126110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 127110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz bool newDeviceNaming = 128110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz (androidHwConfig_getKernelDeviceNaming(android_hw) >= 1); 129110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz pipe_dev_init(newDeviceNaming); 130110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 131110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz memset(&info, 0, sizeof info); 132110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.ram_size = ram_size; 133110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.kernel_filename = kernel_filename; 134110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.kernel_cmdline = kernel_cmdline; 135110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.initrd_filename = initrd_filename; 136110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.nb_cpus = 1; 137110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.is_linux = 1; 138110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz info.board_id = 1441; 139110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 140110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz arm_load_kernel(env, &info); 141110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz} 142110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 143110a956a645f900e100062fbbe19c5835f9b5476Jakob BornecrantzQEMUMachine android_arm_machine = { 144110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz "android_arm", 145110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz "ARM Android Emulator", 146110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz android_arm_init_, 147110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 0, 148110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 0, 149110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 1, 150110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz NULL 151110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz}; 152110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 153110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantzstatic void android_arm_init(void) 154110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz{ 155110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz qemu_register_machine(&android_arm_machine); 156110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz} 157110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz 158110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantzmachine_init(android_arm_init); 159110a956a645f900e100062fbbe19c5835f9b5476Jakob Bornecrantz