Compare commits

...

189 Commits

Author SHA1 Message Date
N00byKing
afa1ed6ad9 Correct Spelling 2018-01-23 14:20:18 +01:00
bunnei
d1b64cdc07 Merge pull request #135 from Subv/no_ports
IPC: Don't create unnecessary ports when returning sub interfaces.
2018-01-22 21:37:15 -05:00
Subv
b0489c9a64 Services: Added a todo about returning interfaces as domain objects in lm, hid and time. 2018-01-22 20:40:43 -05:00
bunnei
d8bd70d396 Merge pull request #133 from Subv/nvflinger2
AppletOE: Stubbed CreateManagedDisplayLayer to create a new layer in the default display.
2018-01-22 17:52:47 -05:00
Subv
7efa6e8801 Time: Don't create unnecessary ports when retrieving the clock service sessions. 2018-01-22 17:42:11 -05:00
Subv
1003996e80 HID: Don't create an unnecessary port in CreateAppletResource. 2018-01-22 17:41:31 -05:00
Subv
1a9c96e4de LM: Don't create an unnecessary port in Initialize. 2018-01-22 17:35:40 -05:00
Subv
67c43e9200 IPC: Don't create an unnecessary port when using PushIpcInterface outside of a domain. 2018-01-22 17:31:23 -05:00
bunnei
de2e5a0855 Merge pull request #134 from gdkchan/audout_hid_fix
Stub OpenAudioOut and fix a issue with HID IAppletResource
2018-01-22 17:09:09 -05:00
gdkchan
832009bfdb Stub OpenAudioOut and fix a issue with HID IAppletResource being created more than once 2018-01-22 17:27:55 -03:00
Subv
10c67bf395 AppletOE: Stubbed CreateManagedDisplayLayer to create a new layer in the Default display.
This function is used by libnx to obtain a new layer.
2018-01-22 13:50:22 -05:00
Subv
eb58f852f8 AppletOE: Make ISelfController keep a reference to nvflinger.
It'll be needed when we implement CreateManagedDisplayLayer.
2018-01-22 13:46:36 -05:00
Subv
42859461f3 Services: Vi shouldn't be responsible for creating nvflinger.
It is now created during Service initialization and passed to all the services that need it.
2018-01-22 13:40:02 -05:00
bunnei
7f19a7d305 Merge pull request #132 from Subv/nvflinger
VI: Move BufferQueue and NVFlinger to their own folder/namespace.
2018-01-22 13:22:20 -05:00
Subv
8d7686ff8e VI: Move BufferQueue and NVFlinger to their own folder/namespace. 2018-01-22 11:54:58 -05:00
st4rk
07355cf7cc Added stubs for audio services. (#116)
* stubs for audout:u, audin:u, audrec:u, audren:u, codecctl and decoding tables with nullptr for future implementations

* fixing the changes requested (remove private, explicit)
2018-01-21 22:03:36 -05:00
bunnei
fdbb039427 Merge pull request #131 from lioncash/enum
nvmap: Make IoctlCommands an enum class
2018-01-21 22:01:27 -05:00
bunnei
32d91fa6d2 Merge pull request #130 from MerryMage/dynarmic
externals: Update dynarmic
2018-01-21 18:08:18 -05:00
David
eeb3b5eed7 Added nvmemp, Added /dev/nvhost-ctrl, SetClientPID now stores pid (#114)
* Added nvmemp, Added /dev/nvhost-ctrl, SetClientPID now stores pid

* used clang-format-3.9 instead

* lowercase pid

* Moved nvmemp handlers to cpp

* Removed unnecessary logging for NvOsGetConfigU32. Cleaned up log and changed to LOG_DEBUG

* using std::arrays instead of c arrays

* nvhost get config now uses std::array completely

* added pid logging back

* updated cmakelist

* missing includes

* added array, removed memcpy

* clang-format6.0
2018-01-21 17:59:50 -05:00
bunnei
2403143ff1 Merge pull request #128 from Subv/parcel_query
VI: Implement the Query transaction of IHOSBinderDriver, and stubbed some results.
2018-01-21 17:56:06 -05:00
Lioncash
06d2e1bd23 nvmap: Add a return 0 underneath the UNIMPLEMENTED macro
This macro resolves to an empty macro in release builds.
2018-01-21 17:07:47 -05:00
Lioncash
687a17acae nvmap: Make IoctlCommands an enum class
Prevents the enum values from polluting the surrounding scope
2018-01-21 17:07:13 -05:00
MerryMage
e7cb20fbf0 externals: Update dynarmic
a6d17e A64: Implement AND (vector)
963453 tests/A64: Randomize vectors
adcd34 tests/A64/unicorn: Print interrupt number when InterruptHook is hit
304c91 tests/A64: Allow RunTestInstance to start from an arbitrary offset
d333b5 A64: Implement ADD (vector, vector)
1cf87a A64: Implement REV, REV32, and REV16 (#126)
9fc157 IR: Simplify types. F32 -> U32, F64 -> U64, F128 -> U128
50c181 reg_alloc: GetBitWidth: Add UNREACHABLE
adccbf reg_alloc: Consider bitwidth of data and registers when emitting instructions
7b7f23 A64: Implement CSEL
2f8413 IR: Implement Conditional Select
ebb3e8 A64/tests: Split unicorn sanity checking from other tests
5740a0 tests/A64: Single random instruction: Test branch instructions as well
0892b4 A64/translate/branch: bug: Read-after-write error in BLR
e77bc2 A64: Implement SBFM, BFM, UBFM
0c37ca A64: Implement MOVN, MOVZ, MOVK
b6bb59 travis: Print current test information
e77207 fuzz_thumb: Off by one error
a04ca2 ir/location_descriptor: Add missing <functional> header for std::hash
1e0f5c travis: Run A64 tests
2018-01-21 22:05:43 +00:00
bunnei
ab8525705b Merge pull request #123 from bunnei/fs
Initial implementation of RomFS filesystem and fsp-srv
2018-01-21 16:15:15 -05:00
bunnei
5035d18baa file_sys: Clang format fixes. 2018-01-21 15:51:45 -05:00
bunnei
8e50d6002b fsp_srv: Various improvements to IStorage:Read implementation. 2018-01-21 15:51:43 -05:00
bunnei
d9a91d7678 deconstructed_rom_directory: Implement istorage loading for RomFS. 2018-01-21 15:39:31 -05:00
David Marcec
d64b7d7dfd filesystem: Implement basic IStorage functionality. 2018-01-21 15:39:28 -05:00
bunnei
00851a5ef4 file_sys: Cleanup to better match Switch file system constructs.
file_sys: Add factory class for RomFS file system.
2018-01-21 15:39:26 -05:00
bunnei
1c06c918af file_sys: Remove disk_archive, savedata_archive, and title_metadata. 2018-01-21 15:39:23 -05:00
bunnei
7988f02489 archive_backend: Minor changes to match Switch IFileSystem. 2018-01-21 15:39:20 -05:00
bunnei
2f71a32363 file_sys: Repurpose 3DS IVFC code for Switch ROMFS. 2018-01-21 15:39:18 -05:00
bunnei
4c07dde472 Merge pull request #129 from Rozelette/master
gdbstub: Update registers and sizes for aarch64
2018-01-21 15:32:15 -05:00
bunnei
ee024eb0a2 Merge pull request #124 from akkatracker/patch-1
Fix minor spelling error in CMakeLists
2018-01-21 13:06:37 -05:00
bunnei
1bcc233245 Merge pull request #125 from MerryMage/bundled-unicorn
Unicorn build fixups
2018-01-21 13:05:32 -05:00
Rozlette
425a78ec1b gdbstub: Update registers and sizes for aarch64
This gets gdbstub working at least to the point where clients can
communicate with it.

What works:
- Reading/writing GPRegs
- Reading/writing memory
- Interrupting the emulated program and continuing

What does NOT work:
- Breakpoints. Sizes have been updated to u64, but support will need to be
  added in the interpreter for them to work.
- VRegs. Mostly because my gdb was having issues with 128-bit regs for
  some reason. However, the current u128 representation is a bit
  awkward to use and should probably be updated first.
2018-01-21 11:12:49 -06:00
Subv
749043c809 VI: Implement the Query transaction of IHOSBinderDriver, and stubbed some results. 2018-01-21 11:13:47 -05:00
MerryMage
add8d40f3f CMakeLists: Fix unicorn build for macOS developers with x86_64-only systems
Some of us do not have any i386 libraries required to build x86-32 universal libraries.
2018-01-21 13:59:43 +00:00
MerryMage
bba785d643 CMakeLists: Do not look for system Unicorn by default
Since we use a custom build of unicorn it doesn't make much sense to look for
the system version, unless the user explicitly wants to override this.
2018-01-21 13:58:39 +00:00
Matthew Brener
af871f8966 Fix spelling error in CMakeLists
Minor spelling error of its --> it's
2018-01-21 17:40:47 +11:00
bunnei
d904b0db58 Merge pull request #72 from N00byKing/patch-2
Implement Pull #3275 from citra: core: Don't Shutdown before we've even Init-ed
2018-01-20 23:11:10 -05:00
bunnei
defaaf4519 Merge pull request #92 from gdkchan/nro_refactor
Fix NRO entry point
2018-01-20 23:10:15 -05:00
bunnei
602cd3886d Merge pull request #122 from tgsm/time-remove-pragma
service/time: remove accidental #pragmas
2018-01-20 22:27:10 -05:00
bunnei
9d6339b887 Merge pull request #121 from Rozelette/master
loader: Minor style fix in deconstructed_rom_directory
2018-01-20 22:14:43 -05:00
tgsm
07cfab72e0 service/time: remove accidental #pragmas 2018-01-20 21:34:37 -05:00
Rozlette
3315af8f09 loader: Minor style fix in deconstructed_rom_directory 2018-01-20 20:13:53 -06:00
bunnei
557b2496d7 Merge pull request #117 from jroweboy/clang-format
Clang format as a build target
2018-01-20 19:12:21 -05:00
James Rowe
96f446ff65 Travis: Add missing PPA for newer libstdc++ 2018-01-20 16:45:11 -07:00
James Rowe
425b3923d2 Travis: Update clang-format to 6.0 2018-01-20 16:45:11 -07:00
James Rowe
096be16636 Format: Run the new clang format on everything 2018-01-20 16:45:11 -07:00
James Rowe
1e662e6e9a CMake: Conditionally turn on bundled libs for MSVC
Removes the annoying step when generating sln for MSVC where you have to
click an extra checkbox after the first generate fails by using a
conditional option. The USE_BUNDLED options will be off by default, but
if the enable_lib option is enabled and the toolset is msvc, they are
turned ON.
2018-01-20 16:44:48 -07:00
James Rowe
1a4e429d9e CMake: Update contributing guide with the new clang format info 2018-01-20 16:44:23 -07:00
James Rowe
c3e22a2f6c CMake: Add a custom clang format target
Checks to see if clang-format can be found, and if it is, sets up a
custom target that will run against the src dir and auto formats all
files. In MSVC, this is a project, and in Makefiles, its a make target
2018-01-20 15:45:59 -07:00
bunnei
6cccbf0eb3 Merge pull request #120 from Rozelette/master
memory: Return false for large VAddr in IsValidVirtualAddress
2018-01-20 17:37:55 -05:00
bunnei
ff883cc563 Merge pull request #119 from bunnei/desconstucted-loader
Separate NSO loading from DesconstuctedRomLoader
2018-01-20 16:26:20 -05:00
Rozlette
de7aa3106a memory: Return false for large VAddr in IsValidVirtualAddress 2018-01-20 14:56:15 -06:00
bunnei
386df282a3 loader: Clean up ctors and includes. 2018-01-20 15:54:17 -05:00
bunnei
e75aba3ed0 loader: Add DeconstructedRomDirectory for game dumps. 2018-01-20 15:54:15 -05:00
bunnei
023aef053c loader: Refactor to also pass filepath into IdentifyType. 2018-01-20 14:59:44 -05:00
bunnei
2dafd0d287 nso: Remove code specific to directory loading. 2018-01-20 14:59:42 -05:00
River City Ransomware
c8a094e164 Port citra #3352 to yuzu (#103)
* Port citra #3352 to yuzu

This change allows non x86_64 architectures to compile yuzu by skipping the building of dynarmic

* Fixed clang-format errors

* fixes more clang-format errors
2018-01-19 19:36:09 -05:00
David
0b6da0c1ab Added CreateSharedMemory & UNIMPLEMENTED() for non existent services. (#113)
* Added svcCreateSharedMemory

* Services which are not implemented now throw UNIMPLEMENTED()

* clang-format

* changed perms to u32

* removed camelcase
2018-01-19 19:35:25 -05:00
River City Ransomware
dd62f125c3 Fixes some cast warnings, partial port of citra #3064 (#106)
* Fixes some cast warnings, partially fixes citra #3064

* Converted casts to uint32_t to u32

* Ran clang-format
2018-01-19 18:01:41 -05:00
bunnei
7b219539a9 Merge pull request #112 from Rozelette/master
ISelfController: Stub LockExit and UnlockExit
2018-01-19 17:54:05 -05:00
goaaats
c457f34eb2 acc, set, applet_oe: stub various functions, add set service (#105)
* Stubs for various acc:u0 funcs needed

* Stub for GetDesiredLanguage in IApplicationFunctions

* Add set service + stubs needed for games

* Fix formatting

* Implement IProfile, IManagerForApplication, return bool in CheckAvailability, style fixes

* Remove IProfile::Get(needs more research), fix IPC response sizes
2018-01-19 15:44:58 -05:00
Rozlette
d9ca9d3472 ISelfController: Stub LockExit and UnlockExit 2018-01-19 14:09:50 -06:00
bunnei
0f363d37e6 Merge pull request #109 from bunnei/libnx-fixes
Fix svcGetInfo for libnx
2018-01-19 14:48:08 -05:00
bunnei
c3005ee4d1 Merge pull request #97 from bunnei/time-stub
time: Stub out GetTotalLocationNameCount and some cleanup.
2018-01-19 14:47:50 -05:00
bunnei
deec326ddf time: Add new line to ends of files. 2018-01-19 00:39:04 -05:00
bunnei
1d49680613 applet_oe: Clang-format. 2018-01-19 00:37:36 -05:00
bunnei
e27accc15d time: Stub out GetTotalLocationNameCount and some cleanup. 2018-01-19 00:32:52 -05:00
bunnei
de646cef2d nvdrv: Stub SetClientPID. 2018-01-18 23:50:18 -05:00
bunnei
e1ee8f4657 svc: Fix svcGetInfo MapRegionBaseAddr. 2018-01-18 23:44:15 -05:00
bunnei
d80991977a svc: Add additional fields to MemoryInfo struct. 2018-01-18 23:37:54 -05:00
bunnei
c85d04ebe1 Merge pull request #108 from gdkchan/dispdrv
Fix dispdrv typo
2018-01-18 23:20:29 -05:00
gdkchan
8f13499bb8 Fix dispdrv typo 2018-01-18 23:21:26 -03:00
bunnei
952dba9c2b Merge pull request #100 from Rozelette/master
time: Refactor time:* to use a single shared module
2018-01-18 21:10:55 -05:00
bunnei
1a5098e8b8 Merge pull request #104 from RiverCityRansomware/resizedConfigWindow
Port citra #3336
2018-01-18 21:08:54 -05:00
bunnei
6b4f37b544 Merge pull request #107 from lioncash/qt
qt: Migrate to Qt 5 signal/slot connection syntax where applicable
2018-01-18 21:07:17 -05:00
Lioncash
5e46a9bb2b qt: Migrate to Qt 5 signal/slot connection syntax where applicable 2018-01-18 20:09:40 -05:00
Evgeni Danailov
cb3ab6ec77 ui: Rename almost all classes in configuration_input.ui (#99)
* Rename verticalLayout_25 to verticalLayout_23.

* Rename almost all classes.
2018-01-18 15:28:18 -05:00
River City Ransomware
da3e13fea5 Port citra #3336 - Resizes the configuration window to not be so stretched out 2018-01-18 15:22:28 -05:00
gdkchan
3a409d5c8f Fix NRO Entry Point 2018-01-18 17:18:43 -03:00
bunnei
0e7749a500 Merge pull request #101 from jroweboy/add-missing-dlls
Build: Add missing dlls to msvc release
2018-01-18 15:03:47 -05:00
gdkchan
59575d5cae Stub PopLaunchParameter and implement Buffer C Descriptors reading on hle_ipc (#96)
* Stub PopLaunchParameter and implement Buffer C Descriptors reading

* Address PR feedback

* Ensure we push a u64 not a size_t

* Fix formatting
2018-01-18 14:54:34 -05:00
flerovium^-^
463356f0a7 Start to implement/stub BSD:U and SFDNSRES services (#78)
* bsd: start stubbing bsd:u and sfdnsres

* bsd: stubbed RegisterClient

* bsd: attempt to get past socket()

* bsd: fix some wrong assumptions about IPC

* bsd: fix format specifiers

* bsd: stubbed Connect()

* bsd: stubbed SendTo()

* made requested changes

* sockets: respect alphabetical order at service installation

* run clang-format

* bsd: start stubbing bsd:u and sfdnsres

* bsd: stubbed RegisterClient

* bsd: attempt to get past socket()

* bsd: fix some wrong assumptions about IPC

* bsd: fix format specifiers

* bsd: stubbed Connect()

* bsd: stubbed SendTo()

* made requested changes

* sockets: respect alphabetical order at service installation

* run clang-format

* run clang-format (2)
2018-01-18 14:35:03 -05:00
James Rowe
195b4b5129 Build: Add missing dlls to msvc release 2018-01-18 10:25:37 -07:00
Rozlette
378cea2ae2 time: Fix use of CamelCase in ToCalendarTimeWithMyRule 2018-01-18 11:02:05 -06:00
Rozlette
c7c180fdf1 time: Refactor time:* to use a single shared module 2018-01-18 10:58:29 -06:00
bunnei
2ff1cebfbe Merge pull request #98 from lioncash/xcode
travis: Use Xcode 9.2
2018-01-18 11:25:11 -05:00
bunnei
b5bc94bce0 Merge pull request #95 from bunnei/lm-skip-byte
lm: Minor logging fix to skip a byte.
2018-01-18 10:57:41 -05:00
Lioncash
da21545a77 travis: Use Xcode 9.2
Uses the latest available Xcode version. This allows the use of more
C++17 facilities without the CI failing.
2018-01-18 07:46:52 -05:00
bunnei
be0e14ab3e Merge pull request #84 from lioncash/cmake
CMakeLists: Derive the source directory grouping from targets themselves
2018-01-18 01:37:17 -05:00
bunnei
4ca5f0c145 Merge pull request #91 from lioncash/svc
svc: Minor clarity changes
2018-01-18 00:27:41 -05:00
bunnei
22465c8722 lm: Minor logging fix to skip a byte. 2018-01-18 00:08:38 -05:00
bunnei
ed788742bf Merge pull request #90 from lioncash/vi-override
vi: Minor clean up/correctness changes
2018-01-17 23:55:07 -05:00
bunnei
cf0daed0b8 Merge pull request #89 from lioncash/vi-vector
vi: Copy data directly into the std::vector within Parcel's ReadBlock function
2018-01-17 23:52:40 -05:00
bunnei
32eb620ef4 Merge pull request #88 from lioncash/include
hotkeys: Add missing <QTreeWidgetItem> include
2018-01-17 23:04:44 -05:00
bunnei
01b3bf119e Merge pull request #87 from lioncash/override
game_list: Add missing override specifier for KeyReleaseEater's eventFilter function
2018-01-17 22:44:03 -05:00
Flame Sage
3ebe56524c Merge pull request #93 from jroweboy/deploy-key
Build: Update deploy keys
2018-01-17 22:43:17 -05:00
James Rowe
138c03d565 Build: Update deploy keys 2018-01-17 20:40:12 -07:00
bunnei
5d38bb36c3 Merge pull request #86 from lioncash/doxygen
game_list: Amend doxygen parameter identifiers
2018-01-17 22:20:50 -05:00
bunnei
36dc44fb22 Merge pull request #85 from lioncash/warn
telemetry: Silence initialization order warnings
2018-01-17 21:59:20 -05:00
Lioncash
e710a1b989 CMakeLists: Derive the source directory grouping from targets themselves
Removes the need to store to separate SRC and HEADER variables, and then
construct the target in most cases.
2018-01-17 21:51:43 -05:00
bunnei
6a36ffb86c controller: Use DuplicateSession for DuplicateSessionEx. 2018-01-17 21:48:17 -05:00
bunnei
18507b09b2 Merge pull request #83 from lioncash/pessimizing-move
input_common/sdl: Silence a -Wpessimizing-move warning
2018-01-17 21:08:01 -05:00
bunnei
73c0ef7453 Merge pull request #82 from lioncash/catch
externals: Update catch to 2.1.0
2018-01-17 20:49:18 -05:00
Lioncash
4497eb4528 svc: Rename some entries to match their analogue on SwitchBrew
Makes the codebase a little more consistent with regards to available documentation. Also amends the duplicate case where there was a similar entry at 0x72 named ConnectToPort.
2018-01-17 20:38:23 -05:00
Lioncash
c81ed5eb33 svc: Add CreateJitMemory and MapJitMemory svc strings
Makes the table match SwitchBrew for these entries
2018-01-17 20:32:56 -05:00
bunnei
62a8c61e36 Merge pull request #81 from lioncash/qt-bootmgr
bootmanager: Minor tidiness/correctness changes
2018-01-17 20:24:56 -05:00
Lioncash
3d19102c48 vi: Make constructors explicit where applicable
Prevents implicit conversions.
2018-01-17 20:21:16 -05:00
Lioncash
14069e6ec4 vi: Add missing override specifiers 2018-01-17 20:16:48 -05:00
Lioncash
b16c89bf65 vi: Copy data directly into the std::vector within Parcel's ReadBlock function
Previously this would unnecessarily zero-initialize the vector before
copying the actual data into the vector instance.
2018-01-17 20:09:41 -05:00
bunnei
01f379baa7 Merge pull request #80 from gdkchan/nro_fix
Fix NRO loading
2018-01-17 20:05:21 -05:00
Lioncash
501d1cc33d hotkeys: Add missing <QTreeWidgetItem> include 2018-01-17 20:00:25 -05:00
Lioncash
94a6515b71 game_list: Add missing override specifier for KeyReleaseEater's eventFilter function 2018-01-17 19:54:06 -05:00
Lioncash
15318b6601 game_list: Amend doxygen parameter identifiers for containsAllWords() 2018-01-17 19:52:15 -05:00
Lioncash
33eba9b96e telemetry: Silence initialization order warnings 2018-01-17 19:43:24 -05:00
Lioncash
ed296e47f1 input_common/sdl: Silence a -Wpessimizing-move warning 2018-01-17 18:44:16 -05:00
Lioncash
2b3ee30a46 externals: Update catch to 2.1.0 2018-01-17 18:40:08 -05:00
Lioncash
e50188374f bootmanager: Minor tidiness/correctness changes
Moved over from #3266 in citra.
2018-01-17 18:35:02 -05:00
bunnei
ee08c39b72 Merge pull request #73 from N00byKing/3093
Implement Pull #3093 from citra: Added missing headers to CMakeLists.txt and fixed includes.
2018-01-17 18:18:34 -05:00
gdkchan
d3e63e4220 Fix NRO loading 2018-01-17 20:16:09 -03:00
bunnei
e2f06dbc17 Merge pull request #76 from Rozelette/master
TIME: consolidate time:* interfaces, stub functions and structs
2018-01-17 17:32:48 -05:00
N00byKing
b17763e3d4 Implement Pull #3306 from citra: citra_qt: Drop Qt 5 version checks in code (#41)
* Update bootmanager.cpp

* This *should* fix the clang error
2018-01-17 17:19:41 -05:00
bunnei
5fcf8d530a Merge pull request #77 from gdkchan/no_relocs
Remove relocation on NSO/NRO
2018-01-17 17:17:07 -05:00
Rozlette
6f22471a72 TIME: consolidate time:* interfaces, stub functions and structs 2018-01-17 14:15:14 -06:00
gdkchan
c65ac49238 Remove relocation on NSO/NRO 2018-01-17 17:01:10 -03:00
bunnei
c7452bab90 Merge pull request #42 from N00byKing/3295
Implement Pull #3295 from citra: citra_qt: CMakeLists: Drop leftover handling code for Qt 4 UI files
2018-01-17 13:50:38 -05:00
bunnei
f2b4b668e3 Merge pull request #57 from nkatz565/fix-tr
Fix non translated string (same as Citra PR 2949)
2018-01-17 13:46:39 -05: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
N00byKing
10955d72ef Update CMakeLists.txt 2018-01-17 18:21:49 +01:00
N00byKing
66388f7576 Update title_metadata.h 2018-01-17 18:20:52 +01:00
bunnei
7fa32af1c7 svc: Clang-format fix. 2018-01-17 12:19:17 -05:00
N00byKing
30d2ba9de3 Update core.cpp 2018-01-17 18:12:06 +01: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
noah katz
1c98f3a9b3 Fixed formatting 2018-01-17 11:20:46 -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
James Rowe
a66eb7351b UI: Fix frame rate perf stats
Adds in a missing EndGameFrame when nvdrv swaps buffers
2018-01-16 20:44:02 -07: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
bunnei
4b156d2e64 acc_u0: Add IPC interface and stub InitializeApplicationInfo. 2018-01-16 21:34:27 -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
bunnei
8c05e935bd Merge pull request #55 from bunnei/subv-improvements
Improvements to IPC, AppletOE, APM, VI, SVC
2018-01-16 21:06:52 -05:00
bunnei
f621310da2 applet_oe: Fix GetOperationMode and GetPerformanceMode. 2018-01-16 20:32:08 -05:00
noah katz
9a9d33a741 Fix non translated string (same as Citra PR 2949) 2018-01-16 19:56:41 -05:00
Subv
cb75b56e45 NV: Implemented the nvdrv service, which uses the same interface as nvdrv:a 2018-01-16 19:04:09 -05:00
Subv
30657f9ca1 NV: Move the nvdrv classes into the Nvidia namespace, and move the functionality to a s single module that services call. 2018-01-16 19:03:49 -05:00
Subv
f827b17dd4 VI: Stubbed GetNativeHandle, Create/DestroyStrayLayer and CloseDisplay 2018-01-16 19:01:03 -05:00
Subv
c5a0408ccc Services: Stubbed APM::OpenSession and the ISession interface.
# Conflicts:
#	src/core/hle/service/am/applet_oe.cpp
#	src/core/hle/service/apm/apm.cpp
2018-01-16 19:00:32 -05:00
Subv
f7dc637a61 AppletOE: Stub a bunch of functions required by libnx homebrew. 2018-01-16 18:58:06 -05:00
Subv
bf0e20c571 SVC: Correct some return values in svcGetInfo and added TitleId and PrivilegedProcessId stubs.
# Conflicts:
#	src/core/hle/kernel/svc.cpp
2018-01-16 18:50:23 -05:00
Subv
3442f4b96a SVC: Add 4.0.0+ comment to GetInfoType enum values. 2018-01-16 18:44:39 -05:00
Subv
5bc14e791a IPC: Push domain objects as move handles when not in a domain. 2018-01-16 18:42:08 -05:00
bunnei
1aa4cdc3c8 Merge pull request #52 from ogniK5377/fsp
added more svcGetInfo pairs for 3.0.0+ support, Changed HEAP_SIZE and TLS_AREA_VADDR. changed mem usage & heap usage stub added, ISelfController, IApplication function stubs. Added SetThreadCoreMask
2018-01-16 18:27:48 -05:00
David
cb8d5328d5 Update memory.h 2018-01-16 15:27:13 -08:00
bunnei
0f6e3421c8 Merge pull request #45 from FearlessTobi/patch-1
Implement Pull #3030 from Citra: Rename derivative class name
2018-01-16 17:59:14 -05:00
bunnei
7338f089f8 Merge pull request #43 from N00byKing/3052
Implement Pull #3052 from citra: Correct spelling of searchfield in comment
2018-01-16 17:58:25 -05:00
bunnei
4dc989f073 Merge pull request #46 from FearlessTobi/patch-2
Implement Pull #3034 from Citra: Change build order to check clang-format first
2018-01-16 17:57:54 -05:00
bunnei
5f6e29831f Merge pull request #53 from nkatz565/nk-fixlabels
Implement Pull #3240 from Citra: Add button labels for sdl joystick mappings
2018-01-16 17:55:59 -05:00
bunnei
07b465d24e Merge pull request #44 from Rozelette/master
nso: Modify .bss size calculation logic
2018-01-16 17:24:49 -05:00
David Marcec
bb7221c5d5 SetThreadCoreMask stub, time to implement fsp 2018-01-16 14:23:53 -08:00
bunnei
52fe15278b Merge pull request #47 from MerryMage/build-fixes
Misc build fixes
2018-01-16 17:23:33 -05:00
David Marcec
104dd867c4 implemented more of ISelfController and IApplicationFunctions 2018-01-16 14:18:18 -08:00
David Marcec
68143af636 Added more svcGetInfo pairs 2018-01-16 14:06:45 -08:00
David Marcec
c903372111 Increased heap size and changed tls area vaddr 2018-01-16 13:53:43 -08:00
muemart
aec3b28547 Use static functions instead of lambdas 2018-01-16 16:49:48 -05:00
muemart
5d5f1dfb68 Add translation support for button labels 2018-01-16 16:49:41 -05:00
muemart
f4f64cc197 Add button labels for sdl joystick mappings 2018-01-16 16:49:29 -05:00
bunnei
f10a7081e3 Merge pull request #48 from spycrab/cmake_python
CMake: Override PYTHON environment variable for libunicorn
2018-01-16 15:20:01 -05:00
spycrab
33778e4984 CMake: Override PYTHON environment variable for libunicorn 2018-01-16 20:05:05 +01:00
MerryMage
e35644c005 clang-format 2018-01-16 18:05:21 +00:00
MerryMage
153205edbb travis: Use more recent cmake on macOS 2018-01-16 18:02:08 +00:00
Tobias
af9a4539b1 Implement Pull #3034 from Citra
Change build order to check clang-format first
2018-01-16 18:56:42 +01:00
Tobias
1de165506f Implement Pull #3030 from Citra
citra-qt: Rename derivative class name
2018-01-16 18:50:04 +01:00
Rozlette
09bcc2042c nso: Modify .bss size calculation logic 2018-01-16 11:14:36 -06:00
N00byKing
7c6c8da218 Update game_list.cpp 2018-01-16 17:55:06 +01:00
N00byKing
0a8d13801a Update CMakeLists.txt 2018-01-16 17:51:08 +01:00
shinyquagsire23
d20a883194 hid: Write to all layouts, implement circular buffers, set up controller metadata. 2018-01-16 03:14:27 -07:00
229 changed files with 4392 additions and 2679 deletions

View File

@@ -1,6 +1,18 @@
language: cpp
matrix:
include:
- os: linux
env: NAME="clang-format"
dist: trusty
addons:
apt:
sources:
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- sourceline: 'deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main'
packages:
- clang-format-6.0
script: "./.travis/clang-format/script.sh"
- os: linux
env: NAME="linux build"
sudo: required
@@ -16,23 +28,15 @@ matrix:
- os: osx
env: NAME="macos build"
sudo: false
osx_image: xcode7.3
osx_image: xcode9.2
install: "./.travis/macos/deps.sh"
script: "./.travis/macos/build.sh"
after_success: "./.travis/macos/upload.sh"
- os: linux
env: NAME="clang-format"
dist: trusty
addons:
apt:
packages:
- clang-format-3.9
script: "./.travis/clang-format/script.sh"
deploy:
provider: releases
api_key:
secure: IuTT8DjxzNgOtaEsyOpz1JaSmtDtHSsWZnJKmSBwXAzgP2ZU4Ja3/q0z5PwbC5Ql7kuFahuYTE5oi7lbJBuu2P3y1Wj2zvFozGUkA3JUvEXDNOPS9QTJ1EYd6O+wenZoj7d/Pn+ZeIgyEafnnZsGBb8lMQnV9MfIHgYlZQ5EyF3n4XikT2h1UbDBYx74ciXZIxFEulx68kDr9Q4/U+zIYQmYv2N+lgXSLDkFrCJ046gRcujPYGPqE6jVw0kKni80CTTpuDF5prU8yIBeiffjkJ3Qx1a17G07eZ4r83P4XUOlaHbRBmA/8ywZvLF2Gep3wGKfSFgMWbPxBJk5ZSYcOOAgMsEcg0+gBK9gLTwO4pbmc2GvqP21yRQBzgtbFoEtAHLu5lVPBkZU7kZuRMJtRdqvFIwOLhpnRS8IknFOD5vjtaFiNdGWaK9ePdsGvplijnXcPafkumakc4+eVEiXb6/KzdX1zXdur5tuUPFytm0Oy6IJcGIf8FHXGvUlmWsnPzwfusij9JgeQOP+uegc9PdBfL+h7L5rk+ilELt3cXD5K7wgov/4hkl5istNJ2bm0IioIstWss8QQQTkyscGoeh/oXmUpOL4FdsTvsWhDR3QKeq8nSzgDkqLe0iSbplQGnC7o7ytNbldmxJvf3nylwglA8w3HlqLHtZLkUOcuQ0=
secure: ElsIAlbvVXBNKsP31nVPysh+mf0GQA4DiL/y5iJeQxKQYR6iRoNo+RfzOBmdswdo0bE/PGeBAlfzCkp15gjhWf6Je0N6dRpczmcmLq6SSQFn1Mpq00xMJB2AgQIlaHs6KFgoUA173EBKbPwgU/NubTFpJFm/Wa+NcSWAHQXKL9KT2M3qKpxNkPl3mKEVsbch4REP+T/46vsa+ikw0VE0kIs6V93LqUQZpI2F0Dhihx8Cxr5iedkE1QsNK+QSX9iItMHbfek9OH980gP7L3lkZltyAA1Pk0c37OAgz2PwczwNKwCT8jg9PMzdcKmWouvLyAkZFuA806ElzwHY3oEd91Zm6+Bk5n24yBKZ9027AZzw38NK2Z2m9Akb8+ar8PdsKU6N5pDutX9qSLayr0oMgJ0s7/xnGBGdL3gfkPCFc50xO/2DxlsOR+zAhPNM9Y76hhGy6A7/40+9uzrJvd4nAuDvIXRzi2Yl2L7mKBE4suMKbFLtk2LlgM0qY5JMVTQ8NliaEtqopfPur2KWFVJUpWDNLtNX8xGqhfwg7cLjIiGmnxSaJBTDuZI6dpEjkWkU0n1xYhGqEqit8DbehYzazozMJ+Vsr8hku7jGlUtlw+U6HG1e19O2y4aGeSwYPROcCNz+BLwmVM8oZE3Roy3qoaa2yiFf+sy6rUHznrhsfEM=
file_glob: true
file: "artifacts/*"
skip_cleanup: true

View File

@@ -7,7 +7,7 @@ if grep -nr '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis*
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-3.9
CLANG_FORMAT=clang-format-6.0
$CLANG_FORMAT --version
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then

View File

@@ -2,3 +2,4 @@
brew update
brew install dylibbundler p7zip qt5 sdl2
brew outdated cmake || brew upgrade cmake

View File

@@ -3,14 +3,19 @@ cmake_minimum_required(VERSION 3.6)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
include(DownloadExternals)
include(CMakeDependentOption)
project(yuzu)
# Set bundled sdl2/qt as dependent options.
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
option(ENABLE_QT "Enable the Qt frontend" ON)
option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_SDL2;MSVC" OFF)
option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
message(STATUS "Copying pre-commit hook")
@@ -54,15 +59,18 @@ function(detect_architecture symbol arch)
endif()
endfunction()
if (MSVC)
detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM)
else()
detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM)
if (NOT ENABLE_GENERIC)
if (MSVC)
detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM)
else()
detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM)
endif()
endif()
if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE "GENERIC")
set(ARCHITECTURE_GENERIC 1)
@@ -203,8 +211,7 @@ else()
endif()
# If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external
find_package(Unicorn QUIET)
if (NOT UNICORN_FOUND)
if (YUZU_USE_BUNDLED_UNICORN)
if (MSVC)
message(STATUS "unicorn not found, falling back to bundled")
# Detect toolchain and platform
@@ -240,8 +247,10 @@ if (NOT UNICORN_FOUND)
set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers" FORCE)
set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/" CACHE PATH "Path to unicorn dynamic library" FORCE)
find_package(PythonInterp 2.7 REQUIRED)
add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY}
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" /bin/sh make.sh
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no
WORKING_DIRECTORY ${UNICORN_PREFIX}
)
# ALL makes this custom target build every time
@@ -251,6 +260,8 @@ if (NOT UNICORN_FOUND)
)
unset(UNICORN_LIB_NAME)
endif()
else()
find_package(Unicorn REQUIRED)
endif()
if (UNICORN_FOUND)
@@ -314,6 +325,53 @@ if (UNIX OR MINGW)
endif()
endif()
# Setup a custom clang-format target (if clang-format can be found) that will run
# against all the src files. This should be used before making a pull request.
# =======================================================================
set(CLANG_FORMAT_POSTFIX "-6.0")
find_program(CLANG_FORMAT
NAMES clang-format${CLANG_FORMAT_POSTFIX}
clang-format
PATHS ${CMAKE_BINARY_DIR}/externals)
# if find_program doesn't find it, try to download from externals
if (NOT CLANG_FORMAT)
if (WIN32)
message(STATUS "Clang format not found! Downloading...")
set(CLANG_FORMAT "${CMAKE_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe")
file(DOWNLOAD
https://github.com/yuzu-emu/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe
"${CLANG_FORMAT}" SHOW_PROGRESS
STATUS DOWNLOAD_SUCCESS)
if (NOT DOWNLOAD_SUCCESS EQUAL 0)
message(WARNING "Could not download clang format! Disabling the clang format target")
file(REMOVE ${CLANG_FORMAT})
unset(CLANG_FORMAT)
endif()
else()
message(WARNING "Clang format not found! Disabling the clang format target")
endif()
endif()
if (CLANG_FORMAT)
set(SRCS ${CMAKE_SOURCE_DIR}/src)
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
if (WIN32)
add_custom_target(clang-format
COMMAND powershell.exe -Command "${CLANG_FORMAT} -i @(Get-ChildItem -Recurse ${SRCS}/* -Include \'*.h\', \'*.cpp\')"
COMMENT ${CCOMMENT})
elseif(MINGW)
add_custom_target(clang-format
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp | xargs `cygpath -u ${CLANG_FORMAT}` -i
COMMENT ${CCOMMENT})
else()
add_custom_target(clang-format
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp | xargs ${CLANG_FORMAT} -i
COMMENT ${CCOMMENT})
endif()
unset(SRCS)
unset(CCOMMENT)
endif()
# Include source code
# ===================
@@ -321,12 +379,14 @@ endif()
# This function should be passed a list of all files in a target. It will automatically generate
# file groups following the directory hierarchy, so that the layout of the files in IDEs matches the
# one in the filesystem.
function(create_directory_groups)
function(create_target_directory_groups target_name)
# Place any files that aren't in the source list in a separate group so that they don't get in
# the way.
source_group("Other Files" REGULAR_EXPRESSION ".")
foreach(file_name ${ARGV})
get_target_property(target_sources "${target_name}" SOURCES)
foreach(file_name IN LISTS target_sources)
get_filename_component(dir_name "${file_name}" PATH)
# Group names use '\' as a separator even though the entire rest of CMake uses '/'...
string(REPLACE "/" "\\" group_name "${dir_name}")

