diff --git a/.travis.yml b/.travis.yml index 2d2a253b2..c523ee590 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ os: env: global: - - LLVM_VERSION=3.8.0 - - LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz + dist: trusty sudo: required @@ -52,6 +51,9 @@ script: # Build and run our simple hello world test. - ./xenia-build build --config=debug --target=xenia-base-tests - ./build/bin/Linux/Debug/xenia-base-tests + # Build and run ppc tests + - ./xenia-build build --config=debug --target=xenia-cpu-ppc-tests + - ./build/bin/Linux/Debug/xenia-cpu-ppc-tests # TODO(DrChat): Enable builds in the future. # Build all of xenia. diff --git a/premake5.lua b/premake5.lua index 2b9e15c13..c7361e507 100644 --- a/premake5.lua +++ b/premake5.lua @@ -76,6 +76,9 @@ filter("platforms:Linux") buildoptions({ "-mlzcnt", -- Assume lzcnt supported. }) + links({ + "pthread", + }) filter({"platforms:Linux", "language:C++"}) buildoptions({ diff --git a/src/xenia/cpu/ppc/ppc_emit_altivec.cc b/src/xenia/cpu/ppc/ppc_emit_altivec.cc index b562ffbab..a0c29f8ce 100644 --- a/src/xenia/cpu/ppc/ppc_emit_altivec.cc +++ b/src/xenia/cpu/ppc/ppc_emit_altivec.cc @@ -13,6 +13,8 @@ #include "xenia/cpu/ppc/ppc_context.h" #include "xenia/cpu/ppc/ppc_hir_builder.h" +#include + namespace xe { namespace cpu { namespace ppc { diff --git a/src/xenia/cpu/ppc/testing/premake5.lua b/src/xenia/cpu/ppc/testing/premake5.lua index 556806715..10195369b 100644 --- a/src/xenia/cpu/ppc/testing/premake5.lua +++ b/src/xenia/cpu/ppc/testing/premake5.lua @@ -35,3 +35,6 @@ project("xenia-cpu-ppc-tests") "2>&1", "1>scratch/stdout-testing.txt", }) + + -- xenia-base needs this + links({"xenia-ui"}) diff --git a/src/xenia/cpu/testing/premake5.lua b/src/xenia/cpu/testing/premake5.lua index 17ea9f44d..0d677f4e9 100644 --- a/src/xenia/cpu/testing/premake5.lua +++ b/src/xenia/cpu/testing/premake5.lua @@ -13,5 +13,6 @@ test_suite("xenia-cpu-tests", project_root, ".", { -- TODO(benvanik): cut these dependencies? "xenia-kernel", + "xenia-ui", -- needed by xenia-base }, }) diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 5b30c2cf7..35924af32 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -49,10 +49,10 @@ class GraphicsSystem { return command_processor_.get(); } - void InitializeRingBuffer(uint32_t ptr, uint32_t log2_size); - void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size); + virtual void InitializeRingBuffer(uint32_t ptr, uint32_t log2_size); + virtual void EnableReadPointerWriteBack(uint32_t ptr, uint32_t block_size); - void SetInterruptCallback(uint32_t callback, uint32_t user_data); + virtual void SetInterruptCallback(uint32_t callback, uint32_t user_data); void DispatchInterruptCallback(uint32_t source, uint32_t cpu); virtual void ClearCaches(); diff --git a/src/xenia/kernel/kernel_module.cc b/src/xenia/kernel/kernel_module.cc index ad01939d1..05304feae 100644 --- a/src/xenia/kernel/kernel_module.cc +++ b/src/xenia/kernel/kernel_module.cc @@ -126,6 +126,9 @@ uint32_t KernelModule::GetProcAddressByOrdinal(uint16_t ordinal) { uint32_t guest_addr = GenerateTrampoline(export_entry->name, handler, export_entry); + XELOGD("GetProcAddressByOrdinal(\"%s\", \"%s\") = %.8X", name().c_str(), + export_entry->name, guest_addr); + // Register the function in our map. guest_trampoline_map_[ordinal] = guest_addr; return guest_addr; diff --git a/src/xenia/kernel/premake5.lua b/src/xenia/kernel/premake5.lua index 02ed327d4..772e2730a 100644 --- a/src/xenia/kernel/premake5.lua +++ b/src/xenia/kernel/premake5.lua @@ -10,9 +10,7 @@ project("xenia-kernel") "xenia-apu", "xenia-base", "xenia-cpu", - "xenia-gpu", "xenia-hid", - "xenia-ui", "xenia-vfs", }) defines({ diff --git a/src/xenia/kernel/user_module.cc b/src/xenia/kernel/user_module.cc index 93d05df8c..20dff3054 100644 --- a/src/xenia/kernel/user_module.cc +++ b/src/xenia/kernel/user_module.cc @@ -108,7 +108,7 @@ X_STATUS UserModule::LoadFromMemory(const void* addr, const size_t length) { module_format_ = kModuleFormatElf; } else { auto magic16 = xe::load_and_swap(addr); - if (magic16 == 'MZ') { + if (magic16 == 0x4D5A) { XELOGE("XNA executables are not yet implemented"); return X_STATUS_NOT_IMPLEMENTED; } else { diff --git a/src/xenia/kernel/xam/xam_net.cc b/src/xenia/kernel/xam/xam_net.cc index 7ccfd1448..9016ffb94 100644 --- a/src/xenia/kernel/xam/xam_net.cc +++ b/src/xenia/kernel/xam/xam_net.cc @@ -22,9 +22,16 @@ #include "xenia/kernel/xthread.h" #include "xenia/xbox.h" +#ifdef XE_PLATFORM_WIN32 // NOTE: must be included last as it expects windows.h to already be included. #define _WINSOCK_DEPRECATED_NO_WARNINGS // inet_addr #include // NOLINT(build/include_order) +#elif XE_PLATFORM_LINUX +#include +#include +#include +#include +#endif namespace xe { namespace kernel { @@ -43,8 +50,8 @@ enum { // https://github.com/pmrowla/hl2sdk-csgo/blob/master/common/xbox/xboxstubs.h typedef struct { // FYI: IN_ADDR should be in network-byte order. - IN_ADDR ina; // IP address (zero if not static/DHCP) - IN_ADDR inaOnline; // Online IP address (zero if not online) + in_addr ina; // IP address (zero if not static/DHCP) + in_addr inaOnline; // Online IP address (zero if not online) xe::be wPortOnline; // Online port uint8_t abEnet[6]; // Ethernet MAC address uint8_t abOnline[20]; // Online identification @@ -53,7 +60,7 @@ typedef struct { typedef struct { xe::be status; xe::be cina; - IN_ADDR aina[8]; + in_addr aina[8]; } XNDNS; struct Xsockaddr_t { @@ -96,7 +103,7 @@ void LoadSockaddr(const uint8_t* ptr, sockaddr* out_addr) { auto in_addr = reinterpret_cast(out_addr); in_addr->sin_port = xe::load_and_swap(ptr + 2); // Maybe? Depends on type. - in_addr->sin_addr.S_un.S_addr = *(uint32_t*)(ptr + 4); + in_addr->sin_addr.s_addr = *(uint32_t*)(ptr + 4); break; } default: @@ -115,7 +122,7 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) { xe::store_and_swap(ptr + 0, in_addr.sin_family); xe::store_and_swap(ptr + 2, in_addr.sin_port); // Maybe? Depends on type. - xe::store_and_swap(ptr + 4, in_addr.sin_addr.S_un.S_addr); + xe::store_and_swap(ptr + 4, in_addr.sin_addr.s_addr); break; } default: @@ -126,19 +133,19 @@ void StoreSockaddr(const sockaddr& addr, uint8_t* ptr) { // https://github.com/joolswills/mameox/blob/master/MAMEoX/Sources/xbox_Network.cpp#L136 struct XNetStartupParams { - BYTE cfgSizeOfStruct; - BYTE cfgFlags; - BYTE cfgSockMaxDgramSockets; - BYTE cfgSockMaxStreamSockets; - BYTE cfgSockDefaultRecvBufsizeInK; - BYTE cfgSockDefaultSendBufsizeInK; - BYTE cfgKeyRegMax; - BYTE cfgSecRegMax; - BYTE cfgQosDataLimitDiv4; - BYTE cfgQosProbeTimeoutInSeconds; - BYTE cfgQosProbeRetries; - BYTE cfgQosSrvMaxSimultaneousResponses; - BYTE cfgQosPairWaitTimeInSeconds; + uint8_t cfgSizeOfStruct; + uint8_t cfgFlags; + uint8_t cfgSockMaxDgramSockets; + uint8_t cfgSockMaxStreamSockets; + uint8_t cfgSockDefaultRecvBufsizeInK; + uint8_t cfgSockDefaultSendBufsizeInK; + uint8_t cfgKeyRegMax; + uint8_t cfgSecRegMax; + uint8_t cfgQosDataLimitDiv4; + uint8_t cfgQosProbeTimeoutInSeconds; + uint8_t cfgQosProbeRetries; + uint8_t cfgQosSrvMaxSimultaneousResponses; + uint8_t cfgQosPairWaitTimeInSeconds; }; XNetStartupParams xnet_startup_params = {0}; @@ -186,13 +193,13 @@ dword_result_t NetDll_XNetGetOpt(dword_t one, dword_t option_id, case 1: if (*buffer_size < sizeof(XNetStartupParams)) { *buffer_size = sizeof(XNetStartupParams); - return WSAEMSGSIZE; + return 0x2738; // WSAEMSGSIZE } std::memcpy(buffer_ptr, &xnet_startup_params, sizeof(XNetStartupParams)); return 0; default: XELOGE("NetDll_XNetGetOpt: option %d unimplemented", option_id); - return WSAEINVAL; + return 0x2726; // WSAEINVAL } } DECLARE_XAM_EXPORT(NetDll_XNetGetOpt, ExportTag::kNetworking); @@ -210,7 +217,8 @@ DECLARE_XAM_EXPORT(NetDll_XNetRandom, dword_result_t NetDll_WSAStartup(dword_t caller, word_t version, pointer_t data_ptr) { - // TODO(benvanik): abstraction layer needed. +// TODO(benvanik): abstraction layer needed. +#ifdef XE_PLATFORM_WIN32 WSADATA wsaData; ZeroMemory(&wsaData, sizeof(WSADATA)); int ret = WSAStartup(version, &wsaData); @@ -230,6 +238,17 @@ dword_result_t NetDll_WSAStartup(dword_t caller, word_t version, uint32_t vendor_ptr = xe::load_and_swap(data_out + 0x190); xe::store_and_swap(data_out + 0x190, vendor_ptr); } +#else + int ret = 0; + if (data_ptr) { + // Guess these values! + data_ptr->version = version.value(); + data_ptr->description[0] = '\0'; + data_ptr->system_status[0] = '\0'; + data_ptr->max_sockets = 100; + data_ptr->max_udpdg = 1024; + } +#endif // DEBUG /* @@ -425,8 +444,8 @@ dword_result_t NetDll_XNetGetTitleXnAddr(dword_t caller, pointer_t addr_ptr) { // Just return a loopback address atm. // FIXME: This needs to return the ethernet MAC address! - addr_ptr->ina.S_un.S_addr = htonl(INADDR_LOOPBACK); - addr_ptr->inaOnline.S_un.S_addr = 0; + addr_ptr->ina.s_addr = htonl(INADDR_LOOPBACK); + addr_ptr->inaOnline.s_addr = 0; addr_ptr->wPortOnline = 0; std::memset(addr_ptr->abEnet, 0, 6); std::memset(addr_ptr->abOnline, 0, 20); @@ -610,9 +629,13 @@ int_result_t NetDll_shutdown(dword_t caller, dword_t socket_handle, int_t how) { } auto ret = socket->Shutdown(how); - if (ret == SOCKET_ERROR) { + if (ret == -1) { +#ifdef XE_PLATFORM_WIN32 uint32_t error_code = WSAGetLastError(); XThread::SetLastError(error_code); +#else + XThread::SetLastError(0x0); +#endif } return ret; } @@ -726,6 +749,12 @@ DECLARE_XAM_EXPORT(NetDll_listen, dword_result_t NetDll_accept(dword_t caller, dword_t socket_handle, pointer_t addr_ptr, lpdword_t addrlen_ptr) { + if (!addr_ptr) { + // WSAEFAULT + XThread::SetLastError(0x271E); + return -1; + } + auto socket = kernel_state()->object_table()->LookupObject(socket_handle); if (!socket) { @@ -889,7 +918,7 @@ dword_result_t NetDll_recvfrom(dword_t caller, dword_t socket_handle, if (from_ptr) { native_from = *from_ptr; } - uint32_t native_fromlen = fromlen_ptr ? *fromlen_ptr : 0; + uint32_t native_fromlen = fromlen_ptr ? fromlen_ptr.value() : 0; int ret = socket->RecvFrom(buf_ptr, buf_len, flags, &native_from, fromlen_ptr ? &native_fromlen : 0); @@ -904,9 +933,13 @@ dword_result_t NetDll_recvfrom(dword_t caller, dword_t socket_handle, } if (ret == -1) { - // TODO: Better way of getting the error code +// TODO: Better way of getting the error code +#ifdef XE_PLATFORM_WIN32 uint32_t error_code = WSAGetLastError(); XThread::SetLastError(error_code); +#else + XThread::SetLastError(0x0); +#endif } return ret; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc index c5dffebbf..653e82c07 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc @@ -79,7 +79,7 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr, // it's simple today we could extend it to do better things in the future. // Must request a size. - if (!base_addr_ptr) { + if (!base_addr_ptr || !region_size_ptr) { return X_STATUS_INVALID_PARAMETER; } // Check allocation type. @@ -106,8 +106,8 @@ dword_result_t NtAllocateVirtualMemory(lpdword_t base_addr_ptr, uint32_t adjusted_base = *base_addr_ptr - (*base_addr_ptr % page_size); // For some reason, some games pass in negative sizes. uint32_t adjusted_size = int32_t(*region_size_ptr) < 0 - ? -int32_t(*region_size_ptr) - : *region_size_ptr; + ? -int32_t(region_size_ptr.value()) + : region_size_ptr.value(); adjusted_size = xe::round_up(adjusted_size, page_size); // Allocate. diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index a8e129922..c659fa216 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -238,7 +238,7 @@ dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr, pointer_t source_ptr, dword_t source_len) { uint32_t copy_len = destination_len >> 1; - copy_len = copy_len < source_len ? copy_len : source_len; + copy_len = copy_len < source_len ? copy_len : source_len.value(); // TODO(benvanik): maybe use MultiByteToUnicode on Win32? would require // swapping. @@ -262,7 +262,7 @@ dword_result_t RtlUnicodeToMultiByteN(pointer_t destination_ptr, lpdword_t written_ptr, lpword_t source_ptr, dword_t source_len) { uint32_t copy_len = source_len >> 1; - copy_len = copy_len < destination_len ? copy_len : destination_len; + copy_len = copy_len < destination_len ? copy_len : destination_len.value(); // TODO(benvanik): maybe use UnicodeToMultiByte on Win32? for (uint32_t i = 0; i < copy_len; i++) { diff --git a/src/xenia/kernel/xsocket.cc b/src/xenia/kernel/xsocket.cc index 515a88b53..571e13123 100644 --- a/src/xenia/kernel/xsocket.cc +++ b/src/xenia/kernel/xsocket.cc @@ -14,10 +14,18 @@ #include "xenia/kernel/xam/xam_module.h" // #include "xenia/kernel/xnet.h" -#if XE_PLATFORM_WIN32 +#ifdef XE_PLATFORM_WIN32 +// clang-format off +#include "xenia/base/platform_win.h" +#include #include -#elif XE_PLATFORM_LINUX -#error TODO: Proper network includes +// clang-format on +#else +#include +#include +#include +#include +#include #endif namespace xe { @@ -54,7 +62,7 @@ X_STATUS XSocket::Close() { #if XE_PLATFORM_WIN32 int ret = closesocket(native_handle_); #elif XE_PLATFORM_LINUX - + int ret = close(native_handle_); #endif if (ret != 0) { @@ -88,6 +96,7 @@ X_STATUS XSocket::SetOption(uint32_t level, uint32_t optname, void* optval_ptr, } X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) { +#ifdef XE_PLATFORM_WIN32 int ret = ioctlsocket(native_handle_, cmd, (u_long*)arg_ptr); if (ret < 0) { // TODO: Get last error @@ -95,6 +104,9 @@ X_STATUS XSocket::IOControl(uint32_t cmd, uint8_t* arg_ptr) { } return X_STATUS_SUCCESS; +#elif XE_PLATFORM_LINUX + return X_STATUS_UNSUCCESSFUL; +#endif } X_STATUS XSocket::Connect(N_XSOCKADDR* name, int name_len) { @@ -129,9 +141,9 @@ X_STATUS XSocket::Listen(int backlog) { object_ref XSocket::Accept(N_XSOCKADDR* name, int* name_len) { sockaddr n_sockaddr; - int n_name_len = sizeof(sockaddr); - SOCKET ret = accept(native_handle_, &n_sockaddr, &n_name_len); - if (ret == INVALID_SOCKET) { + socklen_t n_name_len = sizeof(sockaddr); + uintptr_t ret = accept(native_handle_, &n_sockaddr, &n_name_len); + if (ret == -1) { std::memset(name, 0, *name_len); *name_len = 0; return nullptr; @@ -182,7 +194,7 @@ int XSocket::RecvFrom(uint8_t* buf, uint32_t buf_len, uint32_t flags, */ sockaddr_in nfrom; - int nfromlen = sizeof(sockaddr_in); + socklen_t nfromlen = sizeof(sockaddr_in); int ret = recvfrom(native_handle_, reinterpret_cast(buf), buf_len, flags, (sockaddr*)&nfrom, &nfromlen); if (from) { @@ -219,7 +231,7 @@ int XSocket::SendTo(uint8_t* buf, uint32_t buf_len, uint32_t flags, sockaddr_in nto; if (to) { - nto.sin_addr.S_un.S_addr = to->sin_addr; + nto.sin_addr.s_addr = to->sin_addr; nto.sin_family = to->sin_family; nto.sin_port = to->sin_port; } diff --git a/src/xenia/vfs/devices/stfs_container_file.cc b/src/xenia/vfs/devices/stfs_container_file.cc index 8da5eca81..40d0f7ca7 100644 --- a/src/xenia/vfs/devices/stfs_container_file.cc +++ b/src/xenia/vfs/devices/stfs_container_file.cc @@ -10,6 +10,7 @@ #include "xenia/vfs/devices/stfs_container_file.h" #include +#include #include "xenia/vfs/devices/stfs_container_entry.h"