Commit 66508601adbc5faac5f25d944f073921e82d79d4
1 parent
9467cd46
Set OpenBIOS variables in NVRAM
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2764 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
144 additions
and
5 deletions
hw/sun4m.c
| ... | ... | @@ -117,6 +117,34 @@ static void nvram_set_string (m48t59_t *nvram, uint32_t addr, |
| 117 | 117 | m48t59_write(nvram, addr + max - 1, '\0'); |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | +static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
| 121 | + const unsigned char *str) | |
| 122 | +{ | |
| 123 | + uint32_t len; | |
| 124 | + | |
| 125 | + len = strlen(str) + 1; | |
| 126 | + nvram_set_string(nvram, addr, str, len); | |
| 127 | + | |
| 128 | + return addr + len; | |
| 129 | +} | |
| 130 | + | |
| 131 | +static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
| 132 | + uint32_t end) | |
| 133 | +{ | |
| 134 | + unsigned int i, sum; | |
| 135 | + | |
| 136 | + // Length divided by 16 | |
| 137 | + m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
| 138 | + m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
| 139 | + // Checksum | |
| 140 | + sum = m48t59_read(nvram, start); | |
| 141 | + for (i = 0; i < 14; i++) { | |
| 142 | + sum += m48t59_read(nvram, start + 2 + i); | |
| 143 | + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
| 144 | + } | |
| 145 | + m48t59_write(nvram, start + 1, sum & 0xff); | |
| 146 | +} | |
| 147 | + | |
| 120 | 148 | static m48t59_t *nvram; |
| 121 | 149 | |
| 122 | 150 | extern int nographic; |
| ... | ... | @@ -128,7 +156,8 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
| 128 | 156 | int machine_id) |
| 129 | 157 | { |
| 130 | 158 | unsigned char tmp = 0; |
| 131 | - int i, j; | |
| 159 | + unsigned int i, j; | |
| 160 | + uint32_t start, end; | |
| 132 | 161 | |
| 133 | 162 | // Try to match PPC NVRAM |
| 134 | 163 | 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, |
| 151 | 180 | nvram_set_word(nvram, 0x56, height); |
| 152 | 181 | nvram_set_word(nvram, 0x58, depth); |
| 153 | 182 | |
| 183 | + // OpenBIOS nvram variables | |
| 184 | + // Variable partition | |
| 185 | + start = 252; | |
| 186 | + m48t59_write(nvram, start, 0x70); | |
| 187 | + nvram_set_string(nvram, start + 4, "system", 12); | |
| 188 | + | |
| 189 | + end = start + 16; | |
| 190 | + for (i = 0; i < nb_prom_envs; i++) | |
| 191 | + end = nvram_set_var(nvram, end, prom_envs[i]); | |
| 192 | + | |
| 193 | + m48t59_write(nvram, end++ , 0); | |
| 194 | + end = start + ((end - start + 15) & ~15); | |
| 195 | + nvram_finish_partition(nvram, start, end); | |
| 196 | + | |
| 197 | + // free partition | |
| 198 | + start = end; | |
| 199 | + m48t59_write(nvram, start, 0x7f); | |
| 200 | + nvram_set_string(nvram, start + 4, "free", 12); | |
| 201 | + | |
| 202 | + end = 0x1fd0; | |
| 203 | + nvram_finish_partition(nvram, start, end); | |
| 204 | + | |
| 154 | 205 | // Sun4m specific use |
| 155 | - i = 0x1fd8; | |
| 206 | + start = i = 0x1fd8; | |
| 156 | 207 | m48t59_write(nvram, i++, 0x01); |
| 157 | 208 | m48t59_write(nvram, i++, machine_id); |
| 158 | 209 | j = 0; |
| ... | ... | @@ -164,10 +215,10 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
| 164 | 215 | m48t59_write(nvram, i, macaddr[j]); |
| 165 | 216 | |
| 166 | 217 | /* Calculate checksum */ |
| 167 | - for (i = 0x1fd8; i < 0x1fe7; i++) { | |
| 168 | - tmp ^= m48t59_read(nvram, i); | |
| 218 | + for (i = start; i < start + 15; i++) { | |
| 219 | + tmp ^= m48t59_read(nvram, i); | |
| 169 | 220 | } |
| 170 | - m48t59_write(nvram, 0x1fe7, tmp); | |
| 221 | + m48t59_write(nvram, start + 15, tmp); | |
| 171 | 222 | } |
| 172 | 223 | |
| 173 | 224 | static void *slavio_intctl; | ... | ... |
hw/sun4u.c
| ... | ... | @@ -170,6 +170,34 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) |
| 170 | 170 | return crc; |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | +static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
| 174 | + const unsigned char *str) | |
| 175 | +{ | |
| 176 | + uint32_t len; | |
| 177 | + | |
| 178 | + len = strlen(str) + 1; | |
| 179 | + NVRAM_set_string(nvram, addr, str, len); | |
| 180 | + | |
| 181 | + return addr + len; | |
| 182 | +} | |
| 183 | + | |
| 184 | +static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
| 185 | + uint32_t end) | |
| 186 | +{ | |
| 187 | + unsigned int i, sum; | |
| 188 | + | |
| 189 | + // Length divided by 16 | |
| 190 | + m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
| 191 | + m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
| 192 | + // Checksum | |
| 193 | + sum = m48t59_read(nvram, start); | |
| 194 | + for (i = 0; i < 14; i++) { | |
| 195 | + sum += m48t59_read(nvram, start + 2 + i); | |
| 196 | + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
| 197 | + } | |
| 198 | + m48t59_write(nvram, start + 1, sum & 0xff); | |
| 199 | +} | |
| 200 | + | |
| 173 | 201 | extern int nographic; |
| 174 | 202 | |
| 175 | 203 | 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, |
| 182 | 210 | int width, int height, int depth) |
| 183 | 211 | { |
| 184 | 212 | uint16_t crc; |
| 213 | + unsigned int i; | |
| 214 | + uint32_t start, end; | |
| 185 | 215 | |
| 186 | 216 | /* Set parameters for Open Hack'Ware BIOS */ |
| 187 | 217 | NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); |
| ... | ... | @@ -212,6 +242,28 @@ int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, |
| 212 | 242 | crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); |
| 213 | 243 | NVRAM_set_word(nvram, 0xFC, crc); |
| 214 | 244 | |
| 245 | + // OpenBIOS nvram variables | |
| 246 | + // Variable partition | |
| 247 | + start = 252; | |
| 248 | + m48t59_write(nvram, start, 0x70); | |
| 249 | + NVRAM_set_string(nvram, start + 4, "system", 12); | |
| 250 | + | |
| 251 | + end = start + 16; | |
| 252 | + for (i = 0; i < nb_prom_envs; i++) | |
| 253 | + end = nvram_set_var(nvram, end, prom_envs[i]); | |
| 254 | + | |
| 255 | + m48t59_write(nvram, end++ , 0); | |
| 256 | + end = start + ((end - start + 15) & ~15); | |
| 257 | + nvram_finish_partition(nvram, start, end); | |
| 258 | + | |
| 259 | + // free partition | |
| 260 | + start = end; | |
| 261 | + m48t59_write(nvram, start, 0x7f); | |
| 262 | + NVRAM_set_string(nvram, start + 4, "free", 12); | |
| 263 | + | |
| 264 | + end = 0x1fd0; | |
| 265 | + nvram_finish_partition(nvram, start, end); | |
| 266 | + | |
| 215 | 267 | return 0; |
| 216 | 268 | } |
| 217 | 269 | ... | ... |
qemu-doc.texi
| ... | ... | @@ -1661,6 +1661,15 @@ The following options are specific to the Sparc emulation: |
| 1661 | 1661 | |
| 1662 | 1662 | Set the initial TCX graphic mode. The default is 1024x768. |
| 1663 | 1663 | |
| 1664 | +@item -prom-env string | |
| 1665 | + | |
| 1666 | +Set OpenBIOS variables in NVRAM, for example: | |
| 1667 | + | |
| 1668 | +@example | |
| 1669 | +qemu-system-sparc -prom-env 'auto-boot?=false' \ | |
| 1670 | + -prom-env 'boot-device=sd(0,2,0):d' -prom-env 'boot-args=linux single' | |
| 1671 | +@end example | |
| 1672 | + | |
| 1664 | 1673 | @end table |
| 1665 | 1674 | |
| 1666 | 1675 | @c man end | ... | ... |
vl.c
| ... | ... | @@ -197,6 +197,10 @@ int nb_option_roms; |
| 197 | 197 | int semihosting_enabled = 0; |
| 198 | 198 | int autostart = 1; |
| 199 | 199 | const char *qemu_name; |
| 200 | +#ifdef TARGET_SPARC | |
| 201 | +unsigned int nb_prom_envs = 0; | |
| 202 | +const char *prom_envs[MAX_PROM_ENVS]; | |
| 203 | +#endif | |
| 200 | 204 | |
| 201 | 205 | /***********************************************************/ |
| 202 | 206 | /* x86 ISA bus support */ |
| ... | ... | @@ -6530,6 +6534,9 @@ void help(void) |
| 6530 | 6534 | "-daemonize daemonize QEMU after initializing\n" |
| 6531 | 6535 | #endif |
| 6532 | 6536 | "-option-rom rom load a file, rom, into the option ROM space\n" |
| 6537 | +#ifdef TARGET_SPARC | |
| 6538 | + "-prom-env variable=value set OpenBIOS nvram variables\n" | |
| 6539 | +#endif | |
| 6533 | 6540 | "\n" |
| 6534 | 6541 | "During emulation, the following keys are useful:\n" |
| 6535 | 6542 | "ctrl-alt-f toggle full screen\n" |
| ... | ... | @@ -6624,6 +6631,7 @@ enum { |
| 6624 | 6631 | QEMU_OPTION_option_rom, |
| 6625 | 6632 | QEMU_OPTION_semihosting, |
| 6626 | 6633 | QEMU_OPTION_name, |
| 6634 | + QEMU_OPTION_prom_env, | |
| 6627 | 6635 | }; |
| 6628 | 6636 | |
| 6629 | 6637 | typedef struct QEMUOption { |
| ... | ... | @@ -6721,6 +6729,9 @@ const QEMUOption qemu_options[] = { |
| 6721 | 6729 | { "semihosting", 0, QEMU_OPTION_semihosting }, |
| 6722 | 6730 | #endif |
| 6723 | 6731 | { "name", HAS_ARG, QEMU_OPTION_name }, |
| 6732 | +#if defined(TARGET_SPARC) | |
| 6733 | + { "prom-env", HAS_ARG, QEMU_OPTION_prom_env }, | |
| 6734 | +#endif | |
| 6724 | 6735 | { NULL }, |
| 6725 | 6736 | }; |
| 6726 | 6737 | |
| ... | ... | @@ -7478,6 +7489,16 @@ int main(int argc, char **argv) |
| 7478 | 7489 | case QEMU_OPTION_name: |
| 7479 | 7490 | qemu_name = optarg; |
| 7480 | 7491 | break; |
| 7492 | +#ifdef TARGET_SPARC | |
| 7493 | + case QEMU_OPTION_prom_env: | |
| 7494 | + if (nb_prom_envs >= MAX_PROM_ENVS) { | |
| 7495 | + fprintf(stderr, "Too many prom variables\n"); | |
| 7496 | + exit(1); | |
| 7497 | + } | |
| 7498 | + prom_envs[nb_prom_envs] = optarg; | |
| 7499 | + nb_prom_envs++; | |
| 7500 | + break; | |
| 7501 | +#endif | |
| 7481 | 7502 | } |
| 7482 | 7503 | } |
| 7483 | 7504 | } | ... | ... |
vl.h
| ... | ... | @@ -169,6 +169,12 @@ extern const char *bootp_filename; |
| 169 | 169 | extern const char *option_rom[MAX_OPTION_ROMS]; |
| 170 | 170 | extern int nb_option_roms; |
| 171 | 171 | |
| 172 | +#ifdef TARGET_SPARC | |
| 173 | +#define MAX_PROM_ENVS 128 | |
| 174 | +extern const char *prom_envs[MAX_PROM_ENVS]; | |
| 175 | +extern unsigned int nb_prom_envs; | |
| 176 | +#endif | |
| 177 | + | |
| 172 | 178 | /* XXX: make it dynamic */ |
| 173 | 179 | #define MAX_BIOS_SIZE (4 * 1024 * 1024) |
| 174 | 180 | #if defined (TARGET_PPC) || defined (TARGET_SPARC64) | ... | ... |