View File

@@ -5,7 +5,16 @@
If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside yuzu) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
# Contributing
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible.
# Using clang format (version 6.0)
When generating the native build script for your toolset, cmake will try to find the correct version of clang format (or will download it on windows). Before running cmake, please install clang format version 6.0 for your platform as follows:
* Windows: do nothing; cmake will download a pre built binary for MSVC and MINGW. MSVC users can additionally install a clang format Visual Studio extension to add features like format on save.
* OSX: run `brew install clang-format`.
* Linux: use your package manager to get an appropriate binary.
If clang format is found, then cmake will add a custom build target that can be run at any time to run clang format against *all* source files and update the formatting in them. This should be used before making a pull request so that the reviewers can spend more time reviewing the code instead of having to worry about minor style violations. On MSVC, you can run clang format by building the clang-format project in the solution. On OSX, you can either use the Makefile target `make clang-format` or by building the clang-format target in XCode. For Makefile builds, you can use the clang-format target with `make clang-format`
### General Rules
* A lot of code was taken from other projects (e.g. Citra, Dolphin, PPSSPP, Gekko). In general, when editing other people's code, follow the style of the module you're in (or better yet, fix the style if it drastically differs from our guide).

View File

@@ -13,8 +13,8 @@ environment:
# Tell msys2 to inherit the current directory when starting the shell
CHERE_INVOKING: 1
matrix:
- BUILD_TYPE: mingw
- BUILD_TYPE: msvc
- BUILD_TYPE: mingw
platform:
- x64
@@ -80,12 +80,19 @@ after_build:
$env:BUILD_SYMBOLS = $MSVC_BUILD_PDB
$env:BUILD_UPDATE = $MSVC_SEVENZIP
$BUILD_DIR = ".\msvc_build\bin\Release"
# Make a debug symbol upload
mkdir pdb
Get-ChildItem ".\msvc_build\bin\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
Get-ChildItem "$BUILD_DIR\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
7z a -tzip $MSVC_BUILD_PDB .\pdb\*.pdb
rm "$BUILD_DIR\*.pdb"
mkdir $RELEASE_DIST
Get-ChildItem ".\msvc_build\bin\" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
# get rid of extra exes by copying everything over, then deleting all the exes, then copying just the exes we want
Copy-Item "$BUILD_DIR\*" -Destination $RELEASE_DIST -Recurse
rm "$RELEASE_DIST\*.exe"
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
Copy-Item .\license.txt -Destination $RELEASE_DIST
Copy-Item .\README.md -Destination $RELEASE_DIST
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_DIST\*
@@ -163,7 +170,7 @@ deploy:
provider: GitHub
release: $(appveyor_repo_tag_name)
auth_token:
secure: "argb6oi2TYLB4wDy+HoCC8PuGAmsnocSk12CQ5614XAPO+NVPndlkLv1utnDFfg2"
secure: QqePPnXbkzmXct5c8hZ2X5AbsthbI6cS1Sr+VBzcD8oUOIjfWJJKXVAQGUbQAbb0
artifact: update,build
draft: false
prerelease: false

