Revision d2c63fc1
b/hw/firmware_abi.h | ||
---|---|---|
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 */ |
b/hw/sun4m.c | ||
---|---|---|
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 | 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; |
b/hw/sun4u.c | ||
---|---|---|
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 | 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 | 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 | 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, |
Also available in: Unified diff