summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorsktsqrl <sktsqrl@gmail.com>2012-07-04 16:00:42 -0700
committersktsqrl <sktsqrl@gmail.com>2012-07-04 16:02:05 -0700
commit6cccbb91ec06a47a6369d6cce41f5d1cd1e07983 (patch)
treed187552155905f8f36715414414d08e46f2e62c5 /Source/Core
parent9cff8316d2866895e5cffbdf302f26c36a93f620 (diff)
bba: implement recv buffer full interrupt
(windows) hopefully fix crashes from closing dolphin while recving
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp9
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp42
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceEthernet.h42
3 files changed, 64 insertions, 29 deletions
diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp
index e5cd78eb0e..15d2e1f6bb 100644
--- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp
+++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp
@@ -17,7 +17,6 @@
#include "StringUtil.h"
#include "../Memmap.h"
-//#pragma optimize("",off)
// GROSS CODE ALERT: headers need to be included in the following order
#include "TAP_Win32.h"
#include "../EXI_Device.h"
@@ -314,7 +313,7 @@ bool CEXIETHERNET::RecvInit()
ZeroMemory(&mReadOverlapped, sizeof(mReadOverlapped));
RegisterWaitForSingleObject(&mHReadWait, mHRecvEvent, ReadWaitCallback,
- this, INFINITE, WT_EXECUTEDEFAULT);//WT_EXECUTEINWAITTHREAD
+ this, INFINITE, WT_EXECUTEDEFAULT);
mReadOverlapped.hEvent = mHRecvEvent;
@@ -340,7 +339,7 @@ bool CEXIETHERNET::RecvStart()
if (res)
{
- ERROR_LOG(SP1, "RECV COMPLETED IMMEDIATELY");
+ // Completed immediately
RecvHandlePacket();
}
@@ -352,7 +351,5 @@ void CEXIETHERNET::RecvStop()
if (!IsActivated())
return;
- CancelIo(mHAdapter);
+ UnregisterWaitEx(mHReadWait, INVALID_HANDLE_VALUE);
}
-
-//#pragma optimize("",on)
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp
index 66ecc26bc4..40fc4f12c0 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.cpp
@@ -478,12 +478,11 @@ inline bool CEXIETHERNET::RecvMACFilter()
}
}
-void CEXIETHERNET::inc_rwp()
+inline void CEXIETHERNET::inc_rwp()
{
u16 *rwp = (u16 *)&mBbaMem[BBA_RWP];
if (*rwp + 1 == page_ptr(BBA_RHBP))
- // TODO check if BP is used as well
*rwp = page_ptr(BBA_BP);
else
(*rwp)++;
@@ -497,6 +496,8 @@ bool CEXIETHERNET::RecvHandlePacket()
u8 *end_ptr;
u8 *read_ptr;
Descriptor *descriptor;
+ u32 status = 0;
+ u16 rwp_initial = page_ptr(BBA_RWP);
if (!RecvMACFilter())
goto wait_for_next;
@@ -530,12 +531,24 @@ bool CEXIETHERNET::RecvHandlePacket()
}
if (write_ptr == end_ptr)
- // TODO check if BP is used as well
write_ptr = ptr_from_page_ptr(BBA_BP);
if (write_ptr == read_ptr)
{
- ERROR_LOG(SP1, "recv buffer full error - not implemented");
+ /*
+ halt copy
+ if (cur_packet_size >= PAGE_SIZE)
+ desc.status |= FO | BF
+ if (RBFIM)
+ raise RBFI
+ if (AUTORCVR)
+ discard bad packet
+ else
+ inc MPC instad of recving packets
+ */
+ status |= DESC_FO | DESC_BF;
+ mBbaMem[BBA_IR] |= mBbaMem[BBA_IMR] & INT_RBF;
+ break;
}
}
@@ -551,10 +564,25 @@ bool CEXIETHERNET::RecvHandlePacket()
page_ptr(BBA_RHBP));
#endif
- // Update descriptor
- descriptor->set(*(u16 *)&mBbaMem[BBA_RWP], 4 + mRecvBufferLength, 0);
+ // Is the current frame multicast?
+ if (mRecvBuffer[0] & 0x01)
+ status |= DESC_MF;
+
+ if (status & DESC_BF)
+ {
+ if (mBbaMem[BBA_MISC2] & MISC2_AUTORCVR)
+ {
+ *(u16 *)&mBbaMem[BBA_RWP] = rwp_initial;
+ }
+ else
+ {
+ ERROR_LOG(SP1, "RBF while AUTORCVR == 0!");
+ }
+ }
+
+ descriptor->set(*(u16 *)&mBbaMem[BBA_RWP], 4 + mRecvBufferLength, status);
- mBbaMem[BBA_LRPS] = descriptor->get_status();
+ mBbaMem[BBA_LRPS] = status;
// Raise interrupt
if (mBbaMem[BBA_IMR] & INT_R)
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h
index a7b2260d19..453e8d5843 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h
+++ b/Source/Core/Core/Src/HW/EXI_DeviceEthernet.h
@@ -82,14 +82,26 @@ enum NWAYS
enum MISC1
{
- MISC1_BURSTDMA = 0x01,
- MISC1_DISLDMA = 0x02,
- MISC1_TPF = 0x04,
- MISC1_TPH = 0x08,
- MISC1_TXF = 0x10,
- MISC1_TXH = 0x20,
- MISC1_TXFIFORST = 0x40,
- MISC1_RXFIFORST = 0x80
+ MISC1_BURSTDMA = 0x01,
+ MISC1_DISLDMA = 0x02,
+ MISC1_TPF = 0x04,
+ MISC1_TPH = 0x08,
+ MISC1_TXF = 0x10,
+ MISC1_TXH = 0x20,
+ MISC1_TXFIFORST = 0x40,
+ MISC1_RXFIFORST = 0x80
+};
+
+enum MISC2
+{
+ MISC2_HBRLEN0 = 0x01,
+ MISC2_HBRLEN1 = 0x02,
+ MISC2_RUNTSIZE = 0x04,
+ MISC2_DREQBCTRL = 0x08,
+ MISC2_RINTSEL = 0x10,
+ MISC2_ITPSEL = 0x20,
+ MISC2_A11A8EN = 0x40,
+ MISC2_AUTORCVR = 0x80
};
enum
@@ -148,8 +160,9 @@ enum
enum
{
- BBA_RECV_SIZE = 0x800,
- BBA_MEM_SIZE = 0x1000
+ BBA_NUM_PAGES = 0x10,
+ BBA_PAGE_SIZE = 0x100,
+ BBA_MEM_SIZE = BBA_NUM_PAGES * BBA_PAGE_SIZE
};
enum { EXI_DEVTYPE_ETHER = 0x04020200 };
@@ -178,6 +191,8 @@ enum RecvStatus
DESC_RERR = 0x80
};
+#define BBA_RECV_SIZE 0x800
+
class CEXIETHERNET : public IEXIDevice
{
public:
@@ -261,18 +276,13 @@ public:
{
u32 word;
- void set(u32 const next_page, u32 const packet_length, u32 const status)
+ inline void set(u32 const next_page, u32 const packet_length, u32 const status)
{
word = 0;
word |= (status & 0xff) << 24;
word |= (packet_length & 0xfff) << 12;
word |= next_page & 0xfff;
}
-
- u8 get_status() const
- {
- return (word >> 24) & 0xff;
- }
};
inline u16 page_ptr(int const index) const