Commit b25cf5893f5ad07c2b8eada28250fc9cb8fb7e2a

Authored by aliguori
1 parent 426cd5d6

Add 40-bit DMA support to LSI scsi emulation (Ryan Harper)

This patch fixes Linux machines configured with > 4G of ram and using a
SCSI device.

Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5750 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 32 additions and 4 deletions
hw/lsi53c895a.c
@@ -143,6 +143,14 @@ do { fprintf(stderr, &quot;lsi_scsi: error: &quot; fmt , ##args);} while (0) @@ -143,6 +143,14 @@ do { fprintf(stderr, &quot;lsi_scsi: error: &quot; fmt , ##args);} while (0)
143 #define LSI_CCNTL0_PMJCTL 0x40 143 #define LSI_CCNTL0_PMJCTL 0x40
144 #define LSI_CCNTL0_ENPMJ 0x80 144 #define LSI_CCNTL0_ENPMJ 0x80
145 145
  146 +#define LSI_CCNTL1_EN64DBMV 0x01
  147 +#define LSI_CCNTL1_EN64TIBMV 0x02
  148 +#define LSI_CCNTL1_64TIMOD 0x04
  149 +#define LSI_CCNTL1_DDAC 0x08
  150 +#define LSI_CCNTL1_ZMOD 0x80
  151 +
  152 +#define LSI_CCNTL1_40BIT (LSI_CCNTL1_EN64TIBMV|LSI_CCNTL1_64TIMOD)
  153 +
146 #define PHASE_DO 0 154 #define PHASE_DO 0
147 #define PHASE_DI 1 155 #define PHASE_DI 1
148 #define PHASE_CMD 2 156 #define PHASE_CMD 2
@@ -323,6 +331,13 @@ static void lsi_soft_reset(LSIState *s) @@ -323,6 +331,13 @@ static void lsi_soft_reset(LSIState *s)
323 s->csbc = 0; 331 s->csbc = 0;
324 } 332 }
325 333
  334 +static int lsi_dma_40bit(LSIState *s)
  335 +{
  336 + if ((s->ccntl1 & LSI_CCNTL1_40BIT) == LSI_CCNTL1_40BIT)
  337 + return 1;
  338 + return 0;
  339 +}
  340 +
326 static uint8_t lsi_reg_readb(LSIState *s, int offset); 341 static uint8_t lsi_reg_readb(LSIState *s, int offset);
327 static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val); 342 static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
328 static void lsi_execute_script(LSIState *s); 343 static void lsi_execute_script(LSIState *s);
@@ -449,7 +464,7 @@ static void lsi_resume_script(LSIState *s) @@ -449,7 +464,7 @@ static void lsi_resume_script(LSIState *s)
449 static void lsi_do_dma(LSIState *s, int out) 464 static void lsi_do_dma(LSIState *s, int out)
450 { 465 {
451 uint32_t count; 466 uint32_t count;
452 - uint32_t addr; 467 + target_phys_addr_t addr;
453 468
454 if (!s->current_dma_len) { 469 if (!s->current_dma_len) {
455 /* Wait until data is available. */ 470 /* Wait until data is available. */
@@ -460,9 +475,14 @@ static void lsi_do_dma(LSIState *s, int out) @@ -460,9 +475,14 @@ static void lsi_do_dma(LSIState *s, int out)
460 count = s->dbc; 475 count = s->dbc;
461 if (count > s->current_dma_len) 476 if (count > s->current_dma_len)
462 count = s->current_dma_len; 477 count = s->current_dma_len;
463 - DPRINTF("DMA addr=0x%08x len=%d\n", s->dnad, count);  
464 478
465 addr = s->dnad; 479 addr = s->dnad;
  480 + if (lsi_dma_40bit(s))
  481 + addr |= ((uint64_t)s->dnad64 << 32);
  482 + else if (s->sbms)
  483 + addr |= ((uint64_t)s->sbms << 32);
  484 +
  485 + DPRINTF("DMA addr=0x%" TARGET_FMT_plx " len=%d\n", addr, count);
466 s->csbc += count; 486 s->csbc += count;
467 s->dnad += count; 487 s->dnad += count;
468 s->dbc -= count; 488 s->dbc -= count;
@@ -839,7 +859,7 @@ static void lsi_wait_reselect(LSIState *s) @@ -839,7 +859,7 @@ static void lsi_wait_reselect(LSIState *s)
839 static void lsi_execute_script(LSIState *s) 859 static void lsi_execute_script(LSIState *s)
840 { 860 {
841 uint32_t insn; 861 uint32_t insn;
842 - uint32_t addr; 862 + uint32_t addr, addr_high;
843 int opcode; 863 int opcode;
844 int insn_processed = 0; 864 int insn_processed = 0;
845 865
@@ -848,6 +868,7 @@ again: @@ -848,6 +868,7 @@ again:
848 insn_processed++; 868 insn_processed++;
849 insn = read_dword(s, s->dsp); 869 insn = read_dword(s, s->dsp);
850 addr = read_dword(s, s->dsp + 4); 870 addr = read_dword(s, s->dsp + 4);
  871 + addr_high = 0;
851 DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr); 872 DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
852 s->dsps = addr; 873 s->dsps = addr;
853 s->dcmd = insn >> 24; 874 s->dcmd = insn >> 24;
@@ -870,9 +891,15 @@ again: @@ -870,9 +891,15 @@ again:
870 /* Table indirect addressing. */ 891 /* Table indirect addressing. */
871 offset = sxt24(addr); 892 offset = sxt24(addr);
872 cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8); 893 cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
873 - s->dbc = cpu_to_le32(buf[0]); 894 + /* byte count is stored in bits 0:23 only */
  895 + s->dbc = cpu_to_le32(buf[0]) & 0xffffff;
874 s->rbc = s->dbc; 896 s->rbc = s->dbc;
875 addr = cpu_to_le32(buf[1]); 897 addr = cpu_to_le32(buf[1]);
  898 +
  899 + /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of
  900 + * table, bits [31:24] */
  901 + if (lsi_dma_40bit(s))
  902 + addr_high = cpu_to_le32(buf[0]) >> 24;
876 } 903 }
877 if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { 904 if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
878 DPRINTF("Wrong phase got %d expected %d\n", 905 DPRINTF("Wrong phase got %d expected %d\n",
@@ -881,6 +908,7 @@ again: @@ -881,6 +908,7 @@ again:
881 break; 908 break;
882 } 909 }
883 s->dnad = addr; 910 s->dnad = addr;
  911 + s->dnad64 = addr_high;
884 /* ??? Set ESA. */ 912 /* ??? Set ESA. */
885 s->ia = s->dsp - 8; 913 s->ia = s->dsp - 8;
886 switch (s->sstat1 & 0x7) { 914 switch (s->sstat1 & 0x7) {