Index: qemu/hw/sun4m.c =================================================================== --- qemu.orig/hw/sun4m.c 2007-04-29 19:43:59.000000000 +0000 +++ qemu/hw/sun4m.c 2007-04-30 16:26:59.000000000 +0000 @@ -117,6 +117,34 @@ m48t59_write(nvram, addr + max - 1, '\0'); } +static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, + const unsigned char *str) +{ + uint32_t len; + + len = strlen(str) + 1; + nvram_set_string(nvram, addr, str, len); + + return addr + len; +} + +static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, + uint32_t end) +{ + unsigned int i, sum; + + // Length divided by 16 + m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); + m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); + // Checksum + sum = m48t59_read(nvram, start); + for (i = 0; i < 14; i++) { + sum += m48t59_read(nvram, start + 2 + i); + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; + } + m48t59_write(nvram, start + 1, sum & 0xff); +} + static m48t59_t *nvram; extern int nographic; @@ -128,7 +156,8 @@ int machine_id) { unsigned char tmp = 0; - int i, j; + unsigned int i, j; + uint32_t start, end; // Try to match PPC NVRAM nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); @@ -151,8 +180,30 @@ nvram_set_word(nvram, 0x56, height); nvram_set_word(nvram, 0x58, depth); + // OpenBIOS nvram variables + // Variable partition + start = 252; + m48t59_write(nvram, start, 0x70); + nvram_set_string(nvram, start + 4, "system", 12); + + end = start + 16; + for (i = 0; i < nb_prom_envs; i++) + end = nvram_set_var(nvram, end, prom_envs[i]); + + m48t59_write(nvram, end++ , 0); + end = start + ((end - start + 15) & ~15); + nvram_finish_partition(nvram, start, end); + + // free partition + start = end; + m48t59_write(nvram, start, 0x7f); + nvram_set_string(nvram, start + 4, "free", 12); + + end = 0x1fd0; + nvram_finish_partition(nvram, start, end); + // Sun4m specific use - i = 0x1fd8; + start = i = 0x1fd8; m48t59_write(nvram, i++, 0x01); m48t59_write(nvram, i++, machine_id); j = 0; @@ -164,10 +215,10 @@ m48t59_write(nvram, i, macaddr[j]); /* Calculate checksum */ - for (i = 0x1fd8; i < 0x1fe7; i++) { - tmp ^= m48t59_read(nvram, i); + for (i = start; i < start + 15; i++) { + tmp ^= m48t59_read(nvram, i); } - m48t59_write(nvram, 0x1fe7, tmp); + m48t59_write(nvram, start + 15, tmp); } static void *slavio_intctl; Index: qemu/hw/sun4u.c =================================================================== --- qemu.orig/hw/sun4u.c 2007-04-29 19:43:59.000000000 +0000 +++ qemu/hw/sun4u.c 2007-04-30 16:27:00.000000000 +0000 @@ -170,6 +170,34 @@ return crc; } +static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, + const unsigned char *str) +{ + uint32_t len; + + len = strlen(str) + 1; + NVRAM_set_string(nvram, addr, str, len); + + return addr + len; +} + +static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, + uint32_t end) +{ + unsigned int i, sum; + + // Length divided by 16 + m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); + m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); + // Checksum + sum = m48t59_read(nvram, start); + for (i = 0; i < 14; i++) { + sum += m48t59_read(nvram, start + 2 + i); + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; + } + m48t59_write(nvram, start + 1, sum & 0xff); +} + extern int nographic; int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, @@ -182,6 +210,8 @@ int width, int height, int depth) { uint16_t crc; + unsigned int i; + uint32_t start, end; /* Set parameters for Open Hack'Ware BIOS */ NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); @@ -212,6 +242,27 @@ crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); NVRAM_set_word(nvram, 0xFC, crc); + // OpenBIOS nvram variables + // Variable partition + start = 252; + m48t59_write(nvram, start, 0x70); + NVRAM_set_string(nvram, start + 4, "system", 12); + + end = start + 16; + for (i = 0; i < nb_prom_envs; i++) + end = nvram_set_var(nvram, end, prom_envs[i]); + + m48t59_write(nvram, end++ , 0); + end = start + ((end - start + 15) & ~15); + nvram_finish_partition(nvram, start, end); + + // free partition + start = end; + m48t59_write(nvram, start, 0x7f); + NVRAM_set_string(nvram, start + 4, "free", 12); + + end = 0x1fd0; + nvram_finish_partition(nvram, start, end); return 0; } Index: qemu/vl.c =================================================================== --- qemu.orig/vl.c 2007-04-29 19:48:31.000000000 +0000 +++ qemu/vl.c 2007-04-30 16:27:00.000000000 +0000 @@ -194,6 +194,10 @@ int semihosting_enabled = 0; int autostart = 1; const char *qemu_name; +#ifdef TARGET_SPARC +unsigned int nb_prom_envs = 0; +const char *prom_envs[MAX_PROM_ENVS]; +#endif /***********************************************************/ /* x86 ISA bus support */ @@ -6473,6 +6477,9 @@ "-daemonize daemonize QEMU after initializing\n" #endif "-option-rom rom load a file, rom, into the option ROM space\n" +#ifdef TARGET_SPARC + "-prom-env variable=value set OpenBIOS nvram variables\n" +#endif "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n" @@ -6564,6 +6571,7 @@ QEMU_OPTION_option_rom, QEMU_OPTION_semihosting, QEMU_OPTION_name, + QEMU_OPTION_prom_env, }; typedef struct QEMUOption { @@ -6658,6 +6666,9 @@ { "semihosting", 0, QEMU_OPTION_semihosting }, #endif { "name", HAS_ARG, QEMU_OPTION_name }, +#if defined(TARGET_SPARC) + { "prom-env", HAS_ARG, QEMU_OPTION_prom_env }, +#endif { NULL }, }; @@ -7389,6 +7400,16 @@ case QEMU_OPTION_name: qemu_name = optarg; break; +#ifdef TARGET_SPARC + case QEMU_OPTION_prom_env: + if (nb_prom_envs >= MAX_PROM_ENVS) { + fprintf(stderr, "Too many prom variables\n"); + exit(1); + } + prom_envs[nb_prom_envs] = optarg; + nb_prom_envs++; + break; +#endif } } } Index: qemu/vl.h =================================================================== --- qemu.orig/vl.h 2007-04-29 19:48:32.000000000 +0000 +++ qemu/vl.h 2007-04-30 16:27:00.000000000 +0000 @@ -167,6 +167,12 @@ extern const char *option_rom[MAX_OPTION_ROMS]; extern int nb_option_roms; +#ifdef TARGET_SPARC +#define MAX_PROM_ENVS 128 +extern const char *prom_envs[MAX_PROM_ENVS]; +extern unsigned int nb_prom_envs; +#endif + /* XXX: make it dynamic */ #define MAX_BIOS_SIZE (4 * 1024 * 1024) #if defined (TARGET_PPC) || defined (TARGET_SPARC64)