View File

@@ -1,11 +1,9 @@
set(SRCS
getopt.c
)
set(HEADERS
getopt.h
)
add_library(getopt
getopt.c
getopt.h
)
create_target_directory_groups(getopt)
create_directory_groups(${SRCS} ${HEADERS})
add_library(getopt ${SRCS} ${HEADERS})
target_compile_definitions(getopt PUBLIC STATIC_GETOPT)
target_include_directories(getopt INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -1,13 +1,10 @@
set(SRCS
src/glad.c
)
set(HEADERS
include/KHR/khrplatform.h
include/glad/glad.h
)
add_library(glad STATIC
src/glad.c
include/KHR/khrplatform.h
include/glad/glad.h
)
create_directory_groups(${SRCS} ${HEADERS})
add_library(glad STATIC ${SRCS} ${HEADERS})
create_target_directory_groups(glad)
target_include_directories(glad PUBLIC "include/")
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")

View File

@@ -1,12 +1,9 @@
set(SRCS
inih/ini.c
inih/cpp/INIReader.cpp
)
set(HEADERS
inih/ini.h
inih/cpp/INIReader.h
)
add_library(inih
inih/ini.c
inih/ini.h
inih/cpp/INIReader.cpp
inih/cpp/INIReader.h
)
create_directory_groups(${SRCS} ${HEADERS})
add_library(inih ${SRCS} ${HEADERS})
create_target_directory_groups(inih)
target_include_directories(inih INTERFACE .)

View File

@@ -17,85 +17,79 @@ if ($ENV{CI})
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
# this leaves a trailing space on the last word, but we actually want that
# because of how its styled in the title bar.
# because of how it's styled in the title bar.
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER} ")
endforeach()
endif()
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY)
set(SRCS
break_points.cpp
file_util.cpp
hash.cpp
logging/filter.cpp
logging/text_formatter.cpp
logging/backend.cpp
memory_util.cpp
microprofile.cpp
misc.cpp
param_package.cpp
scm_rev.cpp
string_util.cpp
telemetry.cpp
thread.cpp
timer.cpp
)
set(HEADERS
alignment.h
assert.h
bit_field.h
bit_set.h
break_points.h
chunk_file.h
code_block.h
color.h
common_funcs.h
common_paths.h
common_types.h
file_util.h
hash.h
linear_disk_cache.h
logging/text_formatter.h
logging/filter.h
logging/log.h
logging/backend.h
math_util.h
memory_util.h
microprofile.h
microprofileui.h
param_package.h
platform.h
quaternion.h
scm_rev.h
scope_exit.h
string_util.h
swap.h
synchronized_wrapper.h
telemetry.h
thread.h
thread_queue_list.h
threadsafe_queue.h
timer.h
vector_math.h
)
add_library(common STATIC
alignment.h
assert.h
bit_field.h
bit_set.h
break_points.cpp
break_points.h
chunk_file.h
code_block.h
color.h
common_funcs.h
common_paths.h
common_types.h
file_util.cpp
file_util.h
hash.cpp
hash.h
linear_disk_cache.h
logging/backend.cpp
logging/backend.h
logging/filter.cpp
logging/filter.h
logging/log.h
logging/text_formatter.cpp
logging/text_formatter.h
math_util.h
memory_util.cpp
memory_util.h
microprofile.cpp
microprofile.h
microprofileui.h
misc.cpp
param_package.cpp
param_package.h
platform.h
quaternion.h
scm_rev.cpp
scm_rev.h
scope_exit.h
string_util.cpp
string_util.h
swap.h
synchronized_wrapper.h
telemetry.cpp
telemetry.h
thread.cpp
thread.h
thread_queue_list.h
threadsafe_queue.h
timer.cpp
timer.h
vector_math.h
)
if(ARCHITECTURE_x86_64)
set(SRCS ${SRCS}
target_sources(common
PRIVATE
x64/cpu_detect.cpp
)
set(HEADERS ${HEADERS}
x64/cpu_detect.h
x64/xbyak_abi.h
x64/xbyak_util.h
)
)
endif()
create_directory_groups(${SRCS} ${HEADERS})
create_target_directory_groups(common)
add_library(common STATIC ${SRCS} ${HEADERS})
target_link_libraries(common PUBLIC Boost::boost microprofile)
if (ARCHITECTURE_x86_64)
target_link_libraries(common PRIVATE xbyak)

View File

@@ -236,7 +236,7 @@ public:
IntTy m_val;
};
} // Common
} // namespace Common
typedef Common::BitSet<u8> BitSet8;
typedef Common::BitSet<u16> BitSet16;

View File

@@ -607,8 +607,9 @@ public:
u32 cookie = arbitraryNumber;
Do(cookie);
if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) {
LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
"Aborting savestate load...",
LOG_ERROR(Common,
"After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
"Aborting savestate load...",
prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
SetError(ERROR_FAILURE);
}

View File

@@ -256,4 +256,4 @@ inline void EncodeX24S8(u8 stencil, u8* bytes) {
bytes[3] = stencil;
}
} // namespace
} // namespace Color

View File

@@ -873,20 +873,19 @@ bool IOFile::Flush() {
}
bool IOFile::Resize(u64 size) {
if (!IsOpen() ||
0 !=
if (!IsOpen() || 0 !=
#ifdef _WIN32
// ector: _chsize sucks, not 64-bit safe
// F|RES: changed to _chsize_s. i think it is 64-bit safe
_chsize_s(_fileno(m_file), size)
// ector: _chsize sucks, not 64-bit safe
// F|RES: changed to _chsize_s. i think it is 64-bit safe
_chsize_s(_fileno(m_file), size)
#else
// TODO: handle 64bit and growing
ftruncate(fileno(m_file), size)
// TODO: handle 64bit and growing
ftruncate(fileno(m_file), size)
#endif
)
)
m_good = false;
return m_good;
}
} // namespace
} // namespace FileUtil

View File

@@ -253,7 +253,7 @@ private:
bool m_good = true;
};
} // namespace
} // namespace FileUtil
// To deal with Windows being dumb at unicode:
template <typename T>

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();
@@ -131,4 +132,4 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
PrintColoredMessage(entry);
}
}
} // namespace Log

View File

@@ -47,4 +47,4 @@ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsign
const char* function, const char* format, va_list args);
void SetFilter(Filter* filter);
}
} // namespace Log

View File

@@ -94,4 +94,4 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
bool Filter::CheckMessage(Class log_class, Level level) const {
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);
}
}
} // namespace Log

View File

@@ -50,4 +50,4 @@ public:
private:
std::array<Level, (size_t)Class::Count> class_levels;
};
}
} // namespace Log

View File

@@ -55,11 +55,13 @@ enum class Class : ClassType {
Service_CFG, ///< The CFG (Configuration) service
Service_DSP, ///< The DSP (DSP control) service
Service_HID, ///< The HID (Human interface device) service
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
HW, ///< Low-level hardware emulation
HW_Memory, ///< Memory-map and address translation
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

@@ -129,4 +129,4 @@ void PrintColoredMessage(const Entry& entry) {
#undef ESC
#endif
}
}
} // namespace Log

View File

@@ -28,4 +28,4 @@ void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len);
void PrintMessage(const Entry& entry);
/// Prints the same message as `PrintMessage`, but colored acoording to the severity level.
void PrintColoredMessage(const Entry& entry);
}
} // namespace Log

View File

@@ -40,11 +40,12 @@ void* AllocateExecutableMemory(size_t size, bool low) {
if (low && (!map_hint))
map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
#endif
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE
#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT)
| (low ? MAP_32BIT : 0)
| (low ? MAP_32BIT : 0)
#endif
,
,
-1, 0);
#endif /* defined(_WIN32) */

View File

@@ -46,4 +46,4 @@ inline Quaternion<float> MakeQuaternion(const Math::Vec3<float>& axis, float ang
return {axis * std::sin(angle / 2), std::cos(angle / 2)};
}
} // namspace Math
} // namespace Math

View File

@@ -12,4 +12,4 @@ extern const char g_scm_desc[];
extern const char g_build_name[];
extern const char g_build_date[];
} // namespace
} // namespace Common

View File

@@ -22,7 +22,7 @@ template <typename Func>
ScopeExitHelper<Func> ScopeExit(Func&& func) {
return ScopeExitHelper<Func>(std::move(func));
}
}
} // namespace detail
/**
* This macro allows you to conveniently specify a block of code that will run on scope exit. Handy

View File

@@ -202,7 +202,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
#ifdef _WIN32
":"
#endif
);
);
if (std::string::npos == dir_end)
dir_end = 0;
else
@@ -462,4 +462,4 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_l
return std::string(buffer, len);
}
}
} // namespace Common

View File

@@ -134,4 +134,4 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
* NUL-terminated then the string ends at max_len characters.
*/
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len);
}
} // namespace Common

View File

@@ -53,10 +53,10 @@ template <typename T>
class Field : public FieldInterface {
public:
Field(FieldType type, std::string name, const T& value)
: type(type), name(std::move(name)), value(value) {}
: name(std::move(name)), type(type), value(value) {}
Field(FieldType type, std::string name, T&& value)
: type(type), name(std::move(name)), value(std::move(value)) {}
: name(std::move(name)), type(type), value(std::move(value)) {}
Field(const Field& other) : Field(other.type, other.name, other.value) {}

View File

@@ -158,4 +158,4 @@ private:
std::array<Queue, NUM_QUEUES> queues;
};
} // namespace
} // namespace Common

View File

