Overhauled DMA bus master reads and writes and cleaned up the AMD PCnet code a bit (network queue implementation is pending).

This commit is contained in:
OBattler
2020-04-28 01:01:39 +02:00
parent bc3a2a3b20
commit 59822c6c0e
13 changed files with 361 additions and 232 deletions

View File

@@ -1044,16 +1044,12 @@ enter_smm(int in_hlt)
else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */
smram_save_state_p6(saved_state, in_hlt);
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
mem_writel_phys(smram_state, saved_state[n]);
}
cr0 &= ~0x8000000d;
cpu_state.flags = 2;
cpu_state.eflags = 0;
cr4 = 0;
dr[7] = 0x400;
cpu_state.pc = 0x8000;
@@ -1089,6 +1085,11 @@ enter_smm(int in_hlt)
cpu_state.op32 = use32;
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
writememl(0, smram_state, saved_state[n]);
}
nmi_mask = 0;
if (smi_latched) {
@@ -1146,7 +1147,7 @@ leave_smm(void)
for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) {
smram_state -= 4;
saved_state[n] = mem_readl_phys(smram_state);
saved_state[n] = readmeml(0, smram_state);
x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n);
}

View File

@@ -98,8 +98,8 @@ sff_bus_master_handler(sff8038i_t *dev, int enabled, uint16_t base)
static void
sff_bus_master_next_addr(sff8038i_t *dev)
{
DMAPageRead(dev->ptr_cur, (uint8_t *)&(dev->addr), 4);
DMAPageRead(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4);
dma_bm_read(dev->ptr_cur, (uint8_t *)&(dev->addr), 4, 4);
dma_bm_read(dev->ptr_cur + 4, (uint8_t *)&(dev->count), 4, 4);
sff_log("SFF-8038i Bus master DWORDs: %08X %08X\n", dev->addr, dev->count);
dev->eot = dev->count >> 31;
dev->count &= 0xfffe;
@@ -318,17 +318,17 @@ sff_bus_master_dma(int channel, uint8_t *data, int transfer_length, int out, voi
if (dev->count <= transfer_length) {
sff_log("%sing %i bytes to %08X\n", sop, dev->count, dev->addr);
if (out)
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
else
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), dev->count);
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), dev->count, 4);
transfer_length -= dev->count;
buffer_pos += dev->count;
} else {
sff_log("%sing %i bytes to %08X\n", sop, transfer_length, dev->addr);
if (out)
DMAPageRead(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
dma_bm_read(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
else
DMAPageWrite(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length);
dma_bm_write(dev->addr, (uint8_t *)(data + buffer_pos), transfer_length, 4);
/* Increase addr and decrease count so that resumed transfers do not mess up. */
dev->addr += transfer_length;
dev->count -= transfer_length;

View File

@@ -983,31 +983,47 @@ dma_mode(int channel)
/* DMA Bus Master Page Read/Write */
void
DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize)
dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize, int TransferSize)
{
uint32_t i = 0;
uint32_t i = 0, n, n2;
uint8_t bytes[4] = { 0, 0, 0, 0 };
#if 0
memcpy(DataRead, &ram[PhysAddress], TotalSize);
#else
for (i = 0; i < TotalSize; i++)
DataRead[i] = mem_readb_phys(PhysAddress + i);
#endif
n = TotalSize & ~(TransferSize - 1);
n2 = TotalSize - n;
/* Do the divisible block, if there is one. */
if (n) {
for (i = 0; i < n; i += TransferSize)
mem_read_phys((void *) &(DataRead[i]), PhysAddress + i, TransferSize);
}
/* Do the non-divisible block, if there is one. */
if (n2) {
mem_read_phys((void *) bytes, PhysAddress + n, TransferSize);
memcpy((void *) &(DataRead[n]), bytes, n2);
}
}
void
DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize)
dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize)
{
uint32_t i = 0;
uint32_t i = 0, n, n2;
uint8_t bytes[4] = { 0, 0, 0, 0 };
#if 0
mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1);
memcpy(&ram[PhysAddress], DataWrite, TotalSize);
#else
for (i = 0; i < TotalSize; i++)
mem_writeb_phys(PhysAddress + i, DataWrite[i]);
n = TotalSize & ~(TransferSize - 1);
n2 = TotalSize - n;
mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1);
#endif
/* Do the divisible block, if there is one. */
if (n) {
for (i = 0; i < n; i += TransferSize)
mem_write_phys((void *) &(DataWrite[i]), PhysAddress + i, TransferSize);
}
/* Do the non-divisible block, if there is one. */
if (n2) {
mem_read_phys((void *) bytes, PhysAddress + n, TransferSize);
memcpy(bytes, (void *) &(DataWrite[n]), n2);
mem_write_phys((void *) bytes, PhysAddress + n, TransferSize);
}
}

View File

@@ -90,10 +90,8 @@ extern void dma_alias_set_piix(void);
extern void dma_alias_remove(void);
extern void dma_alias_remove_piix(void);
extern void DMAPageRead(uint32_t PhysAddress, uint8_t *DataRead,
uint32_t TotalSize);
extern void DMAPageWrite(uint32_t PhysAddress, const uint8_t *DataWrite,
uint32_t TotalSize);
extern void dma_bm_read(uint32_t PhysAddress, uint8_t *DataRead, uint32_t TotalSize, int TransferSize);
extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, int TransferSize);
#endif /*EMU_DMA_H*/

View File

@@ -282,9 +282,11 @@ extern void mem_set_mem_state_smm(uint32_t base, uint32_t size, int state);
extern uint8_t mem_readb_phys(uint32_t addr);
extern uint16_t mem_readw_phys(uint32_t addr);
extern uint32_t mem_readl_phys(uint32_t addr);
extern void mem_read_phys(void *dest, uint32_t addr, int tranfer_size);
extern void mem_writeb_phys(uint32_t addr, uint8_t val);
extern void mem_writew_phys(uint32_t addr, uint16_t val);
extern void mem_writel_phys(uint32_t addr, uint32_t val);
extern void mem_write_phys(void *src, uint32_t addr, int tranfer_size);
extern uint8_t mem_read_ram(uint32_t addr, void *priv);
extern uint16_t mem_read_ramw(uint32_t addr, void *priv);

View File

