Compare commits

..

19 Commits

Author SHA1 Message Date
Jhon591
f816d3041c remove_old_new_3DSmode 2018-01-17 22:03:23 +00:00
bunnei
0568346cc3 Merge pull request #64 from shinyquagsire23/hid-timing
hid: Adjust timing based on actual hardware
2018-01-17 12:30:46 -05:00
bunnei
8bff9c9152 Merge pull request #70 from flerovii/nvdrv-close
nvdrv: stubbed Close(cmd 2)
2018-01-17 12:29:23 -05:00
bunnei
7fa32af1c7 svc: Clang-format fix. 2018-01-17 12:19:17 -05:00
bunnei
1998a16557 Merge pull request #71 from N00byKing/patch-1
Implement Pull #3109 from citra: sdl2 default ini: fix framelimit
2018-01-17 12:09:47 -05:00
bunnei
7172ff4d9a Merge pull request #62 from bunnei/domain-close-handle
Implement IPC domain command CloseVirtualHandle
2018-01-17 12:09:12 -05:00
N00byKing
b2386fc712 Update default_ini.h 2018-01-17 18:01:09 +01:00
bunnei
b588cbcb1d hle_ipc: Clang format. 2018-01-17 11:37:26 -05:00
Frederic Meyer
60d650cc4e nvdrv: stubbed Close(cmd 2) 2018-01-17 17:08:46 +01:00
bunnei
d92636d424 Merge pull request #67 from RiverCityRansomware/gdbstubtypo
Fix gdbstub typo
2018-01-17 10:27:00 -05:00
River City Ransomware
d05dc3f4dd Fix gdbstub typo, fixes Citra #3318
Core::System().GetInstance().IsPoweredOn() -> Core::System::GetInstance().IsPoweredOn()
2018-01-17 09:25:25 -05:00
shinyquagsire23
008823724f hid: Adjust timing based on actual hardware 2018-01-17 01:20:25 -07:00
bunnei
9ae55884d2 Merge pull request #60 from jroweboy/game-frame
UI: Fix frame rate perf stats
2018-01-17 01:23:43 -05:00
bunnei
30cb98f874 ipc: Implement domain command CloseVirtualHandle. 2018-01-17 01:20:10 -05:00
bunnei
d15cadd760 loggin: Add IPC logging category. 2018-01-17 01:20:02 -05:00
bunnei
dc905463dc Merge pull request #34 from shinyquagsire23/hid-sharedmem-layouts-circbufs-meta
hid: Write to all layouts, implement circular buffers, set up controller metadata.
2018-01-16 21:54:46 -05:00
shinyquagsire23
eff90550a1 hid: clang-format 2018-01-16 19:22:58 -07:00
shinyquagsire23
36b89787ce hid: Adjust for style guide 2018-01-16 19:22:12 -07:00
shinyquagsire23
d20a883194 hid: Write to all layouts, implement circular buffers, set up controller metadata. 2018-01-16 03:14:27 -07:00
18 changed files with 199 additions and 136 deletions

View File

