1 |
/* |
/* |
2 |
* Copyright (C) 2003-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_sgi_ip32.c,v 1.38 2005/11/21 09:17:27 debug Exp $ |
* $Id: dev_sgi_ip32.c,v 1.45 2006/03/04 12:38:48 debug Exp $ |
29 |
* |
* |
30 |
* SGI IP32 devices. |
* SGI IP32 devices. |
31 |
* |
* |
106 |
/* |
/* |
107 |
* dev_crime_access(): |
* dev_crime_access(): |
108 |
*/ |
*/ |
109 |
int dev_crime_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(crime) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
110 |
{ |
{ |
111 |
struct crime_data *d = extra; |
struct crime_data *d = extra; |
112 |
uint64_t idata = 0; |
uint64_t idata = 0; |
113 |
int i; |
size_t i; |
114 |
|
|
115 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
116 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
180 |
idata &= ~0x200; |
idata &= ~0x200; |
181 |
} |
} |
182 |
if (idata & 0x800) { |
if (idata & 0x800) { |
183 |
|
int j; |
184 |
|
|
185 |
/* This is used by the IP32 PROM's |
/* This is used by the IP32 PROM's |
186 |
"reboot" command: */ |
"reboot" command: */ |
187 |
for (i=0; i<cpu->machine->ncpus; i++) |
for (j=0; j<cpu->machine->ncpus; j++) |
188 |
cpu->machine->cpus[i]->running = 0; |
cpu->machine->cpus[j]->running = 0; |
189 |
cpu->machine-> |
cpu->machine-> |
190 |
exit_without_entering_debugger = 1; |
exit_without_entering_debugger = 1; |
191 |
idata &= ~0x800; |
idata &= ~0x800; |
242 |
|
|
243 |
memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH, |
memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH, |
244 |
dev_crime_access, d, DM_DEFAULT, NULL); |
dev_crime_access, d, DM_DEFAULT, NULL); |
245 |
machine_add_tickfunction(machine, dev_crime_tick, d, CRIME_TICKSHIFT); |
machine_add_tickfunction(machine, dev_crime_tick, d, |
246 |
|
CRIME_TICKSHIFT, 0.0); |
247 |
|
|
248 |
return d; |
return d; |
249 |
} |
} |
255 |
/* |
/* |
256 |
* dev_mace_access(): |
* dev_mace_access(): |
257 |
*/ |
*/ |
258 |
int dev_mace_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(mace) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
259 |
{ |
{ |
260 |
int i; |
size_t i; |
261 |
struct mace_data *d = extra; |
struct mace_data *d = extra; |
262 |
|
|
263 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
334 |
/* |
/* |
335 |
* dev_macepci_access(): |
* dev_macepci_access(): |
336 |
*/ |
*/ |
337 |
int dev_macepci_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(macepci) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
338 |
{ |
{ |
339 |
struct macepci_data *d = (struct macepci_data *) extra; |
struct macepci_data *d = (struct macepci_data *) extra; |
340 |
uint64_t idata = 0, odata=0; |
uint64_t idata = 0, odata=0; |
341 |
int regnr, res = 1; |
int regnr, res = 1, bus, dev, func, pcireg; |
342 |
|
|
343 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
344 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
347 |
|
|
348 |
/* Read from/write to the macepci: */ |
/* Read from/write to the macepci: */ |
349 |
switch (relative_addr) { |
switch (relative_addr) { |
350 |
|
|
351 |
case 0x00: /* Error address */ |
case 0x00: /* Error address */ |
352 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
353 |
} else { |
} else { |
354 |
odata = 0; |
odata = 0; |
355 |
} |
} |
356 |
break; |
break; |
357 |
|
|
358 |
case 0x04: /* Error flags */ |
case 0x04: /* Error flags */ |
359 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
360 |
} else { |
} else { |
361 |
odata = 0x06; |
odata = 0x06; |
362 |
} |
} |
363 |
break; |
break; |
364 |
|
|
365 |
case 0x0c: /* Revision number */ |
case 0x0c: /* Revision number */ |
366 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
367 |
} else { |
} else { |
368 |
odata = 0x01; |
odata = 0x01; |
369 |
} |
} |
370 |
break; |
break; |
371 |
|
|
372 |
case 0xcf8: /* PCI ADDR */ |
case 0xcf8: /* PCI ADDR */ |
373 |
|
bus_pci_decompose_1(idata, &bus, &dev, &func, &pcireg); |
374 |
|
bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, pcireg); |
375 |
|
break; |
376 |
|
|
377 |
case 0xcfc: /* PCI DATA */ |
case 0xcfc: /* PCI DATA */ |
378 |
if (writeflag == MEM_WRITE) { |
bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ? |
379 |
res = bus_pci_access(cpu, mem, relative_addr, |
&odata : &idata, len, writeflag); |
|
&idata, len, writeflag, d->pci_data); |
|
|
} else { |
|
|
res = bus_pci_access(cpu, mem, relative_addr, |
|
|
&odata, len, writeflag, d->pci_data); |
|
|
} |
|
380 |
break; |
break; |
381 |
|
|
382 |
default: |
default: |
383 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
384 |
debug("[ macepci: unimplemented write to address " |
debug("[ macepci: unimplemented write to address " |
400 |
/* |
/* |
401 |
* dev_macepci_init(): |
* dev_macepci_init(): |
402 |
*/ |
*/ |
403 |
struct pci_data *dev_macepci_init(struct memory *mem, uint64_t baseaddr, |
struct pci_data *dev_macepci_init(struct machine *machine, |
404 |
int pciirq) |
struct memory *mem, uint64_t baseaddr, int pciirq) |
405 |
{ |
{ |
406 |
struct macepci_data *d = malloc(sizeof(struct macepci_data)); |
struct macepci_data *d = malloc(sizeof(struct macepci_data)); |
407 |
if (d == NULL) { |
if (d == NULL) { |
410 |
} |
} |
411 |
memset(d, 0, sizeof(struct macepci_data)); |
memset(d, 0, sizeof(struct macepci_data)); |
412 |
|
|
413 |
d->pci_data = bus_pci_init(pciirq, 0,0, 0,0,0, 0,0,0); |
d->pci_data = bus_pci_init(machine, pciirq, 0,0, 0,0,0, 0,0,0); |
414 |
|
|
415 |
memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH, |
memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH, |
416 |
dev_macepci_access, (void *)d, DM_DEFAULT, NULL); |
dev_macepci_access, (void *)d, DM_DEFAULT, NULL); |
768 |
/* |
/* |
769 |
* dev_sgi_mec_access(): |
* dev_sgi_mec_access(): |
770 |
*/ |
*/ |
771 |
int dev_sgi_mec_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_mec) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
772 |
{ |
{ |
773 |
struct sgi_mec_data *d = (struct sgi_mec_data *) extra; |
struct sgi_mec_data *d = (struct sgi_mec_data *) extra; |
774 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
957 |
DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d, |
DEV_SGI_MEC_LENGTH, dev_sgi_mec_access, (void *)d, |
958 |
DM_DEFAULT, NULL); |
DM_DEFAULT, NULL); |
959 |
|
|
960 |
machine_add_tickfunction(machine, dev_sgi_mec_tick, d, MEC_TICK_SHIFT); |
machine_add_tickfunction(machine, dev_sgi_mec_tick, d, |
961 |
|
MEC_TICK_SHIFT, 0.0); |
962 |
|
|
963 |
net_add_nic(machine->emul->net, d, macaddr); |
net_add_nic(machine->emul->net, d, macaddr); |
964 |
} |
} |
975 |
/* |
/* |
976 |
* dev_sgi_ust_access(): |
* dev_sgi_ust_access(): |
977 |
*/ |
*/ |
978 |
int dev_sgi_ust_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_ust) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
979 |
{ |
{ |
980 |
struct sgi_ust_data *d = (struct sgi_ust_data *) extra; |
struct sgi_ust_data *d = (struct sgi_ust_data *) extra; |
981 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
1050 |
/* |
/* |
1051 |
* dev_sgi_mte_access(): |
* dev_sgi_mte_access(): |
1052 |
*/ |
*/ |
1053 |
int dev_sgi_mte_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(sgi_mte) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
1054 |
{ |
{ |
1055 |
struct sgi_mte_data *d = (struct sgi_mte_data *) extra; |
struct sgi_mte_data *d = (struct sgi_mte_data *) extra; |
1056 |
uint64_t first_addr, last_addr, zerobuflen, fill_addr, fill_len; |
uint64_t first_addr, last_addr, zerobuflen, fill_addr, fill_len; |
1157 |
uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)] |
uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)] |
1158 |
>> 16) & 0xfff; |
>> 16) & 0xfff; |
1159 |
uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff; |
uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff; |
1160 |
int y; |
uint32_t y; |
1161 |
|
|
1162 |
op >>= 24; |
op >>= 24; |
1163 |
|
|
1203 |
uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)] |
uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)] |
1204 |
>> 16) & 0xfff; |
>> 16) & 0xfff; |
1205 |
uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff; |
uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff; |
1206 |
int x,y; |
size_t x, y; |
1207 |
|
|
1208 |
if (x2 < x1) { |
if (x2 < x1) { |
1209 |
int tmp = x1; x1 = x2; x2 = tmp; |
int tmp = x1; x1 = x2; x2 = tmp; |
1210 |
} |
} |
1213 |
} |
} |
1214 |
if (x2-x1 <= 15) |
if (x2-x1 <= 15) |
1215 |
data <<= 16; |
data <<= 16; |
1216 |
|
|
1217 |
x=x1; y=y1; |
x=x1; y=y1; |
1218 |
while (x <= x2 && y <= y2) { |
while (x <= x2 && y <= y2) { |
1219 |
unsigned char buf = color; |
unsigned char buf = color; |