summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/svc.cpp14
-rw-r--r--src/core/hle/kernel/svc_wrap.h56
-rw-r--r--src/core/hle/kernel/thread.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp72
-rw-r--r--src/video_core/textures/decoders.cpp16
-rw-r--r--src/video_core/textures/decoders.h6
7 files changed, 132 insertions, 50 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 3e4dd61dc..e406df829 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -95,12 +95,12 @@ ResultCode MapUnmapMemorySanityChecks(const VMManager& vm_manager, VAddr dst_add
const VAddr dst_end_address = dst_addr + size;
if (dst_end_address > vm_manager.GetHeapRegionBaseAddress() &&
- dst_addr < vm_manager.GetHeapRegionEndAddress()) {
+ vm_manager.GetHeapRegionEndAddress() > dst_addr) {
return ERR_INVALID_MEMORY_RANGE;
}
- if (dst_end_address > vm_manager.GetNewMapRegionBaseAddress() &&
- dst_addr < vm_manager.GetMapRegionEndAddress()) {
+ if (dst_end_address > vm_manager.GetMapRegionBaseAddress() &&
+ vm_manager.GetMapRegionEndAddress() > dst_addr) {
return ERR_INVALID_MEMORY_RANGE;
}
@@ -370,15 +370,15 @@ static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
struct BreakReason {
union {
- u64 raw;
- BitField<31, 1, u64> dont_kill_application;
+ u32 raw;
+ BitField<31, 1, u32> signal_debugger;
};
};
/// Break program execution
-static void Break(u64 reason, u64 info1, u64 info2) {
+static void Break(u32 reason, u64 info1, u64 info2) {
BreakReason break_reason{reason};
- if (break_reason.dont_kill_application) {
+ if (break_reason.signal_debugger) {
LOG_ERROR(
Debug_Emulated,
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 22712e64f..cbb80c3c4 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -35,18 +35,18 @@ void SvcWrap() {
template <ResultCode func(u32)>
void SvcWrap() {
- FuncReturn(func((u32)Param(0)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0))).raw);
}
template <ResultCode func(u32, u32)>
void SvcWrap() {
- FuncReturn(func((u32)Param(0), (u32)Param(1)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1))).raw);
}
template <ResultCode func(u32*, u32)>
void SvcWrap() {
u32 param_1 = 0;
- u32 retval = func(&param_1, (u32)Param(1)).raw;
+ u32 retval = func(&param_1, static_cast<u32>(Param(1))).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -61,7 +61,7 @@ void SvcWrap() {
template <ResultCode func(u64, s32)>
void SvcWrap() {
- FuncReturn(func(Param(0), (s32)Param(1)).raw);
+ FuncReturn(func(Param(0), static_cast<s32>(Param(1))).raw);
}
template <ResultCode func(u64, u32)>
@@ -79,19 +79,19 @@ void SvcWrap() {
template <ResultCode func(u32, u64)>
void SvcWrap() {
- FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), Param(1)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw);
}
template <ResultCode func(u32, u32, u64)>
void SvcWrap() {
- FuncReturn(func((u32)(Param(0) & 0xFFFFFFFF), (u32)(Param(1) & 0xFFFFFFFF), Param(2)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1)), Param(2)).raw);
}
template <ResultCode func(u32, u32*, u64*)>
void SvcWrap() {
u32 param_1 = 0;
u64 param_2 = 0;
- ResultCode retval = func((u32)(Param(2) & 0xFFFFFFFF), &param_1, &param_2);
+ ResultCode retval = func(static_cast<u32>(Param(2)), &param_1, &param_2);
Core::CurrentArmInterface().SetReg(1, param_1);
Core::CurrentArmInterface().SetReg(2, param_2);
FuncReturn(retval.raw);
@@ -100,12 +100,12 @@ void SvcWrap() {
template <ResultCode func(u64, u64, u32, u32)>
void SvcWrap() {
FuncReturn(
- func(Param(0), Param(1), (u32)(Param(3) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw);
+ func(Param(0), Param(1), static_cast<u32>(Param(3)), static_cast<u32>(Param(3))).raw);
}
template <ResultCode func(u32, u64, u32)>
void SvcWrap() {
- FuncReturn(func((u32)Param(0), Param(1), (u32)Param(2)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
}
template <ResultCode func(u64, u64, u64)>
@@ -115,25 +115,28 @@ void SvcWrap() {
template <ResultCode func(u32, u64, u64, u32)>
void SvcWrap() {
- FuncReturn(func((u32)Param(0), Param(1), Param(2), (u32)Param(3)).raw);
+ FuncReturn(
+ func(static_cast<u32>(Param(0)), Param(1), Param(2), static_cast<u32>(Param(3))).raw);
}
template <ResultCode func(u32, u64, u64)>
void SvcWrap() {
- FuncReturn(func((u32)Param(0), Param(1), Param(2)).raw);
+ FuncReturn(func(static_cast<u32>(Param(0)), Param(1), Param(2)).raw);
}
template <ResultCode func(u32*, u64, u64, s64)>
void SvcWrap() {
u32 param_1 = 0;
- ResultCode retval = func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (s64)Param(3));
+ ResultCode retval =
+ func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3)));
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval.raw);
}
template <ResultCode func(u64, u64, u32, s64)>
void SvcWrap() {
- FuncReturn(func(Param(0), Param(1), (u32)Param(2), (s64)Param(3)).raw);
+ FuncReturn(
+ func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))).raw);
}
template <ResultCode func(u64*, u64, u64, u64)>
@@ -147,9 +150,9 @@ void SvcWrap() {
template <ResultCode func(u32*, u64, u64, u64, u32, s32)>
void SvcWrap() {
u32 param_1 = 0;
- u32 retval =
- func(&param_1, Param(1), Param(2), Param(3), (u32)Param(4), (s32)(Param(5) & 0xFFFFFFFF))
- .raw;
+ u32 retval = func(&param_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)),
+ static_cast<s32>(Param(5)))
+ .raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -172,7 +175,7 @@ void SvcWrap() {
template <ResultCode func(u32*, u64, u64, u32)>
void SvcWrap() {
u32 param_1 = 0;
- u32 retval = func(&param_1, Param(1), Param(2), (u32)(Param(3) & 0xFFFFFFFF)).raw;
+ u32 retval = func(&param_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval);
}
@@ -181,22 +184,22 @@ template <ResultCode func(Handle*, u64, u32, u32)>
void SvcWrap() {
u32 param_1 = 0;
u32 retval =
- func(&param_1, Param(1), (u32)(Param(2) & 0xFFFFFFFF), (u32)(Param(3) & 0xFFFFFFFF)).raw;
+ func(&param_1, Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw;
Core::CurrentArmInterface().SetReg(1, param_1);
FuncReturn(retval);
}
template <ResultCode func(u64, u32, s32, s64)>
void SvcWrap() {
- FuncReturn(
- func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF), (s64)Param(3))
- .raw);
+ FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
+ static_cast<s64>(Param(3)))
+ .raw);
}
template <ResultCode func(u64, u32, s32, s32)>
void SvcWrap() {
- FuncReturn(func(Param(0), (u32)(Param(1) & 0xFFFFFFFF), (s32)(Param(2) & 0xFFFFFFFF),
- (s32)(Param(3) & 0xFFFFFFFF))
+ FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
+ static_cast<s32>(Param(3)))
.raw);
}
@@ -226,7 +229,7 @@ void SvcWrap() {
template <void func(s64)>
void SvcWrap() {
- func((s64)Param(0));
+ func(static_cast<s64>(Param(0)));
}
template <void func(u64, u64 len)>
@@ -239,4 +242,9 @@ void SvcWrap() {
func(Param(0), Param(1), Param(2));
}
+template <void func(u32, u64, u64)>
+void SvcWrap() {
+ func(static_cast<u32>(Param(0)), Param(1), Param(2));
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 33aed8c23..352ce1725 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -183,13 +183,10 @@ void Thread::ResumeFromWait() {
*/
static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAddr stack_top,
VAddr entry_point, u64 arg) {
- memset(&context, 0, sizeof(Core::ARM_Interface::ThreadContext));
-
+ context = {};
context.cpu_registers[0] = arg;
context.pc = entry_point;
context.sp = stack_top;
- context.pstate = 0;
- context.fpcr = 0;
}
ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 8d194e175..c41ef7058 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -15,6 +15,11 @@
#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
+namespace NvErrCodes {
+enum {
+ InvalidNmapHandle = -22,
+};
+}
nvhost_as_gpu::nvhost_as_gpu(std::shared_ptr<nvmap> nvmap_dev) : nvmap_dev(std::move(nvmap_dev)) {}
nvhost_as_gpu::~nvhost_as_gpu() = default;
@@ -79,14 +84,16 @@ u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output)
std::memcpy(entries.data(), input.data(), input.size());
auto& gpu = Core::System::GetInstance().GPU();
-
for (const auto& entry : entries) {
LOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
entry.offset, entry.nvmap_handle, entry.pages);
Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10;
-
auto object = nvmap_dev->GetObject(entry.nvmap_handle);
- ASSERT(object);
+ if (!object) {
+ LOG_CRITICAL(Service_NVDRV, "nvmap {} is an invalid handle!", entry.nvmap_handle);
+ std::memcpy(output.data(), entries.data(), output.size());
+ return static_cast<u32>(NvErrCodes::InvalidNmapHandle);
+ }
ASSERT(object->status == nvmap::Object::Status::Allocated);
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index a2287cc1b..43651d8a6 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -11,6 +11,13 @@
namespace Service::Nvidia::Devices {
+namespace NvErrCodes {
+enum {
+ OperationNotPermitted = -1,
+ InvalidValue = -22,
+};
+}
+
nvmap::nvmap() = default;
nvmap::~nvmap() = default;
@@ -44,7 +51,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
IocCreateParams params;
std::memcpy(&params, input.data(), sizeof(params));
+ LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
+ if (!params.size) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
// Create a new nvmap object and obtain a handle to it.
auto object = std::make_shared<Object>();
object->id = next_id++;
@@ -55,8 +66,6 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
u32 handle = next_handle++;
handles[handle] = std::move(object);
- LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
-
params.handle = handle;
std::memcpy(output.data(), &params, sizeof(params));
@@ -66,9 +75,29 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
IocAllocParams params;
std::memcpy(&params, input.data(), sizeof(params));
+ LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
+
+ if (!params.handle) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
+ if ((params.align - 1) & params.align) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
+ const u32 min_alignment = 0x1000;
+ if (params.align < min_alignment) {
+ params.align = min_alignment;
+ }
auto object = GetObject(params.handle);
- ASSERT(object);
+ if (!object) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
+ if (object->status == Object::Status::Allocated) {
+ return static_cast<u32>(NvErrCodes::OperationNotPermitted);
+ }
object->flags = params.flags;
object->align = params.align;
@@ -76,8 +105,6 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
object->addr = params.addr;
object->status = Object::Status::Allocated;
- LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
-
std::memcpy(output.data(), &params, sizeof(params));
return 0;
}
@@ -88,8 +115,14 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "called");
+ if (!params.handle) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
auto object = GetObject(params.handle);
- ASSERT(object);
+ if (!object) {
+ return static_cast<u32>(NvErrCodes::OperationNotPermitted);
+ }
params.id = object->id;
@@ -105,7 +138,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
auto itr = std::find_if(handles.begin(), handles.end(),
[&](const auto& entry) { return entry.second->id == params.id; });
- ASSERT(itr != handles.end());
+ if (itr == handles.end()) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
+ auto& object = itr->second;
+ if (object->status != Object::Status::Allocated) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
itr->second->refcount++;
@@ -125,8 +165,13 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
auto object = GetObject(params.handle);
- ASSERT(object);
- ASSERT(object->status == Object::Status::Allocated);
+ if (!object) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+
+ if (object->status != Object::Status::Allocated) {
+ return static_cast<u32>(NvErrCodes::OperationNotPermitted);
+ }
switch (static_cast<ParamTypes>(params.param)) {
case ParamTypes::Size:
@@ -163,9 +208,12 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
auto itr = handles.find(params.handle);
- ASSERT(itr != handles.end());
-
- ASSERT(itr->second->refcount > 0);
+ if (itr == handles.end()) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
+ if (!itr->second->refcount) {
+ return static_cast<u32>(NvErrCodes::InvalidValue);
+ }
itr->second->refcount--;
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 3d5476e5d..0d2456b56 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -4,6 +4,7 @@
#include <cmath>
#include <cstring>
+#include "common/alignment.h"
#include "common/assert.h"
#include "core/memory.h"
#include "video_core/gpu.h"
@@ -199,4 +200,19 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
return rgba_data;
}
+std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
+ u32 block_height, u32 block_depth) {
+ if (tiled) {
+ const u32 gobs_in_x = 64 / bytes_per_pixel;
+ const u32 gobs_in_y = 8;
+ const u32 gobs_in_z = 1;
+ const u32 aligned_width = Common::AlignUp(width, gobs_in_x);
+ const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height);
+ const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth);
+ return aligned_width * aligned_height * aligned_depth * bytes_per_pixel;
+ } else {
+ return width * height * depth * bytes_per_pixel;
+ }
+}
+
} // namespace Tegra::Texture
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 1f7b731be..234d250af 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -32,4 +32,10 @@ void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_
std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat format, u32 width,
u32 height);
+/**
+ * This function calculates the correct size of a texture depending if it's tiled or not.
+ */
+std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
+ u32 block_height, u32 block_depth);
+
} // namespace Tegra::Texture