@@ -425,7 +425,7 @@ typedef struct {
uint32_t Base, rom_addr, /* address of BIOS ROM */
CmdParamLeft, Outgoing,
pad32;
transfer_size;
volatile uint32_t
MailboxInit, MailboxCount,

View File

@@ -133,6 +133,9 @@ static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff };
#endif
#define USE_PHYS_EXEC
#ifdef ENABLE_MEM_LOG
int mem_do_log = ENABLE_MEM_LOG;
@@ -1373,9 +1376,14 @@ mem_readb_phys(uint32_t addr)
{
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS];
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
return _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK];
else if (map && map->read_b)
else
#endif
if (map && map->read_b)
return map->read_b(addr, map->p);
else
return 0xff;
@@ -1386,12 +1394,20 @@ uint16_t
mem_readw_phys(uint32_t addr)
{
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS];
uint16_t temp, *p;
uint16_t temp;
#ifdef USE_PHYS_EXEC
uint16_t *p;
#endif
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
return *p;
} else if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->read_w))
} else
#endif
if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->read_w))
return map->read_w(addr, map->p);
else {
temp = mem_readb_phys(addr + 1) << 8;
@@ -1406,12 +1422,20 @@ uint32_t
mem_readl_phys(uint32_t addr)
{
mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS];
uint32_t temp, *p;
uint32_t temp;
#ifdef USE_PHYS_EXEC
uint32_t *p;
#endif
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
return *p;
} else if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
} else
#endif
if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->read_l))
return map->read_l(addr, map->p);
else {
temp = mem_readw_phys(addr + 2) << 16;
@@ -1422,14 +1446,39 @@ mem_readl_phys(uint32_t addr)
}
void
mem_read_phys(void *dest, uint32_t addr, int transfer_size)
{
uint8_t *pb;
uint16_t *pw;
uint32_t *pl;
if (transfer_size == 4) {
pl = (uint32_t *) dest;
*pl = mem_readl_phys(addr);
} else if (transfer_size == 2) {
pw = (uint16_t *) dest;
*pw = mem_readw_phys(addr);
} else if (transfer_size == 4) {
pb = (uint8_t *) dest;
*pb = mem_readb_phys(addr);
}
}
void
mem_writeb_phys(uint32_t addr, uint8_t val)
{
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if (_mem_exec[addr >> MEM_GRANULARITY_BITS])
_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val;
else if (map && map->write_b)
else
#endif
if (map && map->write_b)
map->write_b(addr, val, map->p);
}
@@ -1438,12 +1487,19 @@ void
mem_writew_phys(uint32_t addr, uint16_t val)
{
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
#ifdef USE_PHYS_EXEC
uint16_t *p;
#endif
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
*p = val;
} else if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->write_w))
} else
#endif
if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->write_w))
map->write_w(addr, val, map->p);
else {
mem_writeb_phys(addr, val & 0xff);
@@ -1456,12 +1512,19 @@ void
mem_writel_phys(uint32_t addr, uint32_t val)
{
mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS];
#ifdef USE_PHYS_EXEC
uint32_t *p;
#endif
mem_logical_addr = 0xffffffff;
#ifdef USE_PHYS_EXEC
if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) {
p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]);
*p = val;
} else if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->write_l))
} else
#endif
if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->write_l))
map->write_l(addr, val, map->p);
else {
mem_writew_phys(addr, val & 0xffff);
@@ -1470,6 +1533,26 @@ mem_writel_phys(uint32_t addr, uint32_t val)
}
void
mem_write_phys(void *src, uint32_t addr, int transfer_size)
{
uint8_t *pb;
uint16_t *pw;
uint32_t *pl;
if (transfer_size == 4) {
pl = (uint32_t *) src;
mem_writel_phys(addr, *pl);
} else if (transfer_size == 2) {
pw = (uint16_t *) src;
mem_writew_phys(addr, *pw);
} else {
pb = (uint8_t *) src;
mem_writeb_phys(addr, *pb);
}
}
uint8_t
mem_read_ram(uint32_t addr, void *priv)
{

View File

@@ -240,6 +240,7 @@ typedef struct {
uint32_t cLinkDownReported;
/** MS to wait before we enable the link. */
uint32_t cMsLinkUpDelay;
int transfer_size;
uint8_t maclocal[6]; /* configured MAC (local) address */
pc_timer_t timer_soft_int, timer_restore;
} nic_t;
@@ -423,6 +424,7 @@ pcnetIsLinkUp(nic_t *dev)
return !dev->fLinkTempDown && dev->fLinkUp;
}
/**
* Load transmit message descriptor
* Make sure we read the own flag first.
@@ -435,34 +437,36 @@ pcnetIsLinkUp(nic_t *dev)
static __inline int
pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn)
{
uint8_t ownbyte;
uint8_t ownbyte, bytes[4] = { 0, 0, 0, 0 };
uint16_t xda[4];
uint32_t xda32[4];
if (BCR_SWSTYLE(dev) == 0) {
uint16_t xda[4];
DMAPageRead(addr+3, &ownbyte, 1);
dma_bm_read(addr, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)&xda[0], sizeof(xda));
dma_bm_read(addr, (uint8_t*)&xda[0], sizeof(xda), dev->transfer_size);
((uint32_t *)tmd)[0] = (uint32_t)xda[0] | ((uint32_t)(xda[1] & 0x00ff) << 16);
((uint32_t *)tmd)[1] = (uint32_t)xda[2] | ((uint32_t)(xda[1] & 0xff00) << 16);
((uint32_t *)tmd)[2] = (uint32_t)xda[3] << 16;
((uint32_t *)tmd)[3] = 0;
} else if (BCR_SWSTYLE(dev) != 3) {
DMAPageRead(addr+7, &ownbyte, 1);
dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)tmd, 16);
dma_bm_read(addr, (uint8_t*)tmd, 16, dev->transfer_size);
} else {
uint32_t xda[4];
DMAPageRead(addr+7, &ownbyte, 1);
dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)&xda[0], sizeof(xda));
((uint32_t *)tmd)[0] = xda[2];
((uint32_t *)tmd)[1] = xda[1];
((uint32_t *)tmd)[2] = xda[0];
((uint32_t *)tmd)[3] = xda[3];
dma_bm_read(addr, (uint8_t*)&xda32[0], sizeof(xda32), dev->transfer_size);
((uint32_t *)tmd)[0] = xda32[2];
((uint32_t *)tmd)[1] = xda32[1];
((uint32_t *)tmd)[2] = xda32[0];
((uint32_t *)tmd)[3] = xda32[3];
}
/* Double check the own bit; guest drivers might be buggy and lock prefixes in the recompiler are ignored by other threads. */
if (tmd->tmd1.own == 1 && !(ownbyte & 0x80))
@@ -481,30 +485,39 @@ pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn)
static __inline void
pcnetTmdStorePassHost(nic_t *dev, TMD *tmd, uint32_t addr)
{
uint8_t bytes[4] = { 0, 0, 0, 0 };
uint16_t xda[4];
uint32_t xda32[3];
if (BCR_SWSTYLE(dev) == 0) {
uint16_t xda[4];
dma_bm_read(addr, (uint8_t *) bytes, sizeof(xda), dev->transfer_size);
xda[0] = ((uint32_t *)tmd)[0] & 0xffff;
xda[1] = ((((uint32_t *)tmd)[0] >> 16) & 0xff) | ((((uint32_t *)tmd)[1]>>16) & 0xff00);
xda[2] = ((uint32_t *)tmd)[1] & 0xffff;
xda[3] = ((uint32_t *)tmd)[2] >> 16;
#if 0
xda[1] |= 0x8000;
DMAPageWrite(addr, (uint8_t*)&xda[0], sizeof(xda));
dma_bm_write(addr, (uint8_t*)&xda[0], sizeof(xda), dev->transfer_size);
#endif
xda[1] &= ~0x8000;
DMAPageWrite(addr+3, (uint8_t*)xda + 3, 1);
dma_bm_write(addr, (uint8_t*)&xda[0], sizeof(xda), dev->transfer_size);
} else if (BCR_SWSTYLE(dev) != 3) {
#if 0
((uint32_t*)tmd)[1] |= 0x80000000;
DMAPageWrite(addr, (uint8_t*)tmd, 12);
dma_bm_write(addr, (uint8_t*)tmd, 12, dev->transfer_size);
#endif
((uint32_t*)tmd)[1] &= ~0x80000000;
DMAPageWrite(addr+7, (uint8_t*)tmd + 7, 1);
dma_bm_write(addr, (uint8_t*)tmd, 12, dev->transfer_size);
} else {
uint32_t xda[3];
xda[0] = ((uint32_t *)tmd)[2];
xda[1] = ((uint32_t *)tmd)[1];
xda[2] = ((uint32_t *)tmd)[0];
xda[1] |= 0x80000000;
DMAPageWrite(addr, (uint8_t*)&xda[0], sizeof(xda));
xda[1] &= ~0x80000000;
DMAPageWrite(addr+7, (uint8_t*)xda + 7, 1);
xda32[0] = ((uint32_t *)tmd)[2];
xda32[1] = ((uint32_t *)tmd)[1];
xda32[2] = ((uint32_t *)tmd)[0];
#if 0
xda32[1] |= 0x80000000;
dma_bm_write(addr, (uint8_t*)&xda32[0], sizeof(xda32), dev->transfer_size);
#endif
xda32[1] &= ~0x80000000;
dma_bm_write(addr, (uint8_t*)&xda32[0], sizeof(xda32), dev->transfer_size);
}
}
@@ -521,33 +534,36 @@ pcnetTmdStorePassHost(nic_t *dev, TMD *tmd, uint32_t addr)
static __inline int
pcnetRmdLoad(nic_t *dev, RMD *rmd, uint32_t addr, int fRetIfNotOwn)
{
uint8_t ownbyte;
uint8_t ownbyte, bytes[4] = { 0, 0, 0, 0 };
uint16_t rda[4];
uint32_t rda32[4];
if (BCR_SWSTYLE(dev) == 0) {
uint16_t rda[4];
DMAPageRead(addr+3, &ownbyte, 1);
dma_bm_read(addr, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)&rda[0], sizeof(rda));
dma_bm_read(addr, (uint8_t*)&rda[0], sizeof(rda), dev->transfer_size);
((uint32_t *)rmd)[0] = (uint32_t)rda[0] | ((rda[1] & 0x00ff) << 16);
((uint32_t *)rmd)[1] = (uint32_t)rda[2] | ((rda[1] & 0xff00) << 16);
((uint32_t *)rmd)[2] = (uint32_t)rda[3];
((uint32_t *)rmd)[3] = 0;
} else if (BCR_SWSTYLE(dev) != 3) {
DMAPageRead(addr+7, &ownbyte, 1);
dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)rmd, 16);
dma_bm_read(addr, (uint8_t*)rmd, 16, dev->transfer_size);
} else {
uint32_t rda[4];
DMAPageRead(addr+7, &ownbyte, 1);
dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size);
ownbyte = bytes[3];
if (!(ownbyte & 0x80) && fRetIfNotOwn)
return 0;
DMAPageRead(addr, (uint8_t*)&rda[0], sizeof(rda));
((uint32_t *)rmd)[0] = rda[2];
((uint32_t *)rmd)[1] = rda[1];
((uint32_t *)rmd)[2] = rda[0];
((uint32_t *)rmd)[3] = rda[3];
dma_bm_read(addr, (uint8_t*)&rda32[0], sizeof(rda32), dev->transfer_size);
((uint32_t *)rmd)[0] = rda32[2];
((uint32_t *)rmd)[1] = rda32[1];
((uint32_t *)rmd)[2] = rda32[0];
((uint32_t *)rmd)[3] = rda32[3];
}
/* Double check the own bit; guest drivers might be buggy and lock prefixes in the recompiler are ignored by other threads. */
if (rmd->rmd1.own == 1 && !(ownbyte & 0x80))
@@ -567,52 +583,41 @@ pcnetRmdLoad(nic_t *dev, RMD *rmd, uint32_t addr, int fRetIfNotOwn)
static __inline void
pcnetRmdStorePassHost(nic_t *dev, RMD *rmd, uint32_t addr)
{
uint16_t rda[4];
uint32_t rda32[3];
if (BCR_SWSTYLE(dev) == 0) {
uint16_t rda[4];
rda[0] = ((uint32_t *)rmd)[0] & 0xffff;
rda[1] = ((((uint32_t *)rmd)[0]>>16) & 0xff) | ((((uint32_t *)rmd)[1]>>16) & 0xff00);
rda[2] = ((uint32_t *)rmd)[1] & 0xffff;
rda[3] = ((uint32_t *)rmd)[2] & 0xffff;
#if 0
rda[1] |= 0x8000;
DMAPageWrite(addr, (uint8_t*)&rda[0], sizeof(rda));
dma_bm_write(addr, (uint8_t*)&rda[0], sizeof(rda), dev->transfer_size);
#endif
rda[1] &= ~0x8000;
DMAPageWrite(addr+3, (uint8_t*)rda + 3, 1);
dma_bm_write(addr, (uint8_t*)&rda[0], sizeof(rda), dev->transfer_size);
} else if (BCR_SWSTYLE(dev) != 3) {
#if 0
((uint32_t*)rmd)[1] |= 0x80000000;
DMAPageWrite(addr, (uint8_t*)rmd, 12);
dma_bm_write(addr, (uint8_t*)rmd, 12, dev->transfer_size);
#endif
((uint32_t*)rmd)[1] &= ~0x80000000;
DMAPageWrite(addr+7, (uint8_t*)rmd + 7, 1);
dma_bm_write(addr, (uint8_t*)rmd, 12, dev->transfer_size);
} else {
uint32_t rda[3];
rda[0] = ((uint32_t *)rmd)[2];
rda[1] = ((uint32_t *)rmd)[1];
rda[2] = ((uint32_t *)rmd)[0];
rda[1] |= 0x80000000;
DMAPageWrite(addr, (uint8_t*)&rda[0], sizeof(rda));
rda[1] &= ~0x80000000;
DMAPageWrite(addr+7, (uint8_t*)rda + 7, 1);
rda32[0] = ((uint32_t *)rmd)[2];
rda32[1] = ((uint32_t *)rmd)[1];
rda32[2] = ((uint32_t *)rmd)[0];
#if 0
rda32[1] |= 0x80000000;
dma_bm_write(addr, (uint8_t*)&rda32[0], sizeof(rda32), dev->transfer_size);
#endif
rda32[1] &= ~0x80000000;
dma_bm_write(addr, (uint8_t*)&rda32[0], sizeof(rda32), dev->transfer_size);
}
}
/**
* Read+Write a TX/RX descriptor to prevent DMAPageWrite() allocating
* pages later when we shouldn't schedule to EMT. Temporarily hack.
*/
static void
pcnetDescTouch(nic_t *dev, uint32_t addr)
{
uint8_t aBuf[16];
int cbDesc;
if (BCR_SWSTYLE(dev) == 0)
cbDesc = 8;
else
cbDesc = 16;
DMAPageRead(addr, aBuf, cbDesc);
DMAPageWrite(addr, aBuf, cbDesc);
}
/** Checks if it's a bad (as in invalid) RMD.*/
#define IS_RMD_BAD(rmd) ((rmd).rmd1.ones != 15)
@@ -926,8 +931,8 @@ pcnetInit(nic_t *dev)
/** @todo Documentation says that RCVRL and XMTRL are stored as two's complement!
* Software is allowed to write these registers directly. */
#define PCNET_INIT() do { \
DMAPageRead(PHYSADDR(dev, CSR_IADR(dev)), \
(uint8_t *)&initblk, sizeof(initblk)); \
dma_bm_read(PHYSADDR(dev, CSR_IADR(dev)), \
(uint8_t *)&initblk, sizeof(initblk), dev->transfer_size); \
dev->aCSR[15] = le16_to_cpu(initblk.mode); \
CSR_RCVRL(dev) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512; \
CSR_XMTRL(dev) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512; \
@@ -964,7 +969,6 @@ pcnetInit(nic_t *dev)
RMD rmd;
uint32_t rdaddr = PHYSADDR(dev, pcnetRdraAddr(dev, i));
pcnetDescTouch(dev, rdaddr);
/* At this time it is not guaranteed that the buffers are already initialized. */
if (pcnetRmdLoad(dev, &rmd, rdaddr, 0)) {
uint32_t cbBuf = 4096U-rmd.rmd1.bcnt;
@@ -972,12 +976,6 @@ pcnetInit(nic_t *dev)
}
}
for (i = CSR_XMTRL(dev); i >= 1; i--) {
uint32_t tdaddr = PHYSADDR(dev, pcnetTdraAddr(dev, i));
pcnetDescTouch(dev, tdaddr);
}
/*
* Heuristics: The Solaris pcn driver allocates too few RX buffers (128 buffers of a
* size of 128 bytes are 16KB in summary) leading to frequent RX buffer overflows. In
@@ -1339,8 +1337,8 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size)
* forbidden as long as it is owned by the device
* - we don't cache any register state beyond this point
*/
DMAPageWrite(rbadr, src, cbBuf);
dma_bm_write(rbadr, src, cbBuf, dev->transfer_size);
/* RX disabled in the meantime? If so, abort RX. */
if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) {
@@ -1383,7 +1381,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size)
/* We have to leave the critical section here or we risk deadlocking
* with EMT when the write is to an unallocated page or has an access
* handler associated with it. See above for additional comments. */
DMAPageWrite(rbadr2, src, cbBuf);
dma_bm_write(rbadr2, src, cbBuf, dev->transfer_size);
/* RX disabled in the meantime? If so, abort RX. */
if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) {
@@ -1508,7 +1506,7 @@ pcnetAsyncTransmit(nic_t *dev)
* zero length if it is not the last one in the chain. */
if (cb <= MAX_FRAME) {
dev->xmit_pos = cb;
DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb);
dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb, dev->transfer_size);
if (fLoopback) {
if (HOST_IS_OWNER(CSR_CRST(dev)))
@@ -1574,7 +1572,7 @@ pcnetAsyncTransmit(nic_t *dev)
*/
unsigned cb = 4096 - tmd.tmd1.bcnt;
dev->xmit_pos = pcnetCalcPacketLen(dev, cb);
DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb);
dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb, dev->transfer_size);
for (;;) {
/*
@@ -1613,7 +1611,7 @@ pcnetAsyncTransmit(nic_t *dev)
if (dev->xmit_pos + cb <= MAX_FRAME) { /** @todo this used to be ... + cb < MAX_FRAME. */
int off = dev->xmit_pos;
dev->xmit_pos = cb + off;
DMAPageRead(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf + off, cb);
dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf + off, cb, dev->transfer_size);
}
/*
@@ -2834,6 +2832,11 @@ pcnet_init(const device_t *info)
dev->is_vlb = !!(info->flags & DEVICE_VLB);
dev->is_isa = !!(info->flags & (DEVICE_ISA | DEVICE_AT));
if (dev->is_pci || dev->is_vlb)
dev->transfer_size = 4;
else
dev->transfer_size = 2;
if (dev->is_pci) {
pcnet_mem_init(dev, 0x0fffff00);
pcnet_mem_disable(dev);

View File

@@ -281,6 +281,8 @@ network_close(void)
network_mutex = NULL;
network_mac = NULL;
/* Here is where we should clear the queue. */
network_log("NETWORK: closed.\n");
}