@@ -60,20 +60,41 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::r9;
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
// GPRs
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::r8, Xbyak::util::r9, Xbyak::util::r10,
Xbyak::util::rcx,
Xbyak::util::rdx,
Xbyak::util::r8,
Xbyak::util::r9,
Xbyak::util::r10,
Xbyak::util::r11,
// XMMs
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
Xbyak::util::xmm0,
Xbyak::util::xmm1,
Xbyak::util::xmm2,
Xbyak::util::xmm3,
Xbyak::util::xmm4,
Xbyak::util::xmm5,
});
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
// GPRs
Xbyak::util::rbx, Xbyak::util::rsi, Xbyak::util::rdi, Xbyak::util::rbp, Xbyak::util::r12,
Xbyak::util::r13, Xbyak::util::r14, Xbyak::util::r15,
Xbyak::util::rbx,
Xbyak::util::rsi,
Xbyak::util::rdi,
Xbyak::util::rbp,
Xbyak::util::r12,
Xbyak::util::r13,
Xbyak::util::r14,
Xbyak::util::r15,
// XMMs
Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9, Xbyak::util::xmm10,
Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13, Xbyak::util::xmm14,
Xbyak::util::xmm6,
Xbyak::util::xmm7,
Xbyak::util::xmm8,
Xbyak::util::xmm9,
Xbyak::util::xmm10,
Xbyak::util::xmm11,
Xbyak::util::xmm12,
Xbyak::util::xmm13,
Xbyak::util::xmm14,
Xbyak::util::xmm15,
});
@@ -90,18 +111,40 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::rcx;
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
// GPRs
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::rdi, Xbyak::util::rsi, Xbyak::util::r8,
Xbyak::util::r9, Xbyak::util::r10, Xbyak::util::r11,
Xbyak::util::rcx,
Xbyak::util::rdx,
Xbyak::util::rdi,
Xbyak::util::rsi,
Xbyak::util::r8,
Xbyak::util::r9,
Xbyak::util::r10,
Xbyak::util::r11,
// XMMs
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
Xbyak::util::xmm5, Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9,
Xbyak::util::xmm10, Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13,
Xbyak::util::xmm14, Xbyak::util::xmm15,
Xbyak::util::xmm0,
Xbyak::util::xmm1,
Xbyak::util::xmm2,
Xbyak::util::xmm3,
Xbyak::util::xmm4,
Xbyak::util::xmm5,
Xbyak::util::xmm6,
Xbyak::util::xmm7,
Xbyak::util::xmm8,
Xbyak::util::xmm9,
Xbyak::util::xmm10,
Xbyak::util::xmm11,
Xbyak::util::xmm12,
Xbyak::util::xmm13,
Xbyak::util::xmm14,
Xbyak::util::xmm15,
});
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
// GPRs
Xbyak::util::rbx, Xbyak::util::rbp, Xbyak::util::r12, Xbyak::util::r13, Xbyak::util::r14,
Xbyak::util::rbx,
Xbyak::util::rbp,
Xbyak::util::r12,
Xbyak::util::r13,
Xbyak::util::r14,
Xbyak::util::r15,
});

View File

@@ -1,171 +1,208 @@
set(SRCS
arm/dynarmic/arm_dynarmic.cpp
arm/unicorn/arm_unicorn.cpp
core.cpp
core_timing.cpp
file_sys/archive_backend.cpp
file_sys/disk_archive.cpp
file_sys/ivfc_archive.cpp
file_sys/path_parser.cpp
file_sys/savedata_archive.cpp
file_sys/title_metadata.cpp
frontend/emu_window.cpp
frontend/framebuffer_layout.cpp
gdbstub/gdbstub.cpp
hle/config_mem.cpp
hle/kernel/address_arbiter.cpp
hle/kernel/client_port.cpp
hle/kernel/client_session.cpp
hle/kernel/condition_variable.cpp
hle/kernel/domain.cpp
hle/kernel/event.cpp
hle/kernel/handle_table.cpp
hle/kernel/hle_ipc.cpp
hle/kernel/kernel.cpp
hle/kernel/memory.cpp
hle/kernel/mutex.cpp
hle/kernel/object_address_table.cpp
hle/kernel/process.cpp
hle/kernel/resource_limit.cpp
hle/kernel/server_port.cpp
hle/kernel/server_session.cpp
hle/kernel/shared_memory.cpp
hle/kernel/svc.cpp
hle/kernel/thread.cpp
hle/kernel/timer.cpp
hle/kernel/vm_manager.cpp
hle/kernel/wait_object.cpp
hle/lock.cpp
hle/romfs.cpp
hle/service/am/am.cpp
hle/service/am/applet_oe.cpp
hle/service/aoc/aoc_u.cpp
hle/service/apm/apm.cpp
hle/service/audio/audio.cpp
hle/service/audio/audout_u.cpp
hle/service/hid/hid.cpp
hle/service/lm/lm.cpp
hle/service/nvdrv/devices/nvdisp_disp0.cpp
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
hle/service/nvdrv/devices/nvmap.cpp
hle/service/nvdrv/nvdrv.cpp
hle/service/nvdrv/nvdrv_a.cpp
hle/service/pctl/pctl.cpp
hle/service/pctl/pctl_a.cpp
hle/service/service.cpp
hle/service/sm/controller.cpp
hle/service/sm/sm.cpp
hle/service/time/time.cpp
hle/service/time/time_s.cpp
hle/service/vi/vi.cpp
hle/service/vi/vi_m.cpp
hle/shared_page.cpp
hw/hw.cpp
hw/lcd.cpp
loader/elf.cpp
loader/linker.cpp
loader/loader.cpp
loader/nro.cpp
loader/nso.cpp
tracer/recorder.cpp
memory.cpp
perf_stats.cpp
settings.cpp
telemetry_session.cpp
)
add_library(core STATIC
arm/arm_interface.h
arm/unicorn/arm_unicorn.cpp
arm/unicorn/arm_unicorn.h
core.cpp
core.h
core_timing.cpp
core_timing.h
file_sys/directory.h
file_sys/errors.h
file_sys/filesystem.cpp
file_sys/filesystem.h
file_sys/path_parser.cpp
file_sys/path_parser.h
file_sys/romfs_factory.cpp
file_sys/romfs_factory.h
file_sys/romfs_filesystem.cpp
file_sys/romfs_filesystem.h
file_sys/storage.h
frontend/emu_window.cpp
frontend/emu_window.h
frontend/framebuffer_layout.cpp
frontend/framebuffer_layout.h
frontend/input.h
gdbstub/gdbstub.cpp
gdbstub/gdbstub.h
hle/config_mem.cpp
hle/config_mem.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/address_arbiter.cpp
hle/kernel/address_arbiter.h
hle/kernel/client_port.cpp
hle/kernel/client_port.h
hle/kernel/client_session.cpp
hle/kernel/client_session.h
hle/kernel/condition_variable.cpp
hle/kernel/condition_variable.h
hle/kernel/domain.cpp
hle/kernel/domain.h
hle/kernel/errors.h
hle/kernel/event.cpp
hle/kernel/event.h
hle/kernel/handle_table.cpp
hle/kernel/handle_table.h
hle/kernel/hle_ipc.cpp
hle/kernel/hle_ipc.h
hle/kernel/kernel.cpp
hle/kernel/kernel.h
hle/kernel/memory.cpp
hle/kernel/memory.h
hle/kernel/mutex.cpp
hle/kernel/mutex.h
hle/kernel/object_address_table.cpp
hle/kernel/object_address_table.h
hle/kernel/process.cpp
hle/kernel/process.h
hle/kernel/resource_limit.cpp
hle/kernel/resource_limit.h
hle/kernel/server_port.cpp
hle/kernel/server_port.h
hle/kernel/server_session.cpp
hle/kernel/server_session.h
hle/kernel/session.h
hle/kernel/shared_memory.cpp
hle/kernel/shared_memory.h
hle/kernel/svc.cpp
hle/kernel/svc.h
hle/kernel/svc_wrap.h
hle/kernel/sync_object.h
hle/kernel/thread.cpp
hle/kernel/thread.h
hle/kernel/timer.cpp
hle/kernel/timer.h
hle/kernel/vm_manager.cpp
hle/kernel/vm_manager.h
hle/kernel/wait_object.cpp
hle/kernel/wait_object.h
hle/lock.cpp
hle/lock.h
hle/result.h
hle/romfs.cpp
hle/romfs.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
hle/service/acc/acc_u0.cpp
hle/service/acc/acc_u0.h
hle/service/am/am.cpp
hle/service/am/am.h
hle/service/am/applet_oe.cpp
hle/service/am/applet_oe.h
hle/service/aoc/aoc_u.cpp
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
hle/service/apm/apm.h
hle/service/audio/audio.cpp
hle/service/audio/audio.h
hle/service/audio/audin_u.cpp
hle/service/audio/audin_u.h
hle/service/audio/audout_u.cpp
hle/service/audio/audout_u.h
hle/service/audio/audrec_u.cpp
hle/service/audio/audrec_u.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/audren_u.cpp
hle/service/audio/audren_u.h
hle/service/audio/codecctl.cpp
hle/service/audio/codecctl.h
hle/service/filesystem/filesystem.cpp
hle/service/filesystem/filesystem.h
hle/service/filesystem/fsp_srv.cpp
hle/service/filesystem/fsp_srv.h
hle/service/hid/hid.cpp
hle/service/hid/hid.h
hle/service/lm/lm.cpp
hle/service/lm/lm.h
hle/service/nvdrv/devices/nvdevice.h
hle/service/nvdrv/devices/nvdisp_disp0.cpp
hle/service/nvdrv/devices/nvdisp_disp0.h
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
hle/service/nvdrv/devices/nvhost_as_gpu.h
hle/service/nvdrv/devices/nvhost_ctrl.cpp
hle/service/nvdrv/devices/nvhost_ctrl.h
hle/service/nvdrv/devices/nvmap.cpp
hle/service/nvdrv/devices/nvmap.h
hle/service/nvdrv/interface.cpp
hle/service/nvdrv/interface.h
hle/service/nvdrv/nvdrv.cpp
hle/service/nvdrv/nvdrv.h
hle/service/nvdrv/nvmemp.cpp
hle/service/nvdrv/nvmemp.h
hle/service/nvflinger/buffer_queue.cpp
hle/service/nvflinger/buffer_queue.h
hle/service/nvflinger/nvflinger.cpp
hle/service/nvflinger/nvflinger.h
hle/service/pctl/pctl.cpp
hle/service/pctl/pctl.h
hle/service/pctl/pctl_a.cpp
hle/service/pctl/pctl_a.h
hle/service/service.cpp
hle/service/service.h
hle/service/set/set.cpp
hle/service/set/set.h
hle/service/sm/controller.cpp
hle/service/sm/controller.h
hle/service/sm/sm.cpp
hle/service/sm/sm.h
hle/service/sockets/bsd_u.cpp
hle/service/sockets/bsd_u.h
hle/service/sockets/sfdnsres.h
hle/service/sockets/sockets.cpp
hle/service/sockets/sockets.h
hle/service/time/time.cpp
hle/service/time/time.h
hle/service/time/time_s.cpp
hle/service/time/time_s.h
hle/service/time/time_u.cpp
hle/service/time/time_u.h
hle/service/vi/vi.cpp
hle/service/vi/vi.h
hle/service/vi/vi_m.cpp
hle/service/vi/vi_m.h
hle/shared_page.cpp
hle/shared_page.h
hw/hw.cpp
hw/hw.h
hw/lcd.cpp
hw/lcd.h
loader/deconstructed_rom_directory.cpp
loader/deconstructed_rom_directory.h
loader/elf.cpp
loader/elf.h
loader/linker.cpp
loader/linker.h
loader/loader.cpp
loader/loader.h
loader/nro.cpp
loader/nro.h
loader/nso.cpp
loader/nso.h
memory.cpp
memory.h
memory_setup.h
mmio.h
perf_stats.cpp
perf_stats.h
settings.cpp
settings.h
telemetry_session.cpp
telemetry_session.h
tracer/citrace.h
tracer/recorder.cpp
tracer/recorder.h
)
set(HEADERS
arm/arm_interface.h
arm/dynarmic/arm_dynarmic.h
arm/unicorn/arm_unicorn.h
core.h
core_timing.h
file_sys/archive_backend.h
file_sys/directory_backend.h
file_sys/disk_archive.h
file_sys/errors.h
file_sys/file_backend.h
file_sys/ivfc_archive.h
file_sys/path_parser.h
file_sys/savedata_archive.h
frontend/emu_window.h
frontend/framebuffer_layout.h
frontend/input.h
gdbstub/gdbstub.h
hle/config_mem.h
hle/ipc.h
hle/ipc_helpers.h
hle/kernel/address_arbiter.h
hle/kernel/client_port.h
hle/kernel/client_session.h
hle/kernel/condition_variable.h
hle/kernel/domain.h
hle/kernel/errors.h
hle/kernel/event.h
hle/kernel/handle_table.h
hle/kernel/hle_ipc.h
hle/kernel/kernel.h
hle/kernel/memory.h
hle/kernel/mutex.h
hle/kernel/object_address_table.h
hle/kernel/process.h
hle/kernel/resource_limit.h
hle/kernel/server_port.h
hle/kernel/server_session.h
hle/kernel/session.h
hle/kernel/shared_memory.h
hle/kernel/sync_object.h
hle/kernel/svc.h
hle/kernel/svc_wrap.h
hle/kernel/thread.h
hle/kernel/timer.h
hle/kernel/vm_manager.h
hle/kernel/wait_object.h
hle/lock.h
hle/result.h
hle/romfs.h
hle/service/am/am.h
hle/service/am/applet_oe.h
hle/service/aoc/aoc_u.h
hle/service/apm/apm.h
hle/service/audio/audio.h
hle/service/audio/audout_u.h
hle/service/hid/hid.h
hle/service/lm/lm.h
hle/service/nvdrv/devices/nvdevice.h
hle/service/nvdrv/devices/nvdisp_disp0.h
hle/service/nvdrv/devices/nvhost_as_gpu.h
hle/service/nvdrv/devices/nvmap.h
hle/service/nvdrv/nvdrv.h
hle/service/nvdrv/nvdrv_a.h
hle/service/pctl/pctl.h
hle/service/pctl/pctl_a.h
hle/service/service.h
hle/service/sm/controller.h
hle/service/sm/sm.h
hle/service/time/time.h
hle/service/time/time_s.h
hle/service/vi/vi.h
hle/service/vi/vi_m.h
hle/shared_page.h
hw/hw.h
hw/lcd.h
loader/elf.h
loader/linker.h
loader/loader.h
loader/nro.h
loader/nso.h
tracer/recorder.h
tracer/citrace.h
memory.h
memory_setup.h
mmio.h
perf_stats.h
settings.h
telemetry_session.h
)
create_target_directory_groups(core)
create_directory_groups(${SRCS} ${HEADERS})
add_library(core STATIC ${SRCS} ${HEADERS})
target_link_libraries(core PUBLIC common PRIVATE dynarmic video_core)
target_link_libraries(core PUBLIC common PRIVATE video_core)
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn)
if (ARCHITECTURE_x86_64)
target_sources(core PRIVATE
arm/dynarmic/arm_dynarmic.cpp
arm/dynarmic/arm_dynarmic.h
)
target_link_libraries(core PRIVATE dynarmic)
endif()

View File

@@ -39,7 +39,8 @@ public:
Run(1);
}
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) {}
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
Kernel::VMAPermission perms) {}
/// Clear all instruction cache
virtual void ClearInstructionCache() = 0;

View File

@@ -46,7 +46,7 @@ public:
ARM_Interface::ThreadContext ctx;
parent.SaveContext(ctx);
parent.inner_unicorn.LoadContext(ctx);
parent.inner_unicorn.ExecuteInstructions(num_instructions);
parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions));
parent.inner_unicorn.SaveContext(ctx);
parent.LoadContext(ctx);
num_interpreted_instructions += num_instructions;
@@ -163,9 +163,9 @@ void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
jit.SetRegisters(ctx.cpu_registers);
jit.SetSP(ctx.sp);
jit.SetPC(ctx.pc);
jit.SetPstate(ctx.cpsr);
jit.SetPstate(static_cast<u32>(ctx.cpsr));
jit.SetVectors(ctx.fpu_registers);
jit.SetFpcr(ctx.fpscr);
jit.SetFpcr(static_cast<u32>(ctx.fpscr));
cb->tpidrr0_el0 = ctx.tls_address;
}

View File

@@ -5,7 +5,9 @@
#include <memory>
#include <utility>
#include "common/logging/log.h"
#ifdef ARCHITECTURE_x86_64
#include "core/arm/dynarmic/arm_dynarmic.h"
#endif
#include "core/arm/unicorn/arm_unicorn.h"
#include "core/core.h"
#include "core/core_timing.h"
@@ -80,7 +82,6 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
if (system_mode.second != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to determine system mode (Error %i)!",
static_cast<int>(system_mode.second));
System::Shutdown();
switch (system_mode.second) {
case Loader::ResultStatus::ErrorEncrypted:
@@ -144,7 +145,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
break;
case Settings::CpuCore::Dynarmic:
default:
#ifdef ARCHITECTURE_x86_64
cpu_core = std::make_unique<ARM_Dynarmic>();
#else
cpu_core = std::make_unique<ARM_Unicorn>();
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
#endif
break;
}

View File

@@ -51,13 +51,13 @@ public:
* requested is not guaranteed to run, as this will be interrupted preemptively if a hardware
* update is requested (e.g. on a thread switch).
* @param tight_loop Number of instructions to execute.
* @return Result status, indicating whethor or not the operation succeeded.
* @return Result status, indicating whether or not the operation succeeded.
*/
ResultStatus RunLoop(int tight_loop = 100000);
/**
* Step the CPU one instruction
* @return Result status, indicating whethor or not the operation succeeded.
* @return Result status, indicating whether or not the operation succeeded.
*/
ResultStatus SingleStep();

View File

@@ -122,7 +122,7 @@ u64 GetTicks() {
}
void AddTicks(u64 ticks) {
downcount -= ticks;
downcount -= static_cast<int>(ticks);
}
u64 GetIdleTicks() {
@@ -208,7 +208,7 @@ void Advance() {
Event evt = std::move(event_queue.front());
std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
event_queue.pop_back();
evt.type->callback(evt.userdata, global_timer - evt.time);
evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time));
}
is_global_timer_sane = false;

View File

@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

View File

