1 |
/* |
/* |
2 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 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.46 2006/08/30 15:07:47 debug Exp $ |
* $Id: dev_sgi_ip32.c,v 1.51 2007/01/29 18:32:01 debug Exp $ |
29 |
* |
* |
30 |
* SGI IP32 devices. |
* SGI IP32 devices. |
31 |
* |
* |
44 |
#include "bus_pci.h" |
#include "bus_pci.h" |
45 |
#include "console.h" |
#include "console.h" |
46 |
#include "cpu.h" |
#include "cpu.h" |
47 |
|
#include "device.h" |
48 |
#include "devices.h" |
#include "devices.h" |
49 |
#include "emul.h" |
#include "emul.h" |
50 |
#include "machine.h" |
#include "machine.h" |
53 |
#include "net.h" |
#include "net.h" |
54 |
|
|
55 |
#include "crimereg.h" |
#include "crimereg.h" |
|
|
|
56 |
#include "if_mecreg.h" |
#include "if_mecreg.h" |
57 |
|
#include "sgi_macereg.h" |
58 |
|
|
59 |
|
|
60 |
#define CRIME_TICKSHIFT 14 |
#define CRIME_TICKSHIFT 14 |
66 |
uint32_t reg[DEV_MACEPCI_LENGTH / 4]; |
uint32_t reg[DEV_MACEPCI_LENGTH / 4]; |
67 |
}; |
}; |
68 |
|
|
69 |
|
#define DEV_CRIME_LENGTH 0x1000 |
70 |
|
struct crime_data { |
71 |
|
unsigned char reg[DEV_CRIME_LENGTH]; |
72 |
|
struct interrupt irq; |
73 |
|
int use_fb; |
74 |
|
}; |
75 |
|
|
76 |
|
|
77 |
|
/* |
78 |
|
* crime_interrupt_assert(): |
79 |
|
* crime_interrupt_deassert(): |
80 |
|
*/ |
81 |
|
void crime_interrupt_assert(struct interrupt *interrupt) |
82 |
|
{ |
83 |
|
struct crime_data *d = (struct crime_data *) interrupt->extra; |
84 |
|
uint32_t line = interrupt->line, asserted; |
85 |
|
|
86 |
|
d->reg[CRIME_INTSTAT + 4] |= ((line >> 24) & 255); |
87 |
|
d->reg[CRIME_INTSTAT + 5] |= ((line >> 16) & 255); |
88 |
|
d->reg[CRIME_INTSTAT + 6] |= ((line >> 8) & 255); |
89 |
|
d->reg[CRIME_INTSTAT + 7] |= (line & 255); |
90 |
|
|
91 |
|
asserted = |
92 |
|
(d->reg[CRIME_INTSTAT + 4] & d->reg[CRIME_INTMASK + 4]) | |
93 |
|
(d->reg[CRIME_INTSTAT + 5] & d->reg[CRIME_INTMASK + 5]) | |
94 |
|
(d->reg[CRIME_INTSTAT + 6] & d->reg[CRIME_INTMASK + 6]) | |
95 |
|
(d->reg[CRIME_INTSTAT + 7] & d->reg[CRIME_INTMASK + 7]); |
96 |
|
|
97 |
|
if (asserted) |
98 |
|
INTERRUPT_ASSERT(d->irq); |
99 |
|
} |
100 |
|
void crime_interrupt_deassert(struct interrupt *interrupt) |
101 |
|
{ |
102 |
|
struct crime_data *d = (struct crime_data *) interrupt->extra; |
103 |
|
uint32_t line = interrupt->line, asserted; |
104 |
|
|
105 |
|
d->reg[CRIME_INTSTAT + 4] &= ~((line >> 24) & 255); |
106 |
|
d->reg[CRIME_INTSTAT + 5] &= ~((line >> 16) & 255); |
107 |
|
d->reg[CRIME_INTSTAT + 6] &= ~((line >> 8) & 255); |
108 |
|
d->reg[CRIME_INTSTAT + 7] &= ~(line & 255); |
109 |
|
|
110 |
|
asserted = |
111 |
|
(d->reg[CRIME_INTSTAT + 4] & d->reg[CRIME_INTMASK + 4]) | |
112 |
|
(d->reg[CRIME_INTSTAT + 5] & d->reg[CRIME_INTMASK + 5]) | |
113 |
|
(d->reg[CRIME_INTSTAT + 6] & d->reg[CRIME_INTMASK + 6]) | |
114 |
|
(d->reg[CRIME_INTSTAT + 7] & d->reg[CRIME_INTMASK + 7]); |
115 |
|
|
116 |
|
if (!asserted) |
117 |
|
INTERRUPT_DEASSERT(d->irq); |
118 |
|
} |
119 |
|
|
120 |
|
|
121 |
/* |
/* |
122 |
* dev_crime_tick(): |
* dev_crime_tick(): |
155 |
} |
} |
156 |
|
|
157 |
|
|
|
/* |
|
|
* dev_crime_access(): |
|
|
*/ |
|
158 |
DEVICE_ACCESS(crime) |
DEVICE_ACCESS(crime) |
159 |
{ |
{ |
160 |
struct crime_data *d = extra; |
struct crime_data *d = extra; |
200 |
else |
else |
201 |
memcpy(data, &d->reg[relative_addr], len); |
memcpy(data, &d->reg[relative_addr], len); |
202 |
|
|
|
if ((relative_addr >= 0x18 && relative_addr <= 0x1f) || |
|
|
(relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) { |
|
|
/* |
|
|
* Force interrupt re-assertion: |
|
|
* |
|
|
* NOTE: Ugly hack. Hopefully CRMERR is never used. |
|
|
*/ |
|
|
#if 0 |
|
|
/* |
|
|
No. If this is enabled, the mec bugs out on either NetBSD or OpenBSD. |
|
|
TODO. |
|
|
*/ |
|
|
cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */ |
|
|
#endif |
|
|
} |
|
|
|
|
203 |
switch (relative_addr) { |
switch (relative_addr) { |
204 |
case CRIME_CONTROL: /* 0x008 */ |
case CRIME_CONTROL: /* 0x008 */ |
205 |
/* TODO: 64-bit write to CRIME_CONTROL, but some things |
/* TODO: 64-bit write to CRIME_CONTROL, but some things |
228 |
"control 0x%016llx ]\n", (long long)idata); |
"control 0x%016llx ]\n", (long long)idata); |
229 |
} |
} |
230 |
break; |
break; |
231 |
#if 0 |
|
232 |
case CRIME_INTSTAT: /* 0x010, Current interrupt status */ |
case CRIME_INTSTAT: /* 0x010, Current interrupt status */ |
233 |
case 0x14: |
case CRIME_INTSTAT + 4: |
234 |
case CRIME_INTMASK: /* 0x018, Current interrupt mask */ |
case CRIME_INTMASK: /* 0x018, Current interrupt mask */ |
235 |
case 0x1c: |
case CRIME_INTMASK + 4: |
236 |
|
if ((d->reg[CRIME_INTSTAT + 4] & d->reg[CRIME_INTMASK + 4]) | |
237 |
|
(d->reg[CRIME_INTSTAT + 5] & d->reg[CRIME_INTMASK + 5]) | |
238 |
|
(d->reg[CRIME_INTSTAT + 6] & d->reg[CRIME_INTMASK + 6]) | |
239 |
|
(d->reg[CRIME_INTSTAT + 7] & d->reg[CRIME_INTMASK + 7]) ) |
240 |
|
INTERRUPT_ASSERT(d->irq); |
241 |
|
else |
242 |
|
INTERRUPT_DEASSERT(d->irq); |
243 |
|
break; |
244 |
case 0x34: |
case 0x34: |
245 |
/* don't dump debug info for these */ |
/* don't dump debug info for these */ |
246 |
break; |
break; |
247 |
#endif |
|
248 |
default: |
default: |
249 |
if (writeflag==MEM_READ) { |
if (writeflag==MEM_READ) { |
250 |
debug("[ crime: read from 0x%x, len=%i:", |
debug("[ crime: read from 0x%x, len=%i:", |
267 |
/* |
/* |
268 |
* dev_crime_init(): |
* dev_crime_init(): |
269 |
*/ |
*/ |
270 |
struct crime_data *dev_crime_init(struct machine *machine, struct memory *mem, |
void dev_crime_init(struct machine *machine, struct memory *mem, |
271 |
uint64_t baseaddr, int irq_nr, int use_fb) |
uint64_t baseaddr, char *irq_path, int use_fb) |
272 |
{ |
{ |
273 |
struct crime_data *d; |
struct crime_data *d; |
274 |
|
char tmpstr[200]; |
275 |
|
int i; |
276 |
|
|
277 |
d = malloc(sizeof(struct crime_data)); |
d = malloc(sizeof(struct crime_data)); |
278 |
if (d == NULL) { |
if (d == NULL) { |
280 |
exit(1); |
exit(1); |
281 |
} |
} |
282 |
memset(d, 0, sizeof(struct crime_data)); |
memset(d, 0, sizeof(struct crime_data)); |
|
d->irq_nr = irq_nr; |
|
283 |
d->use_fb = use_fb; |
d->use_fb = use_fb; |
284 |
|
|
285 |
|
INTERRUPT_CONNECT(irq_path, d->irq); |
286 |
|
|
287 |
|
/* Register 32 crime interrupts (hexadecimal names): */ |
288 |
|
for (i=0; i<32; i++) { |
289 |
|
struct interrupt template; |
290 |
|
char name[400]; |
291 |
|
snprintf(name, sizeof(name), "%s.crime.0x%x", irq_path, 1 << i); |
292 |
|
memset(&template, 0, sizeof(template)); |
293 |
|
template.line = 1 << i; |
294 |
|
template.name = name; |
295 |
|
template.extra = d; |
296 |
|
template.interrupt_assert = crime_interrupt_assert; |
297 |
|
template.interrupt_deassert = crime_interrupt_deassert; |
298 |
|
interrupt_handler_register(&template); |
299 |
|
} |
300 |
|
|
301 |
memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH, |
memory_device_register(mem, "crime", baseaddr, DEV_CRIME_LENGTH, |
302 |
dev_crime_access, d, DM_DEFAULT, NULL); |
dev_crime_access, d, DM_DEFAULT, NULL); |
303 |
|
|
304 |
|
snprintf(tmpstr, sizeof(tmpstr), "mace addr=0x1f310000 irq=%s.crime", |
305 |
|
irq_path); |
306 |
|
device_add(machine, tmpstr); |
307 |
|
|
308 |
machine_add_tickfunction(machine, dev_crime_tick, d, |
machine_add_tickfunction(machine, dev_crime_tick, d, |
309 |
CRIME_TICKSHIFT, 0.0); |
CRIME_TICKSHIFT, 0.0); |
|
|
|
|
return d; |
|
310 |
} |
} |
311 |
|
|
312 |
|
|
313 |
/****************************************************************************/ |
/****************************************************************************/ |
314 |
|
|
315 |
|
|
316 |
|
#define DEV_MACE_LENGTH 0x100 |
317 |
|
struct mace_data { |
318 |
|
unsigned char reg[DEV_MACE_LENGTH]; |
319 |
|
struct interrupt irq_periph; |
320 |
|
struct interrupt irq_misc; |
321 |
|
}; |
322 |
|
|
323 |
|
|
324 |
/* |
/* |
325 |
* dev_mace_access(): |
* mace_interrupt_assert(): |
326 |
|
* mace_interrupt_deassert(): |
327 |
*/ |
*/ |
328 |
|
void mace_interrupt_assert(struct interrupt *interrupt) |
329 |
|
{ |
330 |
|
struct mace_data *d = (struct mace_data *) interrupt->extra; |
331 |
|
uint32_t line = 1 << interrupt->line; |
332 |
|
|
333 |
|
d->reg[MACE_ISA_INT_STATUS + 4] |= ((line >> 24) & 255); |
334 |
|
d->reg[MACE_ISA_INT_STATUS + 5] |= ((line >> 16) & 255); |
335 |
|
d->reg[MACE_ISA_INT_STATUS + 6] |= ((line >> 8) & 255); |
336 |
|
d->reg[MACE_ISA_INT_STATUS + 7] |= (line & 255); |
337 |
|
|
338 |
|
/* High bits = PERIPH */ |
339 |
|
if ((d->reg[MACE_ISA_INT_STATUS+4] & d->reg[MACE_ISA_INT_MASK+4]) | |
340 |
|
(d->reg[MACE_ISA_INT_STATUS+5] & d->reg[MACE_ISA_INT_MASK+5])) |
341 |
|
INTERRUPT_ASSERT(d->irq_periph); |
342 |
|
|
343 |
|
/* Low bits = MISC */ |
344 |
|
if ((d->reg[MACE_ISA_INT_STATUS+6] & d->reg[MACE_ISA_INT_MASK+6]) | |
345 |
|
(d->reg[MACE_ISA_INT_STATUS+7] & d->reg[MACE_ISA_INT_MASK+7])) |
346 |
|
INTERRUPT_ASSERT(d->irq_misc); |
347 |
|
} |
348 |
|
void mace_interrupt_deassert(struct interrupt *interrupt) |
349 |
|
{ |
350 |
|
struct mace_data *d = (struct mace_data *) interrupt->extra; |
351 |
|
uint32_t line = 1 << interrupt->line; |
352 |
|
|
353 |
|
d->reg[MACE_ISA_INT_STATUS + 4] |= ((line >> 24) & 255); |
354 |
|
d->reg[MACE_ISA_INT_STATUS + 5] |= ((line >> 16) & 255); |
355 |
|
d->reg[MACE_ISA_INT_STATUS + 6] |= ((line >> 8) & 255); |
356 |
|
d->reg[MACE_ISA_INT_STATUS + 7] |= (line & 255); |
357 |
|
|
358 |
|
/* High bits = PERIPH */ |
359 |
|
if (!((d->reg[MACE_ISA_INT_STATUS+4] & d->reg[MACE_ISA_INT_MASK+4]) | |
360 |
|
(d->reg[MACE_ISA_INT_STATUS+5] & d->reg[MACE_ISA_INT_MASK+5]))) |
361 |
|
INTERRUPT_DEASSERT(d->irq_periph); |
362 |
|
|
363 |
|
/* Low bits = MISC */ |
364 |
|
if (!((d->reg[MACE_ISA_INT_STATUS+6] & d->reg[MACE_ISA_INT_MASK+6]) | |
365 |
|
(d->reg[MACE_ISA_INT_STATUS+7] & d->reg[MACE_ISA_INT_MASK+7]))) |
366 |
|
INTERRUPT_DEASSERT(d->irq_misc); |
367 |
|
} |
368 |
|
|
369 |
|
|
370 |
DEVICE_ACCESS(mace) |
DEVICE_ACCESS(mace) |
371 |
{ |
{ |
372 |
size_t i; |
size_t i; |
377 |
else |
else |
378 |
memcpy(data, &d->reg[relative_addr], len); |
memcpy(data, &d->reg[relative_addr], len); |
379 |
|
|
|
if ((relative_addr >= 0x18 && relative_addr <= 0x1f) || |
|
|
(relative_addr+len-1 >= 0x18 && relative_addr+len-1 <= 0x1f)) |
|
|
cpu_interrupt_ack(cpu, 8); /* CRM_INT_CRMERR); */ |
|
|
|
|
380 |
switch (relative_addr) { |
switch (relative_addr) { |
381 |
#if 0 |
|
382 |
case 0x10: /* Current interrupt assertions */ |
case MACE_ISA_INT_STATUS: /* Current interrupt assertions */ |
383 |
case 0x14: |
case MACE_ISA_INT_STATUS + 4: |
384 |
/* don't dump debug info for these */ |
/* don't dump debug info for these */ |
385 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
386 |
fatal("[ NOTE/TODO: WRITE to mace intr: " |
fatal("[ NOTE/TODO: WRITE to mace intr: " |
390 |
fatal(" (len=%i) ]\n", len); |
fatal(" (len=%i) ]\n", len); |
391 |
} |
} |
392 |
break; |
break; |
393 |
case 0x18: /* Interrupt mask */ |
case MACE_ISA_INT_MASK: /* Current interrupt mask */ |
394 |
case 0x1c: |
case MACE_ISA_INT_MASK + 4: |
395 |
/* don't dump debug info for these */ |
if ((d->reg[MACE_ISA_INT_STATUS+4]&d->reg[MACE_ISA_INT_MASK+4])| |
396 |
|
(d->reg[MACE_ISA_INT_STATUS+5]&d->reg[MACE_ISA_INT_MASK+5])) |
397 |
|
INTERRUPT_ASSERT(d->irq_periph); |
398 |
|
else |
399 |
|
INTERRUPT_DEASSERT(d->irq_periph); |
400 |
|
|
401 |
|
if ((d->reg[MACE_ISA_INT_STATUS+6]&d->reg[MACE_ISA_INT_MASK+6])| |
402 |
|
(d->reg[MACE_ISA_INT_STATUS+7]&d->reg[MACE_ISA_INT_MASK+7])) |
403 |
|
INTERRUPT_ASSERT(d->irq_misc); |
404 |
|
else |
405 |
|
INTERRUPT_DEASSERT(d->irq_misc); |
406 |
break; |
break; |
407 |
#endif |
|
408 |
default: |
default: |
409 |
if (writeflag == MEM_READ) { |
if (writeflag == MEM_READ) { |
410 |
debug("[ mace: read from 0x%x:", (int)relative_addr); |
debug("[ mace: read from 0x%x:", (int)relative_addr); |
423 |
} |
} |
424 |
|
|
425 |
|
|
426 |
/* |
DEVINIT(mace) |
|
* dev_mace_init(): |
|
|
*/ |
|
|
struct mace_data *dev_mace_init(struct memory *mem, uint64_t baseaddr, |
|
|
int irqnr) |
|
427 |
{ |
{ |
428 |
struct mace_data *d; |
struct mace_data *d; |
429 |
|
char tmpstr[300]; |
430 |
|
int i; |
431 |
|
|
432 |
d = malloc(sizeof(struct mace_data)); |
d = malloc(sizeof(struct mace_data)); |
433 |
if (d == NULL) { |
if (d == NULL) { |
435 |
exit(1); |
exit(1); |
436 |
} |
} |
437 |
memset(d, 0, sizeof(struct mace_data)); |
memset(d, 0, sizeof(struct mace_data)); |
|
d->irqnr = irqnr; |
|
438 |
|
|
439 |
memory_device_register(mem, "mace", baseaddr, DEV_MACE_LENGTH, |
snprintf(tmpstr, sizeof(tmpstr), "%s.0x%x", |
440 |
dev_mace_access, d, DM_DEFAULT, NULL); |
devinit->interrupt_path, MACE_PERIPH_SERIAL); |
441 |
|
INTERRUPT_CONNECT(tmpstr, d->irq_periph); |
442 |
|
|
443 |
|
snprintf(tmpstr, sizeof(tmpstr), "%s.0x%x", |
444 |
|
devinit->interrupt_path, MACE_PERIPH_SERIAL); |
445 |
|
INTERRUPT_CONNECT(tmpstr, d->irq_misc); |
446 |
|
|
447 |
return d; |
/* |
448 |
|
* For Mace interrupts MACE_PERIPH_SERIAL and MACE_PERIPH_MISC, |
449 |
|
* register 32 mace interrupts each. |
450 |
|
*/ |
451 |
|
/* Register 32 crime interrupts (hexadecimal names): */ |
452 |
|
for (i=0; i<32; i++) { |
453 |
|
struct interrupt template; |
454 |
|
char name[400]; |
455 |
|
snprintf(name, sizeof(name), "%s.0x%x.mace.%i", |
456 |
|
devinit->interrupt_path, MACE_PERIPH_SERIAL, i); |
457 |
|
memset(&template, 0, sizeof(template)); |
458 |
|
template.line = i; |
459 |
|
template.name = name; |
460 |
|
template.extra = d; |
461 |
|
template.interrupt_assert = mace_interrupt_assert; |
462 |
|
template.interrupt_deassert = mace_interrupt_deassert; |
463 |
|
interrupt_handler_register(&template); |
464 |
|
|
465 |
|
snprintf(name, sizeof(name), "%s.0x%x.mace.%i", |
466 |
|
devinit->interrupt_path, MACE_PERIPH_MISC, i); |
467 |
|
memset(&template, 0, sizeof(template)); |
468 |
|
template.line = i; |
469 |
|
template.name = name; |
470 |
|
template.extra = d; |
471 |
|
template.interrupt_assert = mace_interrupt_assert; |
472 |
|
template.interrupt_deassert = mace_interrupt_deassert; |
473 |
|
interrupt_handler_register(&template); |
474 |
|
} |
475 |
|
|
476 |
|
memory_device_register(devinit->machine->memory, devinit->name, |
477 |
|
devinit->addr, DEV_MACE_LENGTH, dev_mace_access, d, |
478 |
|
DM_DEFAULT, NULL); |
479 |
|
|
480 |
|
devinit->return_ptr = d; |
481 |
|
return 1; |
482 |
} |
} |
483 |
|
|
484 |
|
|
485 |
/****************************************************************************/ |
/****************************************************************************/ |
486 |
|
|
487 |
|
|
|
/* |
|
|
* dev_macepci_access(): |
|
|
*/ |
|
488 |
DEVICE_ACCESS(macepci) |
DEVICE_ACCESS(macepci) |
489 |
{ |
{ |
490 |
struct macepci_data *d = (struct macepci_data *) extra; |
struct macepci_data *d = (struct macepci_data *) extra; |
552 |
* dev_macepci_init(): |
* dev_macepci_init(): |
553 |
*/ |
*/ |
554 |
struct pci_data *dev_macepci_init(struct machine *machine, |
struct pci_data *dev_macepci_init(struct machine *machine, |
555 |
struct memory *mem, uint64_t baseaddr, int pciirq) |
struct memory *mem, uint64_t baseaddr, char *irq_path) |
556 |
{ |
{ |
557 |
struct macepci_data *d = malloc(sizeof(struct macepci_data)); |
struct macepci_data *d = malloc(sizeof(struct macepci_data)); |
558 |
if (d == NULL) { |
if (d == NULL) { |
561 |
} |
} |
562 |
memset(d, 0, sizeof(struct macepci_data)); |
memset(d, 0, sizeof(struct macepci_data)); |
563 |
|
|
564 |
|
/* TODO: PCI vs ISA interrupt? */ |
565 |
|
|
566 |
d->pci_data = bus_pci_init(machine, |
d->pci_data = bus_pci_init(machine, |
567 |
pciirq, |
irq_path, |
|
0, |
|
568 |
0, |
0, |
569 |
0, |
0, |
570 |
0, |
0, |
571 |
0, |
0, |
572 |
|
"TODO: pci irq path", |
573 |
0x18000003, /* ISA portbase */ |
0x18000003, /* ISA portbase */ |
574 |
0, |
0, |
575 |
0); |
irq_path); |
576 |
|
|
577 |
memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH, |
memory_device_register(mem, "macepci", baseaddr, DEV_MACEPCI_LENGTH, |
578 |
dev_macepci_access, (void *)d, DM_DEFAULT, NULL); |
dev_macepci_access, (void *)d, DM_DEFAULT, NULL); |
601 |
struct sgi_mec_data { |
struct sgi_mec_data { |
602 |
uint64_t reg[DEV_SGI_MEC_LENGTH / sizeof(uint64_t)]; |
uint64_t reg[DEV_SGI_MEC_LENGTH / sizeof(uint64_t)]; |
603 |
|
|
604 |
int irq_nr; |
struct interrupt irq; |
605 |
unsigned char macaddr[6]; |
unsigned char macaddr[6]; |
606 |
|
|
607 |
unsigned char cur_tx_packet[MAX_TX_PACKET_LEN]; |
unsigned char cur_tx_packet[MAX_TX_PACKET_LEN]; |
921 |
sizeof(uint64_t)] & MEC_INT_STATUS_MASK)); |
sizeof(uint64_t)] & MEC_INT_STATUS_MASK)); |
922 |
fflush(stdout); |
fflush(stdout); |
923 |
#endif |
#endif |
924 |
cpu_interrupt(cpu, d->irq_nr); |
INTERRUPT_ASSERT(d->irq); |
925 |
} else |
} else |
926 |
cpu_interrupt_ack(cpu, d->irq_nr); |
INTERRUPT_DEASSERT(d->irq); |
927 |
} |
} |
928 |
|
|
929 |
|
|
|
/* |
|
|
* dev_sgi_mec_access(): |
|
|
*/ |
|
930 |
DEVICE_ACCESS(sgi_mec) |
DEVICE_ACCESS(sgi_mec) |
931 |
{ |
{ |
932 |
struct sgi_mec_data *d = (struct sgi_mec_data *) extra; |
struct sgi_mec_data *d = (struct sgi_mec_data *) extra; |
1087 |
* dev_sgi_mec_init(): |
* dev_sgi_mec_init(): |
1088 |
*/ |
*/ |
1089 |
void dev_sgi_mec_init(struct machine *machine, struct memory *mem, |
void dev_sgi_mec_init(struct machine *machine, struct memory *mem, |
1090 |
uint64_t baseaddr, int irq_nr, unsigned char *macaddr) |
uint64_t baseaddr, char *irq_path, unsigned char *macaddr) |
1091 |
{ |
{ |
1092 |
char *name2; |
char *name2; |
1093 |
size_t nlen = 55; |
size_t nlen = 55; |
1098 |
exit(1); |
exit(1); |
1099 |
} |
} |
1100 |
memset(d, 0, sizeof(struct sgi_mec_data)); |
memset(d, 0, sizeof(struct sgi_mec_data)); |
|
d->irq_nr = irq_nr; |
|
|
memcpy(d->macaddr, macaddr, 6); |
|
1101 |
|
|
1102 |
|
INTERRUPT_CONNECT(irq_path, d->irq); |
1103 |
|
memcpy(d->macaddr, macaddr, 6); |
1104 |
mec_reset(d); |
mec_reset(d); |
1105 |
|
|
1106 |
name2 = malloc(nlen); |
name2 = malloc(nlen); |
1131 |
}; |
}; |
1132 |
|
|
1133 |
|
|
|
/* |
|
|
* dev_sgi_ust_access(): |
|
|
*/ |
|
1134 |
DEVICE_ACCESS(sgi_ust) |
DEVICE_ACCESS(sgi_ust) |
1135 |
{ |
{ |
1136 |
struct sgi_ust_data *d = (struct sgi_ust_data *) extra; |
struct sgi_ust_data *d = (struct sgi_ust_data *) extra; |
1203 |
uint32_t reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)]; |
uint32_t reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)]; |
1204 |
}; |
}; |
1205 |
|
|
1206 |
/* |
|
|
* dev_sgi_mte_access(): |
|
|
*/ |
|
1207 |
DEVICE_ACCESS(sgi_mte) |
DEVICE_ACCESS(sgi_mte) |
1208 |
{ |
{ |
1209 |
struct sgi_mte_data *d = (struct sgi_mte_data *) extra; |
struct sgi_mte_data *d = (struct sgi_mte_data *) extra; |