summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/apt/apt.cpp25
-rw-r--r--src/core/hle/service/apt/apt.h6
-rw-r--r--src/core/hle/service/cfg/cfg.cpp16
-rw-r--r--src/core/hle/service/dsp_dsp.cpp17
-rw-r--r--src/core/hle/service/frd/frd.cpp10
-rw-r--r--src/core/hle/service/fs/archive.cpp22
-rw-r--r--src/core/hle/service/gsp_gpu.cpp83
-rw-r--r--src/core/hle/service/soc_u.cpp100
-rw-r--r--src/core/hle/service/ssl_c.cpp7
9 files changed, 179 insertions, 107 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index bbf170b71..1e54a53dd 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -180,12 +180,12 @@ void SendParameter(Service::Interface* self) {
}
MessageParameter param;
- param.buffer_size = buffer_size;
param.destination_id = dst_app_id;
param.sender_id = src_app_id;
param.object = Kernel::g_handle_table.GetGeneric(handle);
param.signal = signal_type;
- param.data = Memory::GetPointer(buffer);
+ param.buffer.resize(buffer_size);
+ Memory::ReadBlock(buffer, param.buffer.data(), param.buffer.size());
cmd_buff[1] = dest_applet->ReceiveParameter(param).raw;
@@ -203,16 +203,15 @@ void ReceiveParameter(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = next_parameter.sender_id;
cmd_buff[3] = next_parameter.signal; // Signal type
- cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
+ cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size
cmd_buff[5] = 0x10;
cmd_buff[6] = 0;
if (next_parameter.object != nullptr)
cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
- cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
+ cmd_buff[7] = (next_parameter.buffer.size() << 14) | 2;
cmd_buff[8] = buffer;
- if (next_parameter.data)
- memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
+ Memory::WriteBlock(buffer, next_parameter.buffer.data(), next_parameter.buffer.size());
LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
}
@@ -226,16 +225,15 @@ void GlanceParameter(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
cmd_buff[2] = next_parameter.sender_id;
cmd_buff[3] = next_parameter.signal; // Signal type
- cmd_buff[4] = next_parameter.buffer_size; // Parameter buffer size
+ cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size
cmd_buff[5] = 0x10;
cmd_buff[6] = 0;
if (next_parameter.object != nullptr)
cmd_buff[6] = Kernel::g_handle_table.Create(next_parameter.object).MoveFrom();
- cmd_buff[7] = (next_parameter.buffer_size << 14) | 2;
+ cmd_buff[7] = (next_parameter.buffer.size() << 14) | 2;
cmd_buff[8] = buffer;
- if (next_parameter.data)
- memcpy(Memory::GetPointer(buffer), next_parameter.data, std::min(buffer_size, next_parameter.buffer_size));
+ Memory::WriteBlock(buffer, next_parameter.buffer.data(), std::min(static_cast<size_t>(buffer_size), next_parameter.buffer.size()));
LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
}
@@ -373,10 +371,13 @@ void StartLibraryApplet(Service::Interface* self) {
return;
}
+ size_t buffer_size = cmd_buff[2];
+ VAddr buffer_addr = cmd_buff[6];
+
AppletStartupParameter parameter;
- parameter.buffer_size = cmd_buff[2];
parameter.object = Kernel::g_handle_table.GetGeneric(cmd_buff[4]);
- parameter.data = Memory::GetPointer(cmd_buff[6]);
+ parameter.buffer.resize(buffer_size);
+ Memory::ReadBlock(buffer_addr, parameter.buffer.data(), parameter.buffer.size());
cmd_buff[1] = applet->Start(parameter).raw;
}
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index ed7c47cca..76b3a3807 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -20,16 +20,14 @@ struct MessageParameter {
u32 sender_id = 0;
u32 destination_id = 0;
u32 signal = 0;
- u32 buffer_size = 0;
Kernel::SharedPtr<Kernel::Object> object = nullptr;
- u8* data = nullptr;
+ std::vector<u8> buffer;
};
/// Holds information about the parameters used in StartLibraryApplet
struct AppletStartupParameter {
- u32 buffer_size = 0;
Kernel::SharedPtr<Kernel::Object> object = nullptr;
- u8* data = nullptr;
+ std::vector<u8> buffer;
};
/// Used by the application to pass information about the current framebuffer to applets.
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index acc509cb0..e067db645 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -196,28 +196,32 @@ void GetConfigInfoBlk2(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 size = cmd_buff[1];
u32 block_id = cmd_buff[2];
- u8* data_pointer = Memory::GetPointer(cmd_buff[4]);
+ VAddr data_pointer = cmd_buff[4];
- if (data_pointer == nullptr) {
+ if (!Memory::IsValidVirtualAddress(data_pointer)) {
cmd_buff[1] = -1; // TODO(Subv): Find the right error code
return;
}
- cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data_pointer).raw;
+ std::vector<u8> data(size);
+ cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x2, data.data()).raw;
+ Memory::WriteBlock(data_pointer, data.data(), data.size());
}
void GetConfigInfoBlk8(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 size = cmd_buff[1];
u32 block_id = cmd_buff[2];
- u8* data_pointer = Memory::GetPointer(cmd_buff[4]);
+ VAddr data_pointer = cmd_buff[4];
- if (data_pointer == nullptr) {
+ if (!Memory::IsValidVirtualAddress(data_pointer)) {
cmd_buff[1] = -1; // TODO(Subv): Find the right error code
return;
}
- cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data_pointer).raw;
+ std::vector<u8> data(size);
+ cmd_buff[1] = Service::CFG::GetConfigInfoBlock(block_id, size, 0x8, data.data()).raw;
+ Memory::WriteBlock(data_pointer, data.data(), data.size());
}
void UpdateConfigNANDSavegame(Service::Interface* self) {
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 10730d7ac..c8aadd9db 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -140,12 +140,15 @@ static void LoadComponent(Service::Interface* self) {
// TODO(bunnei): Implement real DSP firmware loading
- ASSERT(Memory::GetPointer(buffer) != nullptr);
- ASSERT(size > 0x37C);
+ ASSERT(Memory::IsValidVirtualAddress(buffer));
+
+ std::vector<u8> component_data(size);
+ Memory::ReadBlock(buffer, component_data.data(), component_data.size());
- LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, Common::ComputeHash64(Memory::GetPointer(buffer), size));
+ LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, Common::ComputeHash64(component_data.data(), component_data.size()));
// Some versions of the firmware have the location of DSP structures listed here.
- LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, Common::ComputeHash64(Memory::GetPointer(buffer) + 0x340, 60));
+ ASSERT(size > 0x37C);
+ LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, Common::ComputeHash64(component_data.data() + 0x340, 60));
LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X",
size, prog_mask, data_mask, buffer);
@@ -285,7 +288,7 @@ static void WriteProcessPipe(Service::Interface* self) {
return;
}
- ASSERT_MSG(Memory::GetPointer(buffer) != nullptr, "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe_index, size, buffer);
+ ASSERT_MSG(Memory::IsValidVirtualAddress(buffer), "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer);
std::vector<u8> message(size);
for (u32 i = 0; i < size; i++) {
@@ -324,7 +327,7 @@ static void ReadPipeIfPossible(Service::Interface* self) {
DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index);
- ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe_index, unknown, size, addr);
+ ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr);
cmd_buff[0] = IPC::MakeHeader(0x10, 1, 2);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
@@ -364,7 +367,7 @@ static void ReadPipe(Service::Interface* self) {
DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index);
- ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe_index, unknown, size, addr);
+ ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr);
if (DSP::HLE::GetPipeReadableSize(pipe) >= size) {
std::vector<u8> response = DSP::HLE::PipeRead(pipe, size);
diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp
index 15d604bb6..29d144365 100644
--- a/src/core/hle/service/frd/frd.cpp
+++ b/src/core/hle/service/frd/frd.cpp
@@ -23,7 +23,7 @@ void GetMyPresence(Service::Interface* self) {
ASSERT(shifted_out_size == ((sizeof(MyPresence) << 14) | 2));
- Memory::WriteBlock(my_presence_addr, reinterpret_cast<const u8*>(&my_presence), sizeof(MyPresence));
+ Memory::WriteBlock(my_presence_addr, &my_presence, sizeof(MyPresence));
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
@@ -39,8 +39,7 @@ void GetFriendKeyList(Service::Interface* self) {
FriendKey zero_key = {};
for (u32 i = 0; i < frd_count; ++i) {
- Memory::WriteBlock(frd_key_addr + i * sizeof(FriendKey),
- reinterpret_cast<const u8*>(&zero_key), sizeof(FriendKey));
+ Memory::WriteBlock(frd_key_addr + i * sizeof(FriendKey), &zero_key, sizeof(FriendKey));
}
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
@@ -58,8 +57,7 @@ void GetFriendProfile(Service::Interface* self) {
Profile zero_profile = {};
for (u32 i = 0; i < count; ++i) {
- Memory::WriteBlock(profiles_addr + i * sizeof(Profile),
- reinterpret_cast<const u8*>(&zero_profile), sizeof(Profile));
+ Memory::WriteBlock(profiles_addr + i * sizeof(Profile), &zero_profile, sizeof(Profile));
}
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
@@ -88,7 +86,7 @@ void GetMyFriendKey(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = RESULT_SUCCESS.raw; // No error
- Memory::WriteBlock(cmd_buff[2], reinterpret_cast<const u8*>(&my_friend_key), sizeof(FriendKey));
+ Memory::WriteBlock(cmd_buff[2], &my_friend_key, sizeof(FriendKey));
LOG_WARNING(Service_FRD, "(STUBBED) called");
}
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index cc51ede0c..81b9abe4c 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -108,13 +108,14 @@ ResultVal<bool> File::SyncRequest() {
offset, length, backend->GetSize());
}
- ResultVal<size_t> read = backend->Read(offset, length, Memory::GetPointer(address));
+ std::vector<u8> data(length);
+ ResultVal<size_t> read = backend->Read(offset, data.size(), data.data());
if (read.Failed()) {
cmd_buff[1] = read.Code().raw;
return read.Code();
}
+ Memory::WriteBlock(address, data.data(), *read);
cmd_buff[2] = static_cast<u32>(*read);
- Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(address), length);
break;
}
@@ -128,7 +129,9 @@ ResultVal<bool> File::SyncRequest() {
LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x",
GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush);
- ResultVal<size_t> written = backend->Write(offset, length, flush != 0, Memory::GetPointer(address));
+ std::vector<u8> data(length);
+ Memory::ReadBlock(address, data.data(), data.size());
+ ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data());
if (written.Failed()) {
cmd_buff[1] = written.Code().raw;
return written.Code();
@@ -216,12 +219,14 @@ ResultVal<bool> Directory::SyncRequest() {
{
u32 count = cmd_buff[1];
u32 address = cmd_buff[3];
- auto entries = reinterpret_cast<FileSys::Entry*>(Memory::GetPointer(address));
+ std::vector<FileSys::Entry> entries(count);
LOG_TRACE(Service_FS, "Read %s %s: count=%d",
GetTypeName().c_str(), GetName().c_str(), count);
// Number of entries actually read
- cmd_buff[2] = backend->Read(count, entries);
+ u32 read = backend->Read(entries.size(), entries.data());
+ cmd_buff[2] = read;
+ Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry));
break;
}
@@ -456,11 +461,12 @@ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon
if (result.IsError())
return result;
- u8* smdh_icon = Memory::GetPointer(icon_buffer);
- if (!smdh_icon)
+ if (!Memory::IsValidVirtualAddress(icon_buffer))
return ResultCode(-1); // TODO(Subv): Find the right error code
- ext_savedata->WriteIcon(path, smdh_icon, icon_size);
+ std::vector<u8> smdh_icon(icon_size);
+ Memory::ReadBlock(icon_buffer, smdh_icon.data(), smdh_icon.size());
+ ext_savedata->WriteIcon(path, smdh_icon.data(), smdh_icon.size());
return RESULT_SUCCESS;
}
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 8ded9b09b..f3c7b7df3 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -66,14 +66,26 @@ static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
}
/**
+ * Writes a single GSP GPU hardware registers with a single u32 value
+ * (For internal use.)
+ *
+ * @param base_address The address of the register in question
+ * @param data Data to be written
+ */
+static void WriteSingleHWReg(u32 base_address, u32 data) {
+ DEBUG_ASSERT_MSG((base_address & 3) == 0 && base_address < 0x420000, "Write address out of range or misaligned");
+ HW::Write<u32>(base_address + REGS_BEGIN, data);
+}
+
+/**
* Writes sequential GSP GPU hardware registers using an array of source data
*
* @param base_address The address of the first register in the sequence
* @param size_in_bytes The number of registers to update (size of data)
- * @param data A pointer to the source data
+ * @param data_vaddr A pointer to the source data
* @return RESULT_SUCCESS if the parameters are valid, error code otherwise
*/
-static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) {
+static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, VAddr data_vaddr) {
// This magic number is verified to be done by the gsp module
const u32 max_size_in_bytes = 0x80;
@@ -87,10 +99,10 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* da
return ERR_GSP_REGS_MISALIGNED;
} else {
while (size_in_bytes > 0) {
- HW::Write<u32>(base_address + REGS_BEGIN, *data);
+ WriteSingleHWReg(base_address, Memory::Read32(data_vaddr));
size_in_bytes -= 4;
- ++data;
+ data_vaddr += 4;
base_address += 4;
}
return RESULT_SUCCESS;
@@ -112,7 +124,7 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* da
* @param masks A pointer to the masks
* @return RESULT_SUCCESS if the parameters are valid, error code otherwise
*/
-static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, const u32* data, const u32* masks) {
+static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr, VAddr masks_vaddr) {
// This magic number is verified to be done by the gsp module
const u32 max_size_in_bytes = 0x80;
@@ -131,14 +143,17 @@ static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, const
u32 reg_value;
HW::Read<u32>(reg_value, reg_address);
+ u32 data = Memory::Read32(data_vaddr);
+ u32 mask = Memory::Read32(masks_vaddr);
+
// Update the current value of the register only for set mask bits
- reg_value = (reg_value & ~*masks) | (*data | *masks);
+ reg_value = (reg_value & ~mask) | (data | mask);
- HW::Write<u32>(reg_address, reg_value);
+ WriteSingleHWReg(base_address, reg_value);
size_in_bytes -= 4;
- ++data;
- ++masks;
+ data_vaddr += 4;
+ masks_vaddr += 4;
base_address += 4;
}
return RESULT_SUCCESS;
@@ -164,8 +179,7 @@ static void WriteHWRegs(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
u32 reg_addr = cmd_buff[1];
u32 size = cmd_buff[2];
-
- u32* src = (u32*)Memory::GetPointer(cmd_buff[4]);
+ VAddr src = cmd_buff[4];
cmd_buff[1] = WriteHWRegs(reg_addr, size, src).raw;
}
@@ -186,8 +200,8 @@ static void WriteHWRegsWithMask(Service::Interface* self) {
u32 reg_addr = cmd_buff[1];
u32 size = cmd_buff[2];
- u32* src_data = (u32*)Memory::GetPointer(cmd_buff[4]);
- u32* mask_data = (u32*)Memory::GetPointer(cmd_buff[6]);
+ VAddr src_data = cmd_buff[4];
+ VAddr mask_data = cmd_buff[6];
cmd_buff[1] = WriteHWRegsWithMask(reg_addr, size, src_data, mask_data).raw;
}
@@ -210,13 +224,16 @@ static void ReadHWRegs(Service::Interface* self) {
return;
}
- u32* dst = (u32*)Memory::GetPointer(cmd_buff[0x41]);
+ VAddr dst_vaddr = cmd_buff[0x41];
while (size > 0) {
- HW::Read<u32>(*dst, reg_addr + REGS_BEGIN);
+ u32 value;
+ HW::Read<u32>(value, reg_addr + REGS_BEGIN);
+
+ Memory::Write32(dst_vaddr, value);
size -= 4;
- ++dst;
+ dst_vaddr += 4;
reg_addr += 4;
}
}
@@ -226,22 +243,22 @@ ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) {
PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left);
PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right);
if (info.active_fb == 0) {
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)),
- 4, &phys_address_left);
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)),
- 4, &phys_address_right);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)),
+ phys_address_left);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)),
+ phys_address_right);
} else {
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)),
- 4, &phys_address_left);
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)),
- 4, &phys_address_right);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)),
+ phys_address_left);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)),
+ phys_address_right);
}
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)),
- 4, &info.stride);
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)),
- 4, &info.format);
- WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)),
- 4, &info.shown_fb);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)),
+ info.stride);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)),
+ info.format);
+ WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)),
+ info.shown_fb);
if (Pica::g_debug_context)
Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr);
@@ -432,9 +449,9 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address),
command.dma_request.size);
- memcpy(Memory::GetPointer(command.dma_request.dest_address),
- Memory::GetPointer(command.dma_request.source_address),
- command.dma_request.size);
+ // TODO(Subv): These memory accesses should not go through the application's memory mapping.
+ // They should go through the GSP module's memory mapping.
+ Memory::CopyBlock(command.dma_request.dest_address, command.dma_request.source_address, command.dma_request.size);
SignalInterrupt(InterruptId::DMA);
break;
}
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index d3e5d4bca..9b285567b 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -373,14 +373,18 @@ static void Bind(Service::Interface* self) {
u32* cmd_buffer = Kernel::GetCommandBuffer();
u32 socket_handle = cmd_buffer[1];
u32 len = cmd_buffer[2];
- CTRSockAddr* ctr_sock_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[6]));
- if (ctr_sock_addr == nullptr) {
+ // Virtual address of the sock_addr structure
+ VAddr sock_addr_addr = cmd_buffer[6];
+ if (!Memory::IsValidVirtualAddress(sock_addr_addr)) {
cmd_buffer[1] = -1; // TODO(Subv): Correct code
return;
}
- sockaddr sock_addr = CTRSockAddr::ToPlatform(*ctr_sock_addr);
+ CTRSockAddr ctr_sock_addr;
+ Memory::ReadBlock(sock_addr_addr, reinterpret_cast<u8*>(&ctr_sock_addr), sizeof(CTRSockAddr));
+
+ sockaddr sock_addr = CTRSockAddr::ToPlatform(ctr_sock_addr);
int res = ::bind(socket_handle, &sock_addr, std::max<u32>(sizeof(sock_addr), len));
@@ -496,7 +500,7 @@ static void Accept(Service::Interface* self) {
result = TranslateError(GET_ERRNO);
} else {
CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr);
- Memory::WriteBlock(cmd_buffer[0x104 >> 2], (const u8*)&ctr_addr, max_addr_len);
+ Memory::WriteBlock(cmd_buffer[0x104 >> 2], &ctr_addr, sizeof(ctr_addr));
}
cmd_buffer[0] = IPC::MakeHeader(4, 2, 2);
@@ -547,20 +551,31 @@ static void SendTo(Service::Interface* self) {
u32 flags = cmd_buffer[3];
u32 addr_len = cmd_buffer[4];
- u8* input_buff = Memory::GetPointer(cmd_buffer[8]);
- CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[10]));
+ VAddr input_buff_address = cmd_buffer[8];
+ if (!Memory::IsValidVirtualAddress(input_buff_address)) {
+ cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
+ return;
+ }
- if (ctr_dest_addr == nullptr) {
+ // Memory address of the dest_addr structure
+ VAddr dest_addr_addr = cmd_buffer[10];
+ if (!Memory::IsValidVirtualAddress(dest_addr_addr)) {
cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
return;
}
+ std::vector<u8> input_buff(len);
+ Memory::ReadBlock(input_buff_address, input_buff.data(), input_buff.size());
+
+ CTRSockAddr ctr_dest_addr;
+ Memory::ReadBlock(dest_addr_addr, &ctr_dest_addr, sizeof(ctr_dest_addr));
+
int ret = -1;
if (addr_len > 0) {
- sockaddr dest_addr = CTRSockAddr::ToPlatform(*ctr_dest_addr);
- ret = ::sendto(socket_handle, (const char*)input_buff, len, flags, &dest_addr, sizeof(dest_addr));
+ sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr);
+ ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, &dest_addr, sizeof(dest_addr));
} else {
- ret = ::sendto(socket_handle, (const char*)input_buff, len, flags, nullptr, 0);
+ ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, nullptr, 0);
}
int result = 0;
@@ -591,14 +606,24 @@ static void RecvFrom(Service::Interface* self) {
std::memcpy(&buffer_parameters, &cmd_buffer[64], sizeof(buffer_parameters));
- u8* output_buff = Memory::GetPointer(buffer_parameters.output_buffer_addr);
+ if (!Memory::IsValidVirtualAddress(buffer_parameters.output_buffer_addr)) {
+ cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
+ return;
+ }
+
+ if (!Memory::IsValidVirtualAddress(buffer_parameters.output_src_address_buffer)) {
+ cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
+ return;
+ }
+
+ std::vector<u8> output_buff(len);
sockaddr src_addr;
socklen_t src_addr_len = sizeof(src_addr);
- int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len);
+ int ret = ::recvfrom(socket_handle, reinterpret_cast<char*>(output_buff.data()), len, flags, &src_addr, &src_addr_len);
if (ret >= 0 && buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) {
- CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(buffer_parameters.output_src_address_buffer));
- *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr);
+ CTRSockAddr ctr_src_addr = CTRSockAddr::FromPlatform(src_addr);
+ Memory::WriteBlock(buffer_parameters.output_src_address_buffer, &ctr_src_addr, sizeof(ctr_src_addr));
}
int result = 0;
@@ -606,6 +631,9 @@ static void RecvFrom(Service::Interface* self) {
if (ret == SOCKET_ERROR_VALUE) {
result = TranslateError(GET_ERRNO);
total_received = 0;
+ } else {
+ // Write only the data we received to avoid overwriting parts of the buffer with zeros
+ Memory::WriteBlock(buffer_parameters.output_buffer_addr, output_buff.data(), total_received);
}
cmd_buffer[1] = result;
@@ -617,18 +645,28 @@ static void Poll(Service::Interface* self) {
u32* cmd_buffer = Kernel::GetCommandBuffer();
u32 nfds = cmd_buffer[1];
int timeout = cmd_buffer[2];
- CTRPollFD* input_fds = reinterpret_cast<CTRPollFD*>(Memory::GetPointer(cmd_buffer[6]));
- CTRPollFD* output_fds = reinterpret_cast<CTRPollFD*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
+
+ VAddr input_fds_addr = cmd_buffer[6];
+ VAddr output_fds_addr = cmd_buffer[0x104 >> 2];
+ if (!Memory::IsValidVirtualAddress(input_fds_addr) || !Memory::IsValidVirtualAddress(output_fds_addr)) {
+ cmd_buffer[1] = -1; // TODO(Subv): Find correct error code.
+ return;
+ }
+
+ std::vector<CTRPollFD> ctr_fds(nfds);
+ Memory::ReadBlock(input_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD));
// The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different sizes)
// so we have to copy the data
std::vector<pollfd> platform_pollfd(nfds);
- std::transform(input_fds, input_fds + nfds, platform_pollfd.begin(), CTRPollFD::ToPlatform);
+ std::transform(ctr_fds.begin(), ctr_fds.end(), platform_pollfd.begin(), CTRPollFD::ToPlatform);
const int ret = ::poll(platform_pollfd.data(), nfds, timeout);
// Now update the output pollfd structure
- std::transform(platform_pollfd.begin(), platform_pollfd.end(), output_fds, CTRPollFD::FromPlatform);
+ std::transform(platform_pollfd.begin(), platform_pollfd.end(), ctr_fds.begin(), CTRPollFD::FromPlatform);
+
+ Memory::WriteBlock(output_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD));
int result = 0;
if (ret == SOCKET_ERROR_VALUE)
@@ -643,14 +681,16 @@ static void GetSockName(Service::Interface* self) {
u32 socket_handle = cmd_buffer[1];
socklen_t ctr_len = cmd_buffer[2];
- CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
+ // Memory address of the ctr_dest_addr structure
+ VAddr ctr_dest_addr_addr = cmd_buffer[0x104 >> 2];
sockaddr dest_addr;
socklen_t dest_addr_len = sizeof(dest_addr);
int ret = ::getsockname(socket_handle, &dest_addr, &dest_addr_len);
- if (ctr_dest_addr != nullptr) {
- *ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
+ if (ctr_dest_addr_addr != 0 && Memory::IsValidVirtualAddress(ctr_dest_addr_addr)) {
+ CTRSockAddr ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
+ Memory::WriteBlock(ctr_dest_addr_addr, &ctr_dest_addr, sizeof(ctr_dest_addr));
} else {
cmd_buffer[1] = -1; // TODO(Subv): Verify error
return;
@@ -682,14 +722,16 @@ static void GetPeerName(Service::Interface* self) {
u32 socket_handle = cmd_buffer[1];
socklen_t len = cmd_buffer[2];
- CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
+ // Memory address of the ctr_dest_addr structure
+ VAddr ctr_dest_addr_addr = cmd_buffer[0x104 >> 2];
sockaddr dest_addr;
socklen_t dest_addr_len = sizeof(dest_addr);
int ret = ::getpeername(socket_handle, &dest_addr, &dest_addr_len);
- if (ctr_dest_addr != nullptr) {
- *ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
+ if (ctr_dest_addr_addr != 0 && Memory::IsValidVirtualAddress(ctr_dest_addr_addr)) {
+ CTRSockAddr ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
+ Memory::WriteBlock(ctr_dest_addr_addr, &ctr_dest_addr, sizeof(ctr_dest_addr));
} else {
cmd_buffer[1] = -1;
return;
@@ -711,13 +753,17 @@ static void Connect(Service::Interface* self) {
u32 socket_handle = cmd_buffer[1];
socklen_t len = cmd_buffer[2];
- CTRSockAddr* ctr_input_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[6]));
- if (ctr_input_addr == nullptr) {
+ // Memory address of the ctr_input_addr structure
+ VAddr ctr_input_addr_addr = cmd_buffer[6];
+ if (!Memory::IsValidVirtualAddress(ctr_input_addr_addr)) {
cmd_buffer[1] = -1; // TODO(Subv): Verify error
return;
}
- sockaddr input_addr = CTRSockAddr::ToPlatform(*ctr_input_addr);
+ CTRSockAddr ctr_input_addr;
+ Memory::ReadBlock(ctr_input_addr_addr, &ctr_input_addr, sizeof(ctr_input_addr));
+
+ sockaddr input_addr = CTRSockAddr::ToPlatform(ctr_input_addr);
int ret = ::connect(socket_handle, &input_addr, sizeof(input_addr));
int result = 0;
if (ret != 0)
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index 14a4e98ec..a8aff1abf 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -31,7 +31,6 @@ static void GenerateRandomData(Service::Interface* self) {
u32 size = cmd_buff[1];
VAddr address = cmd_buff[3];
- u8* output_buff = Memory::GetPointer(address);
// Fill the output buffer with random data.
u32 data = 0;
@@ -44,13 +43,13 @@ static void GenerateRandomData(Service::Interface* self) {
if (size > 4) {
// Use up the entire 4 bytes of the random data for as long as possible
- *(u32*)(output_buff + i) = data;
+ Memory::Write32(address + i, data);
i += 4;
} else if (size == 2) {
- *(u16*)(output_buff + i) = (u16)(data & 0xffff);
+ Memory::Write16(address + i, static_cast<u16>(data & 0xffff));
i += 2;
} else {
- *(u8*)(output_buff + i) = (u8)(data & 0xff);
+ Memory::Write8(address + i, static_cast<u8>(data & 0xff));
i++;
}
}