@@ -1,99 +0,0 @@
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cstdio>
#include <memory>
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/disk_archive.h"
#include "core/file_sys/errors.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const {
if (!mode.read_flag)
return ERROR_INVALID_OPEN_FLAGS;
file->Seek(offset, SEEK_SET);
return MakeResult<size_t>(file->ReadBytes(buffer, length));
}
ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush,
const u8* buffer) const {
if (!mode.write_flag)
return ERROR_INVALID_OPEN_FLAGS;
file->Seek(offset, SEEK_SET);
size_t written = file->WriteBytes(buffer, length);
if (flush)
file->Flush();
return MakeResult<size_t>(written);
}
u64 DiskFile::GetSize() const {
return file->GetSize();
}
bool DiskFile::SetSize(const u64 size) const {
file->Resize(size);
file->Flush();
return true;
}
bool DiskFile::Close() const {
return file->Close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
DiskDirectory::DiskDirectory(const std::string& path) : directory() {
unsigned size = FileUtil::ScanDirectoryTree(path, directory);
directory.size = size;
directory.isDirectory = true;
children_iterator = directory.children.begin();
}
u32 DiskDirectory::Read(const u32 count, Entry* entries) {
u32 entries_read = 0;
while (entries_read < count && children_iterator != directory.children.cend()) {
const FileUtil::FSTEntry& file = *children_iterator;
const std::string& filename = file.virtualName;
Entry& entry = entries[entries_read];
LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size,
file.isDirectory);
// TODO(Link Mauve): use a proper conversion to UTF-16.
for (size_t j = 0; j < FILENAME_LENGTH; ++j) {
entry.filename[j] = filename[j];
if (!filename[j])
break;
}
FileUtil::SplitFilename83(filename, entry.short_name, entry.extension);
entry.is_directory = file.isDirectory;
entry.is_hidden = (filename[0] == '.');
entry.is_read_only = 0;
entry.file_size = file.size;
// We emulate a SD card where the archive bit has never been cleared, as it would be on
// most user SD cards.
// Some homebrews (blargSNES for instance) are known to mistakenly use the archive bit as a
// file bit.
entry.is_archive = !file.isDirectory;
++entries_read;
++children_iterator;
}
return entries_read;
}
} // namespace FileSys

View File

@@ -1,68 +0,0 @@
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <cstddef>
#include <memory>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/directory_backend.h"
#include "core/file_sys/file_backend.h"
#include "core/hle/result.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
class DiskFile : public FileBackend {
public:
DiskFile(FileUtil::IOFile&& file_, const Mode& mode_)
: file(new FileUtil::IOFile(std::move(file_))) {
mode.hex = mode_.hex;
}
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override;
u64 GetSize() const override;
bool SetSize(u64 size) const override;
bool Close() const override;
void Flush() const override {
file->Flush();
}
protected:
Mode mode;
std::unique_ptr<FileUtil::IOFile> file;
};
class DiskDirectory : public DirectoryBackend {
public:
DiskDirectory(const std::string& path);
~DiskDirectory() override {
Close();
}
u32 Read(const u32 count, Entry* entries) override;
bool Close() const override {
return true;
}
protected:
u32 total_entries_in_directory;
FileUtil::FSTEntry directory;
// We need to remember the last entry we returned, so a subsequent call to Read will continue
// from the next one. This iterator will always point to the next unread entry.
std::vector<FileUtil::FSTEntry>::iterator children_iterator;
};
} // namespace FileSys

View File

@@ -1,4 +1,4 @@
// Copyright 2015 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -7,7 +7,7 @@
#include <sstream>
#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/filesystem.h"
#include "core/memory.h"
namespace FileSys {
@@ -119,4 +119,4 @@ std::vector<u8> Path::AsBinary() const {
return {};
}
}
}
} // namespace FileSys

View File

