Revision 94e1a912 hw/pcnet.c
b/hw/pcnet.c | ||
---|---|---|
35 | 35 |
* http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR92C990.txt |
36 | 36 |
*/ |
37 | 37 |
|
38 |
#include "sysbus.h" |
|
39 | 38 |
#include "pci.h" |
40 | 39 |
#include "net.h" |
41 | 40 |
#include "loader.h" |
42 | 41 |
#include "qemu-timer.h" |
43 | 42 |
#include "qemu_socket.h" |
44 | 43 |
|
44 |
#include "pcnet.h" |
|
45 |
|
|
45 | 46 |
//#define PCNET_DEBUG |
46 | 47 |
//#define PCNET_DEBUG_IO |
47 | 48 |
//#define PCNET_DEBUG_BCR |
... | ... | |
51 | 52 |
//#define PCNET_DEBUG_MATCH |
52 | 53 |
|
53 | 54 |
|
54 |
#define PCNET_IOPORT_SIZE 0x20 |
|
55 |
#define PCNET_PNPMMIO_SIZE 0x20 |
|
56 |
|
|
57 |
#define PCNET_LOOPTEST_CRC 1 |
|
58 |
#define PCNET_LOOPTEST_NOCRC 2 |
|
59 |
|
|
60 |
|
|
61 |
typedef struct PCNetState_st PCNetState; |
|
62 |
|
|
63 |
struct PCNetState_st { |
|
64 |
VLANClientState *vc; |
|
65 |
NICConf conf; |
|
66 |
QEMUTimer *poll_timer; |
|
67 |
int rap, isr, lnkst; |
|
68 |
uint32_t rdra, tdra; |
|
69 |
uint8_t prom[16]; |
|
70 |
uint16_t csr[128]; |
|
71 |
uint16_t bcr[32]; |
|
72 |
uint64_t timer; |
|
73 |
int mmio_index, xmit_pos; |
|
74 |
uint8_t buffer[4096]; |
|
75 |
int tx_busy; |
|
76 |
qemu_irq irq; |
|
77 |
void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr, |
|
78 |
uint8_t *buf, int len, int do_bswap); |
|
79 |
void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr, |
|
80 |
uint8_t *buf, int len, int do_bswap); |
|
81 |
void *dma_opaque; |
|
82 |
int looptest; |
|
83 |
}; |
|
84 |
|
|
85 | 55 |
typedef struct { |
86 | 56 |
PCIDevice pci_dev; |
87 | 57 |
PCNetState state; |
88 | 58 |
} PCIPCNetState; |
89 | 59 |
|
90 |
typedef struct { |
|
91 |
SysBusDevice busdev; |
|
92 |
PCNetState state; |
|
93 |
} SysBusPCNetState; |
|
94 |
|
|
95 | 60 |
struct qemu_ether_header { |
96 | 61 |
uint8_t ether_dhost[6]; |
97 | 62 |
uint8_t ether_shost[6]; |
... | ... | |
1594 | 1559 |
return val; |
1595 | 1560 |
} |
1596 | 1561 |
|
1597 |
static void pcnet_h_reset(void *opaque)
|
|
1562 |
void pcnet_h_reset(void *opaque) |
|
1598 | 1563 |
{ |
1599 | 1564 |
PCNetState *s = opaque; |
1600 | 1565 |
int i; |
... | ... | |
1650 | 1615 |
return val; |
1651 | 1616 |
} |
1652 | 1617 |
|
1653 |
static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
|
|
1618 |
void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val) |
|
1654 | 1619 |
{ |
1655 | 1620 |
PCNetState *s = opaque; |
1656 | 1621 |
pcnet_poll_timer(s); |
... | ... | |
1673 | 1638 |
pcnet_update_irq(s); |
1674 | 1639 |
} |
1675 | 1640 |
|
1676 |
static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr)
|
|
1641 |
uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr) |
|
1677 | 1642 |
{ |
1678 | 1643 |
PCNetState *s = opaque; |
1679 | 1644 |
uint32_t val = -1; |
... | ... | |
1880 | 1845 |
} |
1881 | 1846 |
|
1882 | 1847 |
|
1883 |
static void pcnet_save(QEMUFile *f, void *opaque)
|
|
1848 |
void pcnet_save(QEMUFile *f, void *opaque) |
|
1884 | 1849 |
{ |
1885 | 1850 |
PCNetState *s = opaque; |
1886 | 1851 |
unsigned int i; |
... | ... | |
1902 | 1867 |
qemu_put_timer(f, s->poll_timer); |
1903 | 1868 |
} |
1904 | 1869 |
|
1905 |
static int pcnet_load(QEMUFile *f, void *opaque, int version_id)
|
|
1870 |
int pcnet_load(QEMUFile *f, void *opaque, int version_id) |
|
1906 | 1871 |
{ |
1907 | 1872 |
PCNetState *s = opaque; |
1908 | 1873 |
int i, dummy; |
... | ... | |
1952 | 1917 |
return pcnet_load(f, &s->state, version_id); |
1953 | 1918 |
} |
1954 | 1919 |
|
1955 |
static void pcnet_common_cleanup(PCNetState *d)
|
|
1920 |
void pcnet_common_cleanup(PCNetState *d) |
|
1956 | 1921 |
{ |
1957 | 1922 |
d->vc = NULL; |
1958 | 1923 |
} |
1959 | 1924 |
|
1960 |
static int pcnet_common_init(DeviceState *dev, PCNetState *s,
|
|
1925 |
int pcnet_common_init(DeviceState *dev, PCNetState *s, |
|
1961 | 1926 |
NetCleanup *cleanup) |
1962 | 1927 |
{ |
1963 | 1928 |
s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s); |
... | ... | |
2093 | 2058 |
pcnet_h_reset(&d->state); |
2094 | 2059 |
} |
2095 | 2060 |
|
2096 |
/* SPARC32 interface */ |
|
2097 |
|
|
2098 |
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failure |
|
2099 |
#include "sun4m.h" |
|
2100 |
|
|
2101 |
static void parent_lance_reset(void *opaque, int irq, int level) |
|
2102 |
{ |
|
2103 |
SysBusPCNetState *d = opaque; |
|
2104 |
if (level) |
|
2105 |
pcnet_h_reset(&d->state); |
|
2106 |
} |
|
2107 |
|
|
2108 |
static void lance_mem_writew(void *opaque, target_phys_addr_t addr, |
|
2109 |
uint32_t val) |
|
2110 |
{ |
|
2111 |
SysBusPCNetState *d = opaque; |
|
2112 |
#ifdef PCNET_DEBUG_IO |
|
2113 |
printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr, |
|
2114 |
val & 0xffff); |
|
2115 |
#endif |
|
2116 |
pcnet_ioport_writew(&d->state, addr, val & 0xffff); |
|
2117 |
} |
|
2118 |
|
|
2119 |
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) |
|
2120 |
{ |
|
2121 |
SysBusPCNetState *d = opaque; |
|
2122 |
uint32_t val; |
|
2123 |
|
|
2124 |
val = pcnet_ioport_readw(&d->state, addr); |
|
2125 |
#ifdef PCNET_DEBUG_IO |
|
2126 |
printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr, |
|
2127 |
val & 0xffff); |
|
2128 |
#endif |
|
2129 |
|
|
2130 |
return val & 0xffff; |
|
2131 |
} |
|
2132 |
|
|
2133 |
static CPUReadMemoryFunc * const lance_mem_read[3] = { |
|
2134 |
NULL, |
|
2135 |
lance_mem_readw, |
|
2136 |
NULL, |
|
2137 |
}; |
|
2138 |
|
|
2139 |
static CPUWriteMemoryFunc * const lance_mem_write[3] = { |
|
2140 |
NULL, |
|
2141 |
lance_mem_writew, |
|
2142 |
NULL, |
|
2143 |
}; |
|
2144 |
|
|
2145 |
static void lance_cleanup(VLANClientState *vc) |
|
2146 |
{ |
|
2147 |
PCNetState *d = vc->opaque; |
|
2148 |
|
|
2149 |
pcnet_common_cleanup(d); |
|
2150 |
} |
|
2151 |
|
|
2152 |
static int lance_init(SysBusDevice *dev) |
|
2153 |
{ |
|
2154 |
SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev); |
|
2155 |
PCNetState *s = &d->state; |
|
2156 |
|
|
2157 |
s->mmio_index = |
|
2158 |
cpu_register_io_memory(lance_mem_read, lance_mem_write, d); |
|
2159 |
|
|
2160 |
qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1); |
|
2161 |
|
|
2162 |
sysbus_init_mmio(dev, 4, s->mmio_index); |
|
2163 |
|
|
2164 |
sysbus_init_irq(dev, &s->irq); |
|
2165 |
|
|
2166 |
s->phys_mem_read = ledma_memory_read; |
|
2167 |
s->phys_mem_write = ledma_memory_write; |
|
2168 |
|
|
2169 |
register_savevm("pcnet", -1, 3, pcnet_save, pcnet_load, s); |
|
2170 |
return pcnet_common_init(&dev->qdev, s, lance_cleanup); |
|
2171 |
} |
|
2172 |
|
|
2173 |
static void lance_reset(DeviceState *dev) |
|
2174 |
{ |
|
2175 |
SysBusPCNetState *d = DO_UPCAST(SysBusPCNetState, busdev.qdev, dev); |
|
2176 |
|
|
2177 |
pcnet_h_reset(&d->state); |
|
2178 |
} |
|
2179 |
|
|
2180 |
static SysBusDeviceInfo lance_info = { |
|
2181 |
.init = lance_init, |
|
2182 |
.qdev.name = "lance", |
|
2183 |
.qdev.size = sizeof(SysBusPCNetState), |
|
2184 |
.qdev.reset = lance_reset, |
|
2185 |
.qdev.props = (Property[]) { |
|
2186 |
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque), |
|
2187 |
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf), |
|
2188 |
DEFINE_PROP_END_OF_LIST(), |
|
2189 |
} |
|
2190 |
}; |
|
2191 |
|
|
2192 |
#endif /* TARGET_SPARC */ |
|
2193 |
|
|
2194 | 2061 |
static PCIDeviceInfo pcnet_info = { |
2195 | 2062 |
.qdev.name = "pcnet", |
2196 | 2063 |
.qdev.size = sizeof(PCIPCNetState), |
... | ... | |
2206 | 2073 |
static void pcnet_register_devices(void) |
2207 | 2074 |
{ |
2208 | 2075 |
pci_qdev_register(&pcnet_info); |
2209 |
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) |
|
2210 |
sysbus_register_withprop(&lance_info); |
|
2211 |
#endif |
|
2212 | 2076 |
} |
2213 | 2077 |
|
2214 | 2078 |
device_init(pcnet_register_devices) |
Also available in: Unified diff