Commit 66508601adbc5faac5f25d944f073921e82d79d4

Authored by blueswir1
1 parent 9467cd46

Set OpenBIOS variables in NVRAM


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2764 c046a42c-6fe2-441c-8c8c-71466251a162
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
... ...
... ... @@ -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 }
... ...
... ... @@ -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)
... ...