@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -15,7 +15,7 @@
namespace FileSys {
class FileBackend;
class StorageBackend;
class DirectoryBackend;
// Path string type
@@ -71,9 +71,9 @@ struct ArchiveFormatInfo {
};
static_assert(std::is_pod<ArchiveFormatInfo>::value, "ArchiveFormatInfo is not POD");
class ArchiveBackend : NonCopyable {
class FileSystemBackend : NonCopyable {
public:
virtual ~ArchiveBackend() {}
virtual ~FileSystemBackend() {}
/**
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
@@ -81,13 +81,12 @@ public:
virtual std::string GetName() const = 0;
/**
* Open a file specified by its path, using the specified mode
* @param path Path relative to the archive
* @param mode Mode to open the file with
* @return Opened file, or error code
* Create a file specified by its path
* @param path Path relative to the Archive
* @param size The size of the new file, filled with zeroes
* @return Result of the operation
*/
virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
const Mode& mode) const = 0;
virtual ResultCode CreateFile(const Path& path, u64 size) const = 0;
/**
* Delete a file specified by its path
@@ -97,12 +96,11 @@ public:
virtual ResultCode DeleteFile(const Path& path) const = 0;
/**
* Rename a File specified by its path
* @param src_path Source path relative to the archive
* @param dest_path Destination path relative to the archive
* Create a directory specified by its path
* @param path Path relative to the archive
* @return Result of the operation
*/
virtual ResultCode RenameFile(const Path& src_path, const Path& dest_path) const = 0;
virtual ResultCode CreateDirectory(const Path& path) const = 0;
/**
* Delete a directory specified by its path
@@ -119,19 +117,12 @@ public:
virtual ResultCode DeleteDirectoryRecursively(const Path& path) const = 0;
/**
* Create a file specified by its path
* @param path Path relative to the Archive
* @param size The size of the new file, filled with zeroes
* Rename a File specified by its path
* @param src_path Source path relative to the archive
* @param dest_path Destination path relative to the archive
* @return Result of the operation
*/
virtual ResultCode CreateFile(const Path& path, u64 size) const = 0;
/**
* Create a directory specified by its path
* @param path Path relative to the archive
* @return Result of the operation
*/
virtual ResultCode CreateDirectory(const Path& path) const = 0;
virtual ResultCode RenameFile(const Path& src_path, const Path& dest_path) const = 0;
/**
* Rename a Directory specified by its path
@@ -141,6 +132,15 @@ public:
*/
virtual ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const = 0;
/**
* Open a file specified by its path, using the specified mode
* @param path Path relative to the archive
* @param mode Mode to open the file with
* @return Opened file, or error code
*/
virtual ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const Path& path,
const Mode& mode) const = 0;
/**
* Open a directory specified by its path
* @param path Path relative to the archive
@@ -152,12 +152,12 @@ public:
* Get the free space
* @return The number of free bytes in the archive
*/
virtual u64 GetFreeBytes() const = 0;
virtual u64 GetFreeSpaceSize() const = 0;
};
class ArchiveFactory : NonCopyable {
class FileSystemFactory : NonCopyable {
public:
virtual ~ArchiveFactory() {}
virtual ~FileSystemFactory() {}
/**
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
@@ -169,7 +169,7 @@ public:
* @param path Path to the archive
* @return An ArchiveBackend corresponding operating specified archive path.
*/
virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) = 0;
virtual ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) = 0;
/**
* Deletes the archive contents and then re-creates the base folder

View File

@@ -6,7 +6,7 @@
#include <string>
#include <vector>
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/filesystem.h"
namespace FileSys {

View File

@@ -0,0 +1,38 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <memory>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/romfs_factory.h"
#include "core/file_sys/romfs_filesystem.h"
namespace FileSys {
RomFS_Factory::RomFS_Factory(Loader::AppLoader& app_loader) {
// Load the RomFS from the app
if (Loader::ResultStatus::Success != app_loader.ReadRomFS(romfs_file, data_offset, data_size)) {
LOG_ERROR(Service_FS, "Unable to read RomFS!");
}
}
ResultVal<std::unique_ptr<FileSystemBackend>> RomFS_Factory::Open(const Path& path) {
auto archive = std::make_unique<RomFS_FileSystem>(romfs_file, data_offset, data_size);
return MakeResult<std::unique_ptr<FileSystemBackend>>(std::move(archive));
}
ResultCode RomFS_Factory::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) {
LOG_ERROR(Service_FS, "Unimplemented Format archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);
}
ResultVal<ArchiveFormatInfo> RomFS_Factory::GetFormatInfo(const Path& path) const {
LOG_ERROR(Service_FS, "Unimplemented GetFormatInfo archive %s", GetName().c_str());
// TODO(bunnei): Find the right error code for this
return ResultCode(-1);
}
} // namespace FileSys

View File

@@ -0,0 +1,35 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "core/file_sys/filesystem.h"
#include "core/hle/result.h"
#include "core/loader/loader.h"
namespace FileSys {
/// File system interface to the RomFS archive
class RomFS_Factory final : public FileSystemFactory {
public:
explicit RomFS_Factory(Loader::AppLoader& app_loader);
std::string GetName() const override {
return "ArchiveFactory_RomFS";
}
ResultVal<std::unique_ptr<FileSystemBackend>> Open(const Path& path) override;
ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override;
ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override;
private:
std::shared_ptr<FileUtil::IOFile> romfs_file;
u64 data_offset;
u64 data_size;
};
} // namespace FileSys

View File

@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -6,84 +6,80 @@
#include <memory>
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/ivfc_archive.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
#include "core/file_sys/romfs_filesystem.h"
namespace FileSys {
std::string IVFCArchive::GetName() const {
return "IVFC";
std::string RomFS_FileSystem::GetName() const {
return "RomFS";
}
ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path,
const Mode& mode) const {
return MakeResult<std::unique_ptr<FileBackend>>(
std::make_unique<IVFCFile>(romfs_file, data_offset, data_size));
ResultVal<std::unique_ptr<StorageBackend>> RomFS_FileSystem::OpenFile(const Path& path,
const Mode& mode) const {
return MakeResult<std::unique_ptr<StorageBackend>>(
std::make_unique<RomFS_Storage>(romfs_file, data_offset, data_size));
}
ResultCode IVFCArchive::DeleteFile(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).",
ResultCode RomFS_FileSystem::DeleteFile(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a file from an ROMFS archive (%s).",
GetName().c_str());
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).",
ResultCode RomFS_FileSystem::RenameFile(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::DeleteDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).",
ResultCode RomFS_FileSystem::DeleteDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::DeleteDirectoryRecursively(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).",
ResultCode RomFS_FileSystem::DeleteDirectoryRecursively(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const {
LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).",
ResultCode RomFS_FileSystem::CreateFile(const Path& path, u64 size) const {
LOG_CRITICAL(Service_FS, "Attempted to create a file in an ROMFS archive (%s).",
GetName().c_str());
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::CreateDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).",
ResultCode RomFS_FileSystem::CreateDirectory(const Path& path) const {
LOG_CRITICAL(Service_FS, "Attempted to create a directory in an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultCode IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).",
ResultCode RomFS_FileSystem::RenameDirectory(const Path& src_path, const Path& dest_path) const {
LOG_CRITICAL(Service_FS, "Attempted to rename a file within an ROMFS archive (%s).",
GetName().c_str());
// TODO(wwylele): Use correct error code
return ResultCode(-1);
}
ResultVal<std::unique_ptr<DirectoryBackend>> IVFCArchive::OpenDirectory(const Path& path) const {
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<IVFCDirectory>());
ResultVal<std::unique_ptr<DirectoryBackend>> RomFS_FileSystem::OpenDirectory(
const Path& path) const {
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::make_unique<ROMFSDirectory>());
}
u64 IVFCArchive::GetFreeBytes() const {
LOG_WARNING(Service_FS, "Attempted to get the free space in an IVFC archive");
u64 RomFS_FileSystem::GetFreeSpaceSize() const {
LOG_WARNING(Service_FS, "Attempted to get the free space in an ROMFS archive");
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buffer) const {
ResultVal<size_t> RomFS_Storage::Read(const u64 offset, const size_t length, u8* buffer) const {
LOG_TRACE(Service_FS, "called offset=%llu, length=%zu", offset, length);
romfs_file->Seek(data_offset + offset, SEEK_SET);
size_t read_length = (size_t)std::min((u64)length, data_size - offset);
@@ -91,19 +87,19 @@ ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buff
return MakeResult<size_t>(romfs_file->ReadBytes(buffer, read_length));
}
ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush,
const u8* buffer) const {
LOG_ERROR(Service_FS, "Attempted to write to IVFC file");
ResultVal<size_t> RomFS_Storage::Write(const u64 offset, const size_t length, const bool flush,
const u8* buffer) const {
LOG_ERROR(Service_FS, "Attempted to write to ROMFS file");
// TODO(Subv): Find error code
return MakeResult<size_t>(0);
}
u64 IVFCFile::GetSize() const {
u64 RomFS_Storage::GetSize() const {
return data_size;
}
bool IVFCFile::SetSize(const u64 size) const {
LOG_ERROR(Service_FS, "Attempted to set the size of an IVFC file");
bool RomFS_Storage::SetSize(const u64 size) const {
LOG_ERROR(Service_FS, "Attempted to set the size of an ROMFS file");
return false;
}

View File

@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -10,30 +10,27 @@
#include <vector>
#include "common/common_types.h"
#include "common/file_util.h"
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/directory_backend.h"
#include "core/file_sys/file_backend.h"
#include "core/file_sys/directory.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/storage.h"
#include "core/hle/result.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
/**
* Helper which implements an interface to deal with IVFC images used in some archives
* This should be subclassed by concrete archive types, which will provide the
* input data (load the raw IVFC archive) and override any required methods
* Helper which implements an interface to deal with Switch .istorage ROMFS images used in some
* archives This should be subclassed by concrete archive types, which will provide the input data
* (load the raw ROMFS archive) and override any required methods
*/
class IVFCArchive : public ArchiveBackend {
class RomFS_FileSystem : public FileSystemBackend {
public:
IVFCArchive(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
RomFS_FileSystem(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
: romfs_file(file), data_offset(offset), data_size(size) {}
std::string GetName() const override;
ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
const Mode& mode) const override;
ResultVal<std::unique_ptr<StorageBackend>> OpenFile(const Path& path,
const Mode& mode) const override;
ResultCode DeleteFile(const Path& path) const override;
ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override;
ResultCode DeleteDirectory(const Path& path) const override;
@@ -42,7 +39,7 @@ public:
ResultCode CreateDirectory(const Path& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
u64 GetFreeBytes() const override;
u64 GetFreeSpaceSize() const override;
protected:
std::shared_ptr<FileUtil::IOFile> romfs_file;
@@ -50,9 +47,9 @@ protected:
u64 data_size;
};
class IVFCFile : public FileBackend {
class RomFS_Storage : public StorageBackend {
public:
IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
RomFS_Storage(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size)
: romfs_file(file), data_offset(offset), data_size(size) {}
ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override;
@@ -70,7 +67,7 @@ private:
u64 data_size;
};
class IVFCDirectory : public DirectoryBackend {
class ROMFSDirectory : public DirectoryBackend {
public:
u32 Read(const u32 count, Entry* entries) override {
return 0;

View File

@@ -1,330 +0,0 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/file_util.h"
#include "core/file_sys/disk_archive.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/path_parser.h"
#include "core/file_sys/savedata_archive.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
ResultVal<std::unique_ptr<FileBackend>> SaveDataArchive::OpenFile(const Path& path,
const Mode& mode) const {
LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
if (mode.hex == 0) {
LOG_ERROR(Service_FS, "Empty open mode");
return ERROR_UNSUPPORTED_OPEN_FLAGS;
}
if (mode.create_flag && !mode.write_flag) {
LOG_ERROR(Service_FS, "Create flag set but write flag not set");
return ERROR_UNSUPPORTED_OPEN_FLAGS;
}
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
case PathParser::DirectoryFound:
LOG_ERROR(Service_FS, "Unexpected file or directory in %s", full_path.c_str());
return ERROR_UNEXPECTED_FILE_OR_DIRECTORY;
case PathParser::NotFound:
if (!mode.create_flag) {
LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.",
full_path.c_str());
return ERROR_FILE_NOT_FOUND;
} else {
// Create the file
FileUtil::CreateEmptyFile(full_path);
}
break;
case PathParser::FileFound:
break; // Expected 'success' case
}
FileUtil::IOFile file(full_path, mode.write_flag ? "r+b" : "rb");
if (!file.IsOpen()) {
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error opening %s", full_path.c_str());
return ERROR_FILE_NOT_FOUND;
}
auto disk_file = std::make_unique<DiskFile>(std::move(file), mode);
return MakeResult<std::unique_ptr<FileBackend>>(std::move(disk_file));
}
ResultCode SaveDataArchive::DeleteFile(const Path& path) const {
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
case PathParser::DirectoryFound:
case PathParser::NotFound:
LOG_ERROR(Service_FS, "File not found %s", full_path.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::FileFound:
break; // Expected 'success' case
}
if (FileUtil::Delete(full_path)) {
return RESULT_SUCCESS;
}
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error deleting %s", full_path.c_str());
return ERROR_FILE_NOT_FOUND;
}
ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
const PathParser path_parser_src(src_path);
// TODO: Verify these return codes with HW
if (!path_parser_src.IsValid()) {
LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const PathParser path_parser_dest(dest_path);
if (!path_parser_dest.IsValid()) {
LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto src_path_full = path_parser_src.BuildHostPath(mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS;
}
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
template <typename T>
static ResultCode DeleteDirectoryHelper(const Path& path, const std::string& mount_point,
T deleter) {
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
if (path_parser.IsRootDirectory())
return ERROR_DIRECTORY_NOT_EMPTY;
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::PathNotFound:
case PathParser::NotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
case PathParser::FileFound:
LOG_ERROR(Service_FS, "Unexpected file or directory %s", full_path.c_str());
return ERROR_UNEXPECTED_FILE_OR_DIRECTORY;
case PathParser::DirectoryFound:
break; // Expected 'success' case
}
if (deleter(full_path)) {
return RESULT_SUCCESS;
}
LOG_ERROR(Service_FS, "Directory not empty %s", full_path.c_str());
return ERROR_DIRECTORY_NOT_EMPTY;
}
ResultCode SaveDataArchive::DeleteDirectory(const Path& path) const {
return DeleteDirectoryHelper(path, mount_point, FileUtil::DeleteDir);
}
ResultCode SaveDataArchive::DeleteDirectoryRecursively(const Path& path) const {
return DeleteDirectoryHelper(
path, mount_point, [](const std::string& p) { return FileUtil::DeleteDirRecursively(p); });
}
ResultCode SaveDataArchive::CreateFile(const FileSys::Path& path, u64 size) const {
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
LOG_ERROR(Service_FS, "Unexpected file in path %s", full_path.c_str());
return ERROR_UNEXPECTED_FILE_OR_DIRECTORY;
case PathParser::DirectoryFound:
case PathParser::FileFound:
LOG_ERROR(Service_FS, "%s already exists", full_path.c_str());
return ERROR_FILE_ALREADY_EXISTS;
case PathParser::NotFound:
break; // Expected 'success' case
}
if (size == 0) {
FileUtil::CreateEmptyFile(full_path);
return RESULT_SUCCESS;
}
FileUtil::IOFile file(full_path, "wb");
// Creates a sparse file (or a normal file on filesystems without the concept of sparse files)
// We do this by seeking to the right size, then writing a single null byte.
if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) {
return RESULT_SUCCESS;
}
LOG_ERROR(Service_FS, "Too large file");
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultCode SaveDataArchive::CreateDirectory(const Path& path) const {
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
LOG_ERROR(Service_FS, "Unexpected file in path %s", full_path.c_str());
return ERROR_UNEXPECTED_FILE_OR_DIRECTORY;
case PathParser::DirectoryFound:
case PathParser::FileFound:
LOG_ERROR(Service_FS, "%s already exists", full_path.c_str());
return ERROR_DIRECTORY_ALREADY_EXISTS;
case PathParser::NotFound:
break; // Expected 'success' case
}
if (FileUtil::CreateDir(mount_point + path.AsString())) {
return RESULT_SUCCESS;
}
LOG_CRITICAL(Service_FS, "(unreachable) Unknown error creating %s", mount_point.c_str());
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
const PathParser path_parser_src(src_path);
// TODO: Verify these return codes with HW
if (!path_parser_src.IsValid()) {
LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const PathParser path_parser_dest(dest_path);
if (!path_parser_dest.IsValid()) {
LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto src_path_full = path_parser_src.BuildHostPath(mount_point);
const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point);
if (FileUtil::Rename(src_path_full, dest_path_full)) {
return RESULT_SUCCESS;
}
// TODO(bunnei): Use correct error code
return ResultCode(-1);
}
ResultVal<std::unique_ptr<DirectoryBackend>> SaveDataArchive::OpenDirectory(
const Path& path) const {
const PathParser path_parser(path);
if (!path_parser.IsValid()) {
LOG_ERROR(Service_FS, "Invalid path %s", path.DebugStr().c_str());
return ERROR_INVALID_PATH;
}
const auto full_path = path_parser.BuildHostPath(mount_point);
switch (path_parser.GetHostStatus(mount_point)) {
case PathParser::InvalidMountPoint:
LOG_CRITICAL(Service_FS, "(unreachable) Invalid mount point %s", mount_point.c_str());
return ERROR_FILE_NOT_FOUND;
case PathParser::PathNotFound:
case PathParser::NotFound:
LOG_ERROR(Service_FS, "Path not found %s", full_path.c_str());
return ERROR_PATH_NOT_FOUND;
case PathParser::FileInPath:
case PathParser::FileFound:
LOG_ERROR(Service_FS, "Unexpected file in path %s", full_path.c_str());
return ERROR_UNEXPECTED_FILE_OR_DIRECTORY;
case PathParser::DirectoryFound:
break; // Expected 'success' case
}
auto directory = std::make_unique<DiskDirectory>(full_path);
return MakeResult<std::unique_ptr<DirectoryBackend>>(std::move(directory));
}
u64 SaveDataArchive::GetFreeBytes() const {
// TODO: Stubbed to return 1GiB
return 1024 * 1024 * 1024;
}
} // namespace FileSys

View File

@@ -1,43 +0,0 @@
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <string>
#include "core/file_sys/archive_backend.h"
#include "core/file_sys/directory_backend.h"
#include "core/file_sys/file_backend.h"
#include "core/hle/result.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
/// Archive backend for general save data archive type (SaveData and SystemSaveData)
class SaveDataArchive : public ArchiveBackend {
public:
explicit SaveDataArchive(const std::string& mount_point_) : mount_point(mount_point_) {}
std::string GetName() const override {
return "SaveDataArchive: " + mount_point;
}
ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
const Mode& mode) const override;
ResultCode DeleteFile(const Path& path) const override;
ResultCode RenameFile(const Path& src_path, const Path& dest_path) const override;
ResultCode DeleteDirectory(const Path& path) const override;
ResultCode DeleteDirectoryRecursively(const Path& path) const override;
ResultCode CreateFile(const Path& path, u64 size) const override;
ResultCode CreateDirectory(const Path& path) const override;
ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const override;
ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const override;
u64 GetFreeBytes() const override;
protected:
std::string mount_point;
};
} // namespace FileSys

View File

@@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -8,15 +8,12 @@
#include "common/common_types.h"
#include "core/hle/result.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
class FileBackend : NonCopyable {
class StorageBackend : NonCopyable {
public:
FileBackend() {}
virtual ~FileBackend() {}
StorageBackend() {}
virtual ~StorageBackend() {}
/**
* Read data from the file
@@ -39,10 +36,9 @@ public:
const u8* buffer) const = 0;
/**
* Get the size of the file in bytes
* @return Size of the file in bytes
* Flushes the file
*/
virtual u64 GetSize() const = 0;
virtual void Flush() const = 0;
/**
* Set the size of the file in bytes
@@ -51,16 +47,17 @@ public:
*/
virtual bool SetSize(u64 size) const = 0;
/**
* Get the size of the file in bytes
* @return Size of the file in bytes
*/
virtual u64 GetSize() const = 0;
/**
* Close the file
* @return true if the file closed correctly
*/
virtual bool Close() const = 0;
/**
* Flushes the file
*/
virtual void Flush() const = 0;
};
} // namespace FileSys

View File

@@ -1,163 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cinttypes>
#include "common/alignment.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/title_metadata.h"
#include "core/loader/loader.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
static u32 GetSignatureSize(u32 signature_type) {
switch (signature_type) {
case Rsa4096Sha1:
case Rsa4096Sha256:
return 0x200;
case Rsa2048Sha1:
case Rsa2048Sha256:
return 0x100;
case EllipticSha1:
case EcdsaSha256:
return 0x3C;
}
}
Loader::ResultStatus TitleMetadata::Load() {
FileUtil::IOFile file(filepath, "rb");
if (!file.IsOpen())
return Loader::ResultStatus::Error;
if (!file.ReadBytes(&signature_type, sizeof(u32_be)))
return Loader::ResultStatus::Error;
// Signature lengths are variable, and the body follows the signature
u32 signature_size = GetSignatureSize(signature_type);
tmd_signature.resize(signature_size);
if (!file.ReadBytes(&tmd_signature[0], signature_size))
return Loader::ResultStatus::Error;
// The TMD body start position is rounded to the nearest 0x40 after the signature
size_t body_start = Common::AlignUp(signature_size + sizeof(u32), 0x40);
file.Seek(body_start, SEEK_SET);
// Read our TMD body, then load the amount of ContentChunks specified
if (file.ReadBytes(&tmd_body, sizeof(TitleMetadata::Body)) != sizeof(TitleMetadata::Body))
return Loader::ResultStatus::Error;
for (u16 i = 0; i < tmd_body.content_count; i++) {
ContentChunk chunk;
if (file.ReadBytes(&chunk, sizeof(ContentChunk)) == sizeof(ContentChunk)) {
tmd_chunks.push_back(chunk);
} else {
LOG_ERROR(Service_FS, "Malformed TMD %s, failed to load content chunk index %u!",
filepath.c_str(), i);
return Loader::ResultStatus::ErrorInvalidFormat;
}
}
return Loader::ResultStatus::Success;
}
Loader::ResultStatus TitleMetadata::Save() {
UNIMPLEMENTED();
return Loader::ResultStatus::Success;
}
u64 TitleMetadata::GetTitleID() const {
return tmd_body.title_id;
}
u32 TitleMetadata::GetTitleType() const {
return tmd_body.title_type;
}
u16 TitleMetadata::GetTitleVersion() const {
return tmd_body.title_version;
}
u64 TitleMetadata::GetSystemVersion() const {
return tmd_body.system_version;
}
size_t TitleMetadata::GetContentCount() const {
return tmd_chunks.size();
}
u32 TitleMetadata::GetBootContentID() const {
return tmd_chunks[TMDContentIndex::Main].id;
}
u32 TitleMetadata::GetManualContentID() const {
return tmd_chunks[TMDContentIndex::Manual].id;
}
u32 TitleMetadata::GetDLPContentID() const {
return tmd_chunks[TMDContentIndex::DLP].id;
}
void TitleMetadata::SetTitleID(u64 title_id) {
tmd_body.title_id = title_id;
}
void TitleMetadata::SetTitleType(u32 type) {
tmd_body.title_type = type;
}
void TitleMetadata::SetTitleVersion(u16 version) {
tmd_body.title_version = version;
}
void TitleMetadata::SetSystemVersion(u64 version) {
tmd_body.system_version = version;
}
void TitleMetadata::AddContentChunk(const ContentChunk& chunk) {
tmd_chunks.push_back(chunk);
}
void TitleMetadata::Print() const {
LOG_DEBUG(Service_FS, "%s - %u chunks", filepath.c_str(),
static_cast<u32>(tmd_body.content_count));
// Content info describes ranges of content chunks
LOG_DEBUG(Service_FS, "Content info:");
for (size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
if (tmd_body.contentinfo[i].command_count == 0)
break;
LOG_DEBUG(Service_FS, " Index %04X, Command Count %04X",
static_cast<u32>(tmd_body.contentinfo[i].index),
static_cast<u32>(tmd_body.contentinfo[i].command_count));
}
// For each content info, print their content chunk range
for (size_t i = 0; i < tmd_body.contentinfo.size(); i++) {
u16 index = static_cast<u16>(tmd_body.contentinfo[i].index);
u16 count = static_cast<u16>(tmd_body.contentinfo[i].command_count);
if (count == 0)
continue;
LOG_DEBUG(Service_FS, "Content chunks for content info index %zu:", i);
for (u16 j = index; j < index + count; j++) {
// Don't attempt to print content we don't have
if (j > tmd_body.content_count)
break;
const ContentChunk& chunk = tmd_chunks[j];
LOG_DEBUG(Service_FS, " ID %08X, Index %04X, Type %04x, Size %016" PRIX64,
static_cast<u32>(chunk.id), static_cast<u32>(chunk.index),
static_cast<u32>(chunk.type), static_cast<u64>(chunk.size));
}
}
}
} // namespace FileSys

View File

@@ -1,125 +0,0 @@
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <string>
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
namespace Loader {
enum class ResultStatus;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
namespace FileSys {
enum TMDSignatureType : u32 {
Rsa4096Sha1 = 0x10000,
Rsa2048Sha1 = 0x10001,
EllipticSha1 = 0x10002,
Rsa4096Sha256 = 0x10003,
Rsa2048Sha256 = 0x10004,
EcdsaSha256 = 0x10005
};
enum TMDContentTypeFlag : u16 {
Encrypted = 1 << 1,
Disc = 1 << 2,
CFM = 1 << 3,
Optional = 1 << 14,
Shared = 1 << 15
};
/**
* Helper which implements an interface to read and write Title Metadata (TMD) files.
* If a file path is provided and the file exists, it can be parsed and used, otherwise
* it must be created. The TMD file can then be interpreted, modified and/or saved.
*/
class TitleMetadata {
public:
struct ContentChunk {
u32_be id;
u16_be index;
u16_be type;
u64_be size;
std::array<u8, 0x20> hash;
};
static_assert(sizeof(ContentChunk) == 0x30, "TMD ContentChunk structure size is wrong");
struct ContentInfo {
u16_be index;
u16_be command_count;
std::array<u8, 0x20> hash;
};
static_assert(sizeof(ContentInfo) == 0x24, "TMD ContentInfo structure size is wrong");
#pragma pack(push, 1)
struct Body {
std::array<u8, 0x40> issuer;
u8 version;
u8 ca_crl_version;
u8 signer_crl_version;
u8 reserved;
u64_be system_version;
u64_be title_id;
u32_be title_type;
u16_be group_id;
u32_be savedata_size;
u32_be srl_private_savedata_size;
std::array<u8, 4> reserved_2;
u8 srl_flag;
std::array<u8, 0x31> reserved_3;
u32_be access_rights;
u16_be title_version;
u16_be content_count;
u16_be boot_content;
std::array<u8, 2> reserved_4;
std::array<u8, 0x20> contentinfo_hash;
std::array<ContentInfo, 64> contentinfo;
};
static_assert(sizeof(Body) == 0x9C4, "TMD body structure size is wrong");
#pragma pack(pop)
explicit TitleMetadata(std::string& path) : filepath(std::move(path)) {}
Loader::ResultStatus Load();
Loader::ResultStatus Save();
u64 GetTitleID() const;
u32 GetTitleType() const;
u16 GetTitleVersion() const;
u64 GetSystemVersion() const;
size_t GetContentCount() const;
u32 GetBootContentID() const;
u32 GetManualContentID() const;
u32 GetDLPContentID() const;
void SetTitleID(u64 title_id);
void SetTitleType(u32 type);
void SetTitleVersion(u16 version);
void SetSystemVersion(u64 version);
void AddContentChunk(const ContentChunk& chunk);
void Print() const;
private:
enum TMDContentIndex { Main = 0, Manual = 1, DLP = 2 };
Body tmd_body;
u32_be signature_type;
std::vector<u8> tmd_signature;
std::vector<ContentChunk> tmd_chunks;
std::string filepath;
};
} // namespace FileSys

View File

@@ -57,9 +57,10 @@ const u32 SIGTERM = 15;
const u32 MSG_WAITALL = 8;
#endif
const u32 R15_REGISTER = 15;
const u32 CPSR_REGISTER = 25;
const u32 FPSCR_REGISTER = 58;
const u32 X30_REGISTER = 30;
const u32 SP_REGISTER = 31;
const u32 PC_REGISTER = 32;
const u32 CPSR_REGISTER = 33;
// For sample XML files see the GDB source /gdb/features
// GDB also wants the l character at the start
@@ -68,48 +69,62 @@ static const char* target_xml =
R"(l<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<feature name="org.gnu.gdb.arm.core">
<reg name="r0" bitsize="32"/>
<reg name="r1" bitsize="32"/>
<reg name="r2" bitsize="32"/>
<reg name="r3" bitsize="32"/>
<reg name="r4" bitsize="32"/>
<reg name="r5" bitsize="32"/>
<reg name="r6" bitsize="32"/>
<reg name="r7" bitsize="32"/>
<reg name="r8" bitsize="32"/>
<reg name="r9" bitsize="32"/>
<reg name="r10" bitsize="32"/>
<reg name="r11" bitsize="32"/>
<reg name="r12" bitsize="32"/>
<reg name="sp" bitsize="32" type="data_ptr"/>
<reg name="lr" bitsize="32"/>
<reg name="pc" bitsize="32" type="code_ptr"/>
<feature name="org.gnu.gdb.aarch64.core">
<reg name="x0" bitsize="64"/>
<reg name="x1" bitsize="64"/>
<reg name="x2" bitsize="64"/>
<reg name="x3" bitsize="64"/>
<reg name="x4" bitsize="64"/>
<reg name="x5" bitsize="64"/>
<reg name="x6" bitsize="64"/>
<reg name="x7" bitsize="64"/>
<reg name="x8" bitsize="64"/>
<reg name="x9" bitsize="64"/>
<reg name="x10" bitsize="64"/>
<reg name="x11" bitsize="64"/>
<reg name="x12" bitsize="64"/>
<reg name="x13" bitsize="64"/>
<reg name="x14" bitsize="64"/>
<reg name="x15" bitsize="64"/>
<reg name="x16" bitsize="64"/>
<reg name="x17" bitsize="64"/>
<reg name="x18" bitsize="64"/>
<reg name="x19" bitsize="64"/>
<reg name="x20" bitsize="64"/>
<reg name="x21" bitsize="64"/>
<reg name="x22" bitsize="64"/>
<reg name="x23" bitsize="64"/>
<reg name="x24" bitsize="64"/>
<reg name="x25" bitsize="64"/>
<reg name="x26" bitsize="64"/>
<reg name="x27" bitsize="64"/>
<reg name="x28" bitsize="64"/>
<reg name="x29" bitsize="64"/>
<reg name="x30" bitsize="64"/>
<reg name="sp" bitsize="64" type="data_ptr"/>
<!-- The CPSR is register 25, rather than register 16, because
the FPA registers historically were placed between the PC
and the CPSR in the "g" packet. -->
<reg name="pc" bitsize="64" type="code_ptr"/>
<reg name="cpsr" bitsize="32" regnum="25"/>
</feature>
<feature name="org.gnu.gdb.arm.vfp">
<reg name="d0" bitsize="64" type="float"/>
<reg name="d1" bitsize="64" type="float"/>
<reg name="d2" bitsize="64" type="float"/>
<reg name="d3" bitsize="64" type="float"/>
<reg name="d4" bitsize="64" type="float"/>
<reg name="d5" bitsize="64" type="float"/>
<reg name="d6" bitsize="64" type="float"/>
<reg name="d7" bitsize="64" type="float"/>
<reg name="d8" bitsize="64" type="float"/>
<reg name="d9" bitsize="64" type="float"/>
<reg name="d10" bitsize="64" type="float"/>
<reg name="d11" bitsize="64" type="float"/>
<reg name="d12" bitsize="64" type="float"/>
<reg name="d13" bitsize="64" type="float"/>
<reg name="d14" bitsize="64" type="float"/>
<reg name="d15" bitsize="64" type="float"/>
<reg name="fpscr" bitsize="32" type="int" group="float"/>
<flags id="cpsr_flags" size="4">
<field name="SP" start="0" end="0"/>
<field name="" start="1" end="1"/>
<field name="EL" start="2" end="3"/>
<field name="nRW" start="4" end="4"/>
<field name="" start="5" end="5"/>
<field name="F" start="6" end="6"/>
<field name="I" start="7" end="7"/>
<field name="A" start="8" end="8"/>
<field name="D" start="9" end="9"/>
<field name="IL" start="20" end="20"/>
<field name="SS" start="21" end="21"/>
<field name="V" start="28" end="28"/>
<field name="C" start="29" end="29"/>
<field name="Z" start="30" end="30"/>
<field name="N" start="31" end="31"/>
</flags>
<reg name="cpsr" bitsize="32" type="cpsr_flags"/>
</feature>
</target>
)";
@@ -143,12 +158,12 @@ WSADATA InitData;
struct Breakpoint {
bool active;
PAddr addr;
u32 len;
u64 len;
};
static std::map<u32, Breakpoint> breakpoints_execute;
static std::map<u32, Breakpoint> breakpoints_read;
static std::map<u32, Breakpoint> breakpoints_write;
static std::map<u64, Breakpoint> breakpoints_execute;
static std::map<u64, Breakpoint> breakpoints_read;
static std::map<u64, Breakpoint> breakpoints_write;
/**
* Turns hex string character into the equivalent byte.
@@ -183,11 +198,11 @@ static u8 NibbleToHex(u8 n) {
}
/**
* Converts input hex string characters into an array of equivalent of u8 bytes.
*
* @param src Pointer to array of output hex string characters.
* @param len Length of src array.
*/
* Converts input hex string characters into an array of equivalent of u8 bytes.
*
* @param src Pointer to array of output hex string characters.
* @param len Length of src array.
*/
static u32 HexToInt(const u8* src, size_t len) {
u32 output = 0;
while (len-- > 0) {
@@ -197,6 +212,21 @@ static u32 HexToInt(const u8* src, size_t len) {
return output;
}
/**
* Converts input hex string characters into an array of equivalent of u8 bytes.
*
* @param src Pointer to array of output hex string characters.
* @param len Length of src array.
*/
static u64 HexToLong(const u8* src, size_t len) {
u64 output = 0;
while (len-- > 0) {
output = (output << 4) | HexCharToValue(src[0]);
src++;
}
return output;
}
/**
* Converts input array of u8 bytes into their equivalent hex string characters.
*
@@ -234,8 +264,21 @@ static void GdbHexToMem(u8* dest, const u8* src, size_t len) {
*/
static void IntToGdbHex(u8* dest, u32 v) {
for (int i = 0; i < 8; i += 2) {
dest[i + 1] = NibbleToHex(v >> (4 * i));
dest[i] = NibbleToHex(v >> (4 * (i + 1)));
dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
}
}
/**
* Convert a u64 into a gdb-formatted hex string.
*
* @param dest Pointer to buffer to store output hex string characters.
* @param v Value to convert.
*/
static void LongToGdbHex(u8* dest, u64 v) {
for (int i = 0; i < 16; i += 2) {
dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
}
}
@@ -255,6 +298,22 @@ static u32 GdbHexToInt(const u8* src) {
return output;
}
/**
* Convert a gdb-formatted hex string into a u64.
*
* @param src Pointer to hex string.
*/
static u64 GdbHexToLong(const u8* src) {
u64 output = 0;
for (int i = 0; i < 16; i += 2) {
output = (output << 4) | HexCharToValue(src[15 - i - 1]);
output = (output << 4) | HexCharToValue(src[15 - i]);
}
return output;
}
/// Read a byte from the gdb client.
static u8 ReadByte() {
u8 c;
@@ -277,7 +336,7 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) {
*
* @param type Type of breakpoint list.
*/
static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) {
static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) {
switch (type) {
case BreakpointType::Execute:
return breakpoints_execute;
@@ -297,19 +356,19 @@ static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) {
* @param addr Address of breakpoint.
*/
static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
auto bp = p.find(addr);
auto bp = p.find(static_cast<u64>(addr));
if (bp != p.end()) {
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n",
bp->second.len, bp->second.addr, type);
p.erase(addr);
p.erase(static_cast<u64>(addr));
}
}
BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) {
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
auto next_breakpoint = p.lower_bound(addr);
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
auto next_breakpoint = p.lower_bound(static_cast<u64>(addr));
BreakpointAddress breakpoint;
if (next_breakpoint != p.end()) {
@@ -328,11 +387,11 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
return false;
}
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
auto bp = p.find(addr);
auto bp = p.find(static_cast<u64>(addr));
if (bp != p.end()) {
u32 len = bp->second.len;
u64 len = bp->second.len;
// IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints
// no matter if it's a 4-byte or 2-byte instruction. When you execute a
@@ -419,7 +478,7 @@ static void HandleQuery() {
SendReply("T0");
} else if (strncmp(query, "Supported", strlen("Supported")) == 0) {
// PacketSize needs to be large enough for target xml
SendReply("PacketSize=800;qXfer:features:read+");
SendReply("PacketSize=2000;qXfer:features:read+");
} else if (strncmp(query, "Xfer:features:read:target.xml:",
strlen("Xfer:features:read:target.xml:")) == 0) {
SendReply(target_xml);
@@ -450,9 +509,7 @@ static void SendSignal(u32 signal) {
latest_signal = signal;
std::string buffer =
Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
htonl(Core::CPU().GetPC()), 13, htonl(Core::CPU().GetReg(13)));
std::string buffer = Common::StringFromFormat("T%02x", latest_signal);
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
SendReply(buffer.c_str());
}
@@ -538,16 +595,12 @@ static void ReadRegister() {
id |= HexCharToValue(command_buffer[2]);
}
if (id <= R15_REGISTER) {
IntToGdbHex(reply, Core::CPU().GetReg(id));
if (id <= SP_REGISTER) {
LongToGdbHex(reply, Core::CPU().GetReg(static_cast<int>(id)));
} else if (id == PC_REGISTER) {
LongToGdbHex(reply, Core::CPU().GetPC());
} else if (id == CPSR_REGISTER) {
IntToGdbHex(reply, Core::CPU().GetCPSR());
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
IntToGdbHex(reply, Core::CPU().GetVFPReg(
id - CPSR_REGISTER -
1)); // VFP registers should start at 26, so one after CSPR_REGISTER
} else if (id == FPSCR_REGISTER) {
UNIMPLEMENTED();
} else {
return SendReply("E01");
}
@@ -562,21 +615,19 @@ static void ReadRegisters() {
u8* bufptr = buffer;
for (int reg = 0; reg <= R15_REGISTER; reg++) {
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetReg(reg));
for (int reg = 0; reg <= SP_REGISTER; reg++) {
LongToGdbHex(bufptr + reg * 16, Core::CPU().GetReg(reg));
}
bufptr += (16 * CHAR_BIT);
bufptr += (32 * 16);
LongToGdbHex(bufptr, Core::CPU().GetPC());
bufptr += 16;
IntToGdbHex(bufptr, Core::CPU().GetCPSR());
bufptr += CHAR_BIT;
for (int reg = 0; reg <= 31; reg++) {
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetVFPReg(reg));
}
bufptr += (32 * CHAR_BIT);
bufptr += 8;
SendReply(reinterpret_cast<char*>(buffer));
}
@@ -592,14 +643,12 @@ static void WriteRegister() {
id |= HexCharToValue(command_buffer[2]);
}
if (id <= R15_REGISTER) {
Core::CPU().SetReg(id, GdbHexToInt(buffer_ptr));
if (id <= SP_REGISTER) {
Core::CPU().SetReg(id, GdbHexToLong(buffer_ptr));
} else if (id == PC_REGISTER) {
Core::CPU().SetPC(GdbHexToLong(buffer_ptr));
} else if (id == CPSR_REGISTER) {
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr));
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
Core::CPU().SetVFPReg(id - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr));
} else if (id == FPSCR_REGISTER) {
UNIMPLEMENTED();
} else {
return SendReply("E01");
}
@@ -614,20 +663,14 @@ static void WriteRegisters() {
if (command_buffer[0] != 'G')
return SendReply("E01");
for (int i = 0, reg = 0; reg <= FPSCR_REGISTER; i++, reg++) {
if (reg <= R15_REGISTER) {
Core::CPU().SetReg(reg, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
for (int i = 0, reg = 0; reg <= CPSR_REGISTER; i++, reg++) {
if (reg <= SP_REGISTER) {
Core::CPU().SetReg(reg, GdbHexToLong(buffer_ptr + i * 16));
} else if (reg == PC_REGISTER) {
Core::CPU().SetPC(GdbHexToLong(buffer_ptr + i * 16));
} else if (reg == CPSR_REGISTER) {
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * CHAR_BIT));
} else if (reg == CPSR_REGISTER - 1) {
// Dummy FPA register, ignore
} else if (reg < CPSR_REGISTER) {
// Dummy FPA registers, ignore
i += 2;
} else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) {
Core::CPU().SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT));
i++; // Skip padding
} else if (reg == FPSCR_REGISTER) {
Core::CPU().SetCPSR(GdbHexToInt(buffer_ptr + i * 16));
} else {
UNIMPLEMENTED();
}
}
@@ -641,13 +684,13 @@ static void ReadMemory() {
auto start_offset = command_buffer + 1;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
start_offset = addr_pos + 1;
u32 len =
HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
u64 len =
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len);
LOG_DEBUG(Debug_GDBStub, "gdb: addr: %016llx len: %016llx\n", addr, len);
if (len * 2 > sizeof(reply)) {
SendReply("E01");
@@ -669,11 +712,11 @@ static void ReadMemory() {
static void WriteMemory() {
auto start_offset = command_buffer + 1;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
VAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
start_offset = addr_pos + 1;
auto len_pos = std::find(start_offset, command_buffer + command_length, ':');
u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset));
u64 len = HexToLong(start_offset, static_cast<u64>(len_pos - start_offset));
if (!Memory::IsValidVirtualAddress(addr)) {
return SendReply("E00");
@@ -726,8 +769,8 @@ static void Continue() {
* @param addr Address of breakpoint.
* @param len Length of breakpoint.
*/
static bool CommitBreakpoint(BreakpointType type, PAddr addr, u32 len) {
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) {
std::map<u64, Breakpoint>& p = GetBreakpointList(type);
Breakpoint breakpoint;
breakpoint.active = true;
@@ -766,11 +809,11 @@ static void AddBreakpoint() {
auto start_offset = command_buffer + 3;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
start_offset = addr_pos + 1;
u32 len =
HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset));
u64 len =
HexToLong(start_offset, static_cast<u64>((command_buffer + command_length) - start_offset));
if (type == BreakpointType::Access) {
// Access is made up of Read and Write types, so add both breakpoints
@@ -815,7 +858,7 @@ static void RemoveBreakpoint() {
auto start_offset = command_buffer + 3;
auto addr_pos = std::find(start_offset, command_buffer + command_length, ',');
PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset));
PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset));
if (type == BreakpointType::Access) {
// Access is made up of Read and Write types, so add both breakpoints
@@ -905,7 +948,7 @@ void ToggleServer(bool status) {
server_enabled = status;
// Start server
if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
Init();
}
} else {
@@ -1034,4 +1077,4 @@ bool GetCpuStepFlag() {
void SetCpuStepFlag(bool is_step) {
step_loop = is_step;
}
};
}; // namespace GDBStub

View File

@@ -91,4 +91,4 @@ bool GetCpuStepFlag();
* @param is_step
*/
void SetCpuStepFlag(bool is_step);
}
} // namespace GDBStub

