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); | ... | ... |