Commit d2c63fc185f3d126ef177105166a491ab3556f5c

Authored by blueswir1
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
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,6 +22,9 @@
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
  25 +#include "m48t59.h"
  26 +#include "firmware_abi.h"
  27 +
25 //#define DEBUG_IRQ 28 //#define DEBUG_IRQ
26 29
27 /* 30 /*
@@ -102,131 +105,87 @@ void DMA_register_channel (int nchan, @@ -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 extern int nographic; 108 extern int nographic;
159 109
160 static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, 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 uint32_t kernel_size, 112 uint32_t kernel_size,
163 int width, int height, int depth, 113 int width, int height, int depth,
164 int machine_id) 114 int machine_id)
165 { 115 {
166 - unsigned char tmp = 0;  
167 - unsigned int i, j; 116 + unsigned int i;
168 uint32_t start, end; 117 uint32_t start, end;
  118 + uint8_t image[0x1ff0];
  119 + ohwcfg_v3_t *header = (ohwcfg_v3_t *)&image;
  120 + struct sparc_arch_cfg *sparc_header;
  121 + struct OpenBIOS_nvpart_v1 *part_header;
  122 +
  123 + memset(image, '\0', sizeof(image));
169 124
170 // Try to match PPC NVRAM 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 if (cmdline) { 140 if (cmdline) {
182 strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); 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 // OpenBIOS nvram variables 160 // OpenBIOS nvram variables
192 // Variable partition 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 for (i = 0; i < nb_prom_envs; i++) 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 end = start + ((end - start + 15) & ~15); 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 // free partition 176 // free partition
206 start = end; 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 end = 0x1fd0; 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 static void *slavio_intctl; 191 static void *slavio_intctl;
hw/sun4u.c
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 */ 23 */
24 #include "vl.h" 24 #include "vl.h"
25 #include "m48t59.h" 25 #include "m48t59.h"
  26 +#include "firmware_abi.h"
26 27
27 #define KERNEL_LOAD_ADDR 0x00404000 28 #define KERNEL_LOAD_ADDR 0x00404000
28 #define CMDLINE_ADDR 0x003ff000 29 #define CMDLINE_ADDR 0x003ff000
@@ -66,179 +67,91 @@ void DMA_register_channel (int nchan, @@ -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 extern int nographic; 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 unsigned int i; 81 unsigned int i;
190 uint32_t start, end; 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 *)&image;
  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 if (cmdline) { 105 if (cmdline) {
203 - /* XXX: put the cmdline in NVRAM too ? */  
204 strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); 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 // OpenBIOS nvram variables 128 // OpenBIOS nvram variables
222 // Variable partition 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 for (i = 0; i < nb_prom_envs; i++) 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 end = start + ((end - start + 15) & ~15); 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 // free partition 144 // free partition
236 start = end; 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 end = 0x1fd0; 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 return 0; 156 return 0;
244 } 157 }
@@ -306,7 +219,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; @@ -306,7 +219,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
306 static fdctrl_t *floppy_controller; 219 static fdctrl_t *floppy_controller;
307 220
308 /* Sun4u hardware initialisation */ 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 DisplayState *ds, const char **fd_filename, int snapshot, 223 DisplayState *ds, const char **fd_filename, int snapshot,
311 const char *kernel_filename, const char *kernel_cmdline, 224 const char *kernel_filename, const char *kernel_cmdline,
312 const char *initrd_filename, const char *cpu_model) 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,7 +341,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device,
428 i8042_init(NULL/*1*/, NULL/*12*/, 0x60); 341 i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
429 floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); 342 floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table);
430 nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); 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 KERNEL_LOAD_ADDR, kernel_size, 345 KERNEL_LOAD_ADDR, kernel_size,
433 kernel_cmdline, 346 kernel_cmdline,
434 INITRD_LOAD_ADDR, initrd_size, 347 INITRD_LOAD_ADDR, initrd_size,