View File

@@ -557,7 +557,7 @@ buslogic_param_len(void *p)
static void
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir, int transfer_size)
{
uint32_t DataPointer = ESCSICmd->DataPointer;
int DataLength = ESCSICmd->DataLength;
@@ -581,10 +581,10 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
DMAPageRead(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength);
dma_bm_read(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
} else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) {
buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address);
DMAPageWrite(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength);
dma_bm_write(Address, (uint8_t *)dev->sc->temp_buffer, TransferLength, transfer_size);
}
}
}
@@ -651,7 +651,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
phase = sd->phase;
if (phase != SCSI_PHASE_STATUS) {
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT));
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT), dev->transfer_size);
scsi_device_command_phase1(sd);
}

View File

@@ -467,7 +467,7 @@ ncr53c8xx_read(ncr53c8xx_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
buf[i] = inb((uint16_t) (addr + i));
} else {
ncr53c8xx_log("NCR 810: Reading from memory address %08X\n", addr);
DMAPageRead(addr, buf, len);
dma_bm_read(addr, buf, len, 4);
}
}
@@ -485,7 +485,7 @@ ncr53c8xx_write(ncr53c8xx_t *dev, uint32_t addr, uint8_t *buf, uint32_t len)
outb((uint16_t) (addr + i), buf[i]);
} else {
ncr53c8xx_log("NCR 810: Writing to memory address %08X\n", addr);
DMAPageWrite(addr, buf, len);
dma_bm_write(addr, buf, len, 4);
}
}
@@ -495,7 +495,7 @@ read_dword(ncr53c8xx_t *dev, uint32_t addr)
{
uint32_t buf;
ncr53c8xx_log("Reading the next DWORD from memory (%08X)...\n", addr);
DMAPageRead(addr, (uint8_t *)&buf, 4);
dma_bm_read(addr, (uint8_t *)&buf, 4, 4);
return buf;
}
@@ -736,7 +736,7 @@ ncr53c8xx_do_command(ncr53c8xx_t *dev, uint8_t id)
uint8_t buf[12];
memset(buf, 0, 12);
DMAPageRead(dev->dnad, buf, MIN(12, dev->dbc));
dma_bm_read(dev->dnad, buf, MIN(12, dev->dbc), 4);
if (dev->dbc > 12) {
ncr53c8xx_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: CDB length %i too big\n", id, dev->current_lun, buf[0], dev->dbc);
dev->dbc = 12;
@@ -871,7 +871,7 @@ static uint8_t
ncr53c8xx_get_msgbyte(ncr53c8xx_t *dev)
{
uint8_t data;
DMAPageRead(dev->dnad, &data, 1);
dma_bm_read(dev->dnad, &data, 1, 4);
dev->dnad++;
dev->dbc--;
return data;
@@ -1082,7 +1082,7 @@ again:
/* 32-bit Table indirect */
offset = sextract32(addr, 0, 24);
DMAPageRead(dev->dsa + offset, (uint8_t *)buf, 8);
dma_bm_read(dev->dsa + offset, (uint8_t *)buf, 8, 4);
/* byte count is stored in bits 0:23 only */
dev->dbc = buf[0] & 0xffffff;
addr = buf[1];
@@ -1370,14 +1370,14 @@ again:
n = (insn & 7);
reg = (insn >> 16) & 0xff;
if (insn & (1 << 24)) {
DMAPageRead(addr, data, n);
dma_bm_read(addr, data, n, 4);
for (i = 0; i < n; i++)
ncr53c8xx_reg_writeb(dev, reg + i, data[i]);
} else {
ncr53c8xx_log("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);
for (i = 0; i < n; i++)
data[i] = ncr53c8xx_reg_readb(dev, reg + i);
DMAPageWrite(addr, data, n);
dma_bm_write(addr, data, n, 4);
}
}
break;

View File

@@ -403,7 +403,7 @@ spock_readw(uint16_t port, void *p)
static void
spock_rd_sge(spock_t *scsi, uint32_t Address, SGE *SG)
{
DMAPageRead(Address, (uint8_t *)SG, sizeof(SGE));
dma_bm_read(Address, (uint8_t *)SG, sizeof(SGE), 2);
spock_add_to_period(scsi, sizeof(SGE));
}
@@ -553,20 +553,20 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
spock_log("Start failed, SCB ID = %d\n", scsi->scb_id);
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2);
DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
break;
}
DMAPageRead(scsi->scb_addr, (uint8_t *)&scb->command, 2);
DMAPageRead(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2);
DMAPageRead(scsi->scb_addr + 4, (uint8_t *)&scb->lba_addr, 4);
DMAPageRead(scsi->scb_addr + 8, (uint8_t *)&scb->sge.sys_buf_addr, 4);
DMAPageRead(scsi->scb_addr + 12, (uint8_t *)&scb->sge.sys_buf_byte_count, 4);
DMAPageRead(scsi->scb_addr + 16, (uint8_t *)&scb->term_status_block_addr, 4);
DMAPageRead(scsi->scb_addr + 20, (uint8_t *)&scb->scb_chain_addr, 4);
DMAPageRead(scsi->scb_addr + 24, (uint8_t *)&scb->block_count, 2);
DMAPageRead(scsi->scb_addr + 26, (uint8_t *)&scb->block_length, 2);
dma_bm_read(scsi->scb_addr, (uint8_t *)&scb->command, 2, 2);
dma_bm_read(scsi->scb_addr + 2, (uint8_t *)&scb->enable, 2, 2);
dma_bm_read(scsi->scb_addr + 4, (uint8_t *)&scb->lba_addr, 4, 2);
dma_bm_read(scsi->scb_addr + 8, (uint8_t *)&scb->sge.sys_buf_addr, 4, 2);
dma_bm_read(scsi->scb_addr + 12, (uint8_t *)&scb->sge.sys_buf_byte_count, 4, 2);
dma_bm_read(scsi->scb_addr + 16, (uint8_t *)&scb->term_status_block_addr, 4, 2);
dma_bm_read(scsi->scb_addr + 20, (uint8_t *)&scb->scb_chain_addr, 4, 2);
dma_bm_read(scsi->scb_addr + 24, (uint8_t *)&scb->block_count, 2, 2);
dma_bm_read(scsi->scb_addr + 26, (uint8_t *)&scb->block_length, 2, 2);
spock_log("SCB : \n"
" Command = %04x\n"
@@ -605,29 +605,29 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
get_complete_stat->cache_info_status = 0;
get_complete_stat->scb_addr = scsi->scb_addr;
DMAPageWrite(scb->sge.sys_buf_addr, (uint8_t *)&get_complete_stat->scb_status, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_complete_stat->retry_count, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_complete_stat->residual_byte_count, 4);
DMAPageWrite(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_complete_stat->sg_list_element_addr, 4);
DMAPageWrite(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_complete_stat->device_dep_status_len, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_complete_stat->cmd_status, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_complete_stat->error, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 18, (uint8_t *)&get_complete_stat->reserved, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 20, (uint8_t *)&get_complete_stat->cache_info_status, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 22, (uint8_t *)&get_complete_stat->scb_addr, 4);
dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *)&get_complete_stat->scb_status, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_complete_stat->retry_count, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_complete_stat->residual_byte_count, 4, 2);
dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_complete_stat->sg_list_element_addr, 4, 2);
dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_complete_stat->device_dep_status_len, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_complete_stat->cmd_status, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_complete_stat->error, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 18, (uint8_t *)&get_complete_stat->reserved, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 20, (uint8_t *)&get_complete_stat->cache_info_status, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 22, (uint8_t *)&get_complete_stat->scb_addr, 4, 2);
scsi->scb_state = 3;
}
break;
case CMD_UNKNOWN_1C10:
spock_log("Unknown 1C10\n");
DMAPageRead(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count);
dma_bm_read(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2);
scsi->scb_state = 3;
break;
case CMD_UNKNOWN_1C11:
spock_log("Unknown 1C11\n");
DMAPageWrite(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count);
dma_bm_write(scb->sge.sys_buf_addr, scsi->buf, scb->sge.sys_buf_byte_count, 2);
scsi->scb_state = 3;
break;
@@ -646,15 +646,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
get_pos_info->pos7 = 0;
get_pos_info->pos8 = 0;
DMAPageWrite(scb->sge.sys_buf_addr, (uint8_t *)&get_pos_info->pos, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_pos_info->pos1, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_pos_info->pos2, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 6, (uint8_t *)&get_pos_info->pos3, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_pos_info->pos4, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 10, (uint8_t *)&get_pos_info->pos5, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_pos_info->pos6, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_pos_info->pos7, 2);
DMAPageWrite(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_pos_info->pos8, 2);
dma_bm_write(scb->sge.sys_buf_addr, (uint8_t *)&get_pos_info->pos, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 2, (uint8_t *)&get_pos_info->pos1, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 4, (uint8_t *)&get_pos_info->pos2, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 6, (uint8_t *)&get_pos_info->pos3, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 8, (uint8_t *)&get_pos_info->pos4, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 10, (uint8_t *)&get_pos_info->pos5, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 12, (uint8_t *)&get_pos_info->pos6, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 14, (uint8_t *)&get_pos_info->pos7, 2, 2);
dma_bm_write(scb->sge.sys_buf_addr + 16, (uint8_t *)&get_pos_info->pos8, 2, 2);
scsi->scb_state = 3;
}
break;
@@ -677,7 +677,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
case CMD_SEND_OTHER_SCSI:
spock_log("Send Other SCSI\n");
DMAPageRead(scsi->scb_addr + 0x18, scsi->cdb, 12);
dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2);
scsi->cdb[1] = (scsi->cdb[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/
scsi->cdb_len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6;
scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id;
@@ -788,18 +788,18 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb)
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
spock_log("Status Check Condition on device ID %d\n", scsi->cdb_id);
DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2);
DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2);
DMAPageWrite(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2);
DMAPageWrite(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xb*2, (uint8_t *)&term_stat_block_addrb, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0xc*2, (uint8_t *)&term_stat_block_addrc, 2, 2);
}
} else if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) {
uint16_t term_stat_block_addr7 = (0xc << 8) | 2;
uint16_t term_stat_block_addr8 = 0x10;
spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL);
scsi->scb_state = 0;
DMAPageWrite(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2);
DMAPageWrite(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2);
dma_bm_write(scb->term_status_block_addr + 0x7*2, (uint8_t *)&term_stat_block_addr7, 2, 2);
dma_bm_write(scb->term_status_block_addr + 0x8*2, (uint8_t *)&term_stat_block_addr8, 2, 2);
}
break;
@@ -892,10 +892,10 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
if ((sd->phase == SCSI_PHASE_DATA_IN) && DataTx) {
spock_log("Writing S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address);
DMAPageWrite(Address, &sd->sc->temp_buffer[sg_pos], DataTx);
dma_bm_write(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2);
} else if ((sd->phase == SCSI_PHASE_DATA_OUT) && DataTx) {
spock_log("Reading S/G segment %i: length %i, pointer %08X\n", c, DataTx, Address);
DMAPageRead(Address, &sd->sc->temp_buffer[sg_pos], DataTx);
dma_bm_read(Address, &sd->sc->temp_buffer[sg_pos], DataTx, 2);
}
sg_pos += scb->sge.sys_buf_byte_count;
@@ -907,9 +907,9 @@ spock_process_scsi(spock_t *scsi, scb_t *scb)
}
} else {
if (sd->phase == SCSI_PHASE_DATA_IN) {
DMAPageWrite(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len));
dma_bm_write(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len), 2);
} else if (sd->phase == SCSI_PHASE_DATA_OUT)
DMAPageRead(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len));
dma_bm_read(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int)scsi->data_len), 2);
}
scsi_device_command_phase1(sd);