View File

@@ -28,4 +28,4 @@ void Init() {
config_mem.firm_ctr_sdk_ver = 0x0000F297;
}
} // namespace
} // namespace ConfigMem

View File

@@ -53,4 +53,4 @@ extern ConfigMemDef config_mem;
void Init();
} // namespace
} // namespace ConfigMem

View File

@@ -19,7 +19,6 @@ constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
// TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
constexpr auto ERR_INVALID_HANDLE = Kernel::ERR_INVALID_HANDLE_OS;
enum class ControlCommand : u32 {
ConvertSessionToDomain = 0,
ConvertDomainToSession = 1,
@@ -81,13 +80,13 @@ struct BufferDescriptorX {
u32_le address_bits_0_31;
u32_le Counter() const {
u32_le counter{ counter_bits_0_5 };
u32_le counter{counter_bits_0_5};
counter |= counter_bits_9_11 << 9;
return counter;
}
VAddr Address() const {
VAddr address{ address_bits_0_31 };
VAddr address{address_bits_0_31};
address |= static_cast<VAddr>(address_bits_32_35) << 32;
address |= static_cast<VAddr>(address_bits_36_38) << 36;
return address;
@@ -107,14 +106,14 @@ struct BufferDescriptorABW {
};
VAddr Address() const {
VAddr address{ address_bits_0_31 };
VAddr address{address_bits_0_31};
address |= static_cast<VAddr>(address_bits_32_35) << 32;
address |= static_cast<VAddr>(address_bits_36_38) << 36;
return address;
}
u64 Size() const {
u64 size{ size_bits_0_31 };
u64 size{size_bits_0_31};
size |= static_cast<u64>(size_bits_32_35) << 32;
return size;
}
@@ -130,10 +129,14 @@ struct BufferDescriptorC {
};
VAddr Address() const {
VAddr address{ address_bits_0_31 };
VAddr address{address_bits_0_31};
address |= static_cast<VAddr>(address_bits_32_47) << 32;
return address;
}
u64 Size() const {
return static_cast<u64>(size);
}
};
static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
@@ -144,6 +147,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 {
@@ -154,7 +162,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

@@ -9,10 +9,13 @@
#include <type_traits>
#include <utility>
#include "core/hle/ipc.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/domain.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/server_port.h"
namespace IPC {
@@ -51,6 +54,10 @@ public:
unsigned GetCurrentOffset() const {
return static_cast<unsigned>(index);
}
void SetCurrentOffset(unsigned offset) {
index = static_cast<ptrdiff_t>(offset);
}
};
class RequestBuilder : public RequestHelperBase {
@@ -63,13 +70,20 @@ public:
: RequestHelperBase(context) {
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
context.ClearIncomingObjects();
IPC::CommandHeader header{};
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
// padding.
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
if (context.IsDomain())
if (context.IsDomain()) {
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
} else {
// If we're not in a domain, turn the domain object parameters into move handles.
num_handles_to_move += num_domain_objects;
num_domain_objects = 0;
}
header.data_size.Assign(raw_data_size);
if (num_handles_to_copy || num_handles_to_move) {
@@ -100,7 +114,16 @@ public:
template <class T, class... Args>
void PushIpcInterface(Args&&... args) {
context->AddDomainObject(std::make_shared<T>(std::forward<Args>(args)...));
auto iface = std::make_shared<T>(std::forward<Args>(args)...);
if (context->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
auto sessions = Kernel::ServerSession::CreateSessionPair(iface->GetServiceName());
auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions);
auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions);
iface->ClientConnected(server);
context->AddMoveObject(std::move(client));
}
}
// Validate on destruction, as there shouldn't be any case where we don't want it
@@ -282,6 +305,11 @@ inline u64 RequestParser::Pop() {
return msw << 32 | lsw;
}
template <>
inline s64 RequestParser::Pop() {
return static_cast<s64>(Pop<u64>());
}
template <>
inline bool RequestParser::Pop() {
return Pop<u8>() != 0;

View File

@@ -57,4 +57,4 @@ private:
~AddressArbiter() override;
};
} // namespace FileSys
} // namespace Kernel

View File

@@ -39,4 +39,4 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
}
} // namespace
} // namespace Kernel

View File

@@ -47,4 +47,4 @@ private:
~ClientPort() override;
};
} // namespace
} // namespace Kernel

View File

@@ -48,4 +48,4 @@ ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) {
return server->HandleSyncRequest(std::move(thread));
}
} // namespace
} // namespace Kernel

View File

@@ -45,4 +45,4 @@ private:
~ClientSession() override;
};
} // namespace
} // namespace Kernel

View File

@@ -43,7 +43,7 @@ void ConditionVariable::Acquire(Thread* thread) {
ResultCode ConditionVariable::Release(s32 target) {
if (target == -1) {
// When -1, wake up all waiting threads
SetAvailableCount(GetWaitingThreads().size());
SetAvailableCount(static_cast<s32>(GetWaitingThreads().size()));
WakeupAllWaitingThreads();
} else {
// Otherwise, wake up just a single thread

View File

@@ -4,8 +4,8 @@
#pragma once
#include <queue>
#include <string>
#include <queue>
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/wait_object.h"

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

@@ -52,4 +52,4 @@ void Event::WakeupAllWaitingThreads() {
signaled = false;
}
} // namespace
} // namespace Kernel

View File

@@ -49,4 +49,4 @@ private:
~Event() override;
};
} // namespace
} // namespace Kernel

View File

