Revision d2c63fc1 hw/sun4m.c
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; |
Also available in: Unified diff