@@ -43,6 +43,7 @@ namespace Log {
SUB(HW, LCD) \
SUB(HW, GPU) \
SUB(HW, AES) \
CLS(IPC) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Software) \
@@ -91,8 +92,8 @@ const char* GetLevelName(Level log_level) {
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
const char* function, const char* format, va_list args) {
using std::chrono::steady_clock;
using std::chrono::duration_cast;
using std::chrono::steady_clock;
static steady_clock::time_point time_origin = steady_clock::now();

View File

@@ -60,6 +60,7 @@ enum class Class : ClassType {
HW_LCD, ///< LCD register emulation
HW_GPU, ///< GPU control emulation
HW_AES, ///< AES engine emulation
IPC, ///< IPC interface
Frontend, ///< Emulator UI
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend

View File

@@ -905,7 +905,7 @@ void ToggleServer(bool status) {
server_enabled = status;
// Start server
if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
Init();
}
} else {

View File

@@ -143,6 +143,11 @@ struct DataPayloadHeader {
static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect");
struct DomainMessageHeader {
enum class CommandType : u32_le {
SendMessage = 1,
CloseVirtualHandle = 2,
};
union {
// Used when responding to an IPC request, Server -> Client.
struct {
@@ -153,7 +158,7 @@ struct DomainMessageHeader {
// Used when performing an IPC request, Client -> Server.
struct {
union {
BitField<0, 8, u32_le> command;
BitField<0, 8, CommandType> command;
BitField<16, 16, u32_le> size;
};
u32_le object_id;

View File

@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/domain.h"
#include "core/hle/kernel/handle_table.h"
@@ -36,7 +38,24 @@ ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) {
if (domain_message_header) {
// If there is a DomainMessageHeader, then this is CommandType "Request"
const u32 object_id{context.GetDomainMessageHeader()->object_id};
return request_handlers[object_id - 1]->HandleSyncRequest(context);
switch (domain_message_header->command) {
case IPC::DomainMessageHeader::CommandType::SendMessage:
return request_handlers[object_id - 1]->HandleSyncRequest(context);
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id);
request_handlers[object_id - 1] = nullptr;
IPC::RequestBuilder rb{context, 2};
rb.Push(RESULT_SUCCESS);
return RESULT_SUCCESS;
}
}
LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
UNIMPLEMENTED();
}
return request_handlers.front()->HandleSyncRequest(context);
}

View File

@@ -102,13 +102,21 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
data_payload_header =
std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
data_payload_offset = rp.GetCurrentOffset();
if (domain_message_header &&
domain_message_header->command ==
IPC::DomainMessageHeader::CommandType::CloseVirtualHandle) {
// CloseVirtualHandle command does not have SFC* or any data
return;
}
if (incoming) {
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I'));
} else {
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O'));
}
data_payload_offset = rp.GetCurrentOffset();
command = rp.Pop<u32_le>();
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
}

View File

@@ -27,23 +27,14 @@ MemoryRegionInfo memory_regions[3];
/// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system
/// memory configuration type.
static const u32 memory_region_sizes[8][3] = {
// Old 3DS layouts
{0x04000000, 0x02C00000, 0x01400000}, // 0
static const u32 memory_region_sizes[3][3] = {
{/* This appears to be unused. */}, // 1
{0x06000000, 0x00C00000, 0x01400000}, // 2
{0x05000000, 0x01C00000, 0x01400000}, // 3
{0x04800000, 0x02400000, 0x01400000}, // 4
{0x02000000, 0x04C00000, 0x01400000}, // 5
// New 3DS layouts
{0x07C00000, 0x06400000, 0x02000000}, // 6
{0x0B200000, 0x02E00000, 0x02000000}, // 7
{0x04800000, 0x02400000, 0x01400000}, // 3
{0x02000000, 0x04C00000, 0x01400000}, // 4
};
void MemoryInit(u32 mem_type) {
// TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead.
ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!");
ASSERT_MSG(mem_type <= 5, "New memory configuration aren't supported yet!");
ASSERT(mem_type != 1);
// The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with
@@ -67,7 +58,6 @@ void MemoryInit(u32 mem_type) {
using ConfigMem::config_mem;
config_mem.app_mem_type = mem_type;
// app_mem_malloc does not always match the configured size for memory_region[0]: in case the
// n3DS type override is in effect it reports the size the game expects, not the real one.
config_mem.app_mem_alloc = memory_region_sizes[mem_type][0];
config_mem.sys_mem_alloc = static_cast<u32_le>(memory_regions[1].size);
config_mem.base_mem_alloc = static_cast<u32_le>(memory_regions[2].size);

View File

@@ -162,7 +162,6 @@ void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
VAddr Process::GetLinearHeapAreaAddress() const {
// Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of
// the extra RAM in the n3DS.
return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR;
}

View File

@@ -255,9 +255,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
/// Attempts to locks a mutex, creating it if it does not already exist
static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
Handle requesting_thread_handle) {
LOG_TRACE(Kernel_SVC,
"called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
"requesting_current_thread_handle=0x%08X",
LOG_TRACE(Kernel_SVC, "called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
"requesting_current_thread_handle=0x%08X",
holding_thread_handle, mutex_addr, requesting_thread_handle);
SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle);
@@ -547,9 +546,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
Core::System::GetInstance().PrepareReschedule();
LOG_TRACE(Kernel_SVC,
"called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
"threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
"threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X",
entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle);
return RESULT_SUCCESS;

View File

@@ -18,9 +18,9 @@ namespace HID {
// Updating period for each HID device.
// TODO(shinyquagsire23): These need better values.
constexpr u64 pad_update_ticks = BASE_CLOCK_RATE / 234;
constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE / 104;
constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE / 101;
constexpr u64 pad_update_ticks = BASE_CLOCK_RATE / 10000;
constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE / 10000;
constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE / 10000;
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
@@ -65,44 +65,71 @@ private:
if (is_device_reload_pending.exchange(false))
LoadInputDevices();
// TODO(shinyquagsire23): This is a hack!
ControllerPadState& state =
mem->controllers[Controller_Handheld].layouts[Layout_Default].entries[0].buttons;
using namespace Settings::NativeButton;
state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
// Set up controllers as neon red+blue Joy-Con attached to console
ControllerHeader& controller_header = mem->controllers[Controller_Handheld].header;
controller_header.type = ControllerType_Handheld | ControllerType_JoyconPair;
controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent;
controller_header.right_color_body = JOYCON_BODY_NEON_RED;
controller_header.right_color_buttons = JOYCON_BUTTONS_NEON_RED;
controller_header.left_color_body = JOYCON_BODY_NEON_BLUE;
controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE;
state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
for (int layoutIdx = 0; layoutIdx < HID_NUM_LAYOUTS; layoutIdx++) {
ControllerLayout& layout = mem->controllers[Controller_Handheld].layouts[layoutIdx];
layout.header.num_entries = HID_NUM_ENTRIES;
layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
// HID shared memory stores the state of the past 17 samples in a circlular buffer,
// each with a timestamp in number of samples since boot.
layout.header.timestamp_ticks = CoreTiming::GetTicks();
layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES;
state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
ControllerInputEntry& entry = layout.entries[layout.header.latest_entry];
entry.connection_state = ConnectionState_Connected | ConnectionState_Wired;
entry.timestamp++;
entry.timestamp_2++; // TODO(shinyquagsire23): Is this always identical to timestamp?
state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
// TODO(shinyquagsire23): Set up some LUTs for each layout mapping in the future?
// For now everything is just the default handheld layout, but split Joy-Con will
// rotate the face buttons and directions for certain layouts.
ControllerPadState& state = entry.buttons;
using namespace Settings::NativeButton;
state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
// TODO(shinyquagsire23): Analog stick vals
state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
// TODO(shinyquagsire23): Update pad info proper, (circular buffers, timestamps, layouts)
state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
// TODO(shinyquagsire23): Analog stick vals
// TODO(shinyquagsire23): Update pad info proper, (circular buffers, timestamps,
// layouts)
}
// TODO(shinyquagsire23): Update touch info

View File

@@ -12,6 +12,16 @@ namespace HID {
// Begin enums and output structs
constexpr u32 HID_NUM_ENTRIES = 17;
constexpr u32 HID_NUM_LAYOUTS = 7;
constexpr s32 HID_JOYSTICK_MAX = 0x8000;
constexpr s32 HID_JOYSTICK_MIN = -0x8000;
constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6;
constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E;
enum ControllerType : u32 {
ControllerType_ProController = 1 << 0,
ControllerType_Handheld = 1 << 1,
@@ -57,10 +67,10 @@ enum ControllerID {
// Begin TouchScreen
struct TouchScreenHeader {
u64 timestampTicks;
u64 numEntries;
u64 latestEntry;
u64 maxEntryIndex;
u64 timestamp_ticks;
u64 num_entries;
u64 latest_entry;
u64 max_entry_index;
u64 timestamp;
};
static_assert(sizeof(TouchScreenHeader) == 0x28,
@@ -68,7 +78,7 @@ static_assert(sizeof(TouchScreenHeader) == 0x28,
struct TouchScreenEntryHeader {
u64 timestamp;
u64 numTouches;
u64 num_touches;
};
static_assert(sizeof(TouchScreenEntryHeader) == 0x10,
"HID touch screen entry header structure has incorrect size");
@@ -76,11 +86,11 @@ static_assert(sizeof(TouchScreenEntryHeader) == 0x10,
struct TouchScreenEntryTouch {
u64 timestamp;
u32 padding;
u32 touchIndex;
u32 touch_index;
u32 x;
u32 y;
u32 diameterX;
u32 diameterY;
u32 diameter_x;
u32 diameter_y;
u32 angle;
u32 padding_2;
};
@@ -107,10 +117,10 @@ static_assert(sizeof(TouchScreen) == 0x3000, "HID touch screen structure has inc
// Begin Mouse
struct MouseHeader {
u64 timestampTicks;
u64 numEntries;
u64 latestEntry;
u64 maxEntryIndex;
u64 timestamp_ticks;
u64 num_entries;
u64 latest_entry;
u64 max_entry_index;
};
static_assert(sizeof(MouseHeader) == 0x20, "HID mouse header structure has incorrect size");
@@ -132,10 +142,10 @@ struct MouseEntry {
u64 timestamp_2;
u32 x;
u32 y;
u32 velocityX;
u32 velocityY;
u32 scrollVelocityX;
u32 scrollVelocityY;
u32 velocity_x;
u32 velocity_y;
u32 scroll_velocity_x;
u32 scroll_velocity_y;
MouseButtonState buttons;
};
static_assert(sizeof(MouseEntry) == 0x30, "HID mouse entry structure has incorrect size");
@@ -152,10 +162,10 @@ static_assert(sizeof(Mouse) == 0x400, "HID mouse structure has incorrect size");
// Begin Keyboard
struct KeyboardHeader {
u64 timestampTicks;
u64 numEntries;
u64 latestEntry;
u64 maxEntryIndex;
u64 timestamp_ticks;
u64 num_entries;
u64 latest_entry;
u64 max_entry_index;
};
static_assert(sizeof(KeyboardHeader) == 0x20, "HID keyboard header structure has incorrect size");
@@ -207,24 +217,24 @@ static_assert(sizeof(ControllerMAC) == 0x20, "HID controller MAC structure has i
struct ControllerHeader {
u32 type;
u32 isHalf;
u32 singleColorsDescriptor;
u32 singleColorBody;
u32 singleColorButtons;
u32 splitColorsDescriptor;
u32 leftColorBody;
u32 leftColorButtons;
u32 rightColorBody;
u32 rightColorbuttons;
u32 is_half;
u32 single_colors_descriptor;
u32 single_color_body;
u32 single_color_buttons;
u32 split_colors_descriptor;
u32 left_color_body;
u32 left_color_buttons;
u32 right_color_body;
u32 right_color_buttons;
};
static_assert(sizeof(ControllerHeader) == 0x28,
"HID controller header structure has incorrect size");
struct ControllerLayoutHeader {
u64 timestampTicks;
u64 numEntries;
u64 latestEntry;
u64 maxEntryIndex;
u64 timestamp_ticks;
u64 num_entries;
u64 latest_entry;
u64 max_entry_index;
};
static_assert(sizeof(ControllerLayoutHeader) == 0x20,
"HID controller layout header structure has incorrect size");
@@ -274,11 +284,11 @@ struct ControllerInputEntry {
u64 timestamp;
u64 timestamp_2;
ControllerPadState buttons;
u32 joystickLeftX;
u32 joystickLeftY;
u32 joystickRightX;
u32 joystickRightY;
u64 connectionState;
u32 joystick_left_x;
u32 joystick_left_y;
u32 joystick_right_x;
u32 joystick_right_y;
u64 connection_state;
};
static_assert(sizeof(ControllerInputEntry) == 0x30,
"HID controller input entry structure has incorrect size");
@@ -294,8 +304,8 @@ struct Controller {
ControllerHeader header;
std::array<ControllerLayout, 7> layouts;
std::array<u8, 0x2a70> unk_1;
ControllerMAC macLeft;
ControllerMAC macRight;
ControllerMAC mac_left;
ControllerMAC mac_right;
std::array<u8, 0xdf8> unk_2;
};
static_assert(sizeof(Controller) == 0x5000, "HID controller structure has incorrect size");
@@ -307,17 +317,17 @@ struct SharedMemory {
TouchScreen touchscreen;
Mouse mouse;
Keyboard keyboard;
std::array<u8, 0x400> unkSection1;
std::array<u8, 0x400> unkSection2;
std::array<u8, 0x400> unkSection3;
std::array<u8, 0x400> unkSection4;
std::array<u8, 0x200> unkSection5;
std::array<u8, 0x200> unkSection6;
std::array<u8, 0x200> unkSection7;
std::array<u8, 0x800> unkSection8;
std::array<u8, 0x4000> controllerSerials;
std::array<u8, 0x400> unk_section_1;
std::array<u8, 0x400> unk_section_2;
std::array<u8, 0x400> unk_section_3;
std::array<u8, 0x400> unk_section_4;
std::array<u8, 0x200> unk_section_5;
std::array<u8, 0x200> unk_section_6;
std::array<u8, 0x200> unk_section_7;
std::array<u8, 0x800> unk_section_8;
std::array<u8, 0x4000> controller_serials;
std::array<Controller, 10> controllers;
std::array<u8, 0x4600> unkSection9;
std::array<u8, 0x4600> unk_section_9;
};
static_assert(sizeof(SharedMemory) == 0x40000, "HID Shared Memory structure has incorrect size");

View File

@@ -48,6 +48,18 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
rb.Push(nv_result);
}
void NVDRV::Close(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestParser rp{ctx};
u32 fd = rp.Pop<u32>();
auto result = nvdrv->Close(fd);
IPC::RequestBuilder rb{ctx, 2};
rb.Push(result);
}
void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestBuilder rb{ctx, 3};
@@ -60,6 +72,7 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
static const FunctionInfo functions[] = {
{0, &NVDRV::Open, "Open"},
{1, &NVDRV::Ioctl, "Ioctl"},
{2, &NVDRV::Close, "Close"},
{3, &NVDRV::Initialize, "Initialize"},
};
RegisterHandlers(functions);

View File

@@ -20,6 +20,7 @@ public:
private:
void Open(Kernel::HLERequestContext& ctx);
void Ioctl(Kernel::HLERequestContext& ctx);
void Close(Kernel::HLERequestContext& ctx);
void Initialize(Kernel::HLERequestContext& ctx);
std::shared_ptr<Module> nvdrv;

View File

@@ -49,5 +49,15 @@ u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector
return device->ioctl(command, input, output);
}
ResultCode Module::Close(u32 fd) {
auto itr = open_files.find(fd);
ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device");
open_files.erase(itr);
// TODO(flerovium): return correct result code if operation failed.
return RESULT_SUCCESS;
}
} // namespace Nvidia
} // namespace Service

View File

@@ -35,6 +35,8 @@ public:
u32 Open(std::string device_name);
/// Sends an ioctl command to the specified file descriptor.
u32 Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output);
/// Closes a device file descriptor and returns operation success.
ResultCode Close(u32 fd);
private:
/// Id to use for the next open file descriptor.

View File

@@ -21,7 +21,6 @@
namespace Memory {
static std::array<u8, Memory::VRAM_SIZE> vram;
static std::array<u8, Memory::N3DS_EXTRA_RAM_SIZE> n3ds_extra_ram;
static PageTable* current_page_table = nullptr;
@@ -283,8 +282,7 @@ u8* GetPhysicalPointer(PAddr address) {
{VRAM_PADDR, VRAM_SIZE},
{IO_AREA_PADDR, IO_AREA_SIZE},
{DSP_RAM_PADDR, DSP_RAM_SIZE},
{FCRAM_PADDR, FCRAM_N3DS_SIZE},
{N3DS_EXTRA_RAM_PADDR, N3DS_EXTRA_RAM_SIZE},
{FCRAM_PADDR, FCRAM_SIZE},
};
const auto area =
@@ -322,9 +320,6 @@ u8* GetPhysicalPointer(PAddr address) {
}
ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address");
break;
case N3DS_EXTRA_RAM_PADDR:
target_pointer = n3ds_extra_ram.data() + offset_into_region;
break;
default:
UNREACHABLE();
}
@@ -740,8 +735,6 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) {
return addr - DSP_RAM_VADDR + DSP_RAM_PADDR;
} else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) {
return addr - IO_AREA_VADDR + IO_AREA_PADDR;
} else if (addr >= N3DS_EXTRA_RAM_VADDR && addr < N3DS_EXTRA_RAM_VADDR_END) {
return addr - N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_PADDR;
}
return boost::none;
@@ -768,8 +761,6 @@ boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) {
return addr - DSP_RAM_PADDR + DSP_RAM_VADDR;
} else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) {
return addr - IO_AREA_PADDR + IO_AREA_VADDR;
} else if (addr >= N3DS_EXTRA_RAM_PADDR && addr < N3DS_EXTRA_RAM_PADDR_END) {
return addr - N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_VADDR;
}
return boost::none;

View File

@@ -98,12 +98,6 @@ enum : PAddr {
VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
/// New 3DS additional memory. Supposedly faster than regular FCRAM. Part of it can be used by
/// applications and system modules if mapped via the ExHeader.
N3DS_EXTRA_RAM_PADDR = 0x1F000000,
N3DS_EXTRA_RAM_SIZE = 0x00400000, ///< New 3DS additional memory size (4MB)
N3DS_EXTRA_RAM_PADDR_END = N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_SIZE,
/// DSP memory
DSP_RAM_PADDR = 0x1FF00000,
DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
@@ -116,10 +110,8 @@ enum : PAddr {
/// Main FCRAM
FCRAM_PADDR = 0x20000000,
FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
FCRAM_SIZE = 0x08000000, ///< FCRAM size on the (128MB)
FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
FCRAM_N3DS_PADDR_END = FCRAM_PADDR + FCRAM_N3DS_SIZE,
};
/// Virtual user-space memory regions
@@ -150,10 +142,6 @@ enum : VAddr {
LINEAR_HEAP_SIZE = 0x08000000,
LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
/// Maps 1:1 to New 3DS additional memory
N3DS_EXTRA_RAM_VADDR = 0x1E800000,
N3DS_EXTRA_RAM_VADDR_END = N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_SIZE,
/// Maps 1:1 to the IO register area.
IO_AREA_VADDR = 0x1EC00000,
IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,

View File

@@ -124,8 +124,8 @@ custom_bottom_top =
custom_bottom_right =
custom_bottom_bottom =
#Whether to toggle frame limiter on or off.
# 0: Off , 1 (default): On
# Whether to toggle frame limiter on or off.
# 0: Off, 1 (default): On
toggle_framelimit =
# Swaps the prominent screen with the other screen.