Commit d2c63fc185f3d126ef177105166a491ab3556f5c
1 parent
57c26279
Update OHW interface to version 3.
Use common ABI description file with OpenBIOS. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3648 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
324 additions
and
254 deletions
hw/firmware_abi.h
0 → 100755
1 | +#ifndef FIRMWARE_ABI_H | |
2 | +#define FIRMWARE_ABI_H | |
3 | + | |
4 | +#ifndef __ASSEMBLY__ | |
5 | +/* Open Hack'Ware NVRAM configuration structure */ | |
6 | + | |
7 | +/* Version 3 */ | |
8 | +typedef struct ohwcfg_v3_t ohwcfg_v3_t; | |
9 | +struct ohwcfg_v3_t { | |
10 | + /* 0x00: structure identifier */ | |
11 | + uint8_t struct_ident[0x10]; | |
12 | + /* 0x10: structure version and NVRAM description */ | |
13 | + uint32_t struct_version; | |
14 | + uint16_t nvram_size; | |
15 | + uint16_t pad0; | |
16 | + uint16_t nvram_arch_ptr; | |
17 | + uint16_t nvram_arch_size; | |
18 | + uint16_t nvram_arch_crc; | |
19 | + uint8_t pad1[0x02]; | |
20 | + /* 0x20: host architecture */ | |
21 | + uint8_t arch[0x10]; | |
22 | + /* 0x30: RAM/ROM description */ | |
23 | + uint64_t RAM0_base; | |
24 | + uint64_t RAM0_size; | |
25 | + uint64_t RAM1_base; | |
26 | + uint64_t RAM1_size; | |
27 | + uint64_t RAM2_base; | |
28 | + uint64_t RAM2_size; | |
29 | + uint64_t RAM3_base; | |
30 | + uint64_t RAM3_size; | |
31 | + uint64_t ROM_base; | |
32 | + uint64_t ROM_size; | |
33 | + /* 0x80: Kernel description */ | |
34 | + uint64_t kernel_image; | |
35 | + uint64_t kernel_size; | |
36 | + /* 0x90: Kernel command line */ | |
37 | + uint64_t cmdline; | |
38 | + uint64_t cmdline_size; | |
39 | + /* 0xA0: Kernel boot image */ | |
40 | + uint64_t initrd_image; | |
41 | + uint64_t initrd_size; | |
42 | + /* 0xB0: NVRAM image */ | |
43 | + uint64_t NVRAM_image; | |
44 | + uint8_t pad2[8]; | |
45 | + /* 0xC0: graphic configuration */ | |
46 | + uint16_t width; | |
47 | + uint16_t height; | |
48 | + uint16_t depth; | |
49 | + uint16_t graphic_flags; | |
50 | + /* 0xC8: CPUs description */ | |
51 | + uint8_t nb_cpus; | |
52 | + uint8_t boot_cpu; | |
53 | + uint8_t nboot_devices; | |
54 | + uint8_t pad3[5]; | |
55 | + /* 0xD0: boot devices */ | |
56 | + uint8_t boot_devices[0x10]; | |
57 | + /* 0xE0 */ | |
58 | + uint8_t pad4[0x1C]; /* 28 */ | |
59 | + /* 0xFC: checksum */ | |
60 | + uint16_t crc; | |
61 | + uint8_t pad5[0x02]; | |
62 | +} __attribute__ (( packed )); | |
63 | + | |
64 | +#define OHW_GF_NOGRAPHICS 0x0001 | |
65 | + | |
66 | +static inline uint16_t | |
67 | +OHW_crc_update (uint16_t prev, uint16_t value) | |
68 | +{ | |
69 | + uint16_t tmp; | |
70 | + uint16_t pd, pd1, pd2; | |
71 | + | |
72 | + tmp = prev >> 8; | |
73 | + pd = prev ^ value; | |
74 | + pd1 = pd & 0x000F; | |
75 | + pd2 = ((pd >> 4) & 0x000F) ^ pd1; | |
76 | + tmp ^= (pd1 << 3) | (pd1 << 8); | |
77 | + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); | |
78 | + | |
79 | + return tmp; | |
80 | +} | |
81 | + | |
82 | +static inline uint16_t | |
83 | +OHW_compute_crc (ohwcfg_v3_t *header, uint32_t start, uint32_t count) | |
84 | +{ | |
85 | + uint32_t i; | |
86 | + uint16_t crc = 0xFFFF; | |
87 | + uint8_t *ptr = (uint8_t *)header; | |
88 | + int odd; | |
89 | + | |
90 | + odd = count & 1; | |
91 | + count &= ~1; | |
92 | + for (i = 0; i != count; i++) { | |
93 | + crc = OHW_crc_update(crc, (ptr[start + i] << 8) | ptr[start + i + 1]); | |
94 | + } | |
95 | + if (odd) { | |
96 | + crc = OHW_crc_update(crc, ptr[start + i] << 8); | |
97 | + } | |
98 | + | |
99 | + return crc; | |
100 | +} | |
101 | + | |
102 | +/* Sparc32 runtime NVRAM structure for SMP CPU boot */ | |
103 | +struct sparc_arch_cfg { | |
104 | + uint32_t smp_ctx; | |
105 | + uint32_t smp_ctxtbl; | |
106 | + uint32_t smp_entry; | |
107 | + uint8_t valid; | |
108 | + uint8_t unused[51]; | |
109 | +}; | |
110 | + | |
111 | +/* OpenBIOS NVRAM partition */ | |
112 | +struct OpenBIOS_nvpart_v1 { | |
113 | + uint8_t signature; | |
114 | + uint8_t checksum; | |
115 | + uint16_t len; // BE, length divided by 16 | |
116 | + char name[12]; | |
117 | +}; | |
118 | + | |
119 | +#define OPENBIOS_PART_SYSTEM 0x70 | |
120 | +#define OPENBIOS_PART_FREE 0x7f | |
121 | + | |
122 | +static inline void | |
123 | +OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size) | |
124 | +{ | |
125 | + unsigned int i, sum; | |
126 | + uint8_t *tmpptr; | |
127 | + | |
128 | + // Length divided by 16 | |
129 | + header->len = cpu_to_be16(size >> 4); | |
130 | + | |
131 | + // Checksum | |
132 | + tmpptr = (uint8_t *)header; | |
133 | + sum = *tmpptr; | |
134 | + for (i = 0; i < 14; i++) { | |
135 | + sum += tmpptr[2 + i]; | |
136 | + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
137 | + } | |
138 | + header->checksum = sum & 0xff; | |
139 | +} | |
140 | + | |
141 | +static inline uint32_t | |
142 | +OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const unsigned char *str) | |
143 | +{ | |
144 | + uint32_t len; | |
145 | + | |
146 | + len = strlen(str) + 1; | |
147 | + memcpy(&nvram[addr], str, len); | |
148 | + | |
149 | + return addr + len; | |
150 | +} | |
151 | + | |
152 | +/* Sun IDPROM structure at the end of NVRAM */ | |
153 | +struct Sun_nvram { | |
154 | + uint8_t type; | |
155 | + uint8_t machine_id; | |
156 | + uint8_t macaddr[6]; | |
157 | + uint8_t unused[7]; | |
158 | + uint8_t checksum; | |
159 | +}; | |
160 | + | |
161 | +static inline void | |
162 | +Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id) | |
163 | +{ | |
164 | + uint8_t tmp, *tmpptr; | |
165 | + unsigned int i; | |
166 | + | |
167 | + header->type = 1; | |
168 | + header->machine_id = machine_id & 0xff; | |
169 | + memcpy(&header->macaddr, macaddr, 6); | |
170 | + /* Calculate checksum */ | |
171 | + tmp = 0; | |
172 | + tmpptr = (uint8_t *)header; | |
173 | + for (i = 0; i < 15; i++) | |
174 | + tmp ^= tmpptr[i]; | |
175 | + | |
176 | + header->checksum = tmp; | |
177 | +} | |
178 | + | |
179 | +#else /* __ASSEMBLY__ */ | |
180 | + | |
181 | +/* Structure offsets for asm use */ | |
182 | + | |
183 | +/* Open Hack'Ware NVRAM configuration structure */ | |
184 | +#define OHW_ARCH_PTR 0x18 | |
185 | +#define OHW_RAM_SIZE 0x38 | |
186 | +#define OHW_BOOT_CPU 0xC9 | |
187 | + | |
188 | +/* Sparc32 runtime NVRAM structure for SMP CPU boot */ | |
189 | +#define SPARC_SMP_CTX 0x0 | |
190 | +#define SPARC_SMP_CTXTBL 0x4 | |
191 | +#define SPARC_SMP_ENTRY 0x8 | |
192 | +#define SPARC_SMP_VALID 0xc | |
193 | + | |
194 | +/* Sun IDPROM structure at the end of NVRAM */ | |
195 | +#define SPARC_MACHINE_ID 0x1fd9 | |
196 | + | |
197 | +#endif /* __ASSEMBLY__ */ | |
198 | +#endif /* FIRMWARE_ABI_H */ | ... | ... |
hw/sun4m.c
... | ... | @@ -22,6 +22,9 @@ |
22 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | +#include "m48t59.h" | |
26 | +#include "firmware_abi.h" | |
27 | + | |
25 | 28 | //#define DEBUG_IRQ |
26 | 29 | |
27 | 30 | /* |
... | ... | @@ -102,131 +105,87 @@ void DMA_register_channel (int nchan, |
102 | 105 | { |
103 | 106 | } |
104 | 107 | |
105 | -static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) | |
106 | -{ | |
107 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
108 | - m48t59_write(nvram, addr++, value & 0xff); | |
109 | -} | |
110 | - | |
111 | -static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) | |
112 | -{ | |
113 | - m48t59_write(nvram, addr++, value >> 24); | |
114 | - m48t59_write(nvram, addr++, (value >> 16) & 0xff); | |
115 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
116 | - m48t59_write(nvram, addr++, value & 0xff); | |
117 | -} | |
118 | - | |
119 | -static void nvram_set_string (m48t59_t *nvram, uint32_t addr, | |
120 | - const unsigned char *str, uint32_t max) | |
121 | -{ | |
122 | - unsigned int i; | |
123 | - | |
124 | - for (i = 0; i < max && str[i] != '\0'; i++) { | |
125 | - m48t59_write(nvram, addr + i, str[i]); | |
126 | - } | |
127 | - m48t59_write(nvram, addr + max - 1, '\0'); | |
128 | -} | |
129 | - | |
130 | -static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
131 | - const unsigned char *str) | |
132 | -{ | |
133 | - uint32_t len; | |
134 | - | |
135 | - len = strlen(str) + 1; | |
136 | - nvram_set_string(nvram, addr, str, len); | |
137 | - | |
138 | - return addr + len; | |
139 | -} | |
140 | - | |
141 | -static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
142 | - uint32_t end) | |
143 | -{ | |
144 | - unsigned int i, sum; | |
145 | - | |
146 | - // Length divided by 16 | |
147 | - m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
148 | - m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
149 | - // Checksum | |
150 | - sum = m48t59_read(nvram, start); | |
151 | - for (i = 0; i < 14; i++) { | |
152 | - sum += m48t59_read(nvram, start + 2 + i); | |
153 | - sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
154 | - } | |
155 | - m48t59_write(nvram, start + 1, sum & 0xff); | |
156 | -} | |
157 | - | |
158 | 108 | extern int nographic; |
159 | 109 | |
160 | 110 | static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
161 | - const char *boot_device, uint32_t RAM_size, | |
111 | + const char *boot_devices, uint32_t RAM_size, | |
162 | 112 | uint32_t kernel_size, |
163 | 113 | int width, int height, int depth, |
164 | 114 | int machine_id) |
165 | 115 | { |
166 | - unsigned char tmp = 0; | |
167 | - unsigned int i, j; | |
116 | + unsigned int i; | |
168 | 117 | uint32_t start, end; |
118 | + uint8_t image[0x1ff0]; | |
119 | + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ | |
120 | + struct sparc_arch_cfg *sparc_header; | |
121 | + struct OpenBIOS_nvpart_v1 *part_header; | |
122 | + | |
123 | + memset(image, '\0', sizeof(image)); | |
169 | 124 | |
170 | 125 | // Try to match PPC NVRAM |
171 | - nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); | |
172 | - nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */ | |
173 | - // NVRAM_size, arch not applicable | |
174 | - m48t59_write(nvram, 0x2D, smp_cpus & 0xff); | |
175 | - m48t59_write(nvram, 0x2E, 0); | |
176 | - m48t59_write(nvram, 0x2F, nographic & 0xff); | |
177 | - nvram_set_lword(nvram, 0x30, RAM_size); | |
178 | - m48t59_write(nvram, 0x34, boot_device[0] & 0xff); | |
179 | - nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR); | |
180 | - nvram_set_lword(nvram, 0x3C, kernel_size); | |
126 | + strcpy(header->struct_ident, "QEMU_BIOS"); | |
127 | + header->struct_version = cpu_to_be32(3); /* structure v3 */ | |
128 | + | |
129 | + header->nvram_size = cpu_to_be16(0x2000); | |
130 | + header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); | |
131 | + header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); | |
132 | + strcpy(header->arch, "sun4m"); | |
133 | + header->nb_cpus = smp_cpus & 0xff; | |
134 | + header->RAM0_base = 0; | |
135 | + header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); | |
136 | + strcpy(header->boot_devices, boot_devices); | |
137 | + header->nboot_devices = strlen(boot_devices) & 0xff; | |
138 | + header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); | |
139 | + header->kernel_size = cpu_to_be64((uint64_t)kernel_size); | |
181 | 140 | if (cmdline) { |
182 | 141 | strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); |
183 | - nvram_set_lword(nvram, 0x40, CMDLINE_ADDR); | |
184 | - nvram_set_lword(nvram, 0x44, strlen(cmdline)); | |
142 | + header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); | |
143 | + header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); | |
185 | 144 | } |
186 | - // initrd_image, initrd_size passed differently | |
187 | - nvram_set_word(nvram, 0x54, width); | |
188 | - nvram_set_word(nvram, 0x56, height); | |
189 | - nvram_set_word(nvram, 0x58, depth); | |
145 | + // XXX add initrd_image, initrd_size | |
146 | + header->width = cpu_to_be16(width); | |
147 | + header->height = cpu_to_be16(height); | |
148 | + header->depth = cpu_to_be16(depth); | |
149 | + if (nographic) | |
150 | + header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); | |
151 | + | |
152 | + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); | |
153 | + | |
154 | + // Architecture specific header | |
155 | + start = sizeof(ohwcfg_v3_t); | |
156 | + sparc_header = (struct sparc_arch_cfg *)&image[start]; | |
157 | + sparc_header->valid = 0; | |
158 | + start += sizeof(struct sparc_arch_cfg); | |
190 | 159 | |
191 | 160 | // OpenBIOS nvram variables |
192 | 161 | // Variable partition |
193 | - start = 252; | |
194 | - m48t59_write(nvram, start, 0x70); | |
195 | - nvram_set_string(nvram, start + 4, "system", 12); | |
162 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
163 | + part_header->signature = OPENBIOS_PART_SYSTEM; | |
164 | + strcpy(part_header->name, "system"); | |
196 | 165 | |
197 | - end = start + 16; | |
166 | + end = start + sizeof(struct OpenBIOS_nvpart_v1); | |
198 | 167 | for (i = 0; i < nb_prom_envs; i++) |
199 | - end = nvram_set_var(nvram, end, prom_envs[i]); | |
168 | + end = OpenBIOS_set_var(image, end, prom_envs[i]); | |
169 | + | |
170 | + // End marker | |
171 | + image[end++] = '\0'; | |
200 | 172 | |
201 | - m48t59_write(nvram, end++ , 0); | |
202 | 173 | end = start + ((end - start + 15) & ~15); |
203 | - nvram_finish_partition(nvram, start, end); | |
174 | + OpenBIOS_finish_partition(part_header, end - start); | |
204 | 175 | |
205 | 176 | // free partition |
206 | 177 | start = end; |
207 | - m48t59_write(nvram, start, 0x7f); | |
208 | - nvram_set_string(nvram, start + 4, "free", 12); | |
178 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
179 | + part_header->signature = OPENBIOS_PART_FREE; | |
180 | + strcpy(part_header->name, "free"); | |
209 | 181 | |
210 | 182 | end = 0x1fd0; |
211 | - nvram_finish_partition(nvram, start, end); | |
212 | - | |
213 | - // Sun4m specific use | |
214 | - start = i = 0x1fd8; | |
215 | - m48t59_write(nvram, i++, 0x01); | |
216 | - m48t59_write(nvram, i++, machine_id); | |
217 | - j = 0; | |
218 | - m48t59_write(nvram, i++, macaddr[j++]); | |
219 | - m48t59_write(nvram, i++, macaddr[j++]); | |
220 | - m48t59_write(nvram, i++, macaddr[j++]); | |
221 | - m48t59_write(nvram, i++, macaddr[j++]); | |
222 | - m48t59_write(nvram, i++, macaddr[j++]); | |
223 | - m48t59_write(nvram, i, macaddr[j]); | |
224 | - | |
225 | - /* Calculate checksum */ | |
226 | - for (i = start; i < start + 15; i++) { | |
227 | - tmp ^= m48t59_read(nvram, i); | |
228 | - } | |
229 | - m48t59_write(nvram, start + 15, tmp); | |
183 | + OpenBIOS_finish_partition(part_header, end - start); | |
184 | + | |
185 | + Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id); | |
186 | + | |
187 | + for (i = 0; i < sizeof(image); i++) | |
188 | + m48t59_write(nvram, i, image[i]); | |
230 | 189 | } |
231 | 190 | |
232 | 191 | static void *slavio_intctl; | ... | ... |
hw/sun4u.c
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | 25 | #include "m48t59.h" |
26 | +#include "firmware_abi.h" | |
26 | 27 | |
27 | 28 | #define KERNEL_LOAD_ADDR 0x00404000 |
28 | 29 | #define CMDLINE_ADDR 0x003ff000 |
... | ... | @@ -66,179 +67,91 @@ void DMA_register_channel (int nchan, |
66 | 67 | { |
67 | 68 | } |
68 | 69 | |
69 | -/* NVRAM helpers */ | |
70 | -static void nvram_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value) | |
71 | -{ | |
72 | - m48t59_write(nvram, addr, value); | |
73 | -} | |
74 | - | |
75 | -static uint8_t nvram_get_byte (m48t59_t *nvram, uint32_t addr) | |
76 | -{ | |
77 | - return m48t59_read(nvram, addr); | |
78 | -} | |
79 | - | |
80 | -static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) | |
81 | -{ | |
82 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
83 | - m48t59_write(nvram, addr++, value & 0xff); | |
84 | -} | |
85 | - | |
86 | -static uint16_t nvram_get_word (m48t59_t *nvram, uint32_t addr) | |
87 | -{ | |
88 | - uint16_t tmp; | |
89 | - | |
90 | - tmp = m48t59_read(nvram, addr) << 8; | |
91 | - tmp |= m48t59_read(nvram, addr + 1); | |
92 | - | |
93 | - return tmp; | |
94 | -} | |
95 | - | |
96 | -static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) | |
97 | -{ | |
98 | - m48t59_write(nvram, addr++, value >> 24); | |
99 | - m48t59_write(nvram, addr++, (value >> 16) & 0xff); | |
100 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
101 | - m48t59_write(nvram, addr++, value & 0xff); | |
102 | -} | |
103 | - | |
104 | -static void nvram_set_string (m48t59_t *nvram, uint32_t addr, | |
105 | - const unsigned char *str, uint32_t max) | |
106 | -{ | |
107 | - unsigned int i; | |
108 | - | |
109 | - for (i = 0; i < max && str[i] != '\0'; i++) { | |
110 | - m48t59_write(nvram, addr + i, str[i]); | |
111 | - } | |
112 | - m48t59_write(nvram, addr + max - 1, '\0'); | |
113 | -} | |
114 | - | |
115 | -static uint16_t nvram_crc_update (uint16_t prev, uint16_t value) | |
116 | -{ | |
117 | - uint16_t tmp; | |
118 | - uint16_t pd, pd1, pd2; | |
119 | - | |
120 | - tmp = prev >> 8; | |
121 | - pd = prev ^ value; | |
122 | - pd1 = pd & 0x000F; | |
123 | - pd2 = ((pd >> 4) & 0x000F) ^ pd1; | |
124 | - tmp ^= (pd1 << 3) | (pd1 << 8); | |
125 | - tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); | |
126 | - | |
127 | - return tmp; | |
128 | -} | |
129 | - | |
130 | -static uint16_t nvram_compute_crc (m48t59_t *nvram, uint32_t start, | |
131 | - uint32_t count) | |
132 | -{ | |
133 | - uint32_t i; | |
134 | - uint16_t crc = 0xFFFF; | |
135 | - int odd; | |
136 | - | |
137 | - odd = count & 1; | |
138 | - count &= ~1; | |
139 | - for (i = 0; i != count; i++) { | |
140 | - crc = nvram_crc_update(crc, nvram_get_word(nvram, start + i)); | |
141 | - } | |
142 | - if (odd) { | |
143 | - crc = nvram_crc_update(crc, nvram_get_byte(nvram, start + i) << 8); | |
144 | - } | |
145 | - | |
146 | - return crc; | |
147 | -} | |
148 | - | |
149 | -static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
150 | - const unsigned char *str) | |
151 | -{ | |
152 | - uint32_t len; | |
153 | - | |
154 | - len = strlen(str) + 1; | |
155 | - nvram_set_string(nvram, addr, str, len); | |
156 | - | |
157 | - return addr + len; | |
158 | -} | |
159 | - | |
160 | -static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
161 | - uint32_t end) | |
162 | -{ | |
163 | - unsigned int i, sum; | |
164 | - | |
165 | - // Length divided by 16 | |
166 | - m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
167 | - m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
168 | - // Checksum | |
169 | - sum = m48t59_read(nvram, start); | |
170 | - for (i = 0; i < 14; i++) { | |
171 | - sum += m48t59_read(nvram, start + 2 + i); | |
172 | - sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
173 | - } | |
174 | - m48t59_write(nvram, start + 1, sum & 0xff); | |
175 | -} | |
176 | - | |
177 | 70 | extern int nographic; |
178 | 71 | |
179 | -int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | |
180 | - const unsigned char *arch, | |
181 | - uint32_t RAM_size, int boot_device, | |
182 | - uint32_t kernel_image, uint32_t kernel_size, | |
183 | - const char *cmdline, | |
184 | - uint32_t initrd_image, uint32_t initrd_size, | |
185 | - uint32_t NVRAM_image, | |
186 | - int width, int height, int depth) | |
72 | +static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | |
73 | + const unsigned char *arch, | |
74 | + uint32_t RAM_size, const char *boot_devices, | |
75 | + uint32_t kernel_image, uint32_t kernel_size, | |
76 | + const char *cmdline, | |
77 | + uint32_t initrd_image, uint32_t initrd_size, | |
78 | + uint32_t NVRAM_image, | |
79 | + int width, int height, int depth) | |
187 | 80 | { |
188 | - uint16_t crc; | |
189 | 81 | unsigned int i; |
190 | 82 | uint32_t start, end; |
191 | - | |
192 | - /* Set parameters for Open Hack'Ware BIOS */ | |
193 | - nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); | |
194 | - nvram_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */ | |
195 | - nvram_set_word(nvram, 0x14, NVRAM_size); | |
196 | - nvram_set_string(nvram, 0x20, arch, 16); | |
197 | - nvram_set_byte(nvram, 0x2f, nographic & 0xff); | |
198 | - nvram_set_lword(nvram, 0x30, RAM_size); | |
199 | - nvram_set_byte(nvram, 0x34, boot_device); | |
200 | - nvram_set_lword(nvram, 0x38, kernel_image); | |
201 | - nvram_set_lword(nvram, 0x3C, kernel_size); | |
83 | + uint8_t image[0x1ff0]; | |
84 | + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ | |
85 | + struct sparc_arch_cfg *sparc_header; | |
86 | + struct OpenBIOS_nvpart_v1 *part_header; | |
87 | + | |
88 | + memset(image, '\0', sizeof(image)); | |
89 | + | |
90 | + // Try to match PPC NVRAM | |
91 | + strcpy(header->struct_ident, "QEMU_BIOS"); | |
92 | + header->struct_version = cpu_to_be32(3); /* structure v3 */ | |
93 | + | |
94 | + header->nvram_size = cpu_to_be16(NVRAM_size); | |
95 | + header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); | |
96 | + header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); | |
97 | + strcpy(header->arch, arch); | |
98 | + header->nb_cpus = smp_cpus & 0xff; | |
99 | + header->RAM0_base = 0; | |
100 | + header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); | |
101 | + strcpy(header->boot_devices, boot_devices); | |
102 | + header->nboot_devices = strlen(boot_devices) & 0xff; | |
103 | + header->kernel_image = cpu_to_be64((uint64_t)kernel_image); | |
104 | + header->kernel_size = cpu_to_be64((uint64_t)kernel_size); | |
202 | 105 | if (cmdline) { |
203 | - /* XXX: put the cmdline in NVRAM too ? */ | |
204 | 106 | strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); |
205 | - nvram_set_lword(nvram, 0x40, CMDLINE_ADDR); | |
206 | - nvram_set_lword(nvram, 0x44, strlen(cmdline)); | |
207 | - } else { | |
208 | - nvram_set_lword(nvram, 0x40, 0); | |
209 | - nvram_set_lword(nvram, 0x44, 0); | |
107 | + header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); | |
108 | + header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); | |
210 | 109 | } |
211 | - nvram_set_lword(nvram, 0x48, initrd_image); | |
212 | - nvram_set_lword(nvram, 0x4C, initrd_size); | |
213 | - nvram_set_lword(nvram, 0x50, NVRAM_image); | |
110 | + header->initrd_image = cpu_to_be64((uint64_t)initrd_image); | |
111 | + header->initrd_size = cpu_to_be64((uint64_t)initrd_size); | |
112 | + header->NVRAM_image = cpu_to_be64((uint64_t)NVRAM_image); | |
113 | + | |
114 | + header->width = cpu_to_be16(width); | |
115 | + header->height = cpu_to_be16(height); | |
116 | + header->depth = cpu_to_be16(depth); | |
117 | + if (nographic) | |
118 | + header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); | |
214 | 119 | |
215 | - nvram_set_word(nvram, 0x54, width); | |
216 | - nvram_set_word(nvram, 0x56, height); | |
217 | - nvram_set_word(nvram, 0x58, depth); | |
218 | - crc = nvram_compute_crc(nvram, 0x00, 0xF8); | |
219 | - nvram_set_word(nvram, 0xFC, crc); | |
120 | + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); | |
121 | + | |
122 | + // Architecture specific header | |
123 | + start = sizeof(ohwcfg_v3_t); | |
124 | + sparc_header = (struct sparc_arch_cfg *)&image[start]; | |
125 | + sparc_header->valid = 0; | |
126 | + start += sizeof(struct sparc_arch_cfg); | |
220 | 127 | |
221 | 128 | // OpenBIOS nvram variables |
222 | 129 | // Variable partition |
223 | - start = 256; | |
224 | - m48t59_write(nvram, start, 0x70); | |
225 | - nvram_set_string(nvram, start + 4, "system", 12); | |
130 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
131 | + part_header->signature = OPENBIOS_PART_SYSTEM; | |
132 | + strcpy(part_header->name, "system"); | |
226 | 133 | |
227 | - end = start + 16; | |
134 | + end = start + sizeof(struct OpenBIOS_nvpart_v1); | |
228 | 135 | for (i = 0; i < nb_prom_envs; i++) |
229 | - end = nvram_set_var(nvram, end, prom_envs[i]); | |
136 | + end = OpenBIOS_set_var(image, end, prom_envs[i]); | |
137 | + | |
138 | + // End marker | |
139 | + image[end++] = '\0'; | |
230 | 140 | |
231 | - m48t59_write(nvram, end++ , 0); | |
232 | 141 | end = start + ((end - start + 15) & ~15); |
233 | - nvram_finish_partition(nvram, start, end); | |
142 | + OpenBIOS_finish_partition(part_header, end - start); | |
234 | 143 | |
235 | 144 | // free partition |
236 | 145 | start = end; |
237 | - m48t59_write(nvram, start, 0x7f); | |
238 | - nvram_set_string(nvram, start + 4, "free", 12); | |
146 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
147 | + part_header->signature = OPENBIOS_PART_FREE; | |
148 | + strcpy(part_header->name, "free"); | |
239 | 149 | |
240 | 150 | end = 0x1fd0; |
241 | - nvram_finish_partition(nvram, start, end); | |
151 | + OpenBIOS_finish_partition(part_header, end - start); | |
152 | + | |
153 | + for (i = 0; i < sizeof(image); i++) | |
154 | + m48t59_write(nvram, i, image[i]); | |
242 | 155 | |
243 | 156 | return 0; |
244 | 157 | } |
... | ... | @@ -306,7 +219,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; |
306 | 219 | static fdctrl_t *floppy_controller; |
307 | 220 | |
308 | 221 | /* Sun4u hardware initialisation */ |
309 | -static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device, | |
222 | +static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_devices, | |
310 | 223 | DisplayState *ds, const char **fd_filename, int snapshot, |
311 | 224 | const char *kernel_filename, const char *kernel_cmdline, |
312 | 225 | const char *initrd_filename, const char *cpu_model) |
... | ... | @@ -428,7 +341,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device, |
428 | 341 | i8042_init(NULL/*1*/, NULL/*12*/, 0x60); |
429 | 342 | floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); |
430 | 343 | nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); |
431 | - sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device[0], | |
344 | + sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_devices, | |
432 | 345 | KERNEL_LOAD_ADDR, kernel_size, |
433 | 346 | kernel_cmdline, |
434 | 347 | INITRD_LOAD_ADDR, initrd_size, | ... | ... |