Commit 9b94dc325b1ab7de421a0419f324d8f8db55aeb4
1 parent
c6d46c20
better PCNET endianness support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2147 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
116 additions
and
157 deletions
hw/pcnet.c
| ... | ... | @@ -71,9 +71,9 @@ struct PCNetState_st { |
| 71 | 71 | int tx_busy; |
| 72 | 72 | void (*set_irq_cb)(void *s, int isr); |
| 73 | 73 | void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr, |
| 74 | - uint8_t *buf, int len); | |
| 74 | + uint8_t *buf, int len, int do_bswap); | |
| 75 | 75 | void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr, |
| 76 | - uint8_t *buf, int len); | |
| 76 | + uint8_t *buf, int len, int do_bswap); | |
| 77 | 77 | void *dma_opaque; |
| 78 | 78 | }; |
| 79 | 79 | |
| ... | ... | @@ -116,7 +116,7 @@ struct qemu_ether_header { |
| 116 | 116 | #define CSR_TXON(S) !!(((S)->csr[0])&0x0010) |
| 117 | 117 | #define CSR_RXON(S) !!(((S)->csr[0])&0x0020) |
| 118 | 118 | #define CSR_INEA(S) !!(((S)->csr[0])&0x0040) |
| 119 | -#define CSR_BIGENDIAN(S) !!(((S)->csr[3])&0x0004) | |
| 119 | +#define CSR_BSWP(S) !!(((S)->csr[3])&0x0004) | |
| 120 | 120 | #define CSR_LAPPEN(S) !!(((S)->csr[3])&0x0020) |
| 121 | 121 | #define CSR_DXSUFLO(S) !!(((S)->csr[3])&0x0040) |
| 122 | 122 | #define CSR_ASTRP_RCV(S) !!(((S)->csr[4])&0x0800) |
| ... | ... | @@ -261,19 +261,11 @@ static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1, |
| 261 | 261 | if (!BCR_SWSTYLE(s)) { |
| 262 | 262 | uint16_t xda[4]; |
| 263 | 263 | s->phys_mem_read(s->dma_opaque, addr, |
| 264 | - (void *)&xda[0], sizeof(xda)); | |
| 265 | - if (CSR_BIGENDIAN(s)) { | |
| 266 | - be16_to_cpus(&xda[0]); | |
| 267 | - be16_to_cpus(&xda[1]); | |
| 268 | - be16_to_cpus(&xda[2]); | |
| 269 | - be16_to_cpus(&xda[3]); | |
| 270 | - } else { | |
| 271 | - le16_to_cpus(&xda[0]); | |
| 272 | - le16_to_cpus(&xda[1]); | |
| 273 | - le16_to_cpus(&xda[2]); | |
| 274 | - le16_to_cpus(&xda[3]); | |
| 275 | - } | |
| 276 | - | |
| 264 | + (void *)&xda[0], sizeof(xda), 0); | |
| 265 | + le16_to_cpus(&xda[0]); | |
| 266 | + le16_to_cpus(&xda[1]); | |
| 267 | + le16_to_cpus(&xda[2]); | |
| 268 | + le16_to_cpus(&xda[3]); | |
| 277 | 269 | tmd[0] = (xda[0]&0xffff) | |
| 278 | 270 | ((xda[1]&0x00ff) << 16); |
| 279 | 271 | tmd[1] = (xda[2]&0xffff)| |
| ... | ... | @@ -284,18 +276,11 @@ static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd1, |
| 284 | 276 | } else { |
| 285 | 277 | uint32_t xda[4]; |
| 286 | 278 | s->phys_mem_read(s->dma_opaque, addr, |
| 287 | - (void *)&xda[0], sizeof(xda)); | |
| 288 | - if (CSR_BIGENDIAN(s)) { | |
| 289 | - be32_to_cpus(&xda[0]); | |
| 290 | - be32_to_cpus(&xda[1]); | |
| 291 | - be32_to_cpus(&xda[2]); | |
| 292 | - be32_to_cpus(&xda[3]); | |
| 293 | - } else { | |
| 294 | - le32_to_cpus(&xda[0]); | |
| 295 | - le32_to_cpus(&xda[1]); | |
| 296 | - le32_to_cpus(&xda[2]); | |
| 297 | - le32_to_cpus(&xda[3]); | |
| 298 | - } | |
| 279 | + (void *)&xda[0], sizeof(xda), 0); | |
| 280 | + le32_to_cpus(&xda[0]); | |
| 281 | + le32_to_cpus(&xda[1]); | |
| 282 | + le32_to_cpus(&xda[2]); | |
| 283 | + le32_to_cpus(&xda[3]); | |
| 299 | 284 | if (BCR_SWSTYLE(s) != 3) { |
| 300 | 285 | memcpy(tmd, xda, sizeof(xda)); |
| 301 | 286 | } else { |
| ... | ... | @@ -318,19 +303,12 @@ static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1, |
| 318 | 303 | ((tmd[1]>>16)&0xff00); |
| 319 | 304 | xda[2] = tmd[1] & 0xffff; |
| 320 | 305 | xda[3] = tmd[2] >> 16; |
| 321 | - if (CSR_BIGENDIAN(s)) { | |
| 322 | - cpu_to_be16s(&xda[0]); | |
| 323 | - cpu_to_be16s(&xda[1]); | |
| 324 | - cpu_to_be16s(&xda[2]); | |
| 325 | - cpu_to_be16s(&xda[3]); | |
| 326 | - } else { | |
| 327 | - cpu_to_le16s(&xda[0]); | |
| 328 | - cpu_to_le16s(&xda[1]); | |
| 329 | - cpu_to_le16s(&xda[2]); | |
| 330 | - cpu_to_le16s(&xda[3]); | |
| 331 | - } | |
| 306 | + cpu_to_le16s(&xda[0]); | |
| 307 | + cpu_to_le16s(&xda[1]); | |
| 308 | + cpu_to_le16s(&xda[2]); | |
| 309 | + cpu_to_le16s(&xda[3]); | |
| 332 | 310 | s->phys_mem_write(s->dma_opaque, addr, |
| 333 | - (void *)&xda[0], sizeof(xda)); | |
| 311 | + (void *)&xda[0], sizeof(xda), 0); | |
| 334 | 312 | } else { |
| 335 | 313 | uint32_t xda[4]; |
| 336 | 314 | if (BCR_SWSTYLE(s) != 3) { |
| ... | ... | @@ -341,19 +319,12 @@ static inline void pcnet_tmd_store(PCNetState *s, const struct pcnet_TMD *tmd1, |
| 341 | 319 | xda[2] = tmd[0]; |
| 342 | 320 | xda[3] = tmd[3]; |
| 343 | 321 | } |
| 344 | - if (CSR_BIGENDIAN(s)) { | |
| 345 | - cpu_to_be32s(&xda[0]); | |
| 346 | - cpu_to_be32s(&xda[1]); | |
| 347 | - cpu_to_be32s(&xda[2]); | |
| 348 | - cpu_to_be32s(&xda[3]); | |
| 349 | - } else { | |
| 350 | - cpu_to_le32s(&xda[0]); | |
| 351 | - cpu_to_le32s(&xda[1]); | |
| 352 | - cpu_to_le32s(&xda[2]); | |
| 353 | - cpu_to_le32s(&xda[3]); | |
| 354 | - } | |
| 322 | + cpu_to_le32s(&xda[0]); | |
| 323 | + cpu_to_le32s(&xda[1]); | |
| 324 | + cpu_to_le32s(&xda[2]); | |
| 325 | + cpu_to_le32s(&xda[3]); | |
| 355 | 326 | s->phys_mem_write(s->dma_opaque, addr, |
| 356 | - (void *)&xda[0], sizeof(xda)); | |
| 327 | + (void *)&xda[0], sizeof(xda), 0); | |
| 357 | 328 | } |
| 358 | 329 | } |
| 359 | 330 | |
| ... | ... | @@ -364,18 +335,12 @@ static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1, |
| 364 | 335 | |
| 365 | 336 | if (!BCR_SWSTYLE(s)) { |
| 366 | 337 | uint16_t rda[4]; |
| 367 | - s->phys_mem_read(s->dma_opaque, addr, (void *)&rda[0], sizeof(rda)); | |
| 368 | - if (CSR_BIGENDIAN(s)) { | |
| 369 | - be16_to_cpus(&rda[0]); | |
| 370 | - be16_to_cpus(&rda[1]); | |
| 371 | - be16_to_cpus(&rda[2]); | |
| 372 | - be16_to_cpus(&rda[3]); | |
| 373 | - } else { | |
| 374 | - le16_to_cpus(&rda[0]); | |
| 375 | - le16_to_cpus(&rda[1]); | |
| 376 | - le16_to_cpus(&rda[2]); | |
| 377 | - le16_to_cpus(&rda[3]); | |
| 378 | - } | |
| 338 | + s->phys_mem_read(s->dma_opaque, addr, | |
| 339 | + (void *)&rda[0], sizeof(rda), 0); | |
| 340 | + le16_to_cpus(&rda[0]); | |
| 341 | + le16_to_cpus(&rda[1]); | |
| 342 | + le16_to_cpus(&rda[2]); | |
| 343 | + le16_to_cpus(&rda[3]); | |
| 379 | 344 | rmd[0] = (rda[0]&0xffff)| |
| 380 | 345 | ((rda[1] & 0x00ff) << 16); |
| 381 | 346 | rmd[1] = (rda[2]&0xffff)| |
| ... | ... | @@ -384,18 +349,12 @@ static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd1, |
| 384 | 349 | rmd[3] = 0; |
| 385 | 350 | } else { |
| 386 | 351 | uint32_t rda[4]; |
| 387 | - s->phys_mem_read(s->dma_opaque, addr, (void *)&rda[0], sizeof(rda)); | |
| 388 | - if (CSR_BIGENDIAN(s)) { | |
| 389 | - be32_to_cpus(&rda[0]); | |
| 390 | - be32_to_cpus(&rda[1]); | |
| 391 | - be32_to_cpus(&rda[2]); | |
| 392 | - be32_to_cpus(&rda[3]); | |
| 393 | - } else { | |
| 394 | - le32_to_cpus(&rda[0]); | |
| 395 | - le32_to_cpus(&rda[1]); | |
| 396 | - le32_to_cpus(&rda[2]); | |
| 397 | - le32_to_cpus(&rda[3]); | |
| 398 | - } | |
| 352 | + s->phys_mem_read(s->dma_opaque, addr, | |
| 353 | + (void *)&rda[0], sizeof(rda), 0); | |
| 354 | + le32_to_cpus(&rda[0]); | |
| 355 | + le32_to_cpus(&rda[1]); | |
| 356 | + le32_to_cpus(&rda[2]); | |
| 357 | + le32_to_cpus(&rda[3]); | |
| 399 | 358 | if (BCR_SWSTYLE(s) != 3) { |
| 400 | 359 | memcpy(rmd, rda, sizeof(rda)); |
| 401 | 360 | } else { |
| ... | ... | @@ -419,19 +378,12 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 419 | 378 | ((rmd[1]>>16)&0xff00); |
| 420 | 379 | rda[2] = rmd[1] & 0xffff; |
| 421 | 380 | rda[3] = rmd[2] & 0xffff; |
| 422 | - if (CSR_BIGENDIAN(s)) { | |
| 423 | - cpu_to_be16s(&rda[0]); | |
| 424 | - cpu_to_be16s(&rda[1]); | |
| 425 | - cpu_to_be16s(&rda[2]); | |
| 426 | - cpu_to_be16s(&rda[3]); | |
| 427 | - } else { | |
| 428 | - cpu_to_le16s(&rda[0]); | |
| 429 | - cpu_to_le16s(&rda[1]); | |
| 430 | - cpu_to_le16s(&rda[2]); | |
| 431 | - cpu_to_le16s(&rda[3]); | |
| 432 | - } | |
| 381 | + cpu_to_le16s(&rda[0]); | |
| 382 | + cpu_to_le16s(&rda[1]); | |
| 383 | + cpu_to_le16s(&rda[2]); | |
| 384 | + cpu_to_le16s(&rda[3]); | |
| 433 | 385 | s->phys_mem_write(s->dma_opaque, addr, |
| 434 | - (void *)&rda[0], sizeof(rda)); | |
| 386 | + (void *)&rda[0], sizeof(rda), 0); | |
| 435 | 387 | } else { |
| 436 | 388 | uint32_t rda[4]; |
| 437 | 389 | if (BCR_SWSTYLE(s) != 3) { |
| ... | ... | @@ -442,19 +394,12 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 442 | 394 | rda[2] = rmd[0]; |
| 443 | 395 | rda[3] = rmd[3]; |
| 444 | 396 | } |
| 445 | - if (CSR_BIGENDIAN(s)) { | |
| 446 | - cpu_to_be32s(&rda[0]); | |
| 447 | - cpu_to_be32s(&rda[1]); | |
| 448 | - cpu_to_be32s(&rda[2]); | |
| 449 | - cpu_to_be32s(&rda[3]); | |
| 450 | - } else { | |
| 451 | - cpu_to_le32s(&rda[0]); | |
| 452 | - cpu_to_le32s(&rda[1]); | |
| 453 | - cpu_to_le32s(&rda[2]); | |
| 454 | - cpu_to_le32s(&rda[3]); | |
| 455 | - } | |
| 397 | + cpu_to_le32s(&rda[0]); | |
| 398 | + cpu_to_le32s(&rda[1]); | |
| 399 | + cpu_to_le32s(&rda[2]); | |
| 400 | + cpu_to_le32s(&rda[3]); | |
| 456 | 401 | s->phys_mem_write(s->dma_opaque, addr, |
| 457 | - (void *)&rda[0], sizeof(rda)); | |
| 402 | + (void *)&rda[0], sizeof(rda), 0); | |
| 458 | 403 | } |
| 459 | 404 | } |
| 460 | 405 | |
| ... | ... | @@ -490,7 +435,7 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 490 | 435 | do { \ |
| 491 | 436 | uint16_t rda[4]; \ |
| 492 | 437 | s->phys_mem_read(s->dma_opaque, (ADDR), \ |
| 493 | - (void *)&rda[0], sizeof(rda)); \ | |
| 438 | + (void *)&rda[0], sizeof(rda), 0); \ | |
| 494 | 439 | (RES) |= (rda[2] & 0xf000)!=0xf000; \ |
| 495 | 440 | (RES) |= (rda[3] & 0xf000)!=0x0000; \ |
| 496 | 441 | } while (0); \ |
| ... | ... | @@ -500,7 +445,7 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 500 | 445 | do { \ |
| 501 | 446 | uint32_t rda[4]; \ |
| 502 | 447 | s->phys_mem_read(s->dma_opaque, (ADDR), \ |
| 503 | - (void *)&rda[0], sizeof(rda)); \ | |
| 448 | + (void *)&rda[0], sizeof(rda), 0); \ | |
| 504 | 449 | (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ |
| 505 | 450 | (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \ |
| 506 | 451 | } while (0); \ |
| ... | ... | @@ -509,7 +454,7 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 509 | 454 | do { \ |
| 510 | 455 | uint32_t rda[4]; \ |
| 511 | 456 | s->phys_mem_read(s->dma_opaque, (ADDR), \ |
| 512 | - (void *)&rda[0], sizeof(rda)); \ | |
| 457 | + (void *)&rda[0], sizeof(rda), 0); \ | |
| 513 | 458 | (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \ |
| 514 | 459 | (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ |
| 515 | 460 | } while (0); \ |
| ... | ... | @@ -523,7 +468,7 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 523 | 468 | do { \ |
| 524 | 469 | uint16_t xda[4]; \ |
| 525 | 470 | s->phys_mem_read(s->dma_opaque, (ADDR), \ |
| 526 | - (void *)&xda[0], sizeof(xda)); \ | |
| 471 | + (void *)&xda[0], sizeof(xda), 0); \ | |
| 527 | 472 | (RES) |= (xda[2] & 0xf000)!=0xf000;\ |
| 528 | 473 | } while (0); \ |
| 529 | 474 | break; \ |
| ... | ... | @@ -533,7 +478,7 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 533 | 478 | do { \ |
| 534 | 479 | uint32_t xda[4]; \ |
| 535 | 480 | s->phys_mem_read(s->dma_opaque, (ADDR), \ |
| 536 | - (void *)&xda[0], sizeof(xda)); \ | |
| 481 | + (void *)&xda[0], sizeof(xda), 0); \ | |
| 537 | 482 | (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \ |
| 538 | 483 | } while (0); \ |
| 539 | 484 | break; \ |
| ... | ... | @@ -546,13 +491,12 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd1, |
| 546 | 491 | struct qemu_ether_header *hdr = (void *)(BUF); \ |
| 547 | 492 | printf("packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " \ |
| 548 | 493 | "shost=%02x:%02x:%02x:%02x:%02x:%02x, " \ |
| 549 | - "type=0x%04x (bcast=%d)\n", \ | |
| 494 | + "type=0x%04x\n", \ | |
| 550 | 495 | hdr->ether_dhost[0],hdr->ether_dhost[1],hdr->ether_dhost[2], \ |
| 551 | 496 | hdr->ether_dhost[3],hdr->ether_dhost[4],hdr->ether_dhost[5], \ |
| 552 | 497 | hdr->ether_shost[0],hdr->ether_shost[1],hdr->ether_shost[2], \ |
| 553 | 498 | hdr->ether_shost[3],hdr->ether_shost[4],hdr->ether_shost[5], \ |
| 554 | - be16_to_cpu(hdr->ether_type), \ | |
| 555 | - !!ETHER_IS_MULTICAST(hdr->ether_dhost)); \ | |
| 499 | + be16_to_cpu(hdr->ether_type)); \ | |
| 556 | 500 | } while (0) |
| 557 | 501 | |
| 558 | 502 | #define MULTICAST_FILTER_LEN 8 |
| ... | ... | @@ -669,7 +613,7 @@ static inline int padr_match(PCNetState *s, const uint8_t *buf, int size) |
| 669 | 613 | |
| 670 | 614 | static inline int padr_bcast(PCNetState *s, const uint8_t *buf, int size) |
| 671 | 615 | { |
| 672 | - static uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | |
| 616 | + static const uint8_t BCAST[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | |
| 673 | 617 | struct qemu_ether_header *hdr = (void *)buf; |
| 674 | 618 | int result = !CSR_DRCVBC(s) && !memcmp(hdr->ether_dhost, BCAST, 6); |
| 675 | 619 | #ifdef PCNET_DEBUG_MATCH |
| ... | ... | @@ -836,35 +780,25 @@ static void pcnet_init(PCNetState *s) |
| 836 | 780 | if (BCR_SSIZE32(s)) { |
| 837 | 781 | struct pcnet_initblk32 initblk; |
| 838 | 782 | s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), |
| 839 | - (uint8_t *)&initblk, sizeof(initblk)); | |
| 783 | + (uint8_t *)&initblk, sizeof(initblk), 0); | |
| 840 | 784 | mode = initblk.mode; |
| 841 | 785 | rlen = initblk.rlen >> 4; |
| 842 | 786 | tlen = initblk.tlen >> 4; |
| 843 | 787 | ladrf = initblk.ladrf; |
| 844 | 788 | padr = initblk.padr; |
| 845 | - if (CSR_BIGENDIAN(s)) { | |
| 846 | - rdra = be32_to_cpu(initblk.rdra); | |
| 847 | - tdra = be32_to_cpu(initblk.tdra); | |
| 848 | - } else { | |
| 849 | - rdra = le32_to_cpu(initblk.rdra); | |
| 850 | - tdra = le32_to_cpu(initblk.tdra); | |
| 851 | - } | |
| 789 | + rdra = le32_to_cpu(initblk.rdra); | |
| 790 | + tdra = le32_to_cpu(initblk.tdra); | |
| 852 | 791 | s->rdra = PHYSADDR(s,initblk.rdra); |
| 853 | 792 | s->tdra = PHYSADDR(s,initblk.tdra); |
| 854 | 793 | } else { |
| 855 | 794 | struct pcnet_initblk16 initblk; |
| 856 | 795 | s->phys_mem_read(s->dma_opaque, PHYSADDR(s,CSR_IADR(s)), |
| 857 | - (uint8_t *)&initblk, sizeof(initblk)); | |
| 796 | + (uint8_t *)&initblk, sizeof(initblk), 0); | |
| 858 | 797 | mode = initblk.mode; |
| 859 | 798 | ladrf = initblk.ladrf; |
| 860 | 799 | padr = initblk.padr; |
| 861 | - if (CSR_BIGENDIAN(s)) { | |
| 862 | - rdra = be32_to_cpu(initblk.rdra); | |
| 863 | - tdra = be32_to_cpu(initblk.tdra); | |
| 864 | - } else { | |
| 865 | - rdra = le32_to_cpu(initblk.rdra); | |
| 866 | - tdra = le32_to_cpu(initblk.tdra); | |
| 867 | - } | |
| 800 | + rdra = le32_to_cpu(initblk.rdra); | |
| 801 | + tdra = le32_to_cpu(initblk.tdra); | |
| 868 | 802 | rlen = rdra >> 29; |
| 869 | 803 | tlen = tdra >> 29; |
| 870 | 804 | rdra &= 0x00ffffff; |
| ... | ... | @@ -878,25 +812,14 @@ static void pcnet_init(PCNetState *s) |
| 878 | 812 | CSR_RCVRL(s) = (rlen < 9) ? (1 << rlen) : 512; |
| 879 | 813 | CSR_XMTRL(s) = (tlen < 9) ? (1 << tlen) : 512; |
| 880 | 814 | s->csr[ 6] = (tlen << 12) | (rlen << 8); |
| 881 | - if (CSR_BIGENDIAN(s)) { | |
| 882 | - s->csr[15] = be16_to_cpu(mode); | |
| 883 | - s->csr[ 8] = be16_to_cpu(ladrf[0]); | |
| 884 | - s->csr[ 9] = be16_to_cpu(ladrf[1]); | |
| 885 | - s->csr[10] = be16_to_cpu(ladrf[2]); | |
| 886 | - s->csr[11] = be16_to_cpu(ladrf[3]); | |
| 887 | - s->csr[12] = be16_to_cpu(padr[0]); | |
| 888 | - s->csr[13] = be16_to_cpu(padr[1]); | |
| 889 | - s->csr[14] = be16_to_cpu(padr[2]); | |
| 890 | - } else { | |
| 891 | - s->csr[15] = le16_to_cpu(mode); | |
| 892 | - s->csr[ 8] = le16_to_cpu(ladrf[0]); | |
| 893 | - s->csr[ 9] = le16_to_cpu(ladrf[1]); | |
| 894 | - s->csr[10] = le16_to_cpu(ladrf[2]); | |
| 895 | - s->csr[11] = le16_to_cpu(ladrf[3]); | |
| 896 | - s->csr[12] = le16_to_cpu(padr[0]); | |
| 897 | - s->csr[13] = le16_to_cpu(padr[1]); | |
| 898 | - s->csr[14] = le16_to_cpu(padr[2]); | |
| 899 | - } | |
| 815 | + s->csr[15] = le16_to_cpu(mode); | |
| 816 | + s->csr[ 8] = le16_to_cpu(ladrf[0]); | |
| 817 | + s->csr[ 9] = le16_to_cpu(ladrf[1]); | |
| 818 | + s->csr[10] = le16_to_cpu(ladrf[2]); | |
| 819 | + s->csr[11] = le16_to_cpu(ladrf[3]); | |
| 820 | + s->csr[12] = le16_to_cpu(padr[0]); | |
| 821 | + s->csr[13] = le16_to_cpu(padr[1]); | |
| 822 | + s->csr[14] = le16_to_cpu(padr[2]); | |
| 900 | 823 | s->rdra = PHYSADDR(s, rdra); |
| 901 | 824 | s->tdra = PHYSADDR(s, tdra); |
| 902 | 825 | |
| ... | ... | @@ -1168,7 +1091,7 @@ static void pcnet_receive(void *opaque, const uint8_t *buf, int size) |
| 1168 | 1091 | #define PCNET_RECV_STORE() do { \ |
| 1169 | 1092 | int count = MIN(4096 - rmd.rmd1.bcnt,size); \ |
| 1170 | 1093 | target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \ |
| 1171 | - s->phys_mem_write(s->dma_opaque, rbadr, src, count); \ | |
| 1094 | + s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \ | |
| 1172 | 1095 | src += count; size -= count; \ |
| 1173 | 1096 | rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \ |
| 1174 | 1097 | RMDSTORE(&rmd, PHYSADDR(s,crda)); \ |
| ... | ... | @@ -1259,14 +1182,16 @@ static void pcnet_transmit(PCNetState *s) |
| 1259 | 1182 | s->xmit_pos = 0; |
| 1260 | 1183 | if (!tmd.tmd1.enp) { |
| 1261 | 1184 | s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr), |
| 1262 | - s->buffer, 4096 - tmd.tmd1.bcnt); | |
| 1185 | + s->buffer, 4096 - tmd.tmd1.bcnt, | |
| 1186 | + CSR_BSWP(s)); | |
| 1263 | 1187 | s->xmit_pos += 4096 - tmd.tmd1.bcnt; |
| 1264 | 1188 | } |
| 1265 | 1189 | xmit_cxda = PHYSADDR(s,CSR_CXDA(s)); |
| 1266 | 1190 | } |
| 1267 | 1191 | if (tmd.tmd1.enp && (s->xmit_pos >= 0)) { |
| 1268 | 1192 | s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tmd0.tbadr), |
| 1269 | - s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt); | |
| 1193 | + s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt, | |
| 1194 | + CSR_BSWP(s)); | |
| 1270 | 1195 | s->xmit_pos += 4096 - tmd.tmd1.bcnt; |
| 1271 | 1196 | #ifdef PCNET_DEBUG |
| 1272 | 1197 | printf("pcnet_transmit size=%d\n", s->xmit_pos); |
| ... | ... | @@ -1953,13 +1878,13 @@ static void pcnet_pci_set_irq_cb(void *opaque, int isr) |
| 1953 | 1878 | } |
| 1954 | 1879 | |
| 1955 | 1880 | static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr, |
| 1956 | - uint8_t *buf, int len) | |
| 1881 | + uint8_t *buf, int len, int do_bswap) | |
| 1957 | 1882 | { |
| 1958 | 1883 | cpu_physical_memory_write(addr, buf, len); |
| 1959 | 1884 | } |
| 1960 | 1885 | |
| 1961 | 1886 | static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr, |
| 1962 | - uint8_t *buf, int len) | |
| 1887 | + uint8_t *buf, int len, int do_bswap) | |
| 1963 | 1888 | { |
| 1964 | 1889 | cpu_physical_memory_read(addr, buf, len); |
| 1965 | 1890 | } | ... | ... |
hw/sparc32_dma.c
| ... | ... | @@ -69,22 +69,56 @@ void ledma_set_irq(void *opaque, int isr) |
| 69 | 69 | pic_set_irq_new(s->intctl, s->leirq, isr); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | -void ledma_memory_read(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len) | |
| 72 | +/* Note: on sparc, the lance 16 bit bus is swapped */ | |
| 73 | +void ledma_memory_read(void *opaque, target_phys_addr_t addr, | |
| 74 | + uint8_t *buf, int len, int do_bswap) | |
| 73 | 75 | { |
| 74 | 76 | DMAState *s = opaque; |
| 77 | + int i; | |
| 75 | 78 | |
| 76 | 79 | DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n", |
| 77 | 80 | s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); |
| 78 | - sparc_iommu_memory_read(s->iommu, addr | s->dmaregs[7], buf, len); | |
| 81 | + addr |= s->dmaregs[7]; | |
| 82 | + if (do_bswap) { | |
| 83 | + sparc_iommu_memory_read(s->iommu, addr, buf, len); | |
| 84 | + } else { | |
| 85 | + addr &= ~1; | |
| 86 | + len &= ~1; | |
| 87 | + sparc_iommu_memory_read(s->iommu, addr, buf, len); | |
| 88 | + for(i = 0; i < len; i += 2) { | |
| 89 | + bswap16s((uint16_t *)(buf + i)); | |
| 90 | + } | |
| 91 | + } | |
| 79 | 92 | } |
| 80 | 93 | |
| 81 | -void ledma_memory_write(void *opaque, target_phys_addr_t addr, uint8_t *buf, int len) | |
| 94 | +void ledma_memory_write(void *opaque, target_phys_addr_t addr, | |
| 95 | + uint8_t *buf, int len, int do_bswap) | |
| 82 | 96 | { |
| 83 | 97 | DMAState *s = opaque; |
| 98 | + int l, i; | |
| 99 | + uint16_t tmp_buf[32]; | |
| 84 | 100 | |
| 85 | 101 | DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n", |
| 86 | 102 | s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]); |
| 87 | - sparc_iommu_memory_write(s->iommu, addr | s->dmaregs[7], buf, len); | |
| 103 | + addr |= s->dmaregs[7]; | |
| 104 | + if (do_bswap) { | |
| 105 | + sparc_iommu_memory_write(s->iommu, addr, buf, len); | |
| 106 | + } else { | |
| 107 | + addr &= ~1; | |
| 108 | + len &= ~1; | |
| 109 | + while (len > 0) { | |
| 110 | + l = len; | |
| 111 | + if (l > sizeof(tmp_buf)) | |
| 112 | + l = sizeof(tmp_buf); | |
| 113 | + for(i = 0; i < l; i += 2) { | |
| 114 | + tmp_buf[i >> 1] = bswap16(*(uint16_t *)(buf + i)); | |
| 115 | + } | |
| 116 | + sparc_iommu_memory_write(s->iommu, addr, (uint8_t *)tmp_buf, l); | |
| 117 | + len -= l; | |
| 118 | + buf += l; | |
| 119 | + addr += l; | |
| 120 | + } | |
| 121 | + } | |
| 88 | 122 | } |
| 89 | 123 | |
| 90 | 124 | void espdma_raise_irq(void *opaque) | ... | ... |
vl.h
| ... | ... | @@ -1086,10 +1086,10 @@ void esp_reset(void *opaque); |
| 1086 | 1086 | void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu, |
| 1087 | 1087 | void *intctl); |
| 1088 | 1088 | void ledma_set_irq(void *opaque, int isr); |
| 1089 | -void ledma_memory_read(void *opaque, target_phys_addr_t addr, uint8_t *buf, | |
| 1090 | - int len); | |
| 1091 | -void ledma_memory_write(void *opaque, target_phys_addr_t addr, uint8_t *buf, | |
| 1092 | - int len); | |
| 1089 | +void ledma_memory_read(void *opaque, target_phys_addr_t addr, | |
| 1090 | + uint8_t *buf, int len, int do_bswap); | |
| 1091 | +void ledma_memory_write(void *opaque, target_phys_addr_t addr, | |
| 1092 | + uint8_t *buf, int len, int do_bswap); | |
| 1093 | 1093 | void espdma_raise_irq(void *opaque); |
| 1094 | 1094 | void espdma_clear_irq(void *opaque); |
| 1095 | 1095 | void espdma_memory_read(void *opaque, uint8_t *buf, int len); | ... | ... |