1409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* 2409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * QEMU/MIPS pseudo-board 3409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * 4409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * emulates a simple machine with ISA-like bus. 5409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * ISA IO space mapped to the 0x14000000 (PHYS) and 6409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * ISA memory at the 0x10000000 (PHYS, 16Mb in size). 7409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * All peripherial devices are attached to this "bus" with 8409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli * the standard PC ISA addresses. 9409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli*/ 10409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "hw.h" 11409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "mips.h" 12409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "pc.h" 13409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "isa.h" 14409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "net.h" 15409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "sysemu.h" 16409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "boards.h" 17409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "flash.h" 18409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "qemu-log.h" 19409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "mips-bios.h" 20409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "ide.h" 21409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "loader.h" 22409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#include "elf.h" 23409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 24409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff) 25409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 26409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) 27409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 28409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#define MAX_IDE_BUS 2 29409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 30409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic const int ide_iobase[2] = { 0x1f0, 0x170 }; 31409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic const int ide_iobase2[2] = { 0x3f6, 0x376 }; 32409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic const int ide_irq[2] = { 14, 15 }; 33409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 34409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic PITState *pit; /* PIT i8254 */ 35409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 36409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli/* i8254 PIT is attached to the IRQ0 at PIC i8259 */ 37409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 38409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic struct _loaderparams { 39409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int ram_size; 40409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *kernel_filename; 41409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *kernel_cmdline; 42409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *initrd_filename; 43409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} loaderparams; 44409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 45409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic void mips_qemu_writel (void *opaque, target_phys_addr_t addr, 46409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli uint32_t val) 47409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 48409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if ((addr & 0xffff) == 0 && val == 42) 49409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_system_reset_request (); 50409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli else if ((addr & 0xffff) == 4 && val == 42) 51409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_system_shutdown_request (); 52409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 53409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 54409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic uint32_t mips_qemu_readl (void *opaque, target_phys_addr_t addr) 55409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 56409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli return 0; 57409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 58409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 59409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic CPUWriteMemoryFunc * const mips_qemu_write[] = { 60409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_writel, 61409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_writel, 62409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_writel, 63409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}; 64409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 65409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic CPUReadMemoryFunc * const mips_qemu_read[] = { 66409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_readl, 67409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_readl, 68409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli &mips_qemu_readl, 69409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}; 70409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 71409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic int mips_qemu_iomemtype = 0; 72409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 73409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallitypedef struct ResetData { 74409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli CPUState *env; 75409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli uint64_t vector; 76409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} ResetData; 77409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 78409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic int64_t load_kernel(void) 79409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 80409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int64_t entry, kernel_low, kernel_high; 81409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli long kernel_size, initrd_size, params_size; 82409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ram_addr_t initrd_offset; 83409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli uint32_t *params_buf; 84409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int big_endian; 85409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 86409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_WORDS_BIGENDIAN 87409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli big_endian = 1; 88409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else 89409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli big_endian = 0; 90409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif 91409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, 92409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli (uint64_t *)&entry, (uint64_t *)&kernel_low, 93409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1); 94409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (kernel_size >= 0) { 95409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if ((entry & ~0x7fffffffULL) == 0x80000000) 96409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli entry = (int32_t)entry; 97409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else { 98409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "qemu: could not load kernel '%s'\n", 99409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.kernel_filename); 100409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 101409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 102409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 103409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* load initrd */ 104409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_size = 0; 105409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_offset = 0; 106409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (loaderparams.initrd_filename) { 107409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_size = get_image_size (loaderparams.initrd_filename); 108409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (initrd_size > 0) { 109409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK; 110409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (initrd_offset + initrd_size > ram_size) { 111409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, 112409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli "qemu: memory too small for initial ram disk '%s'\n", 113409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.initrd_filename); 114409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 115409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 116409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_size = load_image_targphys(loaderparams.initrd_filename, 117409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_offset, 118409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ram_size - initrd_offset); 119409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 120409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (initrd_size == (target_ulong) -1) { 121409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 122409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.initrd_filename); 123409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 124409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 125409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 126409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 127409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* Store command line. */ 128409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli params_size = 264; 129409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli params_buf = qemu_malloc(params_size); 130409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 131409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli params_buf[0] = tswap32(ram_size); 132409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli params_buf[1] = tswap32(0x12345678); 133409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 134409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (initrd_size > 0) { 135409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli snprintf((char *)params_buf + 8, 256, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", 136409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli PHYS_TO_VIRT((uint32_t)initrd_offset), 137409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli initrd_size, loaderparams.kernel_cmdline); 138409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else { 139409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli snprintf((char *)params_buf + 8, 256, "%s", loaderparams.kernel_cmdline); 140409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 141409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 142409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli rom_add_blob_fixed("params", params_buf, params_size, 143409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli (16 << 20) - 264); 144409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 145409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli return entry; 146409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 147409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 148409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic void main_cpu_reset(void *opaque) 149409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 150409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ResetData *s = (ResetData *)opaque; 151409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli CPUState *env = s->env; 152409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 153409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_reset(env); 154409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli env->active_tc.PC = s->vector; 155409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 156409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 157409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic const int sector_len = 32 * 1024; 158409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic 159409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallivoid mips_r4k_init (ram_addr_t ram_size, 160409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *boot_device, 161409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *kernel_filename, const char *kernel_cmdline, 162409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli const char *initrd_filename, const char *cpu_model) 163409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 164409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli char *filename; 165409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ram_addr_t ram_offset; 166409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ram_addr_t bios_offset; 167409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int bios_size; 168409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli CPUState *env; 169409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ResetData *reset_info; 170409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli RTCState *rtc_state; 171409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli int i; 172409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_irq *i8259; 173409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; 174409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli DriveInfo *dinfo; 175409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 176409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* init CPUs */ 177409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (cpu_model == NULL) { 178409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#ifdef TARGET_MIPS64 179409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_model = "R4000"; 180409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#else 181409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_model = "24Kf"; 182409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli#endif 183409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 184409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli env = cpu_init(cpu_model); 185409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (!env) { 186409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "Unable to find CPU definition\n"); 187409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 188409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 189409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli reset_info = qemu_mallocz(sizeof(ResetData)); 190409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli reset_info->env = env; 191409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli reset_info->vector = env->active_tc.PC; 192409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_register_reset(main_cpu_reset, reset_info); 193409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 194409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* allocate RAM */ 195409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (ram_size > (256 << 20)) { 196409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, 197409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n", 198409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ((unsigned int)ram_size / (1 << 20))); 199409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 200409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 201409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli ram_offset = qemu_ram_alloc(ram_size); 202409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 203409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); 204409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 205409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (!mips_qemu_iomemtype) { 206409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli mips_qemu_iomemtype = cpu_register_io_memory(mips_qemu_read, 207409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli mips_qemu_write, NULL); 208409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 209409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_register_physical_memory(0x1fbf0000, 0x10000, mips_qemu_iomemtype); 210409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 211409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* Try to load a BIOS image. If this fails, we continue regardless, 212409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli but initialize the hardware ourselves. When a kernel gets 213409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli preloaded we also initialize the hardware, since the BIOS wasn't 214409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli run. */ 215409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (bios_name == NULL) 216409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_name = BIOS_FILENAME; 217409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); 218409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (filename) { 219409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_size = get_image_size(filename); 220409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else { 221409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_size = -1; 222409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 223409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { 224409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_offset = qemu_ram_alloc(BIOS_SIZE); 225409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_register_physical_memory(0x1fc00000, BIOS_SIZE, 226409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_offset | IO_MEM_ROM); 227409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 228409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); 229409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { 230409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli uint32_t mips_rom = 0x00400000; 231409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_offset = qemu_ram_alloc(mips_rom); 232409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (!pflash_cfi01_register(0x1fc00000, bios_offset, 233409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli dinfo->bdrv, sector_len, mips_rom / sector_len, 234409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 4, 0, 0, 0, 0)) { 235409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "qemu: Error registering flash memory.\n"); 236409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 237409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 238409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli else { 239409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* not fatal */ 240409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", 241409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli bios_name); 242409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 243409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (filename) { 244409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_free(filename); 245409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 246409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 247409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (kernel_filename) { 248409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.ram_size = ram_size; 249409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.kernel_filename = kernel_filename; 250409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.kernel_cmdline = kernel_cmdline; 251409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli loaderparams.initrd_filename = initrd_filename; 252409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli reset_info->vector = load_kernel(); 253409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 254409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 255409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* Init CPU internal devices */ 256409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_mips_irq_init_cpu(env); 257409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli cpu_mips_clock_init(env); 258409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 259409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* The PIC is attached to the MIPS CPU INT0 pin */ 260409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli i8259 = i8259_init(env->irq[2]); 261409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_bus_new(NULL); 262409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_bus_irqs(i8259); 263409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 264409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli rtc_state = rtc_init(2000); 265409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 266409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli /* Register 64 KB of ISA IO space at 0x14000000 */ 267409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_mmio_init(0x14000000, 0x00010000); 268409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_mem_base = 0x10000000; 269409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 270409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli pit = pit_init(0x40, i8259[0]); 271409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 272409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli for(i = 0; i < MAX_SERIAL_PORTS; i++) { 273409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (serial_hds[i]) { 274409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli serial_isa_init(i, serial_hds[i]); 275409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 276409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 277409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 278409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_vga_init(); 279409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 280409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (nd_table[0].vlan) 281409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_ne2000_init(0x300, 9, &nd_table[0]); 282409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 283409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) { 284409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli fprintf(stderr, "qemu: too many IDE bus\n"); 285409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli exit(1); 286409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 287409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 288409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) { 289409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS); 290409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli } 291409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 292409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli for(i = 0; i < MAX_IDE_BUS; i++) 293409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], 294409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli hd[MAX_IDE_DEVS * i], 295409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli hd[MAX_IDE_DEVS * i + 1]); 296409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 297409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli isa_create_simple("i8042"); 298409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 299409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 300409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic QEMUMachine mips_machine = { 301409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli .name = "mips", 302409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli .desc = "mips r4k platform", 303409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli .init = mips_r4k_init, 304409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli}; 305409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 306409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallistatic void mips_machine_init(void) 307409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli{ 308409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli qemu_register_machine(&mips_machine); 309409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli} 310409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapalli 311409c7b66435cf5947cab6bf0710f92507317f22eBhanu Chetlapallimachine_init(mips_machine_init); 312