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 | 103 | #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ |
| 104 | 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 | 111 | typedef struct NE2000State { |
| 109 | 112 | uint8_t cmd; |
| ... | ... | @@ -244,6 +247,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 244 | 247 | /* control register */ |
| 245 | 248 | s->cmd = val; |
| 246 | 249 | if (val & E8390_START) { |
| 250 | + s->isr &= ~ENISR_RESET; | |
| 247 | 251 | /* test specific case: zero length transfert */ |
| 248 | 252 | if ((val & (E8390_RREAD | E8390_RWRITE)) && |
| 249 | 253 | s->rcnt == 0) { |
| ... | ... | @@ -251,7 +255,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 251 | 255 | ne2000_update_irq(s); |
| 252 | 256 | } |
| 253 | 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 | 259 | /* signal end of transfert */ |
| 256 | 260 | s->tsr = ENTSR_PTX; |
| 257 | 261 | s->isr |= ENISR_TX; |
| ... | ... | @@ -300,7 +304,7 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 300 | 304 | s->dcfg = val; |
| 301 | 305 | break; |
| 302 | 306 | case EN0_ISR: |
| 303 | - s->isr &= ~val; | |
| 307 | + s->isr &= ~(val & 0x7f); | |
| 304 | 308 | ne2000_update_irq(s); |
| 305 | 309 | break; |
| 306 | 310 | case EN1_PHYS ... EN1_PHYS + 5: |
| ... | ... | @@ -337,6 +341,12 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) |
| 337 | 341 | case EN0_ISR: |
| 338 | 342 | ret = s->isr; |
| 339 | 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 | 350 | case EN1_PHYS ... EN1_PHYS + 5: |
| 341 | 351 | ret = s->phys[offset - EN1_PHYS]; |
| 342 | 352 | break; |
| ... | ... | @@ -357,24 +367,64 @@ static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) |
| 357 | 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 | 411 | static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 361 | 412 | { |
| 362 | 413 | NE2000State *s = opaque; |
| 363 | - uint8_t *p; | |
| 364 | 414 | |
| 365 | 415 | #ifdef DEBUG_NE2000 |
| 366 | 416 | printf("NE2000: asic write val=0x%04x\n", val); |
| 367 | 417 | #endif |
| 368 | - p = s->mem + s->rsar; | |
| 418 | + if (s->rcnt == 0) | |
| 419 | + return; | |
| 369 | 420 | if (s->dcfg & 0x01) { |
| 370 | 421 | /* 16 bit access */ |
| 371 | - p[0] = val; | |
| 372 | - p[1] = val >> 8; | |
| 422 | + ne2000_mem_writew(s, s->rsar, val); | |
| 373 | 423 | s->rsar += 2; |
| 374 | 424 | s->rcnt -= 2; |
| 375 | 425 | } else { |
| 376 | 426 | /* 8 bit access */ |
| 377 | - p[0] = val; | |
| 427 | + ne2000_mem_writeb(s, s->rsar, val); | |
| 378 | 428 | s->rsar++; |
| 379 | 429 | s->rcnt--; |
| 380 | 430 | } |
| ... | ... | @@ -391,18 +441,16 @@ static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 391 | 441 | static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) |
| 392 | 442 | { |
| 393 | 443 | NE2000State *s = opaque; |
| 394 | - uint8_t *p; | |
| 395 | 444 | int ret; |
| 396 | 445 | |
| 397 | - p = s->mem + s->rsar; | |
| 398 | 446 | if (s->dcfg & 0x01) { |
| 399 | 447 | /* 16 bit access */ |
| 400 | - ret = p[0] | (p[1] << 8); | |
| 448 | + ret = ne2000_mem_readw(s, s->rsar); | |
| 401 | 449 | s->rsar += 2; |
| 402 | 450 | s->rcnt -= 2; |
| 403 | 451 | } else { |
| 404 | 452 | /* 8 bit access */ |
| 405 | - ret = p[0]; | |
| 453 | + ret = ne2000_mem_readb(s, s->rsar); | |
| 406 | 454 | s->rsar++; |
| 407 | 455 | s->rcnt--; |
| 408 | 456 | } |
| ... | ... | @@ -455,5 +503,5 @@ void ne2000_init(int base, int irq, NetDriverState *nd) |
| 455 | 503 | |
| 456 | 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 | } | ... | ... |