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_le.c,v 1.51 2006/07/14 16:33:28 debug Exp $ |
* $Id: dev_le.c,v 1.56 2007/06/15 19:11:15 debug Exp $ |
29 |
* |
* |
30 |
* LANCE ethernet, as used in DECstations. |
* COMMENT: LANCE ethernet, as used in DECstations |
31 |
* |
* |
32 |
* This is based on "PMAD-AA TURBOchannel Ethernet Module Functional |
* This is based on "PMAD-AA TURBOchannel Ethernet Module Functional |
33 |
* Specification". I've tried to keep symbol names in this file to what |
* Specification". I've tried to keep symbol names in this file to what |
85 |
|
|
86 |
|
|
87 |
struct le_data { |
struct le_data { |
88 |
int irq_nr; |
struct interrupt irq; |
89 |
|
int irq_asserted; |
90 |
|
|
91 |
uint64_t buf_start; |
uint64_t buf_start; |
92 |
uint64_t buf_end; |
uint64_t buf_end; |
290 |
/* Start of a new packet: */ |
/* Start of a new packet: */ |
291 |
if (stp) { |
if (stp) { |
292 |
d->tx_packet_len = buflen; |
d->tx_packet_len = buflen; |
293 |
d->tx_packet = malloc(buflen); |
CHECK_ALLOCATION(d->tx_packet = malloc(buflen)); |
|
if (d->tx_packet == NULL) { |
|
|
fprintf(stderr, "out of memory (1) in " |
|
|
"le_tx()\n"); |
|
|
exit(1); |
|
|
} |
|
294 |
} else { |
} else { |
295 |
d->tx_packet_len += buflen; |
d->tx_packet_len += buflen; |
296 |
d->tx_packet = realloc(d->tx_packet, d->tx_packet_len); |
CHECK_ALLOCATION(d->tx_packet = |
297 |
if (d->tx_packet == NULL) { |
realloc(d->tx_packet, d->tx_packet_len)); |
|
fprintf(stderr, "out of memory (2) in" |
|
|
" le_tx()\n"); |
|
|
exit(1); |
|
|
} |
|
298 |
} |
} |
299 |
|
|
300 |
/* Copy data from SRAM into the tx packet: */ |
/* Copy data from SRAM into the tx packet: */ |
523 |
} |
} |
524 |
|
|
525 |
|
|
526 |
/* |
DEVICE_TICK(le) |
|
* dev_le_tick(): |
|
|
*/ |
|
|
void dev_le_tick(struct cpu *cpu, void *extra) |
|
527 |
{ |
{ |
528 |
struct le_data *d = (struct le_data *) extra; |
struct le_data *d = extra; |
529 |
|
int new_assert; |
530 |
|
|
531 |
le_register_fix(cpu->machine->emul->net, d); |
le_register_fix(cpu->machine->emul->net, d); |
532 |
|
|
533 |
if (d->reg[0] & LE_INTR && d->reg[0] & LE_INEA) |
new_assert = (d->reg[0] & LE_INTR) && (d->reg[0] & LE_INEA); |
534 |
cpu_interrupt(cpu, d->irq_nr); |
|
535 |
else |
if (new_assert && !d->irq_asserted) |
536 |
cpu_interrupt_ack(cpu, d->irq_nr); |
INTERRUPT_ASSERT(d->irq); |
537 |
|
if (d->irq_asserted && !new_assert) |
538 |
|
INTERRUPT_DEASSERT(d->irq); |
539 |
|
|
540 |
|
d->irq_asserted = new_assert; |
541 |
} |
} |
542 |
|
|
543 |
|
|
600 |
|
|
601 |
DEVICE_ACCESS(le_sram) |
DEVICE_ACCESS(le_sram) |
602 |
{ |
{ |
603 |
|
struct le_data *d = extra; |
604 |
size_t i; |
size_t i; |
605 |
int retval; |
int retval; |
|
struct le_data *d = extra; |
|
606 |
|
|
607 |
#ifdef LE_DEBUG |
#ifdef LE_DEBUG |
608 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
645 |
|
|
646 |
DEVICE_ACCESS(le) |
DEVICE_ACCESS(le) |
647 |
{ |
{ |
648 |
|
struct le_data *d = extra; |
649 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
|
size_t i; |
|
650 |
int retval = 1; |
int retval = 1; |
651 |
struct le_data *d = extra; |
size_t i; |
652 |
|
|
653 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
654 |
idata = memory_readmax64(cpu, data, len); |
idata = memory_readmax64(cpu, data, len); |
759 |
* dev_le_init(): |
* dev_le_init(): |
760 |
*/ |
*/ |
761 |
void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, |
void dev_le_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, |
762 |
uint64_t buf_start, uint64_t buf_end, int irq_nr, int len) |
uint64_t buf_start, uint64_t buf_end, char *irq_path, int len) |
763 |
{ |
{ |
764 |
char *name2; |
char *name2; |
765 |
size_t nlen = 55; |
size_t nlen = 55; |
766 |
struct le_data *d = malloc(sizeof(struct le_data)); |
struct le_data *d; |
|
|
|
|
if (d == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
767 |
|
|
768 |
|
CHECK_ALLOCATION(d = malloc(sizeof(struct le_data))); |
769 |
memset(d, 0, sizeof(struct le_data)); |
memset(d, 0, sizeof(struct le_data)); |
|
d->irq_nr = irq_nr; |
|
770 |
|
|
771 |
d->sram = malloc(SRAM_SIZE); |
INTERRUPT_CONNECT(irq_path, d->irq); |
772 |
if (d->sram == NULL) { |
|
773 |
fprintf(stderr, "out of memory\n"); |
CHECK_ALLOCATION(d->sram = malloc(SRAM_SIZE)); |
|
exit(1); |
|
|
} |
|
774 |
memset(d->sram, 0, SRAM_SIZE); |
memset(d->sram, 0, SRAM_SIZE); |
775 |
|
|
776 |
/* TODO: Are these actually used yet? */ |
/* TODO: Are these actually used yet? */ |
806 |
DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK |
DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK |
807 |
| DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram); |
| DM_READS_HAVE_NO_SIDE_EFFECTS, d->sram); |
808 |
|
|
809 |
name2 = malloc(nlen); |
CHECK_ALLOCATION(name2 = malloc(nlen)); |
|
if (name2 == NULL) { |
|
|
fprintf(stderr, "out of memory in dev_le_init()\n"); |
|
|
exit(1); |
|
|
} |
|
810 |
snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]", |
snprintf(name2, nlen, "le [%02x:%02x:%02x:%02x:%02x:%02x]", |
811 |
d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]); |
d->rom[0], d->rom[1], d->rom[2], d->rom[3], d->rom[4], d->rom[5]); |
812 |
|
|
813 |
memory_device_register(mem, name2, baseaddr + 0x100000, |
memory_device_register(mem, name2, baseaddr + 0x100000, |
814 |
len - 0x100000, dev_le_access, (void *)d, DM_DEFAULT, NULL); |
len - 0x100000, dev_le_access, (void *)d, DM_DEFAULT, NULL); |
815 |
|
|
816 |
machine_add_tickfunction(machine, dev_le_tick, d, LE_TICK_SHIFT, 0.0); |
machine_add_tickfunction(machine, dev_le_tick, d, LE_TICK_SHIFT); |
817 |
|
|
818 |
net_add_nic(machine->emul->net, d, &d->rom[0]); |
net_add_nic(machine->emul->net, d, &d->rom[0]); |
819 |
} |
} |