25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: machine.c,v 1.470 2005/06/26 11:36:28 debug Exp $ |
* $Id: machine.c,v 1.515 2005/08/16 09:16:26 debug Exp $ |
29 |
* |
* |
30 |
* Emulation of specific machines. |
* Emulation of specific machines. |
31 |
* |
* |
53 |
#include "arcbios.h" |
#include "arcbios.h" |
54 |
#include "bus_pci.h" |
#include "bus_pci.h" |
55 |
#include "cpu.h" |
#include "cpu.h" |
|
#include "cpu_mips.h" |
|
56 |
#include "device.h" |
#include "device.h" |
57 |
#include "devices.h" |
#include "devices.h" |
58 |
#include "diskimage.h" |
#include "diskimage.h" |
64 |
#include "net.h" |
#include "net.h" |
65 |
#include "symbol.h" |
#include "symbol.h" |
66 |
|
|
67 |
|
/* For Alpha emulation: */ |
68 |
|
#include "alpha_rpb.h" |
69 |
|
|
70 |
/* For SGI and ARC emulation: */ |
/* For SGI and ARC emulation: */ |
71 |
#include "sgi_arcbios.h" |
#include "sgi_arcbios.h" |
72 |
#include "crimereg.h" |
#include "crimereg.h" |
73 |
|
|
74 |
|
/* For evbmips emulation: */ |
75 |
|
#include "maltareg.h" |
76 |
|
|
77 |
/* For DECstation emulation: */ |
/* For DECstation emulation: */ |
78 |
#include "dec_prom.h" |
#include "dec_prom.h" |
79 |
#include "dec_bootinfo.h" |
#include "dec_bootinfo.h" |
152 |
m->bintrans_enable = 1; |
m->bintrans_enable = 1; |
153 |
m->old_bintrans_enable = 1; |
m->old_bintrans_enable = 1; |
154 |
#endif |
#endif |
155 |
|
m->arch_pagesize = 4096; /* Should be overriden in |
156 |
|
emul.c for other pagesizes. */ |
157 |
|
m->dyntrans_alignment_check = 1; |
158 |
m->prom_emulation = 1; |
m->prom_emulation = 1; |
159 |
m->speed_tricks = 1; |
m->speed_tricks = 1; |
160 |
m->byte_order_override = NO_BYTE_ORDER_OVERRIDE; |
m->byte_order_override = NO_BYTE_ORDER_OVERRIDE; |
185 |
int *type, int *subtype, int *arch) |
int *type, int *subtype, int *arch) |
186 |
{ |
{ |
187 |
struct machine_entry *me; |
struct machine_entry *me; |
188 |
int i, j, k; |
int i, j, k, nmatches = 0; |
189 |
|
|
190 |
*type = MACHINE_NONE; |
*type = MACHINE_NONE; |
191 |
*subtype = 0; |
*subtype = 0; |
192 |
|
|
193 |
|
/* Check stype, and optionally ssubtype: */ |
194 |
me = first_machine_entry; |
me = first_machine_entry; |
195 |
while (me != NULL) { |
while (me != NULL) { |
196 |
for (i=0; i<me->n_aliases; i++) |
for (i=0; i<me->n_aliases; i++) |
225 |
me = me->next; |
me = me->next; |
226 |
} |
} |
227 |
|
|
228 |
fatal("\nSorry, emulation \"%s\"", stype); |
/* Not found? Then just check ssubtype: */ |
229 |
if (ssubtype != NULL && ssubtype[0] != '\0') |
me = first_machine_entry; |
230 |
fatal(" (subtype \"%s\")", ssubtype); |
while (me != NULL) { |
231 |
fatal(" is unknown.\n"); |
if (me->n_subtypes == 0) { |
232 |
fatal("Use the -H command line option to get a list of available" |
me = me->next; |
233 |
" types and subtypes.\n\n"); |
continue; |
234 |
|
} |
235 |
|
|
236 |
|
/* Check for subtype: */ |
237 |
|
for (j=0; j<me->n_subtypes; j++) |
238 |
|
for (k=0; k<me->subtype[j]->n_aliases; k++) |
239 |
|
if (strcasecmp(ssubtype, me->subtype[j]-> |
240 |
|
aliases[k]) == 0) { |
241 |
|
*type = me->machine_type; |
242 |
|
*arch = me->arch; |
243 |
|
*subtype = me->subtype[j]-> |
244 |
|
machine_subtype; |
245 |
|
nmatches ++; |
246 |
|
} |
247 |
|
|
248 |
|
me = me->next; |
249 |
|
} |
250 |
|
|
251 |
|
switch (nmatches) { |
252 |
|
case 0: fatal("\nSorry, emulation \"%s\"", stype); |
253 |
|
if (ssubtype != NULL && ssubtype[0] != '\0') |
254 |
|
fatal(" (subtype \"%s\")", ssubtype); |
255 |
|
fatal(" is unknown.\n"); |
256 |
|
break; |
257 |
|
case 1: return 1; |
258 |
|
default:fatal("\nSorry, multiple matches for \"%s\"", stype); |
259 |
|
if (ssubtype != NULL && ssubtype[0] != '\0') |
260 |
|
fatal(" (subtype \"%s\")", ssubtype); |
261 |
|
fatal(".\n"); |
262 |
|
} |
263 |
|
|
264 |
|
*type = MACHINE_NONE; |
265 |
|
*subtype = 0; |
266 |
|
|
267 |
|
fatal("Use the -H command line option to get a list of " |
268 |
|
"available types and subtypes.\n\n"); |
269 |
|
|
270 |
return 0; |
return 0; |
271 |
} |
} |
272 |
|
|
388 |
|
|
389 |
|
|
390 |
/* |
/* |
391 |
|
* add_environment_string_dual(): |
392 |
|
* |
393 |
|
* Add "dual" environment strings, one for the variable name and one for the |
394 |
|
* value, and update pointers afterwards. |
395 |
|
*/ |
396 |
|
void add_environment_string_dual(struct cpu *cpu, |
397 |
|
uint64_t *ptrp, uint64_t *addrp, char *s1, char *s2) |
398 |
|
{ |
399 |
|
uint64_t ptr = *ptrp, addr = *addrp; |
400 |
|
|
401 |
|
store_32bit_word(cpu, ptr, addr); |
402 |
|
ptr += sizeof(uint32_t); |
403 |
|
if (addr != 0) { |
404 |
|
store_string(cpu, addr, s1); |
405 |
|
addr += strlen(s1) + 1; |
406 |
|
} |
407 |
|
store_32bit_word(cpu, ptr, addr); |
408 |
|
ptr += sizeof(uint32_t); |
409 |
|
if (addr != 0) { |
410 |
|
store_string(cpu, addr, s2); |
411 |
|
addr += strlen(s2) + 1; |
412 |
|
} |
413 |
|
|
414 |
|
*ptrp = ptr; |
415 |
|
*addrp = addr; |
416 |
|
} |
417 |
|
|
418 |
|
|
419 |
|
/* |
420 |
* store_64bit_word(): |
* store_64bit_word(): |
421 |
* |
* |
422 |
* Stores a 64-bit word in emulated RAM. Byte order is taken into account. |
* Stores a 64-bit word in emulated RAM. Byte order is taken into account. |
1305 |
|
|
1306 |
if (irq_nr < 8) { |
if (irq_nr < 8) { |
1307 |
if (assrt) |
if (assrt) |
1308 |
m->md_int.malta_data->assert_lo |= mask; |
m->md_int.isa_pic_data.pic1->irr |= mask; |
1309 |
else |
else |
1310 |
m->md_int.malta_data->assert_lo &= ~mask; |
m->md_int.isa_pic_data.pic1->irr &= ~mask; |
1311 |
} else if (irq_nr < 16) { |
} else if (irq_nr < 16) { |
1312 |
if (assrt) |
if (assrt) |
1313 |
m->md_int.malta_data->assert_hi |= mask; |
m->md_int.isa_pic_data.pic2->irr |= mask; |
1314 |
else |
else |
1315 |
m->md_int.malta_data->assert_hi &= ~mask; |
m->md_int.isa_pic_data.pic2->irr &= ~mask; |
1316 |
} |
} |
1317 |
|
|
1318 |
/* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ |
/* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ |
1319 |
if (m->md_int.malta_data->assert_hi & |
/* (TODO: don't hardcode this here) */ |
1320 |
~m->md_int.malta_data->disable_hi) |
if (m->md_int.isa_pic_data.pic2->irr & |
1321 |
m->md_int.malta_data->assert_lo |= 0x04; |
~m->md_int.isa_pic_data.pic2->ier) |
1322 |
|
m->md_int.isa_pic_data.pic1->irr |= 0x04; |
1323 |
else |
else |
1324 |
m->md_int.malta_data->assert_lo &= ~0x04; |
m->md_int.isa_pic_data.pic1->irr &= ~0x04; |
1325 |
|
|
1326 |
/* Now, PIC1: */ |
/* Now, PIC1: */ |
1327 |
if (m->md_int.malta_data->assert_lo & |
if (m->md_int.isa_pic_data.pic1->irr & |
1328 |
~m->md_int.malta_data->disable_lo) |
~m->md_int.isa_pic_data.pic1->ier) |
1329 |
cpu_interrupt(cpu, 2); |
cpu_interrupt(cpu, 2); |
1330 |
else |
else |
1331 |
cpu_interrupt_ack(cpu, 2); |
cpu_interrupt_ack(cpu, 2); |
1332 |
|
|
1333 |
|
/* printf("MALTA: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x " |
1334 |
|
"ier=0x%02x\n", m->md_int.isa_pic_data.pic1->irr, |
1335 |
|
m->md_int.isa_pic_data.pic1->ier, |
1336 |
|
m->md_int.isa_pic_data.pic2->irr, |
1337 |
|
m->md_int.isa_pic_data.pic2->ier); */ |
1338 |
|
} |
1339 |
|
|
1340 |
|
|
1341 |
|
/* |
1342 |
|
* Cobalt interrupts: |
1343 |
|
* |
1344 |
|
* (irq_nr = 8 + 16 can be used to just reassert/deassert interrupts.) |
1345 |
|
*/ |
1346 |
|
void cobalt_interrupt(struct machine *m, struct cpu *cpu, int irq_nr, int assrt) |
1347 |
|
{ |
1348 |
|
int mask; |
1349 |
|
|
1350 |
|
irq_nr -= 8; |
1351 |
|
mask = 1 << (irq_nr & 7); |
1352 |
|
|
1353 |
|
if (irq_nr < 8) { |
1354 |
|
if (assrt) |
1355 |
|
m->md_int.isa_pic_data.pic1->irr |= mask; |
1356 |
|
else |
1357 |
|
m->md_int.isa_pic_data.pic1->irr &= ~mask; |
1358 |
|
} else if (irq_nr < 16) { |
1359 |
|
if (assrt) |
1360 |
|
m->md_int.isa_pic_data.pic2->irr |= mask; |
1361 |
|
else |
1362 |
|
m->md_int.isa_pic_data.pic2->irr &= ~mask; |
1363 |
|
} |
1364 |
|
|
1365 |
|
/* Any interrupt assertions on PIC2 go to irq 2 on PIC1 */ |
1366 |
|
/* (TODO: don't hardcode this here) */ |
1367 |
|
if (m->md_int.isa_pic_data.pic2->irr & |
1368 |
|
~m->md_int.isa_pic_data.pic2->ier) |
1369 |
|
m->md_int.isa_pic_data.pic1->irr |= 0x04; |
1370 |
|
else |
1371 |
|
m->md_int.isa_pic_data.pic1->irr &= ~0x04; |
1372 |
|
|
1373 |
|
/* Now, PIC1: */ |
1374 |
|
if (m->md_int.isa_pic_data.pic1->irr & |
1375 |
|
~m->md_int.isa_pic_data.pic1->ier) |
1376 |
|
cpu_interrupt(cpu, 6); |
1377 |
|
else |
1378 |
|
cpu_interrupt_ack(cpu, 6); |
1379 |
|
|
1380 |
|
/* printf("COBALT: pic1.irr=0x%02x ier=0x%02x pic2.irr=0x%02x " |
1381 |
|
"ier=0x%02x\n", m->md_int.isa_pic_data.pic1->irr, |
1382 |
|
m->md_int.isa_pic_data.pic1->ier, |
1383 |
|
m->md_int.isa_pic_data.pic2->irr, |
1384 |
|
m->md_int.isa_pic_data.pic2->ier); */ |
1385 |
} |
} |
1386 |
|
|
1387 |
|
|
1447 |
int i, j; |
int i, j; |
1448 |
struct memory *mem; |
struct memory *mem; |
1449 |
char tmpstr[1000]; |
char tmpstr[1000]; |
1450 |
|
struct cons_data *cons_data; |
1451 |
|
|
1452 |
/* DECstation: */ |
/* DECstation: */ |
1453 |
char *framebuffer_console_name, *serial_console_name; |
char *framebuffer_console_name, *serial_console_name; |
1520 |
printf("\nNo emulation type specified.\n"); |
printf("\nNo emulation type specified.\n"); |
1521 |
exit(1); |
exit(1); |
1522 |
|
|
1523 |
|
#ifdef ENABLE_MIPS |
1524 |
case MACHINE_BAREMIPS: |
case MACHINE_BAREMIPS: |
1525 |
/* |
/* |
1526 |
* A "bare" MIPS test machine. |
* A "bare" MIPS test machine. |
1535 |
/* |
/* |
1536 |
* A MIPS test machine (which happens to work with the |
* A MIPS test machine (which happens to work with the |
1537 |
* code in my master's thesis). :-) |
* code in my master's thesis). :-) |
1538 |
|
* |
1539 |
|
* IRQ map: |
1540 |
|
* 7 CPU counter |
1541 |
|
* 6 SMP IPIs |
1542 |
|
* 5 not used yet |
1543 |
|
* 4 not used yet |
1544 |
|
* 3 ethernet |
1545 |
|
* 2 serial console |
1546 |
*/ |
*/ |
1547 |
cpu->byte_order = EMUL_BIG_ENDIAN; |
cpu->byte_order = EMUL_BIG_ENDIAN; |
1548 |
machine->machine_name = "MIPS test machine"; |
machine->machine_name = "MIPS test machine"; |
1549 |
|
|
1550 |
machine->main_console_handle = dev_cons_init( |
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=2", |
1551 |
machine, mem, DEV_CONS_ADDRESS, "console", 2); |
(long long)DEV_CONS_ADDRESS); |
1552 |
|
cons_data = device_add(machine, tmpstr); |
1553 |
|
machine->main_console_handle = cons_data->console_handle; |
1554 |
|
|
1555 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "mp addr=0x%llx", |
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
1556 |
(long long)DEV_MP_ADDRESS); |
(long long)DEV_MP_ADDRESS); |
1557 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
1558 |
|
|
1559 |
fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC, |
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
1560 |
640,480, 640,480, 24, "generic", 1); |
640,480, 640,480, 24, "testmips generic"); |
1561 |
|
|
1562 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
1563 |
|
(long long)DEV_DISK_ADDRESS); |
1564 |
|
device_add(machine, tmpstr); |
1565 |
|
|
1566 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=3", |
1567 |
|
(long long)DEV_ETHER_ADDRESS); |
1568 |
|
device_add(machine, tmpstr); |
1569 |
|
|
1570 |
break; |
break; |
1571 |
|
|
1572 |
case MACHINE_DEC: |
case MACHINE_DEC: |
1608 |
*/ |
*/ |
1609 |
fb = dev_fb_init(machine, mem, KN01_PHYS_FBUF_START, |
fb = dev_fb_init(machine, mem, KN01_PHYS_FBUF_START, |
1610 |
color_fb_flag? VFB_DEC_VFB02 : VFB_DEC_VFB01, |
color_fb_flag? VFB_DEC_VFB02 : VFB_DEC_VFB01, |
1611 |
0,0,0,0,0, color_fb_flag? "VFB02":"VFB01", 1); |
0,0,0,0,0, color_fb_flag? "VFB02":"VFB01"); |
1612 |
dev_colorplanemask_init(mem, KN01_PHYS_COLMASK_START, &fb->color_plane_mask); |
dev_colorplanemask_init(mem, KN01_PHYS_COLMASK_START, &fb->color_plane_mask); |
1613 |
dev_vdac_init(mem, KN01_SYS_VDAC, fb->rgb_palette, color_fb_flag); |
dev_vdac_init(mem, KN01_SYS_VDAC, fb->rgb_palette, color_fb_flag); |
1614 |
dev_le_init(machine, mem, KN01_SYS_LANCE, KN01_SYS_LANCE_B_START, KN01_SYS_LANCE_B_END, KN01_INT_LANCE, 4*1048576); |
dev_le_init(machine, mem, KN01_SYS_LANCE, KN01_SYS_LANCE_B_START, KN01_SYS_LANCE_B_END, KN01_INT_LANCE, 4*1048576); |
2040 |
dev_le_init(machine, mem, KN230_SYS_LANCE, KN230_SYS_LANCE_B_START, KN230_SYS_LANCE_B_END, KN230_CSR_INTR_LANCE, 4*1048576); |
dev_le_init(machine, mem, KN230_SYS_LANCE, KN230_SYS_LANCE_B_START, KN230_SYS_LANCE_B_END, KN230_CSR_INTR_LANCE, 4*1048576); |
2041 |
dev_sii_init(machine, mem, KN230_SYS_SII, KN230_SYS_SII_B_START, KN230_SYS_SII_B_END, KN230_CSR_INTR_SII); |
dev_sii_init(machine, mem, KN230_SYS_SII, KN230_SYS_SII_B_START, KN230_SYS_SII_B_END, KN230_CSR_INTR_SII); |
2042 |
|
|
2043 |
snprintf(tmpstr, sizeof(tmpstr) - 1, |
snprintf(tmpstr, sizeof(tmpstr), |
2044 |
"kn230 addr=0x%llx", (long long)KN230_SYS_ICSR); |
"kn230 addr=0x%llx", (long long)KN230_SYS_ICSR); |
2045 |
machine->md_int.kn230_csr = device_add(machine, tmpstr); |
machine->md_int.kn230_csr = device_add(machine, tmpstr); |
2046 |
|
|
2279 |
* 4 Tulip 1 |
* 4 Tulip 1 |
2280 |
* 5 16550 UART (serial console) |
* 5 16550 UART (serial console) |
2281 |
* 6 VIA southbridge PIC |
* 6 VIA southbridge PIC |
2282 |
* 7 PCI |
* 7 PCI (Note: Not used. The PCI controller |
2283 |
|
* interrupts at ISA interrupt 9.) |
2284 |
*/ |
*/ |
2285 |
/* dev_XXX_init(cpu, mem, 0x10000000, machine->emulated_hz); */ |
|
2286 |
|
/* ISA interrupt controllers: */ |
2287 |
|
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x10000020"); |
2288 |
|
machine->md_int.isa_pic_data.pic1 = device_add(machine, tmpstr); |
2289 |
|
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x100000a0"); |
2290 |
|
machine->md_int.isa_pic_data.pic2 = device_add(machine, tmpstr); |
2291 |
|
machine->md_interrupt = cobalt_interrupt; |
2292 |
|
|
2293 |
dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4); |
dev_mc146818_init(machine, mem, 0x10000070, 0, MC146818_PC_CMOS, 4); |
2294 |
|
|
2295 |
machine->main_console_handle = dev_ns16550_init(machine, mem, |
machine->main_console_handle = (size_t) |
2296 |
0x1c800000, 5, 1, 1, "serial console"); |
device_add(machine, "ns16550 irq=5 addr=0x1c800000 name2=tty0 in_use=1"); |
2297 |
|
|
2298 |
#if 0 |
#if 0 |
2299 |
dev_ns16550_init(machine, mem, 0x1f000010, 0, 1, 1, |
device_add(machine, "ns16550 irq=0 addr=0x1f000010 name2=tty1 in_use=0"); |
|
"other serial console"); |
|
2300 |
#endif |
#endif |
2301 |
|
|
2302 |
/* |
/* |
2308 |
* pcib0 at pci0 dev 9 function 0, VIA Technologies VT82C586 (Apollo VP) PCI-ISA Bridge, rev 37 |
* pcib0 at pci0 dev 9 function 0, VIA Technologies VT82C586 (Apollo VP) PCI-ISA Bridge, rev 37 |
2309 |
* pciide0 at pci0 dev 9 function 1: VIA Technologies VT82C586 (Apollo VP) ATA33 cr |
* pciide0 at pci0 dev 9 function 1: VIA Technologies VT82C586 (Apollo VP) ATA33 cr |
2310 |
* tlp1 at pci0 dev 12 function 0: DECchip 21143 Ethernet, pass 4.1 |
* tlp1 at pci0 dev 12 function 0: DECchip 21143 Ethernet, pass 4.1 |
2311 |
|
* |
2312 |
|
* The PCI controller interrupts at ISA interrupt 9. |
2313 |
*/ |
*/ |
2314 |
pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 6, 11); /* 7 for PCI, not 6? */ |
pci_data = dev_gt_init(machine, mem, 0x14000000, 2, 8 + 9, 11); |
2315 |
/* bus_pci_add(machine, pci_data, mem, 0, 7, 0, pci_dec21143_init, pci_dec21143_rr); */ |
/* bus_pci_add(machine, pci_data, mem, 0, 7, 0, pci_dec21143_init, pci_dec21143_rr); */ |
2316 |
bus_pci_add(machine, pci_data, mem, 0, 8, 0, NULL, NULL); /* PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */ |
bus_pci_add(machine, pci_data, mem, 0, 8, 0, NULL, NULL); /* PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_860 */ |
2317 |
bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr); |
bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr); |
2322 |
* NetBSD/cobalt expects memsize in a0, but it seems that what |
* NetBSD/cobalt expects memsize in a0, but it seems that what |
2323 |
* it really wants is the end of memory + 0x80000000. |
* it really wants is the end of memory + 0x80000000. |
2324 |
* |
* |
2325 |
* The bootstring should be stored starting 512 bytes before end |
* The bootstring is stored 512 bytes before the end of |
2326 |
* of physical ram. |
* physical ram. |
2327 |
*/ |
*/ |
2328 |
cpu->cd.mips.gpr[MIPS_GPR_A0] = machine->physical_ram_in_mb * 1048576 + 0x80000000; |
cpu->cd.mips.gpr[MIPS_GPR_A0] = |
2329 |
|
machine->physical_ram_in_mb * 1048576 + 0xffffffff80000000ULL; |
2330 |
bootstr = "root=/dev/hda1 ro"; |
bootstr = "root=/dev/hda1 ro"; |
2331 |
/* bootstr = "nfsroot=/usr/cobalt/"; */ |
/* bootstr = "nfsroot=/usr/cobalt/"; */ |
2332 |
store_string(cpu, 0xffffffff80000000ULL + |
/* TODO: bootarg, and/or automagic boot device detection */ |
2333 |
machine->physical_ram_in_mb * 1048576 - 512, bootstr); |
store_string(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0] - 512, bootstr); |
2334 |
break; |
break; |
2335 |
|
|
2336 |
case MACHINE_HPCMIPS: |
case MACHINE_HPCMIPS: |
2367 |
hpcmips_fb_bits = 15; |
hpcmips_fb_bits = 15; |
2368 |
hpcmips_fb_encoding = BIFB_D16_0000; |
hpcmips_fb_encoding = BIFB_D16_0000; |
2369 |
|
|
2370 |
machine->main_console_handle = dev_ns16550_init( |
/* TODO: irq? */ |
2371 |
machine, mem, 0xa008680, 0, 4, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x0a008680 addr_mult=4 in_use=%i", machine->use_x11? 0 : 1); |
2372 |
machine->use_x11? 0 : 1, "serial console"); /* TODO: irq? */ |
machine->main_console_handle = (size_t)device_add(machine, tmpstr); |
2373 |
|
|
2374 |
machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4131); |
machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4131); |
2375 |
machine->md_interrupt = vr41xx_interrupt; |
machine->md_interrupt = vr41xx_interrupt; |
2376 |
|
|
2399 |
hpcmips_fb_bits = 16; |
hpcmips_fb_bits = 16; |
2400 |
hpcmips_fb_encoding = BIFB_D16_0000; |
hpcmips_fb_encoding = BIFB_D16_0000; |
2401 |
|
|
2402 |
machine->main_console_handle = dev_ns16550_init( |
/* TODO: irq? */ |
2403 |
machine, mem, 0xa008680, 0, 4, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x0a008680 addr_mult=4 in_use=%i", machine->use_x11? 0 : 1); |
2404 |
machine->use_x11? 0 : 1, "serial console"); /* TODO: irq? */ |
machine->main_console_handle = (size_t)device_add(machine, tmpstr); |
2405 |
|
|
2406 |
machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121); |
machine->md_int.vr41xx_data = dev_vr41xx_init(machine, mem, 4121); |
2407 |
machine->md_interrupt = vr41xx_interrupt; |
machine->md_interrupt = vr41xx_interrupt; |
2408 |
|
|
2550 |
VRIP_INTR_SIU (=9) here? */ |
VRIP_INTR_SIU (=9) here? */ |
2551 |
{ |
{ |
2552 |
int x; |
int x; |
2553 |
x = dev_ns16550_init(machine, mem, 0x0c000010, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x0c000010", 8 + VRIP_INTR_SIU); |
2554 |
8 + VRIP_INTR_SIU, 1, 1, "serial 0"); |
x = (size_t)device_add(machine, tmpstr); |
2555 |
|
|
2556 |
if (!machine->use_x11) |
if (!machine->use_x11) |
2557 |
machine->main_console_handle = x; |
machine->main_console_handle = x; |
2574 |
break; |
break; |
2575 |
case MACHINE_HPCMIPS_IBM_WORKPAD_Z50: |
case MACHINE_HPCMIPS_IBM_WORKPAD_Z50: |
2576 |
/* 131 MHz VR4121 */ |
/* 131 MHz VR4121 */ |
2577 |
machine->machine_name = "Agenda VR3"; |
machine->machine_name = "IBM Workpad Z50"; |
2578 |
/* TODO: */ |
/* TODO: */ |
2579 |
hpcmips_fb_addr = 0xa000000; |
hpcmips_fb_addr = 0xa000000; |
2580 |
hpcmips_fb_xsize = 640; |
hpcmips_fb_xsize = 640; |
2677 |
dev_fb_init(machine, mem, hpcmips_fb_addr, VFB_HPCMIPS, |
dev_fb_init(machine, mem, hpcmips_fb_addr, VFB_HPCMIPS, |
2678 |
hpcmips_fb_xsize, hpcmips_fb_ysize, |
hpcmips_fb_xsize, hpcmips_fb_ysize, |
2679 |
hpcmips_fb_xsize_mem, hpcmips_fb_ysize_mem, |
hpcmips_fb_xsize_mem, hpcmips_fb_ysize_mem, |
2680 |
hpcmips_fb_bits, "HPCmips", 0); |
hpcmips_fb_bits, "HPCmips"); |
2681 |
|
|
2682 |
/* NetBSD/hpcmips uses framebuffer at physical |
/* NetBSD/hpcmips uses framebuffer at physical |
2683 |
address 0x8.......: */ |
address 0x8.......: */ |
2717 |
machine->md_interrupt = ps2_interrupt; |
machine->md_interrupt = ps2_interrupt; |
2718 |
|
|
2719 |
add_symbol_name(&machine->symbol_context, |
add_symbol_name(&machine->symbol_context, |
2720 |
PLAYSTATION2_SIFBIOS, 0x10000, "[SIFBIOS entry]", 0); |
PLAYSTATION2_SIFBIOS, 0x10000, "[SIFBIOS entry]", 0, 0); |
2721 |
store_32bit_word(cpu, PLAYSTATION2_BDA + 0, PLAYSTATION2_SIFBIOS); |
store_32bit_word(cpu, PLAYSTATION2_BDA + 0, PLAYSTATION2_SIFBIOS); |
2722 |
store_buf(cpu, PLAYSTATION2_BDA + 4, "PS2b", 4); |
store_buf(cpu, PLAYSTATION2_BDA + 4, "PS2b", 4); |
2723 |
|
|
3062 |
* program dumps something there, but it doesn't look like |
* program dumps something there, but it doesn't look like |
3063 |
* readable text. (TODO) |
* readable text. (TODO) |
3064 |
*/ |
*/ |
3065 |
machine->main_console_handle = dev_ns16550_init(machine, mem, 0x1f620170, 0, 1, |
|
3066 |
machine->use_x11? 0 : 1, "serial 0"); /* TODO: irq? */ |
/* TODO: irq! */ |
3067 |
dev_ns16550_init(machine, mem, 0x1f620178, 0, 1, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x1f620170 name2=tty0 in_use=%i", machine->use_x11? 0 : 1); |
3068 |
0, "serial 1"); /* TODO: irq? */ |
machine->main_console_handle = (size_t)device_add(machine, tmpstr); |
3069 |
|
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x1f620178 name2=tty1 in_use=0"); |
3070 |
|
device_add(machine, tmpstr); |
3071 |
|
|
3072 |
/* MardiGras graphics: */ |
/* MardiGras graphics: */ |
3073 |
device_add(machine, "sgi_mardigras addr=0x1c000000"); |
device_add(machine, "sgi_mardigras addr=0x1c000000"); |
3152 |
|
|
3153 |
dev_sgi_ust_init(mem, 0x1f340000); /* ust? */ |
dev_sgi_ust_init(mem, 0x1f340000); /* ust? */ |
3154 |
|
|
3155 |
j = dev_ns16550_init(machine, mem, 0x1f390000, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x1f390000 addr_mult=0x100 in_use=%i name2=tty0", |
3156 |
(1<<20) + MACE_PERIPH_SERIAL, 0x100, |
(1<<20) + MACE_PERIPH_SERIAL, machine->use_x11? 0 : 1); |
3157 |
machine->use_x11? 0 : 1, "serial 0"); /* com0 */ |
j = (size_t)device_add(machine, tmpstr); |
3158 |
dev_ns16550_init(machine, mem, 0x1f398000, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=%i addr=0x1f398000 addr_mult=0x100 in_use=%i name2=tty1", |
3159 |
(1<<26) + MACE_PERIPH_SERIAL, 0x100, |
(1<<26) + MACE_PERIPH_SERIAL, 0); |
3160 |
0, "serial 1"); /* com1 */ |
device_add(machine, tmpstr); |
|
|
|
3161 |
#if 0 |
#if 0 |
3162 |
if (machine->use_x11) |
if (machine->use_x11) |
3163 |
machine->main_console_handle = i; |
machine->main_console_handle = i; |
3254 |
device_add(machine, "sn addr=0x80001000 irq=0"); |
device_add(machine, "sn addr=0x80001000 irq=0"); |
3255 |
dev_mc146818_init(machine, mem, 0x80004000ULL, 0, MC146818_ARC_NEC, 1); |
dev_mc146818_init(machine, mem, 0x80004000ULL, 0, MC146818_ARC_NEC, 1); |
3256 |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, PCKBC_8042, 0, 0, machine->use_x11, 0); |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, PCKBC_8042, 0, 0, machine->use_x11, 0); |
3257 |
j = dev_ns16550_init(machine, mem, 0x80006000ULL, |
|
3258 |
3, 1, machine->use_x11? 0 : 1, "serial 0"); /* com0 */ |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=3 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1); |
3259 |
dev_ns16550_init(machine, mem, 0x80007000ULL, |
j = (size_t)device_add(machine, tmpstr); |
3260 |
0, 1, 0, "serial 1"); /* com1 */ |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x80007000 in_use=%i name2=tty1", 0); |
3261 |
|
device_add(machine, tmpstr); |
3262 |
|
|
3263 |
if (machine->use_x11) |
if (machine->use_x11) |
3264 |
machine->main_console_handle = i; |
machine->main_console_handle = i; |
3278 |
case MACHINE_ARC_NEC_R96: |
case MACHINE_ARC_NEC_R96: |
3279 |
dev_fb_init(machine, mem, 0x100e00000ULL, |
dev_fb_init(machine, mem, 0x100e00000ULL, |
3280 |
VFB_GENERIC, 640,480, 1024,480, |
VFB_GENERIC, 640,480, 1024,480, |
3281 |
8, "necvdfrb", 1); |
8, "necvdfrb"); |
3282 |
break; |
break; |
3283 |
} |
} |
3284 |
break; |
break; |
3374 |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, |
3375 |
PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0); |
PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0); |
3376 |
|
|
3377 |
j = dev_ns16550_init(machine, mem, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=16 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1); |
3378 |
0x80006000ULL, 8 + 8, 1, |
j = (size_t)device_add(machine, tmpstr); |
3379 |
machine->use_x11? 0 : 1, "serial 0"); |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=17 addr=0x80007000 in_use=%i name2=tty1", 0); |
3380 |
dev_ns16550_init(machine, mem, |
device_add(machine, tmpstr); |
|
0x80007000ULL, 8 + 9, 1, 0, "serial 1"); |
|
3381 |
|
|
3382 |
if (machine->use_x11) |
if (machine->use_x11) |
3383 |
machine->main_console_handle = i; |
machine->main_console_handle = i; |
3403 |
/* control at 0x60100000? */ |
/* control at 0x60100000? */ |
3404 |
dev_fb_init(machine, mem, 0x60200000ULL, |
dev_fb_init(machine, mem, 0x60200000ULL, |
3405 |
VFB_GENERIC, 1024,768, 1024,768, |
VFB_GENERIC, 1024,768, 1024,768, |
3406 |
8, "VXL", 1); |
8, "VXL"); |
3407 |
break; |
break; |
3408 |
} |
} |
3409 |
|
|
3452 |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, |
i = dev_pckbc_init(machine, mem, 0x80005000ULL, |
3453 |
PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0); |
PCKBC_JAZZ, 8 + 6, 8 + 7, machine->use_x11, 0); |
3454 |
#endif |
#endif |
3455 |
j = dev_ns16550_init(machine, mem, |
|
3456 |
0x80006000ULL, 8 + 8, 1, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=16 addr=0x80006000 in_use=%i name2=tty0", machine->use_x11? 0 : 1); |
3457 |
machine->use_x11? 0 : 1, "serial 0"); |
j = (size_t)device_add(machine, tmpstr); |
3458 |
dev_ns16550_init(machine, mem, |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=17 addr=0x80007000 in_use=%i name2=tty1", 0); |
3459 |
0x80007000ULL, 8 + 9, 1, 0, "serial 1"); |
device_add(machine, tmpstr); |
3460 |
|
|
3461 |
if (machine->use_x11) |
if (machine->use_x11) |
3462 |
machine->main_console_handle = i; |
machine->main_console_handle = i; |
3479 |
strlcat(machine->machine_name, " (Deskstation Tyne)", |
strlcat(machine->machine_name, " (Deskstation Tyne)", |
3480 |
MACHINE_NAME_MAXBUF); |
MACHINE_NAME_MAXBUF); |
3481 |
|
|
3482 |
i = dev_ns16550_init(machine, mem, 0x9000003f8ULL, 0, 1, machine->use_x11? 0 : 1, "serial 0"); |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=0 addr=0x9000003f8 in_use=%i name2=tty0", machine->use_x11? 0 : 1); |
3483 |
dev_ns16550_init(machine, mem, 0x9000002f8ULL, 0, 1, 0, "serial 1"); |
i = (size_t)device_add(machine, tmpstr); |
3484 |
dev_ns16550_init(machine, mem, 0x9000003e8ULL, 0, 1, 0, "serial 2"); |
device_add(machine, "ns16550 irq=0 addr=0x9000002f8 in_use=0 name2=tty1"); |
3485 |
dev_ns16550_init(machine, mem, 0x9000002e8ULL, 0, 1, 0, "serial 3"); |
device_add(machine, "ns16550 irq=0 addr=0x9000003e8 in_use=0 name2=tty2"); |
3486 |
|
device_add(machine, "ns16550 irq=0 addr=0x9000002e8 in_use=0 name2=tty3"); |
3487 |
|
|
3488 |
dev_mc146818_init(machine, mem, |
dev_mc146818_init(machine, mem, |
3489 |
0x900000070ULL, 2, MC146818_PC_CMOS, 1); |
0x900000070ULL, 2, MC146818_PC_CMOS, 1); |
3839 |
|
|
3840 |
switch (machine->machine_subtype) { |
switch (machine->machine_subtype) { |
3841 |
case MACHINE_EVBMIPS_MALTA: |
case MACHINE_EVBMIPS_MALTA: |
3842 |
machine->machine_name = "MALTA (evbmips)"; |
case MACHINE_EVBMIPS_MALTA_BE: |
3843 |
|
machine->machine_name = "MALTA (evbmips, little endian)"; |
3844 |
|
cpu->byte_order = EMUL_LITTLE_ENDIAN; |
3845 |
|
|
3846 |
machine->md_int.malta_data = |
if (machine->machine_subtype == MACHINE_EVBMIPS_MALTA_BE) { |
3847 |
device_add(machine, "malta addr=0x18000020"); |
machine->machine_name = "MALTA (evbmips, big endian)"; |
3848 |
|
cpu->byte_order = EMUL_BIG_ENDIAN; |
3849 |
|
} |
3850 |
|
|
3851 |
|
/* ISA interrupt controllers: */ |
3852 |
|
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x18000020"); |
3853 |
|
machine->md_int.isa_pic_data.pic1 = device_add(machine, tmpstr); |
3854 |
|
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=24 addr=0x180000a0"); |
3855 |
|
machine->md_int.isa_pic_data.pic2 = device_add(machine, tmpstr); |
3856 |
machine->md_interrupt = malta_interrupt; |
machine->md_interrupt = malta_interrupt; |
3857 |
|
|
3858 |
dev_mc146818_init(machine, mem, 0x18000070, |
dev_mc146818_init(machine, mem, 0x18000070, 8 + 8, MC146818_PC_CMOS, 1); |
3859 |
8 + 8, MC146818_PC_CMOS, 1); |
|
3860 |
machine->main_console_handle = dev_ns16550_init(machine, mem, |
machine->main_console_handle = (size_t) |
3861 |
0x180003f8, 8 + 4, 1, 1, "serial console"); |
device_add(machine, "ns16550 irq=12 addr=0x180003f8 name2=tty0"); |
3862 |
|
device_add(machine, "ns16550 irq=11 addr=0x180002f8 name2=tty1"); |
3863 |
|
|
3864 |
|
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%x name2=tty2", MALTA_CBUSUART); |
3865 |
|
device_add(machine, tmpstr); |
3866 |
/* TODO: Irqs */ |
/* TODO: Irqs */ |
3867 |
pci_data = dev_gt_init(machine, mem, 0x1be00000, |
pci_data = dev_gt_init(machine, mem, 0x1be00000, 8+9, 8+9, 120); |
|
8+16, 8+16, 120); |
|
3868 |
|
|
3869 |
/* TODO: Haha, this is bogus. Just a cut&paste |
/* TODO: Haha, this is bogus. Just a cut&paste |
3870 |
from the Cobalt emulation above. */ |
from the Cobalt emulation above. */ |
3871 |
bus_pci_add(machine, pci_data, mem, 0, 9, 0, |
bus_pci_add(machine, pci_data, mem, 0, 9, 0, pci_vt82c586_isa_init, pci_vt82c586_isa_rr); |
3872 |
pci_vt82c586_isa_init, pci_vt82c586_isa_rr); |
bus_pci_add(machine, pci_data, mem, 0, 9, 1, pci_vt82c586_ide_init, pci_vt82c586_ide_rr); |
|
bus_pci_add(machine, pci_data, mem, 0, 9, 1, |
|
|
pci_vt82c586_ide_init, pci_vt82c586_ide_rr); |
|
3873 |
|
|
3874 |
device_add(machine, "malta_lcd addr=0x1f000400"); |
device_add(machine, "malta_lcd addr=0x1f000400"); |
3875 |
break; |
break; |
3876 |
case MACHINE_EVBMIPS_PB1000: |
case MACHINE_EVBMIPS_PB1000: |
3877 |
machine->machine_name = "PB1000 (evbmips)"; |
machine->machine_name = "PB1000 (evbmips)"; |
3878 |
|
cpu->byte_order = EMUL_BIG_ENDIAN; |
3879 |
|
|
3880 |
machine->md_interrupt = au1x00_interrupt; |
machine->md_interrupt = au1x00_interrupt; |
3881 |
machine->md_int.au1x00_ic_data = |
machine->md_int.au1x00_ic_data = dev_au1x00_init(machine, mem); |
3882 |
dev_au1x00_init(machine, mem); |
/* TODO */ |
3883 |
break; |
break; |
3884 |
default: |
default: |
3885 |
fatal("Unimplemented EVBMIPS model.\n"); |
fatal("Unimplemented EVBMIPS model.\n"); |
3886 |
exit(1); |
exit(1); |
3887 |
} |
} |
3888 |
|
|
3889 |
/* This is just a test. TODO */ |
if (machine->prom_emulation) { |
3890 |
for (i=0; i<32; i++) |
/* This is just a test. TODO */ |
3891 |
cpu->cd.mips.gpr[i] = |
for (i=0; i<32; i++) |
3892 |
0x01230000 + (i << 8) + 0x55; |
cpu->cd.mips.gpr[i] = |
3893 |
|
0x01230000 + (i << 8) + 0x55; |
3894 |
/* NetBSD/evbmips wants these: (at least for Malta) */ |
|
3895 |
|
/* NetBSD/evbmips wants these: (at least for Malta) */ |
3896 |
/* a0 = argc */ |
|
3897 |
cpu->cd.mips.gpr[MIPS_GPR_A0] = 2; |
/* a0 = argc */ |
3898 |
|
cpu->cd.mips.gpr[MIPS_GPR_A0] = 2; |
3899 |
/* a1 = argv */ |
|
3900 |
cpu->cd.mips.gpr[MIPS_GPR_A1] = (int32_t)0x9fc01000; |
/* a1 = argv */ |
3901 |
store_32bit_word(cpu, (int32_t)0x9fc01000, 0x9fc01040); |
cpu->cd.mips.gpr[MIPS_GPR_A1] = (int32_t)0x9fc01000; |
3902 |
store_32bit_word(cpu, (int32_t)0x9fc01004, 0x9fc01200); |
store_32bit_word(cpu, (int32_t)0x9fc01000, 0x9fc01040); |
3903 |
|
store_32bit_word(cpu, (int32_t)0x9fc01004, 0x9fc01200); |
3904 |
bootstr = strdup(machine->boot_kernel_filename); |
store_32bit_word(cpu, (int32_t)0x9fc01008, 0); |
3905 |
bootarg = strdup(machine->boot_string_argument); |
|
3906 |
store_string(cpu, (int32_t)0x9fc01040, bootstr); |
bootstr = strdup(machine->boot_kernel_filename); |
3907 |
store_string(cpu, (int32_t)0x9fc01200, bootarg); |
bootarg = strdup(machine->boot_string_argument); |
3908 |
|
store_string(cpu, (int32_t)0x9fc01040, bootstr); |
3909 |
/* a2 = (yamon_env_var *)envp */ |
store_string(cpu, (int32_t)0x9fc01200, bootarg); |
3910 |
cpu->cd.mips.gpr[MIPS_GPR_A2] = 0; |
|
3911 |
|
/* a2 = (yamon_env_var *)envp */ |
3912 |
/* a3 = memsize */ |
cpu->cd.mips.gpr[MIPS_GPR_A2] = (int32_t)0x9fc01800; |
3913 |
cpu->cd.mips.gpr[MIPS_GPR_A3] = |
{ |
3914 |
machine->physical_ram_in_mb * 1048576; |
uint64_t env = cpu->cd.mips.gpr[MIPS_GPR_A2]; |
3915 |
|
uint64_t tmpptr = 0xffffffff9fc01c00ULL; |
3916 |
/* Yamon emulation vectors at 0x9fc005xx: */ |
char tmps[50]; |
3917 |
for (i=0; i<0x100; i+=4) |
|
3918 |
store_32bit_word(cpu, (int64_t)(int32_t)0x9fc00500 + i, |
snprintf(tmps, sizeof(tmps), "0x%08x", |
3919 |
(int64_t)(int32_t)0x9fc00800 + i); |
machine->physical_ram_in_mb * 1048576); |
3920 |
|
add_environment_string_dual(cpu, |
3921 |
|
&env, &tmpptr, "memsize", tmps); |
3922 |
|
|
3923 |
|
add_environment_string_dual(cpu, |
3924 |
|
&env, &tmpptr, "yamonrev", "02.06"); |
3925 |
|
|
3926 |
|
/* End of env: */ |
3927 |
|
tmpptr = 0; |
3928 |
|
add_environment_string_dual(cpu, |
3929 |
|
&env, &tmpptr, NULL, NULL); |
3930 |
|
} |
3931 |
|
|
3932 |
|
/* a3 = memsize */ |
3933 |
|
cpu->cd.mips.gpr[MIPS_GPR_A3] = |
3934 |
|
machine->physical_ram_in_mb * 1048576; |
3935 |
|
/* Hm. Linux ignores a3. */ |
3936 |
|
|
3937 |
|
/* |
3938 |
|
* TODO: |
3939 |
|
* Core ID numbers. |
3940 |
|
* How much of this is not valid for PBxxxx? |
3941 |
|
* |
3942 |
|
* See maltareg.h for more info. |
3943 |
|
*/ |
3944 |
|
store_32bit_word(cpu, (int32_t)(0x80000000 + MALTA_REVISION), (1 << 10) + 0x26); |
3945 |
|
|
3946 |
|
/* Call vectors at 0x9fc005xx: */ |
3947 |
|
for (i=0; i<0x100; i+=4) |
3948 |
|
store_32bit_word(cpu, (int64_t)(int32_t)0x9fc00500 + i, |
3949 |
|
(int64_t)(int32_t)0x9fc00800 + i); |
3950 |
|
} |
3951 |
break; |
break; |
3952 |
|
|
3953 |
case MACHINE_PSP: |
case MACHINE_PSP: |
3971 |
|
|
3972 |
/* 480 x 272 pixels framebuffer (512 bytes per line) */ |
/* 480 x 272 pixels framebuffer (512 bytes per line) */ |
3973 |
fb = dev_fb_init(machine, mem, 0x04000000, VFB_HPCMIPS, |
fb = dev_fb_init(machine, mem, 0x04000000, VFB_HPCMIPS, |
3974 |
480,272, 512,1088, -15, "Playstation Portable", 0); |
480,272, 512,1088, -15, "Playstation Portable"); |
3975 |
|
|
3976 |
/* |
/* |
3977 |
* TODO/NOTE: This is ugly, but necessary since GXemul doesn't |
* TODO/NOTE: This is ugly, but necessary since GXemul doesn't |
3992 |
cpu->cd.mips.gpr[MIPS_GPR_SP] = 0xfff0; |
cpu->cd.mips.gpr[MIPS_GPR_SP] = 0xfff0; |
3993 |
|
|
3994 |
break; |
break; |
3995 |
|
#endif /* ENABLE_MIPS */ |
3996 |
|
|
3997 |
|
#ifdef ENABLE_PPC |
3998 |
case MACHINE_BAREPPC: |
case MACHINE_BAREPPC: |
3999 |
/* |
/* |
4000 |
* A "bare" PPC machine. |
* A "bare" PPC machine. |
4011 |
machine->machine_name = "PPC test machine"; |
machine->machine_name = "PPC test machine"; |
4012 |
|
|
4013 |
/* TODO: interrupt for PPC? */ |
/* TODO: interrupt for PPC? */ |
4014 |
machine->main_console_handle = dev_cons_init( |
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4015 |
machine, mem, DEV_CONS_ADDRESS, "console", 0); |
(long long)DEV_CONS_ADDRESS); |
4016 |
|
cons_data = device_add(machine, tmpstr); |
4017 |
|
machine->main_console_handle = cons_data->console_handle; |
4018 |
|
|
4019 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "mp addr=0x%llx", |
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4020 |
(long long)DEV_MP_ADDRESS); |
(long long)DEV_MP_ADDRESS); |
4021 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
4022 |
|
|
4023 |
fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC, |
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4024 |
640,480, 640,480, 24, "generic", 1); |
640,480, 640,480, 24, "testppc generic"); |
4025 |
|
|
4026 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4027 |
|
(long long)DEV_DISK_ADDRESS); |
4028 |
|
device_add(machine, tmpstr); |
4029 |
|
|
4030 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4031 |
|
(long long)DEV_ETHER_ADDRESS); |
4032 |
|
device_add(machine, tmpstr); |
4033 |
|
|
4034 |
break; |
break; |
4035 |
|
|
4036 |
case MACHINE_WALNUT: |
case MACHINE_WALNUT: |
4050 |
dev_pmppc_init(mem); |
dev_pmppc_init(mem); |
4051 |
|
|
4052 |
/* com0 = 0xff600300, com1 = 0xff600400 */ |
/* com0 = 0xff600300, com1 = 0xff600400 */ |
4053 |
machine->main_console_handle = dev_ns16550_init(machine, mem, |
|
4054 |
0xff600300, 0, 1, 1, "serial 0"); |
machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0xff600300 name2=tty0"); |
4055 |
dev_ns16550_init(machine, mem, |
device_add(machine, "ns16550 irq=0 addr=0xff600400 in_use=0 name2=tty1"); |
|
0xff600400, 0, 1, 0, "serial 1"); |
|
4056 |
|
|
4057 |
break; |
break; |
4058 |
|
|
4079 |
|
|
4080 |
device_add(machine, "bebox"); |
device_add(machine, "bebox"); |
4081 |
|
|
4082 |
/* Serial, used by NetBSD: */ |
machine->main_console_handle = (size_t) |
4083 |
machine->main_console_handle = dev_ns16550_init(machine, mem, |
device_add(machine, "ns16550 irq=0 addr=0x800003f8 name2=tty0"); |
4084 |
0x800003f8, 0, 1, 1, "serial 0"); |
device_add(machine, "ns16550 irq=0 addr=0x800002f8 name2=tty1 in_use=0"); |
4085 |
|
|
4086 |
/* Serial, used by Linux: */ |
if (machine->use_x11) |
4087 |
dev_ns16550_init(machine, mem, 0x800002f8, 0, 1, 0, "serial 1"); |
dev_vga_init(machine, mem, 0xc00a0000ULL, 0x800003c0ULL, |
4088 |
|
machine->machine_name); |
|
/* This is used by Linux too: */ |
|
|
dev_vga_init(machine, mem, 0xc00a0000ULL, 0x800003c0ULL, |
|
|
machine->machine_name); |
|
4089 |
|
|
4090 |
store_32bit_word(cpu, 0x3010, |
store_32bit_word(cpu, 0x3010, |
4091 |
machine->physical_ram_in_mb * 1048576); |
machine->physical_ram_in_mb * 1048576); |
4112 |
|
|
4113 |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 12, 20); /* next */ |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 12, 20); /* next */ |
4114 |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 16, 1); /* console */ |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 16, 1); /* console */ |
4115 |
store_buf(cpu, cpu->cd.ppc.gpr[6] + 20, "com", 4); |
store_buf(cpu, cpu->cd.ppc.gpr[6] + 20, |
4116 |
|
machine->use_x11? "vga" : "com", 4); |
4117 |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 24, 0x3f8);/* addr */ |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 24, 0x3f8);/* addr */ |
4118 |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 28, 9600);/* speed */ |
store_32bit_word(cpu, cpu->cd.ppc.gpr[6] + 28, 9600);/* speed */ |
4119 |
|
|
4162 |
/* For playing with PMON2000 for PPC: */ |
/* For playing with PMON2000 for PPC: */ |
4163 |
machine->machine_name = "DB64360"; |
machine->machine_name = "DB64360"; |
4164 |
|
|
4165 |
machine->main_console_handle = dev_ns16550_init(machine, mem, |
machine->main_console_handle = (size_t)device_add(machine, "ns16550 irq=0 addr=0x1d000020"); |
|
0x1d000020, 0, 4, 1, "serial console"); |
|
4166 |
|
|
4167 |
{ |
{ |
4168 |
int i; |
int i; |
4172 |
} |
} |
4173 |
|
|
4174 |
break; |
break; |
4175 |
|
#endif /* ENABLE_PPC */ |
4176 |
|
|
4177 |
|
#ifdef ENABLE_SPARC |
4178 |
case MACHINE_BARESPARC: |
case MACHINE_BARESPARC: |
4179 |
/* A bare SPARC machine, with no devices. */ |
/* A bare SPARC machine, with no devices. */ |
4180 |
machine->machine_name = "\"Bare\" SPARC machine"; |
machine->machine_name = "\"Bare\" SPARC machine"; |
4181 |
break; |
break; |
4182 |
|
|
4183 |
|
case MACHINE_TESTSPARC: |
4184 |
|
machine->machine_name = "SPARC test machine"; |
4185 |
|
|
4186 |
|
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4187 |
|
(long long)DEV_CONS_ADDRESS); |
4188 |
|
cons_data = device_add(machine, tmpstr); |
4189 |
|
machine->main_console_handle = cons_data->console_handle; |
4190 |
|
|
4191 |
|
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4192 |
|
(long long)DEV_MP_ADDRESS); |
4193 |
|
device_add(machine, tmpstr); |
4194 |
|
|
4195 |
|
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4196 |
|
640,480, 640,480, 24, "testsparc generic"); |
4197 |
|
|
4198 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4199 |
|
(long long)DEV_DISK_ADDRESS); |
4200 |
|
device_add(machine, tmpstr); |
4201 |
|
|
4202 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4203 |
|
(long long)DEV_ETHER_ADDRESS); |
4204 |
|
device_add(machine, tmpstr); |
4205 |
|
|
4206 |
|
break; |
4207 |
|
|
4208 |
case MACHINE_ULTRA1: |
case MACHINE_ULTRA1: |
4209 |
/* |
/* |
4210 |
* NetBSD/sparc64 (http://www.netbsd.org/Ports/sparc64/) |
* NetBSD/sparc64 (http://www.netbsd.org/Ports/sparc64/) |
4212 |
*/ |
*/ |
4213 |
machine->machine_name = "Sun Ultra1"; |
machine->machine_name = "Sun Ultra1"; |
4214 |
break; |
break; |
4215 |
|
#endif /* ENABLE_SPARC */ |
4216 |
|
|
4217 |
case MACHINE_BAREURISC: |
#ifdef ENABLE_ALPHA |
4218 |
machine->machine_name = "\"Bare\" URISC machine"; |
case MACHINE_BAREALPHA: |
4219 |
|
machine->machine_name = "\"Bare\" Alpha machine"; |
4220 |
break; |
break; |
4221 |
|
|
4222 |
case MACHINE_TESTURISC: |
case MACHINE_TESTALPHA: |
4223 |
machine->machine_name = "URISC test machine"; |
machine->machine_name = "Alpha test machine"; |
4224 |
|
|
4225 |
/* TODO */ |
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4226 |
/* A special "device" for accessing normal devices |
(long long)DEV_CONS_ADDRESS); |
4227 |
using urisc accesses? */ |
cons_data = device_add(machine, tmpstr); |
4228 |
|
machine->main_console_handle = cons_data->console_handle; |
4229 |
|
|
4230 |
device_add(machine, "urisc addr=0x12341234"); |
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4231 |
|
(long long)DEV_MP_ADDRESS); |
4232 |
|
device_add(machine, tmpstr); |
4233 |
|
|
4234 |
break; |
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4235 |
|
640,480, 640,480, 24, "testalpha generic"); |
4236 |
|
|
4237 |
case MACHINE_BAREHPPA: |
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4238 |
machine->machine_name = "\"Bare\" HPPA machine"; |
(long long)DEV_DISK_ADDRESS); |
4239 |
break; |
device_add(machine, tmpstr); |
4240 |
|
|
4241 |
case MACHINE_TESTHPPA: |
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4242 |
machine->machine_name = "HPPA test machine"; |
(long long)DEV_ETHER_ADDRESS); |
4243 |
|
device_add(machine, tmpstr); |
4244 |
|
|
|
/* TODO */ |
|
4245 |
break; |
break; |
4246 |
|
|
4247 |
case MACHINE_BAREALPHA: |
case MACHINE_ALPHA: |
4248 |
machine->machine_name = "\"Bare\" Alpha machine"; |
/* TODO: Most of these... They are used by NetBSD/alpha: */ |
4249 |
break; |
/* a0 = First free Page Frame Number */ |
4250 |
|
/* a1 = PFN of current Level 1 page table */ |
4251 |
|
/* a2 = Bootinfo magic */ |
4252 |
|
/* a3 = Bootinfo pointer */ |
4253 |
|
/* a4 = Bootinfo version */ |
4254 |
|
cpu->cd.alpha.r[ALPHA_A0] = 16*1024*1024 / 8192; |
4255 |
|
cpu->cd.alpha.r[ALPHA_A1] = 0; |
4256 |
|
cpu->cd.alpha.r[ALPHA_A2] = 0; |
4257 |
|
cpu->cd.alpha.r[ALPHA_A3] = 0; |
4258 |
|
cpu->cd.alpha.r[ALPHA_A4] = 0; |
4259 |
|
|
4260 |
|
if (machine->prom_emulation) { |
4261 |
|
struct rpb rpb; |
4262 |
|
struct crb crb; |
4263 |
|
struct ctb ctb; |
4264 |
|
|
4265 |
|
/* HWRPB: Hardware Restart Parameter Block */ |
4266 |
|
memset(&rpb, 0, sizeof(struct rpb)); |
4267 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4268 |
|
&(rpb.rpb_phys), HWRPB_ADDR); |
4269 |
|
strlcpy((char *)&(rpb.rpb_magic), "HWRPB", 8); |
4270 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4271 |
|
&(rpb.rpb_size), sizeof(struct rpb)); |
4272 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4273 |
|
&(rpb.rpb_page_size), 8192); |
4274 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4275 |
|
&(rpb.rpb_type), machine->machine_subtype); |
4276 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4277 |
|
&(rpb.rpb_cc_freq), 100000000); |
4278 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4279 |
|
&(rpb.rpb_ctb_off), CTB_ADDR - HWRPB_ADDR); |
4280 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4281 |
|
&(rpb.rpb_crb_off), CRB_ADDR - HWRPB_ADDR); |
4282 |
|
|
4283 |
|
/* CTB: Console Terminal Block */ |
4284 |
|
memset(&ctb, 0, sizeof(struct ctb)); |
4285 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4286 |
|
&(ctb.ctb_term_type), machine->use_x11? |
4287 |
|
CTB_GRAPHICS : CTB_PRINTERPORT); |
4288 |
|
|
4289 |
|
/* CRB: Console Routine Block */ |
4290 |
|
memset(&crb, 0, sizeof(struct crb)); |
4291 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
4292 |
|
&(crb.crb_v_dispatch), CRB_ADDR - 0x100); |
4293 |
|
store_64bit_word(cpu, CRB_ADDR - 0x100 + 8, 0x10000); |
4294 |
|
|
4295 |
case MACHINE_TESTALPHA: |
/* |
4296 |
machine->machine_name = "Alpha test machine"; |
* Place a special "hack" palcode call at 0x10000: |
4297 |
|
* (Hopefully nothing else will be there.) |
4298 |
|
*/ |
4299 |
|
store_32bit_word(cpu, 0x10000, 0x3fffffe); |
4300 |
|
|
4301 |
|
store_buf(cpu, HWRPB_ADDR, (char *)&rpb, sizeof(struct rpb)); |
4302 |
|
store_buf(cpu, CTB_ADDR, (char *)&ctb, sizeof(struct ctb)); |
4303 |
|
store_buf(cpu, CRB_ADDR, (char *)&crb, sizeof(struct crb)); |
4304 |
|
} |
4305 |
|
|
4306 |
|
switch (machine->machine_subtype) { |
4307 |
|
case ST_DEC_3000_300: |
4308 |
|
machine->machine_name = "DEC 3000/300"; |
4309 |
|
break; |
4310 |
|
default:fatal("Unimplemented Alpha machine type %i\n", |
4311 |
|
machine->machine_subtype); |
4312 |
|
exit(1); |
4313 |
|
} |
4314 |
|
|
|
/* TODO */ |
|
4315 |
break; |
break; |
4316 |
|
#endif /* ENABLE_ALPHA */ |
4317 |
|
|
4318 |
|
#ifdef ENABLE_ARM |
4319 |
case MACHINE_BAREARM: |
case MACHINE_BAREARM: |
4320 |
machine->machine_name = "\"Bare\" ARM machine"; |
machine->machine_name = "\"Bare\" ARM machine"; |
4321 |
break; |
break; |
4323 |
case MACHINE_TESTARM: |
case MACHINE_TESTARM: |
4324 |
machine->machine_name = "ARM test machine"; |
machine->machine_name = "ARM test machine"; |
4325 |
|
|
4326 |
machine->main_console_handle = dev_cons_init( |
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4327 |
machine, mem, DEV_CONS_ADDRESS, "console", 2); |
(long long)DEV_CONS_ADDRESS); |
4328 |
|
cons_data = device_add(machine, tmpstr); |
4329 |
|
machine->main_console_handle = cons_data->console_handle; |
4330 |
|
|
4331 |
|
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4332 |
|
(long long)DEV_MP_ADDRESS); |
4333 |
|
device_add(machine, tmpstr); |
4334 |
|
|
4335 |
|
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4336 |
|
640,480, 640,480, 24, "testarm generic"); |
4337 |
|
|
4338 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4339 |
|
(long long)DEV_DISK_ADDRESS); |
4340 |
|
device_add(machine, tmpstr); |
4341 |
|
|
4342 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4343 |
|
(long long)DEV_ETHER_ADDRESS); |
4344 |
|
device_add(machine, tmpstr); |
4345 |
|
|
4346 |
|
/* Place a tiny stub at end of memory, and set the link |
4347 |
|
register to point to it. This stub halts the machine. */ |
4348 |
|
cpu->cd.arm.r[ARM_SP] = |
4349 |
|
machine->physical_ram_in_mb * 1048576 - 4096; |
4350 |
|
cpu->cd.arm.r[ARM_LR] = cpu->cd.arm.r[ARM_SP] + 32; |
4351 |
|
store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 0, 0xe3a00201); |
4352 |
|
store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 4, 0xe5c00010); |
4353 |
|
store_32bit_word(cpu, cpu->cd.arm.r[ARM_LR] + 8, |
4354 |
|
0xeafffffe); |
4355 |
|
break; |
4356 |
|
#endif /* ENABLE_ARM */ |
4357 |
|
|
4358 |
|
#ifdef ENABLE_IA64 |
4359 |
|
case MACHINE_BAREIA64: |
4360 |
|
machine->machine_name = "\"Bare\" IA64 machine"; |
4361 |
|
break; |
4362 |
|
|
4363 |
|
case MACHINE_TESTIA64: |
4364 |
|
machine->machine_name = "IA64 test machine"; |
4365 |
|
|
4366 |
|
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4367 |
|
(long long)DEV_CONS_ADDRESS); |
4368 |
|
cons_data = device_add(machine, tmpstr); |
4369 |
|
machine->main_console_handle = cons_data->console_handle; |
4370 |
|
|
4371 |
|
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4372 |
|
(long long)DEV_MP_ADDRESS); |
4373 |
|
device_add(machine, tmpstr); |
4374 |
|
|
4375 |
|
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4376 |
|
640,480, 640,480, 24, "testia64 generic"); |
4377 |
|
|
4378 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4379 |
|
(long long)DEV_DISK_ADDRESS); |
4380 |
|
device_add(machine, tmpstr); |
4381 |
|
|
4382 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4383 |
|
(long long)DEV_ETHER_ADDRESS); |
4384 |
|
device_add(machine, tmpstr); |
4385 |
|
|
4386 |
|
break; |
4387 |
|
#endif /* ENABLE_IA64 */ |
4388 |
|
|
4389 |
|
#ifdef ENABLE_M68K |
4390 |
|
case MACHINE_BAREM68K: |
4391 |
|
machine->machine_name = "\"Bare\" M68K machine"; |
4392 |
|
break; |
4393 |
|
|
4394 |
|
case MACHINE_TESTM68K: |
4395 |
|
machine->machine_name = "M68K test machine"; |
4396 |
|
|
4397 |
|
snprintf(tmpstr, sizeof(tmpstr), "cons addr=0x%llx irq=0", |
4398 |
|
(long long)DEV_CONS_ADDRESS); |
4399 |
|
cons_data = device_add(machine, tmpstr); |
4400 |
|
machine->main_console_handle = cons_data->console_handle; |
4401 |
|
|
4402 |
|
snprintf(tmpstr, sizeof(tmpstr), "mp addr=0x%llx", |
4403 |
|
(long long)DEV_MP_ADDRESS); |
4404 |
|
device_add(machine, tmpstr); |
4405 |
|
|
4406 |
|
fb = dev_fb_init(machine, mem, DEV_FB_ADDRESS, VFB_GENERIC, |
4407 |
|
640,480, 640,480, 24, "testm68k generic"); |
4408 |
|
|
4409 |
|
snprintf(tmpstr, sizeof(tmpstr), "disk addr=0x%llx", |
4410 |
|
(long long)DEV_DISK_ADDRESS); |
4411 |
|
device_add(machine, tmpstr); |
4412 |
|
|
4413 |
|
snprintf(tmpstr, sizeof(tmpstr), "ether addr=0x%llx irq=0", |
4414 |
|
(long long)DEV_ETHER_ADDRESS); |
4415 |
|
device_add(machine, tmpstr); |
4416 |
|
|
|
fb = dev_fb_init(machine, mem, 0x12000000, VFB_GENERIC, |
|
|
640,480, 640,480, 24, "generic", 1); |
|
4417 |
break; |
break; |
4418 |
|
#endif /* ENABLE_M68K */ |
4419 |
|
|
4420 |
|
#ifdef ENABLE_X86 |
4421 |
case MACHINE_BAREX86: |
case MACHINE_BAREX86: |
4422 |
machine->machine_name = "\"Bare\" x86 machine"; |
machine->machine_name = "\"Bare\" x86 machine"; |
4423 |
break; |
break; |
4429 |
machine->machine_name = "Generic x86 PC"; |
machine->machine_name = "Generic x86 PC"; |
4430 |
|
|
4431 |
/* Interrupt controllers: */ |
/* Interrupt controllers: */ |
4432 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "8259 addr=0x%llx", |
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx", |
4433 |
(long long)(X86_IO_BASE + 0x20)); |
(long long)(X86_IO_BASE + 0x20)); |
4434 |
machine->md.pc.pic1 = device_add(machine, tmpstr); |
machine->md.pc.pic1 = device_add(machine, tmpstr); |
4435 |
if (machine->machine_subtype != MACHINE_X86_XT) { |
if (machine->machine_subtype != MACHINE_X86_XT) { |
4436 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "8259 addr=0x%llx irq=2", |
snprintf(tmpstr, sizeof(tmpstr), "8259 irq=16 addr=0x%llx irq=2", |
4437 |
(long long)(X86_IO_BASE + 0xa0)); |
(long long)(X86_IO_BASE + 0xa0)); |
4438 |
machine->md.pc.pic2 = device_add(machine, tmpstr); |
machine->md.pc.pic2 = device_add(machine, tmpstr); |
4439 |
} |
} |
4441 |
machine->md_interrupt = x86_pc_interrupt; |
machine->md_interrupt = x86_pc_interrupt; |
4442 |
|
|
4443 |
/* Timer: */ |
/* Timer: */ |
4444 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "8253 addr=0x%llx irq=0", |
snprintf(tmpstr, sizeof(tmpstr), "8253 addr=0x%llx irq=0", |
4445 |
(long long)(X86_IO_BASE + 0x40)); |
(long long)(X86_IO_BASE + 0x40)); |
4446 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
4447 |
|
|
4448 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "pccmos addr=0x%llx", |
snprintf(tmpstr, sizeof(tmpstr), "pccmos addr=0x%llx", |
4449 |
(long long)(X86_IO_BASE + 0x70)); |
(long long)(X86_IO_BASE + 0x70)); |
4450 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
4451 |
|
|
4460 |
dev_wdc_init(machine, mem, X86_IO_BASE + 0x170, 15, 2); |
dev_wdc_init(machine, mem, X86_IO_BASE + 0x170, 15, 2); |
4461 |
|
|
4462 |
/* Floppy controller at irq 6 */ |
/* Floppy controller at irq 6 */ |
4463 |
snprintf(tmpstr, sizeof(tmpstr) - 1, "fdc addr=0x%llx irq=6", |
snprintf(tmpstr, sizeof(tmpstr), "fdc addr=0x%llx irq=6", |
4464 |
(long long)(X86_IO_BASE + 0x3f0)); |
(long long)(X86_IO_BASE + 0x3f0)); |
4465 |
device_add(machine, tmpstr); |
device_add(machine, tmpstr); |
4466 |
|
|
4469 |
/* TODO: parallel port */ |
/* TODO: parallel port */ |
4470 |
|
|
4471 |
/* Serial ports: (TODO: 8250 for PC XT?) */ |
/* Serial ports: (TODO: 8250 for PC XT?) */ |
4472 |
dev_ns16550_init(machine, mem, X86_IO_BASE + 0x3f8, 4, 1, 0, "com1"); |
|
4473 |
dev_ns16550_init(machine, mem, X86_IO_BASE + 0x378, 3, 1, 0, "com2"); |
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=4 addr=0x%llx name2=com1 in_use=0", |
4474 |
|
(long long)X86_IO_BASE + 0x3f8); |
4475 |
|
device_add(machine, tmpstr); |
4476 |
|
snprintf(tmpstr, sizeof(tmpstr), "ns16550 irq=3 addr=0x%llx name2=com2 in_use=0", |
4477 |
|
(long long)X86_IO_BASE + 0x2f8); |
4478 |
|
device_add(machine, tmpstr); |
4479 |
|
|
4480 |
/* VGA + keyboard: */ |
/* VGA + keyboard: */ |
4481 |
dev_vga_init(machine, mem, 0xa0000ULL, X86_IO_BASE + 0x3c0, |
dev_vga_init(machine, mem, 0xa0000ULL, X86_IO_BASE + 0x3c0, |
4494 |
"-------------------------------------" |
"-------------------------------------" |
4495 |
"------------------------------------------\n"); |
"------------------------------------------\n"); |
4496 |
break; |
break; |
4497 |
|
#endif /* ENABLE_X86 */ |
4498 |
|
|
4499 |
default: |
default: |
4500 |
fatal("Unknown emulation type %i\n", machine->machine_type); |
fatal("Unknown emulation type %i\n", machine->machine_type); |
4596 |
m->physical_ram_in_mb = 32; |
m->physical_ram_in_mb = 32; |
4597 |
} |
} |
4598 |
break; |
break; |
4599 |
case MACHINE_BEBOX: |
case MACHINE_ALPHA: |
4600 |
m->physical_ram_in_mb = 64; |
m->physical_ram_in_mb = 64; |
4601 |
break; |
break; |
4602 |
case MACHINE_BAREURISC: |
case MACHINE_BEBOX: |
4603 |
case MACHINE_TESTURISC: |
m->physical_ram_in_mb = 64; |
|
m->physical_ram_in_mb = 2; |
|
4604 |
break; |
break; |
4605 |
case MACHINE_X86: |
case MACHINE_X86: |
4606 |
if (m->machine_subtype == MACHINE_X86_XT) |
if (m->machine_subtype == MACHINE_X86_XT) |
4740 |
case MACHINE_EVBMIPS: |
case MACHINE_EVBMIPS: |
4741 |
switch (m->machine_subtype) { |
switch (m->machine_subtype) { |
4742 |
case MACHINE_EVBMIPS_MALTA: |
case MACHINE_EVBMIPS_MALTA: |
4743 |
|
case MACHINE_EVBMIPS_MALTA_BE: |
4744 |
m->cpu_name = strdup("5Kc"); |
m->cpu_name = strdup("5Kc"); |
4745 |
break; |
break; |
4746 |
case MACHINE_EVBMIPS_PB1000: |
case MACHINE_EVBMIPS_PB1000: |
4800 |
|
|
4801 |
/* SPARC: */ |
/* SPARC: */ |
4802 |
case MACHINE_BARESPARC: |
case MACHINE_BARESPARC: |
4803 |
m->cpu_name = strdup("SPARCV9"); |
case MACHINE_TESTSPARC: |
|
break; |
|
4804 |
case MACHINE_ULTRA1: |
case MACHINE_ULTRA1: |
4805 |
m->cpu_name = strdup("SPARCV9"); |
m->cpu_name = strdup("SPARCv9"); |
|
break; |
|
|
|
|
|
/* URISC: */ |
|
|
case MACHINE_BAREURISC: |
|
|
case MACHINE_TESTURISC: |
|
|
m->cpu_name = strdup("URISC"); |
|
|
break; |
|
|
|
|
|
/* HPPA: */ |
|
|
case MACHINE_BAREHPPA: |
|
|
case MACHINE_TESTHPPA: |
|
|
m->cpu_name = strdup("HPPA2.0"); |
|
4806 |
break; |
break; |
4807 |
|
|
4808 |
/* Alpha: */ |
/* Alpha: */ |
4809 |
case MACHINE_BAREALPHA: |
case MACHINE_BAREALPHA: |
4810 |
case MACHINE_TESTALPHA: |
case MACHINE_TESTALPHA: |
4811 |
m->cpu_name = strdup("EV4"); |
case MACHINE_ALPHA: |
4812 |
|
m->cpu_name = strdup("Alpha"); |
4813 |
break; |
break; |
4814 |
|
|
4815 |
/* ARM: */ |
/* ARM: */ |
4818 |
m->cpu_name = strdup("ARM"); |
m->cpu_name = strdup("ARM"); |
4819 |
break; |
break; |
4820 |
|
|
4821 |
|
/* IA64: */ |
4822 |
|
case MACHINE_BAREIA64: |
4823 |
|
case MACHINE_TESTIA64: |
4824 |
|
m->cpu_name = strdup("IA64"); |
4825 |
|
break; |
4826 |
|
|
4827 |
|
/* M68K: */ |
4828 |
|
case MACHINE_BAREM68K: |
4829 |
|
case MACHINE_TESTM68K: |
4830 |
|
m->cpu_name = strdup("68020"); |
4831 |
|
break; |
4832 |
|
|
4833 |
/* x86: */ |
/* x86: */ |
4834 |
case MACHINE_BAREX86: |
case MACHINE_BAREX86: |
4835 |
case MACHINE_X86: |
case MACHINE_X86: |
4876 |
if (m->single_step_on_bad_addr) |
if (m->single_step_on_bad_addr) |
4877 |
debug("single-step on bad addresses\n"); |
debug("single-step on bad addresses\n"); |
4878 |
|
|
4879 |
if (m->bintrans_enable) |
if (m->arch == ARCH_MIPS) { |
4880 |
debug("bintrans enabled (%i MB cache)\n", |
if (m->bintrans_enable) |
4881 |
(int) (m->bintrans_size / 1048576)); |
debug("bintrans enabled (%i MB cache)\n", |
4882 |
else |
(int) (m->bintrans_size / 1048576)); |
4883 |
debug("bintrans disabled, other speedtricks %s\n", |
else |
4884 |
m->speed_tricks? "enabled" : "disabled"); |
debug("bintrans disabled, other speedtricks %s\n", |
4885 |
|
m->speed_tricks? "enabled" : "disabled"); |
4886 |
|
} |
4887 |
|
|
4888 |
debug("clock: "); |
debug("clock: "); |
4889 |
if (m->automatic_clock_adjustment) |
if (m->automatic_clock_adjustment) |
5070 |
debug("\n"); |
debug("\n"); |
5071 |
|
|
5072 |
useremul_list_emuls(); |
useremul_list_emuls(); |
5073 |
|
debug("Userland emulation works for programs with the complexity" |
5074 |
|
" of Hello World,\nbut not much more.\n"); |
5075 |
} |
} |
5076 |
|
|
5077 |
|
|
5113 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5114 |
} |
} |
5115 |
|
|
5116 |
/* Test-machine for URISC: */ |
/* Test-machine for SPARC: */ |
5117 |
me = machine_entry_new("Test-machine for URISC", ARCH_URISC, |
me = machine_entry_new("Test-machine for SPARC", ARCH_SPARC, |
5118 |
MACHINE_TESTURISC, 1, 0); |
MACHINE_TESTSPARC, 1, 0); |
5119 |
me->aliases[0] = "testurisc"; |
me->aliases[0] = "testsparc"; |
5120 |
if (cpu_family_ptr_by_number(ARCH_URISC) != NULL) { |
if (cpu_family_ptr_by_number(ARCH_SPARC) != NULL) { |
5121 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5122 |
} |
} |
5123 |
|
|
5137 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5138 |
} |
} |
5139 |
|
|
5140 |
/* Test-machine for HPPA: */ |
/* Test-machine for M68K: */ |
5141 |
me = machine_entry_new("Test-machine for HPPA", ARCH_HPPA, |
me = machine_entry_new("Test-machine for M68K", ARCH_M68K, |
5142 |
MACHINE_TESTHPPA, 1, 0); |
MACHINE_TESTM68K, 1, 0); |
5143 |
me->aliases[0] = "testhppa"; |
me->aliases[0] = "testm68k"; |
5144 |
if (cpu_family_ptr_by_number(ARCH_HPPA) != NULL) { |
if (cpu_family_ptr_by_number(ARCH_M68K) != NULL) { |
5145 |
|
me->next = first_machine_entry; first_machine_entry = me; |
5146 |
|
} |
5147 |
|
|
5148 |
|
/* Test-machine for IA64: */ |
5149 |
|
me = machine_entry_new("Test-machine for IA64", ARCH_IA64, |
5150 |
|
MACHINE_TESTIA64, 1, 0); |
5151 |
|
me->aliases[0] = "testia64"; |
5152 |
|
if (cpu_family_ptr_by_number(ARCH_IA64) != NULL) { |
5153 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5154 |
} |
} |
5155 |
|
|
5195 |
} |
} |
5196 |
|
|
5197 |
/* SGI: */ |
/* SGI: */ |
5198 |
me = machine_entry_new("SGI", ARCH_MIPS, MACHINE_SGI, 2, 9); |
me = machine_entry_new("SGI", ARCH_MIPS, MACHINE_SGI, 2, 10); |
5199 |
me->aliases[0] = "silicon graphics"; |
me->aliases[0] = "silicon graphics"; |
5200 |
me->aliases[1] = "sgi"; |
me->aliases[1] = "sgi"; |
5201 |
me->subtype[0] = machine_entry_subtype_new("IP19", 19, 1); |
me->subtype[0] = machine_entry_subtype_new("IP12", 12, 1); |
5202 |
me->subtype[0]->aliases[0] = "ip19"; |
me->subtype[0]->aliases[0] = "ip12"; |
5203 |
me->subtype[1] = machine_entry_subtype_new("IP20", 20, 1); |
me->subtype[1] = machine_entry_subtype_new("IP19", 19, 1); |
5204 |
me->subtype[1]->aliases[0] = "ip20"; |
me->subtype[1]->aliases[0] = "ip19"; |
5205 |
me->subtype[2] = machine_entry_subtype_new("IP22", 22, 2); |
me->subtype[2] = machine_entry_subtype_new("IP20", 20, 1); |
5206 |
me->subtype[2]->aliases[0] = "ip22"; |
me->subtype[2]->aliases[0] = "ip20"; |
5207 |
me->subtype[2]->aliases[1] = "indy"; |
me->subtype[3] = machine_entry_subtype_new("IP22", 22, 2); |
5208 |
me->subtype[3] = machine_entry_subtype_new("IP24", 24, 1); |
me->subtype[3]->aliases[0] = "ip22"; |
5209 |
me->subtype[3]->aliases[0] = "ip24"; |
me->subtype[3]->aliases[1] = "indy"; |
5210 |
me->subtype[4] = machine_entry_subtype_new("IP27", 27, 3); |
me->subtype[4] = machine_entry_subtype_new("IP24", 24, 1); |
5211 |
me->subtype[4]->aliases[0] = "ip27"; |
me->subtype[4]->aliases[0] = "ip24"; |
5212 |
me->subtype[4]->aliases[1] = "origin 200"; |
me->subtype[5] = machine_entry_subtype_new("IP27", 27, 3); |
5213 |
me->subtype[4]->aliases[2] = "origin 2000"; |
me->subtype[5]->aliases[0] = "ip27"; |
5214 |
me->subtype[5] = machine_entry_subtype_new("IP28", 28, 1); |
me->subtype[5]->aliases[1] = "origin 200"; |
5215 |
me->subtype[5]->aliases[0] = "ip28"; |
me->subtype[5]->aliases[2] = "origin 2000"; |
5216 |
me->subtype[6] = machine_entry_subtype_new("IP30", 30, 2); |
me->subtype[6] = machine_entry_subtype_new("IP28", 28, 1); |
5217 |
me->subtype[6]->aliases[0] = "ip30"; |
me->subtype[6]->aliases[0] = "ip28"; |
5218 |
me->subtype[6]->aliases[1] = "octane"; |
me->subtype[7] = machine_entry_subtype_new("IP30", 30, 2); |
5219 |
me->subtype[7] = machine_entry_subtype_new("IP32", 32, 2); |
me->subtype[7]->aliases[0] = "ip30"; |
5220 |
me->subtype[7]->aliases[0] = "ip32"; |
me->subtype[7]->aliases[1] = "octane"; |
5221 |
me->subtype[7]->aliases[1] = "o2"; |
me->subtype[8] = machine_entry_subtype_new("IP32", 32, 2); |
5222 |
me->subtype[8] = machine_entry_subtype_new("IP35", 35, 1); |
me->subtype[8]->aliases[0] = "ip32"; |
5223 |
me->subtype[8]->aliases[0] = "ip35"; |
me->subtype[8]->aliases[1] = "o2"; |
5224 |
|
me->subtype[9] = machine_entry_subtype_new("IP35", 35, 1); |
5225 |
|
me->subtype[9]->aliases[0] = "ip35"; |
5226 |
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
5227 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5228 |
} |
} |
5267 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5268 |
} |
} |
5269 |
|
|
|
/* Evaluation Boards (MALTA etc): */ |
|
|
me = machine_entry_new("evbmips", ARCH_MIPS, |
|
|
MACHINE_EVBMIPS, 1, 2); |
|
|
me->aliases[0] = "evbmips"; |
|
|
me->subtype[0] = machine_entry_subtype_new("Malta", |
|
|
MACHINE_EVBMIPS_MALTA, 1); |
|
|
me->subtype[0]->aliases[0] = "malta"; |
|
|
me->subtype[1] = machine_entry_subtype_new("PB1000", |
|
|
MACHINE_EVBMIPS_PB1000, 1); |
|
|
me->subtype[1]->aliases[0] = "pb1000"; |
|
|
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
|
|
me->next = first_machine_entry; first_machine_entry = me; |
|
|
} |
|
|
|
|
5270 |
/* Macintosh (PPC): */ |
/* Macintosh (PPC): */ |
5271 |
me = machine_entry_new("Macintosh (PPC)", ARCH_PPC, |
me = machine_entry_new("Macintosh (PPC)", ARCH_PPC, |
5272 |
MACHINE_MACPPC, 1, 2); |
MACHINE_MACPPC, 1, 2); |
5282 |
} |
} |
5283 |
|
|
5284 |
/* HPCmips: */ |
/* HPCmips: */ |
5285 |
me = machine_entry_new("Handheld MIPS (HPC)", |
me = machine_entry_new("Handheld MIPS (HPCmips)", |
5286 |
ARCH_MIPS, MACHINE_HPCMIPS, 2, 8); |
ARCH_MIPS, MACHINE_HPCMIPS, 1, 8); |
5287 |
me->aliases[0] = "hpcmips"; |
me->aliases[0] = "hpcmips"; |
|
me->aliases[1] = "hpc"; |
|
5288 |
me->subtype[0] = machine_entry_subtype_new( |
me->subtype[0] = machine_entry_subtype_new( |
5289 |
"Casio Cassiopeia BE-300", MACHINE_HPCMIPS_CASIO_BE300, 2); |
"Casio Cassiopeia BE-300", MACHINE_HPCMIPS_CASIO_BE300, 2); |
5290 |
me->subtype[0]->aliases[0] = "be-300"; |
me->subtype[0]->aliases[0] = "be-300"; |
5325 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5326 |
} |
} |
5327 |
|
|
|
/* Generic "bare" URISC machine: */ |
|
|
me = machine_entry_new("Generic \"bare\" URISC machine", ARCH_URISC, |
|
|
MACHINE_BAREURISC, 1, 0); |
|
|
me->aliases[0] = "bareurisc"; |
|
|
if (cpu_family_ptr_by_number(ARCH_URISC) != NULL) { |
|
|
me->next = first_machine_entry; first_machine_entry = me; |
|
|
} |
|
|
|
|
5328 |
/* Generic "bare" SPARC machine: */ |
/* Generic "bare" SPARC machine: */ |
5329 |
me = machine_entry_new("Generic \"bare\" SPARC machine", ARCH_SPARC, |
me = machine_entry_new("Generic \"bare\" SPARC machine", ARCH_SPARC, |
5330 |
MACHINE_BARESPARC, 1, 0); |
MACHINE_BARESPARC, 1, 0); |
5349 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5350 |
} |
} |
5351 |
|
|
5352 |
/* Generic "bare" HPPA machine: */ |
/* Generic "bare" M68K machine: */ |
5353 |
me = machine_entry_new("Generic \"bare\" HPPA machine", ARCH_HPPA, |
me = machine_entry_new("Generic \"bare\" M68K machine", ARCH_M68K, |
5354 |
MACHINE_BAREHPPA, 1, 0); |
MACHINE_BAREM68K, 1, 0); |
5355 |
me->aliases[0] = "barehppa"; |
me->aliases[0] = "barem68k"; |
5356 |
if (cpu_family_ptr_by_number(ARCH_HPPA) != NULL) { |
if (cpu_family_ptr_by_number(ARCH_M68K) != NULL) { |
5357 |
|
me->next = first_machine_entry; first_machine_entry = me; |
5358 |
|
} |
5359 |
|
|
5360 |
|
/* Generic "bare" IA64 machine: */ |
5361 |
|
me = machine_entry_new("Generic \"bare\" IA64 machine", ARCH_IA64, |
5362 |
|
MACHINE_BAREIA64, 1, 0); |
5363 |
|
me->aliases[0] = "bareia64"; |
5364 |
|
if (cpu_family_ptr_by_number(ARCH_IA64) != NULL) { |
5365 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5366 |
} |
} |
5367 |
|
|
5381 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5382 |
} |
} |
5383 |
|
|
5384 |
|
/* Evaluation Boards (MALTA etc): */ |
5385 |
|
me = machine_entry_new("Evaluation boards (evbmips)", ARCH_MIPS, |
5386 |
|
MACHINE_EVBMIPS, 1, 3); |
5387 |
|
me->aliases[0] = "evbmips"; |
5388 |
|
me->subtype[0] = machine_entry_subtype_new("Malta", |
5389 |
|
MACHINE_EVBMIPS_MALTA, 1); |
5390 |
|
me->subtype[0]->aliases[0] = "malta"; |
5391 |
|
me->subtype[1] = machine_entry_subtype_new("Malta (Big-Endian)", |
5392 |
|
MACHINE_EVBMIPS_MALTA_BE, 1); |
5393 |
|
me->subtype[1]->aliases[0] = "maltabe"; |
5394 |
|
me->subtype[2] = machine_entry_subtype_new("PB1000", |
5395 |
|
MACHINE_EVBMIPS_PB1000, 1); |
5396 |
|
me->subtype[2]->aliases[0] = "pb1000"; |
5397 |
|
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
5398 |
|
me->next = first_machine_entry; first_machine_entry = me; |
5399 |
|
} |
5400 |
|
|
5401 |
/* DECstation: */ |
/* DECstation: */ |
5402 |
me = machine_entry_new("DECstation/DECsystem", |
me = machine_entry_new("DECstation/DECsystem", |
5403 |
ARCH_MIPS, MACHINE_DEC, 3, 9); |
ARCH_MIPS, MACHINE_DEC, 3, 9); |
5529 |
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
if (cpu_family_ptr_by_number(ARCH_MIPS) != NULL) { |
5530 |
me->next = first_machine_entry; first_machine_entry = me; |
me->next = first_machine_entry; first_machine_entry = me; |
5531 |
} |
} |
5532 |
|
|
5533 |
|
/* Alpha: */ |
5534 |
|
me = machine_entry_new("Alpha", ARCH_ALPHA, MACHINE_ALPHA, 1, 1); |
5535 |
|
me->aliases[0] = "alpha"; |
5536 |
|
me->subtype[0] = machine_entry_subtype_new( |
5537 |
|
"DEC 3000/300", ST_DEC_3000_300, 1); |
5538 |
|
me->subtype[0]->aliases[0] = "3000/300"; |
5539 |
|
if (cpu_family_ptr_by_number(ARCH_ALPHA) != NULL) { |
5540 |
|
me->next = first_machine_entry; first_machine_entry = me; |
5541 |
|
} |
5542 |
} |
} |
5543 |
|
|