Set OpenBIOS variables in NVRAM

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2764 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2007-05-01 14:16:52 +00:00
parent 9467cd4602
commit 66508601ad
5 changed files with 144 additions and 5 deletions

View File

@ -117,6 +117,34 @@ static void nvram_set_string (m48t59_t *nvram, uint32_t addr,
m48t59_write(nvram, addr + max - 1, '\0'); 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; static m48t59_t *nvram;
extern int nographic; extern int nographic;
@ -128,7 +156,8 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
int machine_id) int machine_id)
{ {
unsigned char tmp = 0; unsigned char tmp = 0;
int i, j; unsigned int i, j;
uint32_t start, end;
// Try to match PPC NVRAM // Try to match PPC NVRAM
nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
@ -151,8 +180,30 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
nvram_set_word(nvram, 0x56, height); nvram_set_word(nvram, 0x56, height);
nvram_set_word(nvram, 0x58, depth); 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 // Sun4m specific use
i = 0x1fd8; start = i = 0x1fd8;
m48t59_write(nvram, i++, 0x01); m48t59_write(nvram, i++, 0x01);
m48t59_write(nvram, i++, machine_id); m48t59_write(nvram, i++, machine_id);
j = 0; j = 0;
@ -164,10 +215,10 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
m48t59_write(nvram, i, macaddr[j]); m48t59_write(nvram, i, macaddr[j]);
/* Calculate checksum */ /* Calculate checksum */
for (i = 0x1fd8; i < 0x1fe7; i++) { for (i = start; i < start + 15; i++) {
tmp ^= m48t59_read(nvram, i); tmp ^= m48t59_read(nvram, i);
} }
m48t59_write(nvram, 0x1fe7, tmp); m48t59_write(nvram, start + 15, tmp);
} }
static void *slavio_intctl; static void *slavio_intctl;

View File

@ -170,6 +170,34 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
return crc; 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; extern int nographic;
int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
@ -182,6 +210,8 @@ int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
int width, int height, int depth) int width, int height, int depth)
{ {
uint16_t crc; uint16_t crc;
unsigned int i;
uint32_t start, end;
/* Set parameters for Open Hack'Ware BIOS */ /* Set parameters for Open Hack'Ware BIOS */
NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
@ -212,6 +242,28 @@ int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
NVRAM_set_word(nvram, 0xFC, crc); 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; return 0;
} }

View File

@ -1661,6 +1661,15 @@ The following options are specific to the Sparc emulation:
Set the initial TCX graphic mode. The default is 1024x768. 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 @end table
@c man end @c man end

21
vl.c
View File

@ -197,6 +197,10 @@ int nb_option_roms;
int semihosting_enabled = 0; int semihosting_enabled = 0;
int autostart = 1; int autostart = 1;
const char *qemu_name; 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 */ /* x86 ISA bus support */
@ -6530,6 +6534,9 @@ void help(void)
"-daemonize daemonize QEMU after initializing\n" "-daemonize daemonize QEMU after initializing\n"
#endif #endif
"-option-rom rom load a file, rom, into the option ROM space\n" "-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" "\n"
"During emulation, the following keys are useful:\n" "During emulation, the following keys are useful:\n"
"ctrl-alt-f toggle full screen\n" "ctrl-alt-f toggle full screen\n"
@ -6624,6 +6631,7 @@ enum {
QEMU_OPTION_option_rom, QEMU_OPTION_option_rom,
QEMU_OPTION_semihosting, QEMU_OPTION_semihosting,
QEMU_OPTION_name, QEMU_OPTION_name,
QEMU_OPTION_prom_env,
}; };
typedef struct QEMUOption { typedef struct QEMUOption {
@ -6721,6 +6729,9 @@ const QEMUOption qemu_options[] = {
{ "semihosting", 0, QEMU_OPTION_semihosting }, { "semihosting", 0, QEMU_OPTION_semihosting },
#endif #endif
{ "name", HAS_ARG, QEMU_OPTION_name }, { "name", HAS_ARG, QEMU_OPTION_name },
#if defined(TARGET_SPARC)
{ "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
#endif
{ NULL }, { NULL },
}; };
@ -7478,6 +7489,16 @@ int main(int argc, char **argv)
case QEMU_OPTION_name: case QEMU_OPTION_name:
qemu_name = optarg; qemu_name = optarg;
break; 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
} }
} }
} }

6
vl.h
View File

@ -169,6 +169,12 @@ extern const char *bootp_filename;
extern const char *option_rom[MAX_OPTION_ROMS]; extern const char *option_rom[MAX_OPTION_ROMS];
extern int nb_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 */ /* XXX: make it dynamic */
#define MAX_BIOS_SIZE (4 * 1024 * 1024) #define MAX_BIOS_SIZE (4 * 1024 * 1024)
#if defined (TARGET_PPC) || defined (TARGET_SPARC64) #if defined (TARGET_PPC) || defined (TARGET_SPARC64)