mirror of
https://github.com/xenia-project/xenia.git
synced 2025-12-06 07:12:03 +01:00
Added System-V ABI support in x64 backend & fixed mmap initialization
This commit is contained in:
commit
add1b008e2
|
|
@ -85,11 +85,8 @@ void* AllocFixed(void* base_address, size_t length,
|
||||||
AllocationType allocation_type, PageAccess access) {
|
AllocationType allocation_type, PageAccess access) {
|
||||||
// mmap does not support reserve / commit, so ignore allocation_type.
|
// mmap does not support reserve / commit, so ignore allocation_type.
|
||||||
uint32_t prot = ToPosixProtectFlags(access);
|
uint32_t prot = ToPosixProtectFlags(access);
|
||||||
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
void* result = mmap(base_address, length, prot,
|
||||||
if (base_address != nullptr) {
|
MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
|
||||||
flags |= MAP_FIXED;
|
|
||||||
}
|
|
||||||
void* result = mmap(base_address, length, prot, flags, -1, 0);
|
|
||||||
if (result == MAP_FAILED) {
|
if (result == MAP_FAILED) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -480,9 +480,9 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
|
||||||
code_offsets.prolog = getSize();
|
code_offsets.prolog = getSize();
|
||||||
|
|
||||||
// rsp + 0 = return address
|
// rsp + 0 = return address
|
||||||
mov(qword[rsp + 8 * 3], rdx);
|
// mov(qword[rsp + 8 * 3], rdx);
|
||||||
mov(qword[rsp + 8 * 2], rsi);
|
// mov(qword[rsp + 8 * 2], rsi);
|
||||||
mov(qword[rsp + 8 * 1], rdi);
|
// mov(qword[rsp + 8 * 1], rdi);
|
||||||
sub(rsp, stack_size);
|
sub(rsp, stack_size);
|
||||||
|
|
||||||
code_offsets.prolog_stack_alloc = getSize();
|
code_offsets.prolog_stack_alloc = getSize();
|
||||||
|
|
@ -501,9 +501,9 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
|
||||||
code_offsets.epilog = getSize();
|
code_offsets.epilog = getSize();
|
||||||
|
|
||||||
add(rsp, stack_size);
|
add(rsp, stack_size);
|
||||||
mov(rdi, qword[rsp + 8 * 1]);
|
// mov(rdi, qword[rsp + 8 * 1]);
|
||||||
mov(rsi, qword[rsp + 8 * 2]);
|
// mov(rsi, qword[rsp + 8 * 2]);
|
||||||
mov(rdx, qword[rsp + 8 * 3]);
|
// mov(rdx, qword[rsp + 8 * 3]);
|
||||||
ret();
|
ret();
|
||||||
#else
|
#else
|
||||||
assert_always("Unknown platform ABI in host to guest thunk!");
|
assert_always("Unknown platform ABI in host to guest thunk!");
|
||||||
|
|
|
||||||
|
|
@ -17,33 +17,9 @@
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/vfs/devices/stfs_container_entry.h"
|
#include "xenia/vfs/devices/stfs_container_entry.h"
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
#include "xenia/base/platform_win.h"
|
|
||||||
#define timegm _mkgmtime
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace vfs {
|
namespace vfs {
|
||||||
|
|
||||||
// Convert FAT timestamp to 100-nanosecond intervals since January 1, 1601 (UTC)
|
|
||||||
uint64_t decode_fat_timestamp(uint32_t date, uint32_t time) {
|
|
||||||
struct tm tm = {0};
|
|
||||||
// 80 is the difference between 1980 (FAT) and 1900 (tm);
|
|
||||||
tm.tm_year = ((0xFE00 & date) >> 9) + 80;
|
|
||||||
tm.tm_mon = (0x01E0 & date) >> 5;
|
|
||||||
tm.tm_mday = (0x001F & date) >> 0;
|
|
||||||
tm.tm_hour = (0xF800 & time) >> 11;
|
|
||||||
tm.tm_min = (0x07E0 & time) >> 5;
|
|
||||||
tm.tm_sec = (0x001F & time) << 1; // the value stored in 2-seconds intervals
|
|
||||||
tm.tm_isdst = 0;
|
|
||||||
time_t timet = timegm(&tm);
|
|
||||||
if (timet == -1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// 11644473600LL is a difference between 1970 and 1601
|
|
||||||
return (timet + 11644473600LL) * 10000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
StfsContainerDevice::StfsContainerDevice(const std::string_view mount_path,
|
StfsContainerDevice::StfsContainerDevice(const std::string_view mount_path,
|
||||||
const std::filesystem::path& host_path)
|
const std::filesystem::path& host_path)
|
||||||
: Device(mount_path),
|
: Device(mount_path),
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,40 @@
|
||||||
#ifndef XENIA_VFS_DEVICES_STFS_XBOX_H_
|
#ifndef XENIA_VFS_DEVICES_STFS_XBOX_H_
|
||||||
#define XENIA_VFS_DEVICES_STFS_XBOX_H_
|
#define XENIA_VFS_DEVICES_STFS_XBOX_H_
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "xenia/xbox.h"
|
||||||
#include "xenia/base/string_util.h"
|
#include "xenia/base/string_util.h"
|
||||||
#include "xenia/kernel/util/xex2_info.h"
|
#include "xenia/kernel/util/xex2_info.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace vfs {
|
namespace vfs {
|
||||||
|
|
||||||
|
// Convert FAT timestamp to 100-nanosecond intervals since January 1, 1601 (UTC)
|
||||||
|
inline uint64_t decode_fat_timestamp(const uint32_t date, const uint32_t time) {
|
||||||
|
struct tm tm = {0};
|
||||||
|
// 80 is the difference between 1980 (FAT) and 1900 (tm);
|
||||||
|
tm.tm_year = ((0xFE00 & date) >> 9) + 80;
|
||||||
|
tm.tm_mon = ((0x01E0 & date) >> 5) - 1;
|
||||||
|
tm.tm_mday = (0x001F & date) >> 0;
|
||||||
|
tm.tm_hour = (0xF800 & time) >> 11;
|
||||||
|
tm.tm_min = (0x07E0 & time) >> 5;
|
||||||
|
tm.tm_sec = (0x001F & time) << 1; // the value stored in 2-seconds intervals
|
||||||
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
time_t timet = _mkgmtime(&tm);
|
||||||
|
#else
|
||||||
|
time_t timet = timegm(&tm);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (timet == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// 11644473600LL is a difference between 1970 and 1601
|
||||||
|
return (timet + 11644473600LL) * 10000000;
|
||||||
|
}
|
||||||
|
|
||||||
// Structs used for interchange between Xenia and actual Xbox360 kernel/XAM
|
// Structs used for interchange between Xenia and actual Xbox360 kernel/XAM
|
||||||
|
|
||||||
inline uint32_t load_uint24_be(const uint8_t* p) {
|
inline uint32_t load_uint24_be(const uint8_t* p) {
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,5 @@ project("xenia-vfs-dump")
|
||||||
resincludedirs({
|
resincludedirs({
|
||||||
project_root,
|
project_root,
|
||||||
})
|
})
|
||||||
|
include("testing")
|
||||||
|
|
||||||
|
|
|
||||||
8
src/xenia/vfs/testing/premake5.lua
Normal file
8
src/xenia/vfs/testing/premake5.lua
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
project_root = "../../../.."
|
||||||
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
|
test_suite("xenia-vfs-tests", project_root, ".", {
|
||||||
|
links = {
|
||||||
|
"xenia-vfs",
|
||||||
|
},
|
||||||
|
})
|
||||||
28
src/xenia/vfs/testing/vfs_test.cc
Normal file
28
src/xenia/vfs/testing/vfs_test.cc
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2023 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/vfs/devices/stfs_xbox.h"
|
||||||
|
|
||||||
|
#include "third_party/catch/include/catch.hpp"
|
||||||
|
|
||||||
|
namespace xe::vfs::test {
|
||||||
|
|
||||||
|
TEST_CASE("STFS Decode date and time", "[stfs_decode]") {
|
||||||
|
SECTION("10 June 2022 19:46:00 UTC - Decode") {
|
||||||
|
const uint16_t date = 0x54CA;
|
||||||
|
const uint16_t time = 0x9DBD;
|
||||||
|
const uint64_t result = 132993639580000000;
|
||||||
|
|
||||||
|
const uint64_t timestamp = decode_fat_timestamp(date, time);
|
||||||
|
|
||||||
|
REQUIRE(timestamp == result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace xe::vfs::test
|
||||||
Loading…
Reference in a new issue