View File

@@ -250,7 +250,7 @@ completion_code(uint8_t *sense)
static uint8_t
x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, uint32_t addr)
x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, uint32_t addr, int transfer_size)
{
dev->buffer_length = -1;
@@ -269,12 +269,12 @@ x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len,
if (buf)
memcpy(buf, dev->sc->temp_buffer, dev->buffer_length);
else
DMAPageWrite(addr, dev->sc->temp_buffer, dev->buffer_length);
dma_bm_write(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size);
} else if (dev->phase == SCSI_PHASE_DATA_OUT) {
if (buf)
memcpy(dev->sc->temp_buffer, buf, dev->buffer_length);
else
DMAPageRead(addr, dev->sc->temp_buffer, dev->buffer_length);
dma_bm_read(addr, dev->sc->temp_buffer, dev->buffer_length, transfer_size);
}
}
@@ -285,7 +285,7 @@ x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len,
static uint8_t
x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf)
x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf, int transfer_size)
{
uint8_t *cdb;
uint8_t ret;
@@ -295,7 +295,7 @@ x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf)
cdb[0] = GPCMD_READ_CDROM_CAPACITY;
memset(buf, 0, 8);
ret = x54x_bios_scsi_command(sd, cdb, buf, 8, 0);
ret = x54x_bios_scsi_command(sd, cdb, buf, 8, 0, transfer_size);
free(cdb);
@@ -304,7 +304,7 @@ x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf)
static uint8_t
x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf)
x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf, int transfer_size)
{
uint8_t *cdb;
uint8_t ret;
@@ -315,7 +315,7 @@ x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf)
cdb[4] = 36;
memset(buf, 0, 36);
ret = x54x_bios_scsi_command(sd, cdb, buf, 36, 0);
ret = x54x_bios_scsi_command(sd, cdb, buf, 36, 0, transfer_size);
free(cdb);
@@ -324,7 +324,7 @@ x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf)
static uint8_t
x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer)
x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer, int transfer_size)
{
uint8_t *rcbuf;
uint8_t ret;
@@ -333,7 +333,7 @@ x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer)
memset(buffer, 0x00, 6);
rcbuf = (uint8_t *) malloc(8);
ret = x54x_bios_read_capacity(sd, rcbuf);
ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size);
if (ret) {
free(rcbuf);
return(ret);
@@ -354,7 +354,7 @@ x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer)
static int
x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer)
x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer, int transfer_size)
{
uint8_t *inqbuf, *rcbuf;
uint8_t ret;
@@ -363,7 +363,7 @@ x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer)
memset(buffer, 0x00, 6);
inqbuf = (uint8_t *) malloc(36);
ret = x54x_bios_inquiry(sd, inqbuf);
ret = x54x_bios_inquiry(sd, inqbuf, transfer_size);
if (ret) {
free(inqbuf);
return(ret);
@@ -373,7 +373,7 @@ x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer)
buffer[5] = inqbuf[1];
rcbuf = (uint8_t *) malloc(8);
ret = x54x_bios_read_capacity(sd, rcbuf);
ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size);
if (ret) {
free(rcbuf);
free(inqbuf);
@@ -463,8 +463,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
if (sector_len > 0) {
x54x_log("BIOS DMA: Reading 14 bytes at %08X\n",
dma_address);
DMAPageWrite(dma_address,
scsi_device_sense(dev), 14);
dma_bm_write(dma_address, scsi_device_sense(dev), 14, x54x->transfer_size);
}
return(0);
@@ -485,7 +484,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
if (cmd->command != 0x0c)
cdb[8] = sector_len;
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address);
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size);
if (cmd->command == 0x0c)
ret = !!ret;
break;
@@ -519,7 +518,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
cdb[0] = bios_cmd_to_scsi[cmd->command];
cdb[1] = (cmd->lun & 7) << 5;
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address);
ret = x54x_bios_scsi_command(dev, cdb, NULL, sector_len, dma_address, x54x->transfer_size);
break;
case 0x08: /* Read Drive Parameters */
@@ -530,12 +529,12 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
buf = (uint8_t *) malloc(6);
if (cmd->command == 0x08)
ret = x54x_bios_command_08(dev, buf);
ret = x54x_bios_command_08(dev, buf, x54x->transfer_size);
else
ret = x54x_bios_command_15(dev, buf);
ret = x54x_bios_command_15(dev, buf, x54x->transfer_size);
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
DMAPageWrite(dma_address, buf, 4);
dma_bm_write(dma_address, buf, 4, x54x->transfer_size);
free(buf);
break;
@@ -597,12 +596,15 @@ static void
x54x_ccb(x54x_t *dev)
{
Req_t *req = &dev->Req;
uint8_t bytes[4] = { 0, 0, 0, 0};
/* Rewrite the CCB up to the CDB. */
x54x_log("CCB completion code and statuses rewritten (pointer %08X)\n", req->CCBPointer);
DMAPageWrite(req->CCBPointer + 0x000D, &(req->MailboxCompletionCode), 1);
DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1);
DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1);
dma_bm_read(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size);
bytes[1] = req->MailboxCompletionCode;
bytes[2] = req->HostStatus;
bytes[3] = req->TargetStatus;
dma_bm_write(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size);
x54x_add_to_period(dev, 3);
if (dev->MailboxOutInterrupts)
@@ -623,6 +625,7 @@ x54x_mbi(x54x_t *dev)
uint8_t TargetStatus = req->TargetStatus;
uint32_t MailboxCompletionCode = req->MailboxCompletionCode;
uint32_t Incoming;
uint8_t bytes[4] = { 0, 0, 0, 0 };
Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * ((dev->flags & X54X_MBX_24BIT) ? sizeof(Mailbox_t) : sizeof(Mailbox32_t)));
@@ -632,8 +635,10 @@ x54x_mbi(x54x_t *dev)
/* Rewrite the CCB up to the CDB. */
x54x_log("CCB statuses rewritten (pointer %08X)\n", req->CCBPointer);
DMAPageWrite(req->CCBPointer + 0x000E, &(req->HostStatus), 1);
DMAPageWrite(req->CCBPointer + 0x000F, &(req->TargetStatus), 1);
dma_bm_read(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size);
bytes[2] = req->HostStatus;
bytes[3] = req->TargetStatus;
dma_bm_write(req->CCBPointer + 0x000C, (uint8_t *) bytes, 4, dev->transfer_size);
x54x_add_to_period(dev, 2);
} else {
x54x_log("Mailbox not found!\n");
@@ -644,16 +649,19 @@ x54x_mbi(x54x_t *dev)
if (dev->flags & X54X_MBX_24BIT) {
U32_TO_ADDR(CCBPointer, req->CCBPointer);
x54x_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer);
DMAPageWrite(Incoming, &(req->MailboxCompletionCode), 1);
DMAPageWrite(Incoming + 1, (uint8_t *)&CCBPointer, 3);
bytes[0] = req->MailboxCompletionCode;
memcpy(&(bytes[1]), (uint8_t *)&CCBPointer, 3);
dma_bm_write(Incoming, (uint8_t *) bytes, 4, dev->transfer_size);
x54x_add_to_period(dev, 4);
x54x_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming);
} else {
x54x_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", req->MailboxCompletionCode, CCBPointer);
DMAPageWrite(Incoming, (uint8_t *)&(req->CCBPointer), 4);
DMAPageWrite(Incoming + 4, &(req->HostStatus), 1);
DMAPageWrite(Incoming + 5, &(req->TargetStatus), 1);
DMAPageWrite(Incoming + 7, &(req->MailboxCompletionCode), 1);
dma_bm_write(Incoming, (uint8_t *)&(req->CCBPointer), 4, dev->transfer_size);
dma_bm_read(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size);
bytes[0] = req->HostStatus;
bytes[1] = req->TargetStatus;
bytes[3] = req->MailboxCompletionCode;
dma_bm_write(Incoming + 4, (uint8_t *) bytes, 4, dev->transfer_size);
x54x_add_to_period(dev, 7);
x54x_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming);
}
@@ -672,9 +680,17 @@ static void
x54x_rd_sge(x54x_t *dev, int Is24bit, uint32_t Address, SGE32 *SG)
{
SGE SGE24;
uint8_t bytes[8];
if (Is24bit) {
DMAPageRead(Address, (uint8_t *)&SGE24, sizeof(SGE));
if (dev->transfer_size == 4) {
/* 32-bit device, do this to make the transfer divisible by 4 bytes. */
dma_bm_read(Address, (uint8_t *) bytes, 8, dev->transfer_size);
memcpy((uint8_t *)&SGE24, bytes, sizeof(SGE));
} else {
/* 16-bit device, special handling not needed. */
dma_bm_read(Address, (uint8_t *)&SGE24, 8, dev->transfer_size);
}
x54x_add_to_period(dev, sizeof(SGE));
/* Convert the 24-bit entries into 32-bit entries. */
@@ -682,7 +698,7 @@ x54x_rd_sge(x54x_t *dev, int Is24bit, uint32_t Address, SGE32 *SG)
SG->Segment = ADDR_TO_U32(SGE24.Segment);
SG->SegmentPointer = ADDR_TO_U32(SGE24.SegmentPointer);
} else {
DMAPageRead(Address, (uint8_t *)SG, sizeof(SGE32));
dma_bm_read(Address, (uint8_t *)SG, sizeof(SGE32), dev->transfer_size);
x54x_add_to_period(dev, sizeof(SGE32));
}
}
@@ -737,6 +753,7 @@ x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength)
uint32_t Residue = 0;
addr24 Residue24;
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
uint8_t bytes[4] = { 0, 0, 0, 0 };
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
@@ -749,11 +766,13 @@ x54x_set_residue(x54x_t *dev, Req_t *req, int32_t TransferLength)
if (req->Is24bit) {
U32_TO_ADDR(Residue24, Residue);
DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue24, 3);
dma_bm_read(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size);
memcpy((uint8_t *) bytes, (uint8_t *)&Residue24, 3);
dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *) bytes, 4, dev->transfer_size);
x54x_add_to_period(dev, 3);
x54x_log("24-bit Residual data length for reading: %d\n", Residue);
} else {
DMAPageWrite(req->CCBPointer + 0x0004, (uint8_t *)&Residue, 4);
dma_bm_write(req->CCBPointer + 0x0004, (uint8_t *)&Residue, 4, dev->transfer_size);
x54x_add_to_period(dev, 4);
x54x_log("32-bit Residual data length for reading: %d\n", Residue);
}
@@ -799,11 +818,11 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if (read_from_host && DataToTransfer) {
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
DMAPageRead(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer);
dma_bm_read(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else if (write_to_host && DataToTransfer) {
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
DMAPageWrite(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer);
dma_bm_write(Address, &(scsi_devices[req->TargetID].sc->temp_buffer[sg_pos]), DataToTransfer, dev->transfer_size);
}
else
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
@@ -823,9 +842,9 @@ x54x_buf_dma_transfer(x54x_t *dev, Req_t *req, int Is24bit, int TransferLength,
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
if (read_from_host)
DMAPageRead(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength));
dma_bm_read(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
else if (write_to_host)
DMAPageWrite(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength));
dma_bm_write(Address, scsi_devices[req->TargetID].sc->temp_buffer, MIN(BufLen, (int) DataLength), dev->transfer_size);
}
}
}
@@ -884,7 +903,7 @@ SenseBufferFree(x54x_t *dev, Req_t *req, int Copy)
x54x_log("SenseBufferFree(): Writing %i bytes at %08X\n",
SenseLength, SenseBufferAddress);
DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength);
dma_bm_write(SenseBufferAddress, temp_sense, SenseLength, dev->transfer_size);
x54x_add_to_period(dev, SenseLength);
x54x_log("Sense data written to buffer: %02X %02X %02X\n",
temp_sense[2], temp_sense[12], temp_sense[13]);
@@ -986,7 +1005,7 @@ x54x_request_sense(x54x_t *dev)
sd->buffer_length = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
if ((sd->status != SCSI_STATUS_OK) && (sd->buffer_length > 0)) {
SenseBufferAddress = SenseBufferPointer(req);
DMAPageWrite(SenseBufferAddress, scsi_devices[req->TargetID].sc->temp_buffer, sd->buffer_length);
dma_bm_write(SenseBufferAddress, scsi_devices[req->TargetID].sc->temp_buffer, sd->buffer_length, dev->transfer_size);
x54x_add_to_period(dev, sd->buffer_length);
}
scsi_device_command_phase1(sd);
@@ -1021,7 +1040,7 @@ x54x_mbo_free(x54x_t *dev)
CodeOffset = (dev->flags & X54X_MBX_24BIT) ? 0 : 7;
x54x_log("x54x_mbo_free(): Writing %i bytes at %08X\n", sizeof(CmdStatus), dev->Outgoing + CodeOffset);
DMAPageWrite(dev->Outgoing + CodeOffset, &CmdStatus, 1);
dma_bm_write(dev->Outgoing + CodeOffset, &CmdStatus, 1, dev->transfer_size);
}
@@ -1045,7 +1064,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
scsi_device_t *sd;
/* Fetch data from the Command Control Block. */
DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32));
dma_bm_read(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32), dev->transfer_size);
x54x_add_to_period(dev, sizeof(CCB32));
req->Is24bit = !!(dev->flags & X54X_MBX_24BIT);
@@ -1107,7 +1126,7 @@ x54x_req_abort(x54x_t *dev, uint32_t CCBPointer)
CCBU CmdBlock;
/* Fetch data from the Command Control Block. */
DMAPageRead(CCBPointer, (uint8_t *)&CmdBlock, sizeof(CCB32));
dma_bm_read(CCBPointer, (uint8_t *)&CmdBlock, sizeof(CCB32), dev->transfer_size);
x54x_add_to_period(dev, sizeof(CCB32));
x54x_mbi_setup(dev, CCBPointer, &CmdBlock,
@@ -1135,7 +1154,7 @@ x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32)
if (dev->flags & X54X_MBX_24BIT) {
Outgoing = Addr + (Cur * sizeof(Mailbox_t));
DMAPageRead(Outgoing, (uint8_t *)&MailboxOut, sizeof(Mailbox_t));
dma_bm_read(Outgoing, (uint8_t *)&MailboxOut, sizeof(Mailbox_t), dev->transfer_size);
x54x_add_to_period(dev, sizeof(Mailbox_t));
ccbp = *(uint32_t *) &MailboxOut;
@@ -1144,7 +1163,7 @@ x54x_mbo(x54x_t *dev, Mailbox32_t *Mailbox32)
} else {
Outgoing = Addr + (Cur * sizeof(Mailbox32_t));
DMAPageRead(Outgoing, (uint8_t *)Mailbox32, sizeof(Mailbox32_t));
dma_bm_read(Outgoing, (uint8_t *)Mailbox32, sizeof(Mailbox32_t), dev->transfer_size);
x54x_add_to_period(dev, sizeof(Mailbox32_t));
}
@@ -1716,7 +1735,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
Address.lo = dev->CmdBuf[2];
FIFOBuf = ADDR_TO_U32(Address);
x54x_log("Adaptec LocalRAM: Reading 64 bytes at %08X\n", FIFOBuf);
DMAPageRead(FIFOBuf, dev->dma_buffer, 64);
dma_bm_read(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size);
break;
case CMD_READ_CH2: /* write channel 2 buffer */
@@ -1726,7 +1745,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
Address.lo = dev->CmdBuf[2];
FIFOBuf = ADDR_TO_U32(Address);
x54x_log("Adaptec LocalRAM: Writing 64 bytes at %08X\n", FIFOBuf);
DMAPageWrite(FIFOBuf, dev->dma_buffer, 64);
dma_bm_write(FIFOBuf, dev->dma_buffer, 64, dev->transfer_size);
break;
case CMD_OPTIONS: /* Set adapter options */
@@ -1906,6 +1925,11 @@ x54x_init(const device_t *info)
dev->timer.period = 10.0;
timer_set_delay_u64(&dev->timer, (uint64_t) (dev->timer.period * ((double) TIMER_USEC)));
if (x54x_is_32bit(dev))
dev->transfer_size = 4;
else
dev->transfer_size = 2;
return(dev);
}