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) | ... | ... |