@@ -104,4 +104,4 @@ void HandleTable::Clear() {
next_free_slot = 0;
}
} // namespace
} // namespace Kernel

View File

@@ -130,4 +130,4 @@ private:
extern HandleTable g_handle_table;
} // namespace
} // namespace Kernel

View File

@@ -81,13 +81,8 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
for (unsigned i = 0; i < command_header->num_buf_w_descriptors; ++i) {
buffer_w_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
}
if (command_header->buf_c_descriptor_flags !=
IPC::CommandHeader::BufferDescriptorCFlag::Disabled) {
if (command_header->buf_c_descriptor_flags !=
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
UNIMPLEMENTED();
}
}
buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
// Padding to align to 16 bytes
rp.AlignWithPadding();
@@ -102,13 +97,45 @@ 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();
rp.SetCurrentOffset(buffer_c_offset);
// For Inline buffers, the response data is written directly to buffer_c_offset
// and in this case we don't have any BufferDescriptorC on the request.
if (command_header->buf_c_descriptor_flags >
IPC::CommandHeader::BufferDescriptorCFlag::InlineDescriptor) {
if (command_header->buf_c_descriptor_flags ==
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
} else {
unsigned num_buf_c_descriptors =
static_cast<unsigned>(command_header->buf_c_descriptor_flags.Value()) - 2;
// This is used to detect possible underflows, in case something is broken
// with the two ifs above and the flags value is == 0 || == 1.
ASSERT(num_buf_c_descriptors < 14);
for (unsigned i = 0; i < num_buf_c_descriptors; ++i) {
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
}
}
}
rp.SetCurrentOffset(data_payload_offset);
command = rp.Pop<u32_le>();
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
}
@@ -182,7 +209,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
for (auto& object : domain_objects) {
request_handlers.emplace_back(object);
dst_cmdbuf[domain_offset++] = request_handlers.size();
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
}
}
return RESULT_SUCCESS;

View File

@@ -143,6 +143,10 @@ public:
return buffer_b_desciptors;
}
const std::vector<IPC::BufferDescriptorC>& BufferDescriptorC() const {
return buffer_c_desciptors;
}
const std::unique_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
return domain_message_header;
}
@@ -151,13 +155,13 @@ public:
return domain != nullptr;
}
template<typename T>
template <typename T>
SharedPtr<T> GetCopyObject(size_t index) {
ASSERT(index < copy_objects.size());
return DynamicObjectCast<T>(copy_objects[index]);
}
template<typename T>
template <typename T>
SharedPtr<T> GetMoveObject(size_t index) {
ASSERT(index < move_objects.size());
return DynamicObjectCast<T>(move_objects[index]);
@@ -175,6 +179,14 @@ public:
domain_objects.emplace_back(std::move(object));
}
/// Clears the list of objects so that no lingering objects are written accidentally to the
/// response buffer.
void ClearIncomingObjects() {
move_objects.clear();
copy_objects.clear();
domain_objects.clear();
}
private:
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
SharedPtr<Kernel::Domain> domain;
@@ -192,8 +204,10 @@ private:
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
std::vector<IPC::BufferDescriptorABW> buffer_w_desciptors;
std::vector<IPC::BufferDescriptorC> buffer_c_desciptors;
unsigned data_payload_offset{};
unsigned buffer_c_offset{};
u32_le command{};
};

View File

@@ -105,7 +105,6 @@ public:
UNREACHABLE();
}
public:
static unsigned int next_object_id;

View File

@@ -95,10 +95,8 @@ MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
}
}
void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {
}
void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
void MapSharedPages(VMManager& address_space) {
}
void MapSharedPages(VMManager& address_space) {}
} // namespace Kernel

View File

@@ -41,9 +41,9 @@ public:
return HANDLE_TYPE;
}
u32 priority; ///< The priority of the mutex, used for priority inheritance.
std::string name; ///< Name of mutex (optional)
VAddr guest_addr; ///< Address of the guest mutex value
u32 priority; ///< The priority of the mutex, used for priority inheritance.
std::string name; ///< Name of mutex (optional)
VAddr guest_addr; ///< Address of the guest mutex value
/**
* Elevate the mutex priority to the best priority

View File

@@ -131,6 +131,8 @@ public:
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
/// this value from the process header.
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
u32 is_virtual_address_memory_enabled = 0;
/// Current status of the process
ProcessStatus status;

View File

@@ -151,4 +151,4 @@ void ResourceLimitsInit() {
void ResourceLimitsShutdown() {}
} // namespace
} // namespace Kernel

View File

@@ -123,4 +123,4 @@ void ResourceLimitsInit();
// Destroys the resource limits
void ResourceLimitsShutdown();
} // namespace
} // namespace Kernel

View File

@@ -50,4 +50,4 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP
return std::make_tuple(std::move(server_port), std::move(client_port));
}
} // namespace
} // namespace Kernel

View File

@@ -72,4 +72,4 @@ private:
~ServerPort() override;
};
} // namespace
} // namespace Kernel

View File

@@ -113,4 +113,4 @@ private:
* in the command buffer.
*/
ResultCode TranslateHLERequest(ServerSession* server_session);
}
} // namespace Kernel

View File

@@ -9,4 +9,4 @@ namespace Kernel {
Session::Session() {}
Session::~Session() {}
}
} // namespace Kernel

View File

@@ -24,4 +24,4 @@ public:
ServerSession* server = nullptr; ///< The server endpoint of the session.
SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional).
};
}
} // namespace Kernel

View File

@@ -98,10 +98,10 @@ public:
ResultCode Unmap(Process* target_process, VAddr address);
/**
* Gets a pointer to the shared memory block
* @param offset Offset from the start of the shared memory block to get pointer
* @return Pointer to the shared memory block from the specified offset
*/
* Gets a pointer to the shared memory block
* @param offset Offset from the start of the shared memory block to get pointer
* @return Pointer to the shared memory block from the specified offset
*/
u8* GetPointer(u32 offset = 0);
/// Process that created this shared memory block.
@@ -129,4 +129,4 @@ private:
~SharedMemory() override;
};
} // namespace
} // namespace Kernel

View File

@@ -57,7 +57,7 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
}
/// Connect to an OS service given the port name, returns the handle to the port to out
static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) {
static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) {
if (!Memory::IsValidVirtualAddress(port_name_address))
return ERR_NOT_FOUND;
@@ -253,8 +253,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) {
static ResultCode ArbitrateLock(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",
@@ -278,7 +278,7 @@ static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
}
/// Unlock a mutex
static ResultCode UnlockMutex(VAddr mutex_addr) {
static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr);
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
@@ -305,14 +305,27 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
info_sub_id, handle);
ASSERT(handle == 0 || handle == CurrentProcess);
auto& vm_manager = g_current_process->vm_manager;
switch (static_cast<GetInfoType>(info_id)) {
case GetInfoType::AllowedCpuIdBitmask:
*result = g_current_process->allowed_processor_mask;
break;
case GetInfoType::AllowedThreadPrioBitmask:
*result = g_current_process->allowed_thread_priority_mask;
break;
case GetInfoType::MapRegionBaseAddr:
*result = vm_manager.GetMapRegionBaseAddr();
break;
case GetInfoType::MapRegionSize:
*result = vm_manager.GetAddressSpaceSize();
break;
case GetInfoType::HeapRegionBaseAddr:
*result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
break;
case GetInfoType::HeapRegionSize:
*result = Memory::HEAP_SIZE;
break;
case GetInfoType::TotalMemoryUsage:
*result = vm_manager.GetTotalMemoryUsage();
break;
@@ -334,6 +347,18 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
case GetInfoType::NewMapRegionSize:
*result = vm_manager.GetNewMapRegionSize();
break;
case GetInfoType::IsVirtualAddressMemoryEnabled:
*result = g_current_process->is_virtual_address_memory_enabled;
break;
case GetInfoType::TitleId:
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
*result = 0;
break;
case GetInfoType::PrivilegedProcessId:
LOG_WARNING(Kernel_SVC,
"(STUBBED) Attempted to query priviledged process id bounds, returned 0");
*result = 0;
break;
default:
UNIMPLEMENTED();
}
@@ -709,6 +734,23 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
return RESULT_SUCCESS;
}
static ResultCode SetThreadCoreMask(u64, u64, u64) {
LOG_WARNING(Kernel_SVC, "(STUBBED) called");
return RESULT_SUCCESS;
}
static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions,
u32 remote_permissions) {
LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz,
local_permissions, remote_permissions);
auto sharedMemHandle = SharedMemory::Create(
g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz,
(Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions);
CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
return RESULT_SUCCESS;
}
namespace {
struct FunctionDef {
using Func = void();
@@ -735,7 +777,7 @@ static const FunctionDef SVC_Table[] = {
{0x0C, SvcWrap<GetThreadPriority>, "GetThreadPriority"},
{0x0D, SvcWrap<SetThreadPriority>, "SetThreadPriority"},
{0x0E, nullptr, "GetThreadCoreMask"},
{0x0F, nullptr, "SetThreadCoreMask"},
{0x0F, SvcWrap<SetThreadCoreMask>, "SetThreadCoreMask"},
{0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"},
{0x11, nullptr, "SignalEvent"},
{0x12, nullptr, "ClearEvent"},
@@ -746,12 +788,12 @@ static const FunctionDef SVC_Table[] = {
{0x17, SvcWrap<ResetSignal>, "ResetSignal"},
{0x18, SvcWrap<WaitSynchronization>, "WaitSynchronization"},
{0x19, SvcWrap<CancelSynchronization>, "CancelSynchronization"},
{0x1A, SvcWrap<LockMutex>, "LockMutex"},
{0x1B, SvcWrap<UnlockMutex>, "UnlockMutex"},
{0x1A, SvcWrap<ArbitrateLock>, "ArbitrateLock"},
{0x1B, SvcWrap<ArbitrateUnlock>, "ArbitrateUnlock"},
{0x1C, SvcWrap<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"},
{0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"},
{0x1E, SvcWrap<GetSystemTick>, "GetSystemTick"},
{0x1F, SvcWrap<ConnectToPort>, "ConnectToPort"},
{0x1F, SvcWrap<ConnectToNamedPort>, "ConnectToNamedPort"},
{0x20, nullptr, "SendSyncRequestLight"},
{0x21, SvcWrap<SendSyncRequest>, "SendSyncRequest"},
{0x22, nullptr, "SendSyncRequestWithUserBuffer"},
@@ -795,12 +837,12 @@ static const FunctionDef SVC_Table[] = {
{0x48, nullptr, "Unknown"},
{0x49, nullptr, "Unknown"},
{0x4A, nullptr, "Unknown"},
{0x4B, nullptr, "Unknown"},
{0x4C, nullptr, "Unknown"},
{0x4B, nullptr, "CreateJitMemory"},
{0x4C, nullptr, "MapJitMemory"},
{0x4D, nullptr, "SleepSystem"},
{0x4E, nullptr, "ReadWriteRegister"},
{0x4F, nullptr, "SetProcessActivity"},
{0x50, nullptr, "CreateSharedMemory"},
{0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"},
{0x51, nullptr, "MapTransferMemory"},
{0x52, nullptr, "UnmapTransferMemory"},
{0x53, nullptr, "CreateInterruptEvent"},

View File

@@ -14,7 +14,11 @@ struct MemoryInfo {
u32 type;
u32 attributes;
u32 permission;
u32 device_refcount;
u32 ipc_refcount;
INSERT_PADDING_WORDS(1);
};
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
struct PageInfo {
u64 flags;
@@ -24,14 +28,28 @@ struct PageInfo {
enum class GetInfoType : u64 {
// 1.0.0+
AllowedCpuIdBitmask = 0,
AllowedThreadPrioBitmask = 1,
MapRegionBaseAddr = 2,
MapRegionSize = 3,
HeapRegionBaseAddr = 4,
HeapRegionSize = 5,
TotalMemoryUsage = 6,
TotalHeapUsage = 7,
IsCurrentProcessBeingDebugged = 8,
ResourceHandleLimit = 9,
IdleTickCount = 10,
RandomEntropy = 11,
PerformanceCounter = 0xF0000002,
// 2.0.0+
AddressSpaceBaseAddr = 12,
AddressSpaceSize = 13,
NewMapRegionBaseAddr = 14,
NewMapRegionSize = 15,
// 3.0.0+
IsVirtualAddressMemoryEnabled = 16,
TitleId = 18,
// 4.0.0+
PrivilegedProcessId = 19,
};
void CallSVC(u32 immediate);

View File

@@ -145,6 +145,15 @@ void SvcWrap() {
FuncReturn(retval);
}
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;
Core::CPU().SetReg(1, param_1);
FuncReturn(retval);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// Function wrappers that return type u32

View File

@@ -111,4 +111,4 @@ void TimersInit() {
void TimersShutdown() {}
} // namespace
} // namespace Kernel

View File

@@ -76,4 +76,4 @@ void TimersInit();
/// Tears down the timer variables
void TimersShutdown();
} // namespace
} // namespace Kernel

View File

@@ -6,9 +6,9 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/arm/arm_interface.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/vm_manager.h"
#include "core/core.h"
#include "core/memory.h"
#include "core/memory_setup.h"
#include "core/mmio.h"
@@ -86,7 +86,8 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
VirtualMemoryArea& final_vma = vma_handle->second;
ASSERT(final_vma.size == size);
Core::CPU().MapBackingMemory(target, size, block->data() + offset, VMAPermission::ReadWriteExecute);
Core::CPU().MapBackingMemory(target, size, block->data() + offset,
VMAPermission::ReadWriteExecute);
final_vma.type = VMAType::AllocatedMemoryBlock;
final_vma.permissions = VMAPermission::ReadWrite;
@@ -356,12 +357,12 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
u64 VMManager::GetTotalMemoryUsage() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x400000;
return 0xBE000000;
}
u64 VMManager::GetTotalHeapUsage() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x10000;
return 0x0;
}
VAddr VMManager::GetAddressSpaceBaseAddr() {
@@ -374,6 +375,11 @@ u64 VMManager::GetAddressSpaceSize() {
return MAX_ADDRESS;
}
VAddr VMManager::GetMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return Memory::HEAP_VADDR;
}
VAddr VMManager::GetNewMapRegionBaseAddr() {
LOG_WARNING(Kernel, "(STUBBED) called");
return 0x8000000;

View File

@@ -192,6 +192,9 @@ public:
/// Gets the total address space address size, used by svcGetInfo
u64 GetAddressSpaceSize();
/// Gets the map region base address, used by svcGetInfo
VAddr GetMapRegionBaseAddr();
/// Gets the base address for a new memory region, used by svcGetInfo
VAddr GetNewMapRegionBaseAddr();

View File

@@ -19,6 +19,8 @@
enum class ErrorDescription : u32 {
Success = 0,
RemoteProcessDead = 301,
InvalidOffset = 6061,
InvalidLength = 6062,
};
/**

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/acc/acc.h"
#include "core/hle/service/acc/acc_u0.h"
namespace Service {
namespace Account {
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<ACC_U0>()->InstallAsService(service_manager);
}
} // namespace Account
} // namespace Service

View File

@@ -0,0 +1,16 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Account {
/// Registers all ACC services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace Account
} // namespace Service

View File

@@ -0,0 +1,87 @@
// Copyright 2018 yuzu emulator team
// 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/service/acc/acc_u0.h"
namespace Service {
namespace Account {
class IProfile final : public ServiceFramework<IProfile> {
public:
IProfile() : ServiceFramework("IProfile") {
static const FunctionInfo functions[] = {
{1, &IProfile::GetBase, "GetBase"},
};
RegisterHandlers(functions);
}
private:
void GetBase(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
ProfileBase profile_base{};
IPC::RequestBuilder rb{ctx, 16};
rb.Push(RESULT_SUCCESS);
rb.PushRaw(profile_base);
}
};
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
public:
IManagerForApplication() : ServiceFramework("IProfile") {
static const FunctionInfo functions[] = {
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
};
RegisterHandlers(functions);
}
private:
void CheckAvailability(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(true); // TODO: Check when this is supposed to return true and when not
}
};
void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(true); // TODO: Check when this is supposed to return true and when not
}
void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IProfile>();
LOG_DEBUG(Service, "called");
}
void ACC_U0::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service, "(STUBBED) called");
IPC::RequestBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void ACC_U0::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IManagerForApplication>();
LOG_DEBUG(Service, "called");
}
ACC_U0::ACC_U0() : ServiceFramework("acc:u0") {
static const FunctionInfo functions[] = {
{1, &ACC_U0::GetUserExistence, "GetUserExistence"},
{5, &ACC_U0::GetProfile, "GetProfile"},
{100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
};
RegisterHandlers(functions);
}
} // namespace Account
} // namespace Service

View File

@@ -0,0 +1,37 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace Account {
// TODO: RE this structure
struct UserData {
INSERT_PADDING_BYTES(0x80);
};
static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size");
// TODO: RE this structure
struct ProfileBase {
INSERT_PADDING_BYTES(0x38);
};
static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
class ACC_U0 final : public ServiceFramework<ACC_U0> {
public:
ACC_U0();
~ACC_U0() = default;
private:
void GetUserExistence(Kernel::HLERequestContext& ctx);
void GetProfile(Kernel::HLERequestContext& ctx);
void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
};
} // namespace Account
} // namespace Service

View File

@@ -8,8 +8,9 @@
namespace Service {
namespace AM {
void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<AppletOE>()->InstallAsService(service_manager);
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
}
} // namespace AM

View File

@@ -4,13 +4,19 @@
#pragma once
#include <memory>
#include "core/hle/service/service.h"
namespace Service {
namespace NVFlinger {
class NVFlinger;
}
namespace AM {
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
} // namespace AM
} // namespace Service

Some files were not shown because too many files have changed in this diff Show More