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;
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);
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;
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;
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,
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);
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;
}
Set the initial TCX graphic mode. The default is 1024x768.
+@item -prom-env string
+
+Set OpenBIOS variables in NVRAM, for example:
+
+@example
+qemu-system-sparc -prom-env 'auto-boot?=false' \
+ -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single'
+@end example
+
@end table
@c man end
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 */
"-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"
QEMU_OPTION_option_rom,
QEMU_OPTION_semihosting,
QEMU_OPTION_name,
+ QEMU_OPTION_prom_env,
};
typedef struct QEMUOption {
{ "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 },
};
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
}
}
}
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)