code cleanup for win32/tap/eth

This commit is contained in:
sktsqrl 2012-07-04 13:44:37 -07:00
parent 9a3dd778cb
commit 9cff8316d2
3 changed files with 126 additions and 138 deletions

View File

@ -192,28 +192,26 @@ bool CEXIETHERNET::Activate()
if (IsActivated())
return true;
INFO_LOG(SP1, "Activating BBA...");
DWORD len;
std::vector<std::string> device_guids;
if (!Win32TAPHelper::GetGUIDs(device_guids))
{
INFO_LOG(SP1, "Failed to find a TAP GUID");
ERROR_LOG(SP1, "Failed to find a TAP GUID");
return false;
}
for (int i = 0; i < device_guids.size(); i++)
for (size_t i = 0; i < device_guids.size(); i++)
{
if (Win32TAPHelper::OpenTAP(mHAdapter, device_guids.at(i)))
{
ERROR_LOG(SP1, "OPENED %s", device_guids.at(i).c_str());
INFO_LOG(SP1, "OPENED %s", device_guids.at(i).c_str());
i = device_guids.size();
}
}
if (mHAdapter == INVALID_HANDLE_VALUE)
{
INFO_LOG(SP1, "Failed to open any TAP");
ERROR_LOG(SP1, "Failed to open any TAP");
return false;
}
@ -240,14 +238,11 @@ bool CEXIETHERNET::Activate()
if (!DeviceIoControl(mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS,
&status, sizeof(status), &status, sizeof(status), &len, NULL))
{
INFO_LOG(SP1, "WARNING: The TAP-Win32 driver rejected a"
ERROR_LOG(SP1, "WARNING: The TAP-Win32 driver rejected a"
"TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
return false;
}
//RecvInit();
INFO_LOG(SP1, "Success!");
return true;
}
@ -270,50 +265,27 @@ bool CEXIETHERNET::IsActivated()
return mHAdapter != INVALID_HANDLE_VALUE;
}
// TODO check if still needed
// Required for lwip...not sure why
void fixup_ip_checksum(u16 *dataptr, u16 len)
{
u32 acc = 0;
u16 *data = dataptr;
u16 *chksum = &dataptr[5];
*chksum = 0;
while (len > 1) {
u16 s = *data++;
acc += Common::swap16(s);
len -= 2;
}
acc = (acc >> 16) + (acc & 0xffff);
acc += (acc >> 16);
*chksum = Common::swap16(~acc);
}
bool CEXIETHERNET::SendFrame(u8 *frame, u32 size)
{
//fixup_ip_checksum((u16*)frame + 7, 20);
DEBUG_LOG(SP1, "SendFrame %x\n%s", size, ArrayToString(frame, size, 0x10).c_str());
DEBUG_LOG(SP1, "SendFrame %x\n%s",
size, ArrayToString(frame, size, 0x10).c_str());
DWORD numBytesWrit;
OVERLAPPED overlap;
ZeroMemory(&overlap, sizeof(overlap));
//overlap.hEvent = mHRecvEvent;
if (!WriteFile(mHAdapter, frame, size, &numBytesWrit, &overlap))
{
// Fail Boat
DWORD res = GetLastError();
WARN_LOG(SP1, "Failed to send packet with error 0x%X", res);
ERROR_LOG(SP1, "Failed to send packet with error 0x%X", res);
}
if (numBytesWrit != size)
{
WARN_LOG(SP1, "BBA SendFrame %i only got %i bytes sent!", size, numBytesWrit);
return false;
ERROR_LOG(SP1, "BBA SendFrame %i only got %i bytes sent!", size, numBytesWrit);
}
// Always report the packet as being sent successfully, even though it might be a lie
SendComplete();
return true;
@ -324,7 +296,7 @@ VOID CALLBACK CEXIETHERNET::ReadWaitCallback(PVOID lpParameter, BOOLEAN TimerFir
CEXIETHERNET* self = (CEXIETHERNET*)lpParameter;
GetOverlappedResult(self->mHAdapter, &self->mReadOverlapped,
&self->mRecvBufferLength, false);
(LPDWORD)&self->mRecvBufferLength, false);
self->RecvHandlePacket();
}
@ -335,7 +307,7 @@ bool CEXIETHERNET::RecvInit()
if ((mHRecvEvent = CreateEvent(NULL, false, false, NULL)) == NULL)
{
INFO_LOG(SP1, "Failed to create recv event:%x", GetLastError());
ERROR_LOG(SP1, "Failed to create recv event:%x", GetLastError());
return false;
}
@ -358,7 +330,7 @@ bool CEXIETHERNET::RecvStart()
RecvInit();
DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE,
&mRecvBufferLength, &mReadOverlapped);
(LPDWORD)&mRecvBufferLength, &mReadOverlapped);
if (!res && (GetLastError() != ERROR_IO_PENDING))
{

View File

@ -16,16 +16,21 @@
// http://code.google.com/p/dolphin-emu/
#include "Memmap.h"
//#pragma optimize("",off)
#include "EXI_Device.h"
#include "EXI_DeviceEthernet.h"
#include "StringUtil.h"
// XXX: The BBA stores multi-byte elements as little endian.
// Multiple parts of this implementation depend on dolphin
// being compiled for a little endian host.
CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
{
tx_fifo = new u8[1518];
mBbaMem = new u8[BBA_MEM_SIZE];
mRecvBuffer = new u8 [BBA_RECV_SIZE];
mRecvBufferLength = 0;
MXHardReset();
@ -34,7 +39,7 @@ CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
int x = 0;
u8 new_addr[6] = { 0 };
for (int i = 0; i < (int)mac_addr.size() && x < 12; i++)
for (size_t i = 0; i < mac_addr.size() && x < 12; i++)
{
char c = mac_addr.at(i);
if (c >= '0' && c <= '9') {
@ -61,8 +66,6 @@ CEXIETHERNET::CEXIETHERNET(const std::string& mac_addr)
#elif defined(__linux__)
fd = -1;
#endif
mRecvBufferLength = 0;
}
CEXIETHERNET::~CEXIETHERNET()
@ -76,8 +79,6 @@ CEXIETHERNET::~CEXIETHERNET()
void CEXIETHERNET::SetCS(int cs)
{
DEBUG_LOG(SP1, "chip select: %s", cs ? "true" : "false");
if (cs)
{
// Invalidate the previous transfer
@ -109,14 +110,17 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
transfer.address = (data >> 8) & 0xffff;
transfer.direction = IsWriteCommand(data) ? transfer.WRITE : transfer.READ;
WARN_LOG(SP1, "%s %s %s %x",
DEBUG_LOG(SP1, "%s %s %s %x",
IsMXCommand(data) ? "mx " : "exi",
IsWriteCommand(data) ? "write" : "read ",
GetRegisterName(),
transfer.address);
if (transfer.address == BBA_IOB && transfer.region == transfer.MX)
{
ERROR_LOG(SP1, "Usage of BBA_IOB indicates that the rx packet descriptor has been corrupted, killing dolphin...");
exit(0);
}
// transfer has been setup
return;
@ -124,7 +128,7 @@ void CEXIETHERNET::ImmWrite(u32 data, u32 size)
// Reach here if we're actually writing data to the EXI or MX region.
WARN_LOG(SP1, "%s write %0*x",
DEBUG_LOG(SP1, "%s write %0*x",
transfer.region == transfer.MX ? "mx " : "exi", size * 2, data);
if (transfer.region == transfer.EXI)
@ -178,7 +182,7 @@ u32 CEXIETHERNET::ImmRead(u32 size)
ret |= mBbaMem[transfer.address++] << (i * 8);
}
WARN_LOG(SP1, "imm r%i: %0*x", size, size * 2, ret);
DEBUG_LOG(SP1, "imm r%i: %0*x", size, size * 2, ret);
ret <<= (4 - size) * 8;
@ -187,7 +191,7 @@ u32 CEXIETHERNET::ImmRead(u32 size)
void CEXIETHERNET::DMAWrite(u32 addr, u32 size)
{
WARN_LOG(SP1, "dma w: %08x %x", addr, size);
DEBUG_LOG(SP1, "dma w: %08x %x", addr, size);
if (transfer.region == transfer.MX &&
transfer.direction == transfer.WRITE &&
@ -205,7 +209,7 @@ void CEXIETHERNET::DMAWrite(u32 addr, u32 size)
void CEXIETHERNET::DMARead(u32 addr, u32 size)
{
ERROR_LOG(SP1, "dma r: %08x %x", addr, size);
DEBUG_LOG(SP1, "dma r: %08x %x", addr, size);
memcpy(Memory::GetPointer(addr), &mBbaMem[transfer.address], size);
@ -216,6 +220,7 @@ void CEXIETHERNET::DoState(PointerWrap &p)
{
p.Do(mBbaMem);
// TODO ... the rest...
ERROR_LOG(SP1, "CEXIETHERNET::DoState not implemented!");
}
bool CEXIETHERNET::IsMXCommand(u32 const data)
@ -320,14 +325,14 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
case BBA_NCRA:
if (data & NCRA_RESET)
{
WARN_LOG(SP1, "software reset");
DEBUG_LOG(SP1, "software reset");
//MXSoftReset();
Activate();
}
if ((mBbaMem[BBA_NCRA] & NCRA_SR) ^ (data & NCRA_SR))
{
WARN_LOG(SP1, "%s rx", (data & NCRA_SR) ? "start" : "stop");
DEBUG_LOG(SP1, "%s rx", (data & NCRA_SR) ? "start" : "stop");
if (data & NCRA_SR)
RecvStart();
@ -338,7 +343,7 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
// Only start transfer if there isn't one currently running
if (!(mBbaMem[BBA_NCRA] & (NCRA_ST0 | NCRA_ST1)))
{
// TODO Might have to check TXDMA status as well?
// Technically transfer dma status is kept in TXDMA - not implemented
if (data & NCRA_ST0)
{
@ -347,7 +352,7 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
}
else if (data & NCRA_ST1)
{
WARN_LOG(SP1, "start tx - direct fifo");
DEBUG_LOG(SP1, "start tx - direct fifo");
SendFromDirectFIFO();
// Kind of a hack: send completes instantly, so we don't
// actually write the "send in status" bit to the register
@ -371,12 +376,11 @@ void CEXIETHERNET::MXCommandHandler(u32 data, u32 size)
write_to_register:
default:
{
for (int i = size - 1; i >= 0; i--)
{
mBbaMem[transfer.address++] = (data >> (i * 8)) & 0xff;
}
}
return;
}
}
@ -390,6 +394,9 @@ void CEXIETHERNET::DirectFIFOWrite(u8 *data, u32 size)
memcpy(tx_fifo + *tx_fifo_count, data, size);
*tx_fifo_count += size;
// TODO not sure this mask is correct.
// However, BBA_TXFIFOCNT should never get even close to this amount,
// so it shouldn't matter
*tx_fifo_count &= (1 << 12) - 1;
}
@ -418,7 +425,7 @@ void CEXIETHERNET::SendComplete()
mBbaMem[BBA_LTPS] = 0;
}
u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
inline u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
{
// Calculate crc
u32 crc = 0xffffffff;
@ -440,7 +447,7 @@ u8 CEXIETHERNET::HashIndex(u8 *dest_eth_addr)
return crc >> 26;
}
bool CEXIETHERNET::RecvMACFilter()
inline bool CEXIETHERNET::RecvMACFilter()
{
static u8 const broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@ -471,19 +478,19 @@ bool CEXIETHERNET::RecvMACFilter()
}
}
#define PAGE_PTR(x) ((mBbaMem[x + 1] << 8) | mBbaMem[x])
void CEXIETHERNET::inc_rwp()
{
u16 *rwp = (u16 *)&mBbaMem[BBA_RWP];
if (*rwp + 1 == PAGE_PTR(BBA_RHBP))
if (*rwp + 1 == page_ptr(BBA_RHBP))
// TODO check if BP is used as well
*rwp = PAGE_PTR(BBA_BP);
*rwp = page_ptr(BBA_BP);
else
(*rwp)++;
}
// This function is on the critical path for recving data.
// Be very careful about calling into the logger and other slow things
bool CEXIETHERNET::RecvHandlePacket()
{
u8 *write_ptr;
@ -494,23 +501,22 @@ bool CEXIETHERNET::RecvHandlePacket()
if (!RecvMACFilter())
goto wait_for_next;
#ifdef BBA_TACK_PAGE_PTRS
WARN_LOG(SP1, "RecvHandlePacket %x\n%s", mRecvBufferLength,
ArrayToString(mRecvBuffer, mRecvBufferLength, 0x100).c_str());
#define PTR_FROM_PAGE_PTR(x) &mBbaMem[PAGE_PTR(x) << 8]
WARN_LOG(SP1, "%x %x %x %x",
page_ptr(BBA_BP),
page_ptr(BBA_RRP),
page_ptr(BBA_RWP),
page_ptr(BBA_RHBP));
#endif
ERROR_LOG(SP1, "%x %x %x %x",
PAGE_PTR(BBA_BP),
PAGE_PTR(BBA_RRP),
PAGE_PTR(BBA_RWP),
PAGE_PTR(BBA_RHBP));
write_ptr = PTR_FROM_PAGE_PTR(BBA_RWP);
end_ptr = PTR_FROM_PAGE_PTR(BBA_RHBP);
read_ptr = PTR_FROM_PAGE_PTR(BBA_RRP);
write_ptr = ptr_from_page_ptr(BBA_RWP);
end_ptr = ptr_from_page_ptr(BBA_RHBP);
read_ptr = ptr_from_page_ptr(BBA_RRP);
descriptor = (Descriptor *)write_ptr;
//u8 *descriptor = write_ptr;
write_ptr += 4;
for (u32 i = 0, off = 4; i < mRecvBufferLength; ++i, ++off)
@ -525,7 +531,7 @@ bool CEXIETHERNET::RecvHandlePacket()
if (write_ptr == end_ptr)
// TODO check if BP is used as well
write_ptr = PTR_FROM_PAGE_PTR(BBA_BP);
write_ptr = ptr_from_page_ptr(BBA_BP);
if (write_ptr == read_ptr)
{
@ -537,11 +543,13 @@ bool CEXIETHERNET::RecvHandlePacket()
if ((mRecvBufferLength + 4) % 256)
inc_rwp();
ERROR_LOG(SP1, "%x %x %x %x",
PAGE_PTR(BBA_BP),
PAGE_PTR(BBA_RRP),
PAGE_PTR(BBA_RWP),
PAGE_PTR(BBA_RHBP));
#ifdef BBA_TACK_PAGE_PTRS
WARN_LOG(SP1, "%x %x %x %x",
page_ptr(BBA_BP),
page_ptr(BBA_RRP),
page_ptr(BBA_RWP),
page_ptr(BBA_RHBP));
#endif
// Update descriptor
descriptor->set(*(u16 *)&mBbaMem[BBA_RWP], 4 + mRecvBufferLength, 0);
@ -557,15 +565,13 @@ bool CEXIETHERNET::RecvHandlePacket()
}
else
{
ERROR_LOG(SP1, "NOT raising recv interrupt");
// This occurs if software is still processing the last raised recv interrupt
WARN_LOG(SP1, "NOT raising recv interrupt");
}
wait_for_next:
if (mBbaMem[BBA_NCRA] & NCRA_SR)
RecvStart();
#undef PTR_FROM_PAGE_PTR
return true;
}
//#pragma optimize("",on)

View File

@ -275,6 +275,16 @@ public:
}
};
inline u16 page_ptr(int const index) const
{
return ((u16)mBbaMem[index + 1] << 8) | mBbaMem[index];
}
inline u8 *ptr_from_page_ptr(int const index) const
{
return &mBbaMem[page_ptr(index) << 8];
}
bool IsMXCommand(u32 const data);
bool IsWriteCommand(u32 const data);
char const * const GetRegisterName() const;
@ -302,6 +312,7 @@ public:
void RecvStop();
u8 *mRecvBuffer;
u32 mRecvBufferLength;
#if defined(_WIN32)
HANDLE mHAdapter, mHRecvEvent, mHReadWait;
@ -314,7 +325,6 @@ public:
volatile bool readEnabled;
#endif
u32 mRecvBufferLength;
};
#endif