Commit ee9dbb297db6adcac1df966e160e33b166b5a92a
1 parent
c20709aa
NE2000 fixes for windows (Renzo Davoli)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@731 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
61 additions
and
13 deletions
hw/ne2000.c
@@ -103,7 +103,10 @@ | @@ -103,7 +103,10 @@ | ||
103 | #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ | 103 | #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ |
104 | #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ | 104 | #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ |
105 | 105 | ||
106 | -#define NE2000_MEM_SIZE 32768 | 106 | +#define NE2000_PMEM_SIZE (32*1024) |
107 | +#define NE2000_PMEM_START (16*1024) | ||
108 | +#define NE2000_PMEM_END (NE2000_PMEM_SIZE+NE2000_PMEM_START) | ||
109 | +#define NE2000_MEM_SIZE NE2000_PMEM_END | ||
107 | 110 | ||
108 | typedef struct NE2000State { | 111 | typedef struct NE2000State { |
109 | uint8_t cmd; | 112 | uint8_t cmd; |
@@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
244 | /* control register */ | 247 | /* control register */ |
245 | s->cmd = val; | 248 | s->cmd = val; |
246 | if (val & E8390_START) { | 249 | if (val & E8390_START) { |
250 | + s->isr &= ~ENISR_RESET; | ||
247 | /* test specific case: zero length transfert */ | 251 | /* test specific case: zero length transfert */ |
248 | if ((val & (E8390_RREAD | E8390_RWRITE)) && | 252 | if ((val & (E8390_RREAD | E8390_RWRITE)) && |
249 | s->rcnt == 0) { | 253 | s->rcnt == 0) { |
@@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
251 | ne2000_update_irq(s); | 255 | ne2000_update_irq(s); |
252 | } | 256 | } |
253 | if (val & E8390_TRANS) { | 257 | if (val & E8390_TRANS) { |
254 | - net_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); | 258 | + qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); |
255 | /* signal end of transfert */ | 259 | /* signal end of transfert */ |
256 | s->tsr = ENTSR_PTX; | 260 | s->tsr = ENTSR_PTX; |
257 | s->isr |= ENISR_TX; | 261 | s->isr |= ENISR_TX; |
@@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
300 | s->dcfg = val; | 304 | s->dcfg = val; |
301 | break; | 305 | break; |
302 | case EN0_ISR: | 306 | case EN0_ISR: |
303 | - s->isr &= ~val; | 307 | + s->isr &= ~(val & 0x7f); |
304 | ne2000_update_irq(s); | 308 | ne2000_update_irq(s); |
305 | break; | 309 | break; |
306 | case EN1_PHYS ... EN1_PHYS + 5: | 310 | case EN1_PHYS ... EN1_PHYS + 5: |
@@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) | @@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) | ||
337 | case EN0_ISR: | 341 | case EN0_ISR: |
338 | ret = s->isr; | 342 | ret = s->isr; |
339 | break; | 343 | break; |
344 | + case EN0_RSARLO: | ||
345 | + ret = s->rsar & 0x00ff; | ||
346 | + break; | ||
347 | + case EN0_RSARHI: | ||
348 | + ret = s->rsar >> 8; | ||
349 | + break; | ||
340 | case EN1_PHYS ... EN1_PHYS + 5: | 350 | case EN1_PHYS ... EN1_PHYS + 5: |
341 | ret = s->phys[offset - EN1_PHYS]; | 351 | ret = s->phys[offset - EN1_PHYS]; |
342 | break; | 352 | break; |
@@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) | @@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) | ||
357 | return ret; | 367 | return ret; |
358 | } | 368 | } |
359 | 369 | ||
370 | +static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, | ||
371 | + uint32_t val) | ||
372 | +{ | ||
373 | + if (addr < 32 || | ||
374 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | ||
375 | + s->mem[addr] = val; | ||
376 | + } | ||
377 | +} | ||
378 | + | ||
379 | +static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr, | ||
380 | + uint32_t val) | ||
381 | +{ | ||
382 | + addr &= ~1; /* XXX: check exact behaviour if not even */ | ||
383 | + if (addr < 32 || | ||
384 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | ||
385 | + s->mem[addr] = val; | ||
386 | + s->mem[addr + 1] = val >> 8; | ||
387 | + } | ||
388 | +} | ||
389 | + | ||
390 | +static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr) | ||
391 | +{ | ||
392 | + if (addr < 32 || | ||
393 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | ||
394 | + return s->mem[addr]; | ||
395 | + } else { | ||
396 | + return 0xff; | ||
397 | + } | ||
398 | +} | ||
399 | + | ||
400 | +static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr) | ||
401 | +{ | ||
402 | + addr &= ~1; /* XXX: check exact behaviour if not even */ | ||
403 | + if (addr < 32 || | ||
404 | + (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { | ||
405 | + return s->mem[addr] | (s->mem[addr + 1] << 8); | ||
406 | + } else { | ||
407 | + return 0xffff; | ||
408 | + } | ||
409 | +} | ||
410 | + | ||
360 | static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | 411 | static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
361 | { | 412 | { |
362 | NE2000State *s = opaque; | 413 | NE2000State *s = opaque; |
363 | - uint8_t *p; | ||
364 | 414 | ||
365 | #ifdef DEBUG_NE2000 | 415 | #ifdef DEBUG_NE2000 |
366 | printf("NE2000: asic write val=0x%04x\n", val); | 416 | printf("NE2000: asic write val=0x%04x\n", val); |
367 | #endif | 417 | #endif |
368 | - p = s->mem + s->rsar; | 418 | + if (s->rcnt == 0) |
419 | + return; | ||
369 | if (s->dcfg & 0x01) { | 420 | if (s->dcfg & 0x01) { |
370 | /* 16 bit access */ | 421 | /* 16 bit access */ |
371 | - p[0] = val; | ||
372 | - p[1] = val >> 8; | 422 | + ne2000_mem_writew(s, s->rsar, val); |
373 | s->rsar += 2; | 423 | s->rsar += 2; |
374 | s->rcnt -= 2; | 424 | s->rcnt -= 2; |
375 | } else { | 425 | } else { |
376 | /* 8 bit access */ | 426 | /* 8 bit access */ |
377 | - p[0] = val; | 427 | + ne2000_mem_writeb(s, s->rsar, val); |
378 | s->rsar++; | 428 | s->rsar++; |
379 | s->rcnt--; | 429 | s->rcnt--; |
380 | } | 430 | } |
@@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
391 | static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) | 441 | static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) |
392 | { | 442 | { |
393 | NE2000State *s = opaque; | 443 | NE2000State *s = opaque; |
394 | - uint8_t *p; | ||
395 | int ret; | 444 | int ret; |
396 | 445 | ||
397 | - p = s->mem + s->rsar; | ||
398 | if (s->dcfg & 0x01) { | 446 | if (s->dcfg & 0x01) { |
399 | /* 16 bit access */ | 447 | /* 16 bit access */ |
400 | - ret = p[0] | (p[1] << 8); | 448 | + ret = ne2000_mem_readw(s, s->rsar); |
401 | s->rsar += 2; | 449 | s->rsar += 2; |
402 | s->rcnt -= 2; | 450 | s->rcnt -= 2; |
403 | } else { | 451 | } else { |
404 | /* 8 bit access */ | 452 | /* 8 bit access */ |
405 | - ret = p[0]; | 453 | + ret = ne2000_mem_readb(s, s->rsar); |
406 | s->rsar++; | 454 | s->rsar++; |
407 | s->rcnt--; | 455 | s->rcnt--; |
408 | } | 456 | } |
@@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd) | @@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd) | ||
455 | 503 | ||
456 | ne2000_reset(s); | 504 | ne2000_reset(s); |
457 | 505 | ||
458 | - qemu_add_fd_read_handler(nd->fd, ne2000_can_receive, ne2000_receive, s); | 506 | + qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); |
459 | } | 507 | } |