#define LSI_CCNTL0_PMJCTL 0x40
#define LSI_CCNTL0_ENPMJ 0x80
+#define LSI_CCNTL1_EN64DBMV 0x01
+#define LSI_CCNTL1_EN64TIBMV 0x02
+#define LSI_CCNTL1_64TIMOD 0x04
+#define LSI_CCNTL1_DDAC 0x08
+#define LSI_CCNTL1_ZMOD 0x80
+
+#define LSI_CCNTL1_40BIT (LSI_CCNTL1_EN64TIBMV|LSI_CCNTL1_64TIMOD)
+
#define PHASE_DO 0
#define PHASE_DI 1
#define PHASE_CMD 2
s->csbc = 0;
}
+static int lsi_dma_40bit(LSIState *s)
+{
+ if ((s->ccntl1 & LSI_CCNTL1_40BIT) == LSI_CCNTL1_40BIT)
+ return 1;
+ return 0;
+}
+
static uint8_t lsi_reg_readb(LSIState *s, int offset);
static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
static void lsi_execute_script(LSIState *s);
static void lsi_do_dma(LSIState *s, int out)
{
uint32_t count;
- uint32_t addr;
+ target_phys_addr_t addr;
if (!s->current_dma_len) {
/* Wait until data is available. */
count = s->dbc;
if (count > s->current_dma_len)
count = s->current_dma_len;
- DPRINTF("DMA addr=0x%08x len=%d\n", s->dnad, count);
addr = s->dnad;
+ if (lsi_dma_40bit(s))
+ addr |= ((uint64_t)s->dnad64 << 32);
+ else if (s->sbms)
+ addr |= ((uint64_t)s->sbms << 32);
+
+ DPRINTF("DMA addr=0x%" TARGET_FMT_plx " len=%d\n", addr, count);
s->csbc += count;
s->dnad += count;
s->dbc -= count;
static void lsi_execute_script(LSIState *s)
{
uint32_t insn;
- uint32_t addr;
+ uint32_t addr, addr_high;
int opcode;
int insn_processed = 0;
insn_processed++;
insn = read_dword(s, s->dsp);
addr = read_dword(s, s->dsp + 4);
+ addr_high = 0;
DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);
s->dsps = addr;
s->dcmd = insn >> 24;
/* Table indirect addressing. */
offset = sxt24(addr);
cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
- s->dbc = cpu_to_le32(buf[0]);
+ /* byte count is stored in bits 0:23 only */
+ s->dbc = cpu_to_le32(buf[0]) & 0xffffff;
s->rbc = s->dbc;
addr = cpu_to_le32(buf[1]);
+
+ /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of
+ * table, bits [31:24] */
+ if (lsi_dma_40bit(s))
+ addr_high = cpu_to_le32(buf[0]) >> 24;
}
if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
DPRINTF("Wrong phase got %d expected %d\n",
break;
}
s->dnad = addr;
+ s->dnad64 = addr_high;
/* ??? Set ESA. */
s->ia = s->dsp - 8;
switch (s->sstat1 & 0x7) {