#include #include /* Magic knowledge - qemu loads image here. * However, we use the value from NVRAM if possible... */ #define KERNELBASE 0x01000000 /* When starting qemu make sure to give the correct * amount of memory! * * NOTE: Code now supports reading the actual memory * amount from NVRAM. The residual copy in RAM * is fixed-up accordingly. */ #define MEM_MEGS 32 /* Mock up a minimal/fake residual; just enough to make the * bootloader happy. */ struct fake_data { unsigned long dat_len; unsigned long res_off; unsigned long cmd_off; unsigned long cmd_len; unsigned long img_adr; RESIDUAL fake_residual; char cmdline[1024]; } fake_data = { dat_len: sizeof(fake_data), res_off: (unsigned long) &fake_data.fake_residual -(unsigned long) &fake_data, cmd_off: (unsigned long) &fake_data.cmdline -(unsigned long) &fake_data, cmd_len: sizeof(fake_data.cmdline), img_adr: KERNELBASE, fake_residual: { ResidualLength: sizeof(RESIDUAL), Version: 0, Revision: 0, EC: 0, VitalProductData: { FirmwareSupplier: QEMU, ProcessorHz: 300000000, /* fantasy */ ProcessorBusHz: 100000000, /* qemu timebase clock */ TimeBaseDivisor:1*1000, }, MaxNumCpus: 1, ActualNumCpus: 1, Cpus: { { CpuType: 0x00040103, /* FIXME: fill from PVR */ CpuNumber: 0, CpuState: 0, }, }, /* Memory */ TotalMemory: 1024*1024*MEM_MEGS, GoodMemory: 1024*1024*MEM_MEGS, ActualNumMemSegs: 13, Segs: { { 0x2000, 0xFFF00, 0x00100 }, { 0x0020, MEM_MEGS*0x100, 0x80000 - MEM_MEGS*0x100 }, { 0x0008, 0x00800, 0x00168 }, { 0x0004, 0x00000, 0x00005 }, { 0x0001, 0x006F1, 0x0010F }, { 0x0002, 0x006AD, 0x00044 }, { 0x0010, 0x00005, 0x006A8 }, { 0x0010, 0x00968, MEM_MEGS*0x100 - 0x00968 }, { 0x0800, 0xC0000, 0x3F000 }, { 0x0600, 0xBF800, 0x00800 }, { 0x0500, 0x81000, 0x3E800 }, { 0x0480, 0x80800, 0x00800 }, { 0x0440, 0x80000, 0x00800 } }, ActualNumMemories: 0, Memories: { {0}, }, /* Devices */ ActualNumDevices: 1, Devices: { { DeviceId: { BusId: PROCESSORDEVICE, BaseType: BridgeController, SubType: PCIBridge, Interface: PCIBridgeIndirect, }, } }, DevicePnPHeap: {0} }, /* This is overwritten by command line passed by qemu. */ cmdline: { '-','-','n','e','2','k','-','i','r','q','=','9', 0, } }; /* Read one byte from NVRAM */ static inline uint8_t nvram_rd(void) { uint8_t rval = *(volatile uint8_t*)0x80000077; asm volatile("eieio"); return rval; } /* Set NVRAM address pointer */ static inline void nvram_addr(uint16_t addr) { *(volatile uint8_t*)0x80000074 = (addr & 0xff); asm volatile("eieio"); *(volatile uint8_t*)0x80000075 = ((addr>>8) & 0xff); asm volatile("eieio"); } /* Read a 32-bit (big-endian) work from NVRAM */ static uint32_t nvram_rdl_be(uint16_t addr) { int i; uint32_t rval = 0; for ( i=0; i 0 ) { /* have a command-line; copy it into our local buffer */ if ( l > sizeof( p->cmdline ) - 1 ) { l = sizeof( p->cmdline ) - 1; } /* original may overlap our buffer; must safely move around */ if ( p->cmdline < (char*)cmdl ) { for ( i=0; icmdline[i] = ((char*)cmdl)[i]; } } else { for ( i=l-1; i>=0; i-- ) { p->cmdline[i] = ((char*)cmdl)[i]; } } } p->cmdline[l] = 0; /* Copy rest of residual */ for ( i=0; ifake_residual); i++ ) ((char*)&p->fake_residual)[i] = ((char*)&fake_data.fake_residual)[i]; p->dat_len = fake_data.dat_len; p->res_off = fake_data.res_off; p->cmd_off = fake_data.cmd_off; p->cmd_len = l+1; p->img_adr = imga; /* Fix up memory in residual from NVRAM settings */ mem_sz = nvram_rdl_be( 0x0030 ); pgs = mem_sz >> 12; p->fake_residual.TotalMemory = mem_sz; p->fake_residual.GoodMemory = mem_sz; p->fake_residual.Segs[1].BasePage = pgs; p->fake_residual.Segs[1].PageCount = 0x80000 - pgs; p->fake_residual.Segs[7].PageCount = pgs - 0x00968; return (uint32_t)p; }