Commit graph

1301 commits

Author SHA1 Message Date
Fernando Sahmkow dde0814837 Use MultiLevelQueue instead of old ThreadQueueList 2019-03-27 14:34:32 -04:00
bunnei 47f2405ab1
Merge pull request #2285 from lioncash/unused-struct
kernel/process: Remove unused AddressMapping struct
2019-03-26 11:17:03 -04:00
bunnei 595511876e
Merge pull request #2287 from lioncash/coretiming-cb
core/core_timing: Make callback parameters consistent
2019-03-25 21:06:33 -04:00
Lioncash c5d41fd812 core/core_timing: Make callback parameters consistent
In some cases, our callbacks were using s64 as a parameter, and in other
cases, they were using an int, which is inconsistent.

To make all callbacks consistent, we can just use an s64 as the type for
late cycles, given it gets rid of the need to cast internally.

While we're at it, also resolve some signed/unsigned conversions that
were occurring related to the callback registration.
2019-03-24 18:12:17 -04:00
Lioncash bd7ec1a749 kernel/kernel: Remove unnecessary forward declaration
This is no longer necessary, as ResultVal isn't used anywhere in the
header.
2019-03-24 17:48:54 -04:00
Lioncash 7c4bc7b883 kernel/process: Remove unused AddressMapping struct
Another leftover from citra that's now no longer necessary.
2019-03-24 17:40:11 -04:00
Lioncash 1e92ba2785 kernel/vm_manager: Handle shrinking of the heap size within SetHeapSize()
One behavior that we weren't handling properly in our heap allocation
process was the ability for the heap to be shrunk down in size if a
larger size was previously requested.

This adds the basic behavior to do so and also gets rid of HeapFree, as
it's no longer necessary now that we have allocations and deallocations
going through the same API function.

While we're at it, fully document the behavior that this function
performs.
2019-03-24 17:08:30 -04:00
Lioncash 99a163478b kernel/vm_manager: Rename HeapAllocate to SetHeapSize
Makes it more obvious that this function is intending to stand in for
the actual supervisor call itself, and not acting as a general heap
allocation function.

Also the following change will merge the freeing behavior of HeapFree
into this function, so leaving it as HeapAllocate would be misleading.
2019-03-24 17:08:30 -04:00
Lioncash abdb81ccaf kernel/vm_manager: Handle case of identical calls to HeapAllocate
In cases where HeapAllocate is called with the same size of the current
heap, we can simply do nothing and return successfully.

This avoids doing work where we otherwise don't have to. This is also
what the kernel itself does in this scenario.
2019-03-24 17:08:30 -04:00
Lioncash 9f63acac0f kernel/vm_manager: Remove unused class variables
Over time these have fallen out of use due to refactoring, so these can
be removed.
2019-03-24 17:08:30 -04:00
Lioncash 52980df1aa kernel/vm_manager: Remove unnecessary heap_used data member
This isn't required anymore, as all the kernel ever queries is the size
of the current heap, not the total usage of it.
2019-03-24 17:08:16 -04:00
Lioncash 586cab6172 kernel/vm_manager: Tidy up heap allocation code
Another holdover from citra that can be tossed out is the notion of the
heap needing to be allocated in different addresses. On the switch, the
base address of the heap will always be managed by the memory allocator
in the kernel, so this doesn't need to be specified in the function's
interface itself.

The heap on the switch is always allocated with read/write permissions,
so we don't need to add specifying the memory permissions as part of the
heap allocation itself either.

This also corrects the error code returned from within the function.
If the size of the heap is larger than the entire heap region, then the
kernel will report an out of memory condition.
2019-03-24 16:17:31 -04:00
bunnei 3f74518e19
Merge pull request #2232 from lioncash/transfer-memory
core/hle/kernel: Split transfer memory handling out into its own class
2019-03-24 16:00:23 -04:00
Lioncash c0a01f3adc kernel/codeset: Make CodeSet's memory data member a regular std::vector
The use of a shared_ptr is an implementation detail of the VMManager
itself when mapping memory. Because of that, we shouldn't require all
users of the CodeSet to have to allocate the shared_ptr ahead of time.
It's intended that CodeSet simply pass in the required direct data, and
that the memory manager takes care of it from that point on.

This means we just do the shared pointer allocation in a single place,
when loading modules, as opposed to in each loader.
2019-03-22 18:43:46 -04:00
bunnei 7b6d516faa
Merge pull request #2234 from lioncash/mutex
core/hle/kernel: Make Mutex a per-process class.
2019-03-21 22:18:36 -04:00
bunnei 4d95adcac5
Merge pull request #2275 from lioncash/memflags
kernel/vm_manager: Amend flag value for code data
2019-03-21 21:43:15 -04:00
bunnei 639f0c524d
Merge pull request #1933 from DarkLordZach/cheat-engine
file_sys: Implement parser and interpreter for game memory cheats
2019-03-21 21:41:59 -04:00
Lioncash 18918f5f2f kernel/vm_manager: Rename CodeStatic/CodeMutable to Code and CodeData respectively
Makes it more evident that one is for actual code and one is for actual
data. Mutable and static are less than ideal terms here, because
read-only data is technically not mutable, but we were mapping it with
that label.
2019-03-21 11:43:35 -04:00
Lioncash 56c80a2a21 kernel/vm_manager: Amend flag values for CodeMutable
This should actually be using the data flags, rather than the code
flags.
2019-03-21 11:23:14 -04:00
bunnei e76f442a0e
Merge pull request #2268 from lioncash/codeset
core/kernel: Migrate CodeSet to its own source files
2019-03-20 22:37:58 -04:00
Lioncash 8f454a5c68 kernel/process: Make MapSegment lambda reference parameter const
The segment itself isn't actually modified.
2019-03-20 13:07:09 -04:00
Lioncash 1b6bd9d6df kernel: Move CodeSet structure to its own source files
Given this is utilized by the loaders, this allows avoiding inclusion of
the kernel process definitions where avoidable.

This also keeps the loading format for all executable data separate from
the kernel objects.
2019-03-20 13:07:04 -04:00
Fernando Sahmkow 8a320a6ee2 Fix crash caused by 2238. 2019-03-19 22:45:34 -04:00
Fernando Sahmkow 9c7319a4d4 Fix small bug that kept a thread as a condvar thread after being signalled. 2019-03-19 22:43:13 -04:00
Fernando Sahmkow acbdfdae64 Add CondVar Thread State. 2019-03-19 20:32:47 -04:00
Fernando Sahmkow 774f139e65 Small fixes to address_arbiter to better match the IDB. 2019-03-19 20:32:46 -04:00
bunnei 30f228a8c9
Merge pull request #2238 from lioncash/thread
kernel/thread: Amend conditional test and assignment within UpdatePriority()
2019-03-17 22:27:33 -04:00
bunnei 57ca1e3e69
Merge pull request #2252 from bunnei/move-page-table
core: Move PageTable struct into Common.
2019-03-17 14:42:57 -04:00
bunnei 93da8e0abf core: Move PageTable struct into Common. 2019-03-16 22:05:40 -04:00
Lioncash 99f982dce2 kernel/thread: Actually remove the definition of ExitCurrentThread()
This was intended to be removed in
51d7f6bffc, but I guess I forgot to
actually save the file like a dingus.
2019-03-16 00:51:44 -04:00
bunnei bdf2da4ee8
Merge pull request #2242 from lioncash/thread-fn
kernel/thread: Remove WaitCurrentThread_Sleep() and ExitCurrentThread()
2019-03-16 00:43:09 -04:00
Lioncash 51d7f6bffc kernel/thread: Move thread exiting logic from ExitCurrentThread to svcExitThread
Puts the operation on global state in the same places as the rest of the
svc calls.
2019-03-15 23:58:37 -04:00
Lioncash c892cf01fa kernel/thread: Migrate WaitCurrentThread_Sleep into the Thread interface
Rather than make a global accessor for this sort of thing. We can make
it a part of the thread interface itself. This allows getting rid of a
hidden global accessor in the kernel code.
2019-03-15 23:58:31 -04:00
Lioncash db47d7e471 kernel/thread: Expand documentation of nominal_priority and current_priority
Aims to disambiguate why each priority instance exists a little bit.
While we're at it, also add an explanatory comment to UpdatePriority().
2019-03-15 23:02:14 -04:00
Lioncash e0d1f11968 kernel/thread: Make bracing consistent within UpdatePriority() 2019-03-15 23:02:10 -04:00
Lioncash 39483b92b7 kernel/thread: Amend condition within UpdatePriority()
This condition was checking against the nominal thread priority, whereas
the kernel itself checks against the current priority instead. We were
also assigning the nominal priority, when we should be assigning
current_priority, which takes priority inheritance into account.

This can lead to the incorrect priority being assigned to a thread.

Given we recursively update the relevant threads, we don't need to go
through the whole mutex waiter list. This matches what the kernel does
as well (only accessing the first entry within the waiting list).
2019-03-15 23:01:43 -04:00
Lioncash 0b78cfcc53 kernel/thread: Maintain priority ordering of added mutex waiting threads
The kernel keeps the internal waiting list ordered by priority. This is
trivial to do with std::find_if followed by an insertion.
2019-03-15 23:01:39 -04:00
Lioncash d71cad6ed0 core/hle/kernel/mutex: Remove usages of global system accessors
Removes the use of global system accessors, and instead uses the
explicit interface provided.
2019-03-14 20:55:52 -04:00
Lioncash 555cd26ec2 core/hle/kernel: Make Mutex a per-process class.
Makes it an instantiable class like it is in the actual kernel. This
will also allow removing reliance on global accessors in a following
change, now that we can encapsulate a reference to the system instance
in the class.
2019-03-14 20:55:52 -04:00
bunnei 2d9546848e
Merge pull request #2230 from lioncash/global
kernel/process: Remove use of global system accessors
2019-03-14 20:42:46 -04:00
bunnei e7850a7f11
Merge pull request #2226 from lioncash/private
kernel/server_port: Make data members private
2019-03-13 14:44:21 -04:00
Lioncash 5379063108 core/hle/kernel/svc: Implement svcUnmapTransferMemory
Similarly, like svcMapTransferMemory, we can also implement
svcUnmapTransferMemory fairly trivially as well.
2019-03-13 06:04:49 -04:00
Lioncash 567134f874 core/hle/kernel/svc: Implement svcMapTransferMemory
Now that transfer memory handling is separated from shared memory, we
can implement svcMapTransferMemory pretty trivially.
2019-03-13 06:04:49 -04:00
Lioncash cb198d7985 core/hle/kernel: Split transfer memory handling out into its own class
Within the kernel, shared memory and transfer memory facilities exist as
completely different kernel objects. They also have different validity
checking as well. Therefore, we shouldn't be treating the two as the
same kind of memory.

They also differ in terms of their behavioral aspect as well. Shared
memory is intended for sharing memory between processes, while transfer
memory is intended to be for transferring memory to other processes.

This breaks out the handling for transfer memory into its own class and
treats it as its own kernel object. This is also important when we
consider resource limits as well. Particularly because transfer memory
is limited by the resource limit value set for it.

While we currently don't handle resource limit testing against objects
yet (but we do allow setting them), this will make implementing that
behavior much easier in the future, as we don't need to distinguish
between shared memory and transfer memory allocations in the same place.
2019-03-13 06:04:44 -04:00
Lioncash 6eddb60db0 kernel/process: Remove use of global system accessors
Now that we pass in a reference to the system instance, we can utilize
it to eliminate the global accessors in Process-related code.
2019-03-12 19:03:28 -04:00
bunnei 3bfd199497
Merge pull request #2211 from lioncash/arbiter
kernel: Make the address arbiter instance per-process
2019-03-12 17:54:48 -04:00
Lioncash aa44eb639b kernel/server_port: Make data members private
With this, all kernel objects finally have all of their data members
behind an interface, making it nicer to reason about interactions with
other code (as external code no longer has the freedom to totally alter
internals and potentially messing up invariants).
2019-03-11 10:41:05 -04:00
bunnei 037d9bdde3
Merge pull request #2193 from lioncash/global
kernel/scheduler: Pass in system instance in constructor
2019-03-10 17:29:01 -04:00
bunnei 9909d40530
Merge pull request #2210 from lioncash/optional
kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
2019-03-08 16:35:57 -05:00
Lioncash fbb82e61e3 kernel/hle_ipc: Convert std::shared_ptr IPC header instances to std::optional
There's no real need to use a shared lifetime here, since we don't
actually expose them to anything else. This is also kind of an
unnecessary use of the heap given the objects themselves are so small;
small enough, in fact that changing over to optionals actually reduces
the overall size of the HLERequestContext struct (818 bytes to 808
bytes).
2019-03-07 23:34:37 -05:00
Lioncash 8e510d5afa kernel: Make the address arbiter instance per-process
Now that we have the address arbiter extracted to its own class, we can
fix an innaccuracy with the kernel. Said inaccuracy being that there
isn't only one address arbiter. Each process instance contains its own
AddressArbiter instance in the actual kernel.

This fixes that and gets rid of another long-standing issue that could
arise when attempting to create more than one process.
2019-03-07 23:27:51 -05:00
Lioncash b7f331afa3 kernel/svc: Move address arbiter signaling behind a unified API function
Similar to how WaitForAddress was isolated to its own function, we can
also move the necessary conditional checking into the address arbiter
class itself, allowing us to hide the implementation details of it from
public use.
2019-03-07 23:27:47 -05:00
Lioncash 0209de123b kernel/svc: Move address arbiter waiting behind a unified API function
Rather than let the service call itself work out which function is the
proper one to call, we can make that a behavior of the arbiter itself,
so we don't need to directly expose those implementation details.
2019-03-07 23:27:20 -05:00
bunnei d26ee6e01e
Merge pull request #2195 from lioncash/shared-global
kernel/shared_memory: Get rid of the use of global accessor functions within Create()
2019-03-07 17:26:11 -05:00
bunnei c63a0e88b7
Merge pull request #2202 from lioncash/port-priv
kernel/client_session, kernel/server_session: Make data members private
2019-03-07 15:31:26 -05:00
bunnei ed0bdcc638
Merge pull request #2197 from lioncash/include
core/hle/ipc: Remove unnecessary includes
2019-03-06 21:55:16 -05:00
bunnei 75b417489a
Merge pull request #2199 from lioncash/arbiter
kernel/address_arbiter: Convert the address arbiter into a class
2019-03-06 15:55:56 -05:00
bunnei 234f00bdd4
Merge pull request #2194 from lioncash/mem
svc: Move memory range checking functions to the VMManager class
2019-03-06 11:43:07 -05:00
Lioncash 221613d4ea kernel/server_session: Make data members private
Makes it much nicer to locally reason about server session behavior, as
part of its functionality isn't placed around other classes.
2019-03-05 20:10:07 -05:00
Lioncash 7526b6fce3 kernel/client_session: Make data members private
These can be made private, as they aren't accessed in contexts that
require them to be public.
2019-03-05 20:10:03 -05:00
Lioncash c161389a0f kernel/address_arbiter: Pass in system instance to constructor
Allows getting rid of reliance on the global accessor functions and
instead operating on the provided system instance.
2019-03-05 15:47:03 -05:00
Lioncash 9d9676f620 kernel/address_arbiter: Minor tidying up
- Invert conditions into guard clases where applicable.
- Mark std::vector parameter of WakeThreads as const
2019-03-05 12:58:31 -05:00
Lioncash ec6664f6d6 kernel/address_arbiter: Convert the address arbiter into a class
Places all of the functions for address arbiter operation into a class.
This will be necessary for future deglobalizing efforts related to both
the memory and system itself.
2019-03-05 12:58:26 -05:00
Zach Hilman 52ac6419da vm_manager: Remove cheat-specific ranges from VMManager 2019-03-05 10:09:36 -05:00
Lioncash 79f970e6de kernel/thread: Remove obsolete TODO in Create()
This is a TODO carried over from Citra that doesn't apply here.
2019-03-05 10:05:49 -05:00
Lioncash 02bc9e9de1 core/hle/ipc: Remove unnecessary includes
Removes a few inclusion dependencies from the headers or replaces
existing ones with ones that don't indirectly include the required
headers.

This allows removing an inclusion of core/memory.h, meaning that if the
memory header is ever changed in the future, it won't result in
rebuilding the entirety of the HLE services (as the IPC headers are used
quite ubiquitously throughout the HLE service implementations).
2019-03-05 09:53:38 -05:00
Zach Hilman b952a30555 vm_manager: Add support for storing and getting main code region
Used as root for one region of cheats, set by loader
2019-03-04 18:39:58 -05:00
Lioncash 40de7f6fe8 vm_manager: Use range helpers in HeapAlloc() and HeapFree()
Significantly tidies up two guard conditionals.
2019-03-04 17:16:52 -05:00
Lioncash 6c42a23550 vm_manager: Provide address range checking functions for other memory regions
Makes the interface uniform when it comes to checking various memory
regions.
2019-03-04 17:08:55 -05:00
Lioncash fad20213e6 kernel/scheduler: Pass in system instance in constructor
Avoids directly relying on the global system instance and instead makes
an arbitrary system instance an explicit dependency on construction.

This also allows removing dependencies on some global accessor functions
as well.
2019-03-04 17:01:37 -05:00
Lioncash f59040d752 kernel/shared_memory: Get rid of the use of global accessor functions within Create()
Given we already pass in a reference to the kernel that the shared
memory instance is created under, we can just use that to check the
current process, rather than using the global accessor functions.

This allows removing direct dependency on the system instance entirely.
2019-03-04 16:52:36 -05:00
Lioncash 0be8fffc99 svc: Migrate address range checking functions to VMManager
Provides a bit of a more proper interface for these functions.
2019-03-04 16:32:03 -05:00
Lioncash d29f9e9709 kernel/handle_table: Make local variables as const where applicable
Makes immutable state explicit.
2019-02-25 11:12:38 -05:00
Lioncash 5167d1577d kernel/handle_table: Allow process capabilities to limit the handle table size
The kernel allows restricting the total size of the handle table through
the process capability descriptors. Until now, this functionality wasn't
hooked up. With this, the process handle tables become properly restricted.

In the case of metadata-less executables, the handle table will assume
the maximum size is requested, preserving the behavior that existed
before these changes.
2019-02-25 11:12:32 -05:00
Lioncash 4f8cd74061 kernel/handle-table: In-class initialize data members
Directly initializes members where applicable.
2019-02-25 10:14:05 -05:00
Lioncash 0220862ba5 kernel/handle_table: Resolve truncation warnings
Avoids implicit truncation warnings from u32 -> u16 (the truncation is
desirable behavior here).
2019-02-25 09:53:21 -05:00
Lioncash 0113c36300 address_arbiter: Use nested namespaces where applicable
A fairly trivial change. Other sections of the codebase use nested
namespaces instead of separate namespaces here. This one must have just
been overlooked.
2019-02-16 12:41:30 -05:00
Lioncash bd983414f6 core_timing: Convert core timing into a class
Gets rid of the largest set of mutable global state within the core.
This also paves a way for eliminating usages of GetInstance() on the
System class as a follow-up.

Note that no behavioral changes have been made, and this simply extracts
the functionality into a class. This also has the benefit of making
dependencies on the core timing functionality explicit within the
relevant interfaces.
2019-02-15 21:50:25 -05:00
Lioncash 48d9d66dc5 core_timing: Rename CoreTiming namespace to Core::Timing
Places all of the timing-related functionality under the existing Core
namespace to keep things consistent, rather than having the timing
utilities sitting in its own completely separate namespace.
2019-02-12 12:42:17 -05:00
Lioncash 414cc1eb1f kernel: Remove the Timer class
A holdover from citra, the Horizon kernel on the switch has no
prominent kernel object that functions as a timer. At least not
to the degree of sophistication that this class provided.

As such, this can be removed entirely. This class also wasn't used at
all in any meaningful way within the core, so this was just code sitting
around doing nothing. This also allows removing a few things from the
main KernelCore class that allows it to use slightly less resources
overall (though very minor and not anything really noticeable).
2019-01-31 23:05:15 -05:00
Lioncash a3cdd773c3 kernel/wait_object: Devirtualize functions related to manipulating the thread list directly
No inheritors of the WaitObject class actually make use of their own
implementations of these functions, so they can be made non-virtual.

It's also kind of sketchy to allow overriding how the threads get added
to the list anyways, given the kernel itself on the actual hardware
doesn't seem to customize based off this.
2019-01-30 12:50:37 -05:00
Lioncash 4596ef5274 kernel/timer: Remove unnecessary WakeupAllWaitingThreads() override
This implementation just calls the base class variant of the function,
so this isn't necessary.
2019-01-30 12:45:00 -05:00
Lioncash 1a302d4d47 kernel/readable_event: Remove unnecessary WakeupAllWaitingThreads() override
This just calls the base variant of the function, so it can be removed.
2019-01-30 12:45:00 -05:00
Lioncash 7842536ddb
kernel/svc: Log out uncaught C++ exceptions from svcBreak
Looking into the implementation of the C++ standard facilities that seem
to be within all modules, it appears that they use 7 as a break reason
to indicate an uncaught C++ exception.

This was primarily found via the third last function called within
Horizon's equivalent of libcxxabi's demangling_terminate_handler(),
which passes the value 0x80000007 to svcBreak.
2019-01-26 21:19:13 -05:00
David Marcec 4f41fd84ff Removed pulse event type
Pulse is considered a hack and nothing should be using it. We should completely remove it
2019-01-04 20:47:20 +11:00
Lioncash 1f0c8bfeda core/kernel: Remove unnecessary inclusions
Gets rid of a few unnecessary header dependencies in some source files.
2018-12-31 19:04:16 -05:00
Lioncash b4242633ad kernel/svc: Correct misleading error message within CreateThread()
This is a bounds check to ensure that the thread priority is within the
valid range of 0-64. If it exceeds 64, that doesn't necessarily mean
that an actual priority of 64 was expected (it actually means whoever
called the function screwed up their math).

Instead clarify the message to indicate the allowed range of thread
priorities.
2018-12-30 21:29:38 -05:00
Lioncash 3a8d38be7e kernel/svc: Sanitize core number and thread priorities in CreateThread()
Now that we handle the kernel capability descriptors we can correct
CreateThread to properly check against the core and priority masks
like the actual kernel does.
2018-12-30 21:23:56 -05:00
Lioncash 8769604144 kernel/process: Rename GetAllowedProcessorMask() and GetAllowedThreadPriorityMask()
Makes them consistent with their kernel capability counterparts.
2018-12-30 21:09:46 -05:00
Lioncash 205e6d3b97 kernel/svc: Simplify thread core ID sanitizing in CreateThread
Rather than use a switch here, this can be collapsed into a simple range
check, which is a little easier on the eyes.
2018-12-30 20:59:54 -05:00
Sebastian Valle e5dfbe22ee
Merge pull request #1956 from lioncash/process-thread
kernel/process: Start the main thread using the specified ideal core
2018-12-30 20:32:41 -05:00
bunnei 331c252509
Merge pull request #1847 from ogniK5377/backtrace-break
Print backtrace on svcBreak
2018-12-29 22:58:13 -05:00
Lioncash a81ff6f54c kernel/process: Start the main thread using the specified ideal core
This matches kernel behavior in that processes are started using their
specified ideal core, rather than always starting on core 0.
2018-12-27 21:50:16 -05:00
Lioncash f80bc712ea kernel: Rename 'default' CPU core to 'ideal' core
This makes the naming more closely match its meaning. It's just a
preferred core, not a required default core. This also makes the usages
of this term consistent across the thread and process implementations.
2018-12-27 21:48:49 -05:00
Lioncash 771431f625 kernel/thread: Move process thread initialization into process.cpp
This function isn't a general purpose function that should be exposed to
everything, given it's specific to initializing the main thread for a
Process instance.

Given that, it's a tad bit more sensible to place this within
process.cpp, which keeps it visible only to the code that actually needs
it.
2018-12-27 20:32:30 -05:00
Lioncash fbeaa330a3 kernel/process: Remove most allocation functions from Process' interface
In all cases that these functions are needed, the VMManager can just be
retrieved and used instead of providing the same functions in Process'
interface.

This also makes it a little nicer dependency-wise, since it gets rid of
cases where the VMManager interface was being used, and then switched
over to using the interface for a Process instance. Instead, it makes
all accesses uniform and uses the VMManager instance for all necessary
tasks.

All the basic memory mapping functions did was forward to the Process'
VMManager instance anyways.
2018-12-27 19:08:47 -05:00
bunnei 795335af0f
Merge pull request #1928 from lioncash/caps
kernel: Handle kernel capability descriptors
2018-12-27 11:15:34 -05:00
Lioncash 1392597ede kernel/vm_manager: Reset region attributes when unmapping a VMA
Like the other members related to memory regions, the attributes need to
be reset back to their defaults as well.
2018-12-26 20:15:29 -05:00
bunnei ae582b6669
Merge pull request #1849 from encounter/svcSetThreadActivity
svc: Implement SetThreadActivity (thread suspension)
2018-12-26 15:54:14 -05:00
bunnei e75e8b9580
Merge pull request #1921 from ogniK5377/no-unit
Fixed uninitialized memory due to missing returns in canary
2018-12-21 14:12:54 -05:00
bunnei 59ac3346eb
Merge pull request #1925 from lioncash/pid
kernel/{process, thread}: Amend behavior related to IDs
2018-12-21 13:45:27 -05:00
Lioncash 002ae08bbd kernel/process: Hook up the process capability parser to the process itself
While we're at it, we can also toss out the leftover capability parsing
from Citra.
2018-12-21 07:05:34 -05:00
Lioncash d09fb82113 kernel/process_capability: Handle debug capability flags 2018-12-21 07:05:34 -05:00
Lioncash 10824c5d63 kernel/process_capability: Handle handle table capability flags
This just specifies the handle table size. There's also a section of
reserved bits that are checked against.
2018-12-21 07:05:34 -05:00
Lioncash e0e84aede0 kernel/process_capability: Handle kernel version capability flags 2018-12-21 07:05:34 -05:00
Lioncash 010bc677f3 kernel/process_capability: Handle program capability flags 2018-12-21 07:05:34 -05:00
Lioncash 0f216d20e3 kernel/process_capability: Handle interrupt capability flags
Similar to the service capability flags, however, we currently don't
emulate the GIC, so this currently handles all interrupts as being valid
for the time being.
2018-12-21 07:05:34 -05:00
Lioncash 3dc59b74ec kernel/process_capability: Handle syscall capability flags 2018-12-21 07:05:34 -05:00
Lioncash 27caf71204 kernel/process_capability: Handle the priority mask and core mask flags
Handles the priority mask and core mask flags to allow building up the
masks to determine the usable thread priorities and cores for a kernel
process instance.
2018-12-21 07:05:34 -05:00
Lioncash 6ff5135521 kernel/process: Introduce process capability parsing skeleton
We've had the old kernel capability parser from Citra, however, this is
unused code and doesn't actually map to how the kernel on the Switch
does it. This introduces the basic functional skeleton for parsing
process capabilities.
2018-12-21 07:05:31 -05:00
Lioncash b74eb88c68 kernel/svc: Handle thread handles within GetProcessId
If a thread handle is passed to svcGetProcessId, the kernel attempts to
access the process ID via the thread's instance's owning process.

Technically, this function should also be handling the kernel debug
objects as well, however we currently don't handle those kernel objects
yet, so I've left a note via a comment about it to remind myself when
implementing it in the future.
2018-12-19 12:16:15 -05:00
bunnei e73dd39413
Merge pull request #1907 from lioncash/attribute
kernel/svc: Implement svcSetMemoryAttribute
2018-12-19 11:50:50 -05:00
Lioncash caab838bdb svc: Implement svcSetMemoryAttribute
With all the basic backing functionality implemented, we can now unstub
svcSetMemoryAttribute.
2018-12-19 10:59:40 -05:00
Lioncash 622242e345 vm_manager: Add member function for setting memory attributes across an address range
This puts the backing functionality for svcSetMemoryAttribute in place,
which will be utilized in a following change.
2018-12-19 10:59:40 -05:00
Lioncash 603cc72168 vm_manager: Add member function for checking a memory range adheres to certain attributes, permissions and states 2018-12-19 10:59:36 -05:00
Lioncash 62d4377053 kernel/kernel: Use correct initial PID for userland Process instances
Starts the process ID counter off at 81, which is what the kernel itself
checks against internally when creating processes. It's actually
supposed to panic if the PID is less than 81 for a userland process.
2018-12-18 22:54:01 -05:00
Lioncash 0906302ca9 kernel/svc: Correct output parameter for svcGetThreadId
The service call uses a 64-bit value, just like svcGetProcessId. This
amends the function signature accordingly.
2018-12-18 22:38:26 -05:00
Lioncash 8435451093 kernel/thread: Make thread_id a 64-bit value
The kernel uses a 64-bit value for the thread ID, so we shouldn't be
using a 32-bit value.
2018-12-18 22:37:03 -05:00
Lioncash 43e1189688 kernel/svc: Correct output parameter for svcGetProcessId
svcGetProcessId's out parameter is a pointer to a 64-bit value, not a
32-bit one.
2018-12-18 22:30:56 -05:00
Lioncash 9b3a38e3d3 kernel/process: Make process_id a 64-bit value
In the actual kernel, this is a 64-bit value, so we shouldn't be using a
32-bit type to handle it.
2018-12-18 22:28:55 -05:00
David Marcec 08d5663cb8 Moved backtrace to ArmInterface 2018-12-19 14:10:51 +11:00
David Marcec fdd649e2ef Fixed uninitialized memory due to missing returns in canary
Functions which are suppose to crash on non canary builds usually don't return anything which lead to uninitialized memory being used.
2018-12-19 12:52:32 +11:00
MerryMage eef6ce79a9 kernel/thread: Set default fpcr 2018-12-18 17:37:03 +00:00
Lioncash 4dc8a7da3f vm_manager: Rename meminfo_state to state
This is shorter and more concise. This also removes the now-innaccurate
comment, as it's not returned wholesale to svcQueryMemory anymore.
2018-12-15 19:43:36 -05:00
Lioncash 34b24a47e9 vm_manager: Add backing functionality for memory attributes
Adds the barebones enumeration constants and functions in place to
handle memory attributes, while also essentially leaving the attribute
itself non-functional.
2018-12-15 19:43:32 -05:00
bunnei 2f2fc47af2
Merge pull request #1732 from DarkLordZach/yield-types
svc: Implement yield types 0 and -1
2018-12-15 00:28:12 -05:00
bunnei 1a23970d17
Merge pull request #1899 from lioncash/state
vm_manager/svc: Modify MemoryState enum, and correct error handling for svcQueryMemory
2018-12-14 15:30:02 -05:00
bunnei 1006df7fc1
Merge pull request #1900 from lioncash/wrapper
svc_wrap: Correct register index for a wrapper specialization
2018-12-14 13:12:55 -05:00
Lioncash b79f086613 svc: Enable svcQueryProcessMemory
svcQueryProcessMemory is trivial to implement, given all the behavior
necessary for it is present, it just needs a handler for it.
2018-12-12 15:45:05 -05:00
Lioncash 09a219d5b4 svc: Write out the complete MemoryInfo structure in QueryProcessMemory
In the previous change, the memory writing was moved into the service
function itself, however it still had a problem, in that the entire
MemoryInfo structure wasn't being written out, only the first 32 bytes
of it were being written out. We still need to write out the trailing
two reference count members and zero out the padding bits.

Not doing this can result in wrong behavior in userland code in the following
scenario:

MemoryInfo info;                 // Put on the stack, not quaranteed to be zeroed out.
svcQueryMemory(&info, ...);

if (info.device_refcount == ...) // Whoops, uninitialized read.

This can also cause the wrong thing to happen if the user code uses
std::memcmp to compare the struct, with another one (questionable, but
allowed), as the padding bits are not guaranteed to be a deterministic
value. Note that the kernel itself also fully zeroes out the structure
before writing it out including the padding bits.
2018-12-12 15:44:58 -05:00
Lioncash d8deb39b83 svc: Handle memory writing explicitly within QueryProcessMemory
Moves the memory writes directly into QueryProcessMemory instead of
letting the wrapper function do it. It would be inaccurate to allow the
handler to do it because there's cases where memory shouldn't even be
written to. For example, if the given process handle is invalid.

HOWEVER, if the memory writing is within the wrapper, then we have no
control over if these memory writes occur, meaning in an error case, 68
bytes of memory randomly get trashed with zeroes, 64 of those being
written to wherever the memory info address points to, and the remaining
4 being written wherever the page info address points to.

One solution in this case would be to just conditionally check within
the handler itself, but this is kind of smelly, given the handler
shouldn't be performing conditional behavior itself, it's a behavior of
the managed function. In other words, if you remove the handler from the
equation entirely, does the function still retain its proper behavior?
In this case, no.

Now, we don't potentially trash memory from this function if an invalid
query is performed.
2018-12-12 15:43:31 -05:00
Lioncash b1b855c5d9 vm_manager: Correct ordering of last two struct members of MemoryInfo
These should be swapped.
2018-12-12 15:43:31 -05:00
Lioncash 22230a2eca svc_wrap: Correct register index for a wrapper specialization
This would result in svcSetMemoryAttribute getting the wrong value for
its third parameter. This is currently fine, given the service function
is stubbed, however this will be unstubbed in a future change, so this
needs to change.
2018-12-12 15:14:28 -05:00
Lioncash eb5f3f67f6 vm_manager: Amend the returned values for invalid memory queries in QueryMemory()
The kernel returns a memory info instance with the base address set to
the end of the address space, and the size of said block as
0 - address_space_end, it doesn't set both of said members to zero.
2018-12-12 15:08:06 -05:00
Lioncash a8cc03502b vm_manager: Migrate memory querying to the VMManager interface
Gets rid of the need to directly access the managed VMAs outside of the
memory manager itself just for querying memory.
2018-12-12 15:07:30 -05:00
Lioncash c02b8c895b vm_manager: Migrate MemoryInfo and PageInfo to vm_manager.h
Gets the two structures out of an unrelated header and places them with
the rest of the memory management code.

This also corrects the structures. PageInfo appears to only contain a
32-bit flags member, and the extra padding word in MemoryInfo isn't
necessary.
2018-12-12 14:03:53 -05:00
Lioncash 366985ca92 vm_manager: Amend MemoryState enum members
Amends the MemoryState enum to use the same values like the actual
kernel does. Also provides the necessary operators to operate on them.
This will be necessary in the future for implementing
svcSetMemoryAttribute, as memory block state is checked before applying
the attribute.
2018-12-12 14:03:50 -05:00
Jens Schmer ae390ad5a2 Fix Process object leak on emulation stop
The Process object kept itself alive indefinitely because its handle_table
contains a SharedMemory object which owns a reference to the same Process object,
creating a circular ownership scenario.

Break that up by storing only a non-owning pointer in the SharedMemory object.
2018-12-12 17:25:56 +01:00
Hexagon12 315f3342f7
Merge pull request #1872 from lioncash/proc-info
kernel/process: Set ideal core from metadata
2018-12-10 18:44:14 +02:00
bunnei 74242a8fb4
Merge pull request #1876 from lioncash/vma
vm_manager: Make vma_map private
2018-12-10 10:09:50 -05:00
Lioncash d4c1b9d311 vm_manager: Make vma_map private
This was only ever public so that code could check whether or not a
handle was valid or not. Instead of exposing the object directly and
allowing external code to potentially mess with the map contents, we
just provide a member function that allows checking whether or not a
handle is valid.

This makes all member variables of the VMManager class private except
for the page table.
2018-12-06 15:02:17 -05:00
Lioncash 547eecf119 kernel/process: Set ideal core from metadata
A very trivial change. If metadata is available, the process should use
it to retrieve the desired core for the process to run on.
2018-12-05 16:59:37 -05:00
Zach Hilman e6f7825a24 svc: Avoid incorrect fast yield condition 2018-12-04 22:11:32 -05:00
Lioncash 2f253986df kernel/svc: Correct behavior of svcResetSignal()
While partially correct, this service call allows the retrieved event to
be null, as it also uses the same handle to check if it was referring to
a Process instance. The previous two changes put the necessary machinery
in place to allow for this, so we can simply call those member functions
here and be done with it.
2018-12-04 20:14:59 -05:00
Lioncash c7462ce712 kernel/process: Make Process a WaitObject
Process instances can be waited upon for state changes. This is also
utilized by svcResetSignal, which will be modified in an upcoming
change. This simply puts all of the WaitObject related machinery in
place.
2018-12-04 20:14:59 -05:00
Lioncash a3aa7aaf0b kernel/readable_event: Add member function for enforcing a strict reset contract
svcResetSignal relies on the event instance to have already been
signaled before attempting to reset it. If this isn't the case, then an
error code has to be returned.
2018-12-04 20:14:55 -05:00
Lioncash 8ea1f28614 kernel/svc: Remove unused header inclusion 2018-12-04 15:48:20 -05:00
Lioncash a543c35962 kernel/svc: Implement svcSignalEvent()
This function simply does a handle table lookup for a writable event
instance identified by the given handle value. If a writable event
cannot be found for the given handle, then an invalid handle error is
returned. If a writable event is found, then it simply signals the
event, as one would expect.
2018-12-04 15:47:59 -05:00
Lioncash 2a1f59b301 kernel/svc: Implement svcCreateEvent()
svcCreateEvent operates by creating both a readable and writable event
and then attempts to add both to the current process' handle table.

If adding either of the events to the handle table fails, then the
relevant error from the handle table is returned.

If adding the readable event after the writable event to the table
fails, then the writable event is removed from the handle table and the
relevant error from the handle table is returned.

Note that since we do not currently test resource limits, we don't check
the resource limit table yet.
2018-12-04 15:47:55 -05:00
bunnei d533767623
Merge pull request #1853 from lioncash/event
kernel/object: Amend handle types to distinguish between readable and writable events
2018-12-04 12:25:40 -05:00
Lioncash 5eb057f422 kernel/object: Amend handle types to distinguish between readable and writable events
Two kernel object should absolutely never have the same handle ID type.
This can cause incorrect behavior when it comes to retrieving object
types from the handle table. In this case it allows converting a
WritableEvent into a ReadableEvent and vice-versa, which is undefined
behavior, since the object types are not the same.

This also corrects ClearEvent() to check both kernel types like the
kernel itself does.
2018-12-04 02:20:47 -05:00
Lioncash ac966e4213 kernel/handle_table: Amend reference to CTR-OS in Create()
Another hold-over from Citra.
2018-12-04 01:50:44 -05:00
Lioncash 312690b450 kernel/svc: Implement the resource limit svcGetInfo option
Allows a process to register the resource limit as part of its handle
table.
2018-12-04 01:50:30 -05:00
Luke Street 3e75175d02 svc: Implement SetThreadActivity (thread suspension) 2018-12-04 01:23:50 -05:00
V.Kalyuzhny b330b495dc [Kernel::CreateThread] Match format specifiers to LOG_TRACE's arguments 2018-12-04 05:13:50 +02:00
Zach Hilman ddf5903cd9 scheduler: Avoid manual Reschedule call
This will automatically occur anyway when PrepareReschedule is called
2018-12-03 21:22:09 -05:00
bunnei 9f1ac96afa
Merge pull request #1840 from lioncash/info
svc: Reorganize svcGetInfo, handle more error cases for existing implemented info categories
2018-12-03 18:46:22 -05:00
Zach Hilman b5af41a07b scheduler: Only work steal higher priority threads from other cores 2018-12-03 17:29:30 -05:00
bunnei ef69b4b830
Merge pull request #1803 from DarkLordZach/k-able-event
kernel: Divide Event into ReadableEvent and WritableEvent
2018-12-03 17:05:57 -05:00
David Marcec 5102c91256 Moved backtrace to ArmInterface
Added to both dynarmic and unicorn
2018-12-03 20:13:48 +11:00
David Marcec 7149332712 Print backtrace on svcBreak
When we get an svcBreak we get a backtrace now
2018-12-03 19:12:09 +11:00
Lioncash 7fe27de26e svc: Use the current process' handle table for retrieving the process instance to act upon
The kernel uses the handle table of the current process to retrieve the
process that should be used to retrieve certain information. To someone
not familiar with the kernel, this might raise the question of "Ok,
sounds nice, but doesn't this make it impossible to retrieve information
about the current process?".

No, it doesn't, because HandleTable instances in the kernel have the
notion of a "pseudo-handle", where certain values allow the kernel to
lookup objects outside of a given handle table. Currently, there's only
a pseudo-handle for the current process (0xFFFF8001) and a pseudo-handle
for the current thread (0xFFFF8000), so to retrieve the current process,
one would just pass 0xFFFF8001 into svcGetInfo.

The lookup itself in the handle table would be something like:

template <typename T>
T* Lookup(Handle handle) {
    if (handle == PSEUDO_HANDLE_CURRENT_PROCESS) {
        return CurrentProcess();
    }

    if (handle == PSUEDO_HANDLE_CURRENT_THREAD) {
        return CurrentThread();
    }

    return static_cast<T*>(&objects[handle]);
}

which, as is shown, allows accessing the current process or current
thread, even if those two objects aren't actually within the HandleTable
instance.
2018-12-02 03:41:49 -05:00
Lioncash 6712e7402c svc: Reorganize svcGetInfo, handle more error cases for existing implemented info categories
Our implementation of svcGetInfo was slightly incorrect in that we
weren't doing proper error checking everywhere. Instead, reorganize it
to be similar to how the kernel seems to do it.
2018-12-02 03:40:10 -05:00
Zach Hilman 3476830b26 svc: Avoid performance-degrading unnecessary reschedule 2018-12-02 00:44:40 -05:00
Lioncash e88cdcc912 Fix debug build
A non-existent parameter was left in some formatting calls (the logging
macro for which only does anything meaningful on debug builds)
2018-12-01 02:11:42 -05:00
Zach Hilman 170d707850 hle_ipc: Refactor SleepClientThread to avoid ReadableEvent 2018-11-29 09:14:20 -05:00
Zach Hilman a342bcc9b1 kernel/event: Reference ReadableEvent from WritableEvent 2018-11-29 08:48:40 -05:00
Zach Hilman ff610103b5 core: Port all current usages of Event to Readable/WritableEvent 2018-11-29 08:45:41 -05:00
Zach Hilman a56fc84e7a hle_ipc: Use event pair for SleepClientThread 2018-11-29 08:42:26 -05:00
Zach Hilman c61d2a2841 kernel: Add named event table
Used to store ReadableEvents of all events on the system.
2018-11-29 08:42:26 -05:00
Zach Hilman c713383816 kernel: Divide Event into ReadableEvent and WritableEvent
More hardware accurate. On the actual system, there is a differentiation between the signaler and signalee, they form a client/server relationship much like ServerPort and ClientPort.
2018-11-29 08:42:26 -05:00
Zach Hilman d92989e787 kernel/object: Add descriptions to ResetTypes 2018-11-29 08:42:26 -05:00
bunnei 1e49a85106
Merge pull request #1801 from ogniK5377/log-before-execute
Changed logging to be "Log before execution", Added more error logging, all services/svc should now log on some level
2018-11-29 00:58:46 -05:00
Lioncash 5905162e36 svc: Implement svcSetResourceLimitLimitValue()
The opposite of the getter functions, this function sets the limit value
for a particular ResourceLimit resource category, with the restriction
that the  new limit value must be equal to or greater than the current
resource value. If this is violated, then ERR_INVALID_STATE is returned.

e.g.

Assume:

current[Events] = 10;
limit[Events] = 20;

a call to this service function lowering the limit value to 10 would be
fine, however, attempting to lower it to 9 in this case would cause an
invalid state error.
2018-11-26 21:23:15 -05:00
Lioncash eb5596044d svc: Implement svcGetResourceLimitCurrentValue()
This kernel service function is essentially the exact same as
svcGetResourceLimitLimitValue(), with the only difference being that it
retrieves the current value for a given resource category using the
provided resource limit handle, rather than retrieving the limiting
value of that resource limit instance.

Given these are exactly the same and only differ on returned values, we
can extract the existing code for svcGetResourceLimitLimitValue() to
handle both values.
2018-11-26 21:23:11 -05:00
Lioncash 1d6399c222 svc: Implement svcGetResourceLimitLimitValue()
This kernel service function retrieves the maximum allowable value for
a provided resource category for a given resource limit instance. Given
we already have the functionality added to the resource limit instance
itself, it's sufficient to just hook it up.

The error scenarios for this are:

1. If an invalid resource category type is provided, then ERR_INVALID_ENUM is returned.

2. If an invalid handle is provided, then ERR_INVALID_HANDLE is returned (bad thing goes in, bad thing goes out, as one would expect).

If neither of the above error cases occur, then the out parameter is
provided with the maximum limit value for the given category and success
is returned.
2018-11-26 21:12:13 -05:00
Lioncash 4ef2af8c98 svc: Implement svcCreateResourceLimit()
This function simply creates a ResourceLimit instance and attempts to
create a handle for it within the current process' handle table. If the
kernal fails to either create the ResourceLimit instance or create a
handle for the ResourceLimit instance, it returns a failure code
(OUT_OF_RESOURCE, and HANDLE_TABLE_FULL respectively). Finally, it exits
by providing the output parameter with the handle value for the
ResourceLimit instance and returning that it was successful.

Note: We do not return OUT_OF_RESOURCE because, if yuzu runs out of
available memory, then new will currently throw. We *could* allocate the
kernel instance with std::nothrow, however this would be inconsistent
with how all other kernel objects are currently allocated.
2018-11-26 21:10:31 -05:00
David Marcec cc4521fc70 Added comment on Main memory size for more clarity 2018-11-27 12:56:50 +11:00
David Marcec f058de337e Made svcSetHeapSize and svcCreateSharedMemory more readable 2018-11-27 12:53:18 +11:00
David Marcec f271316822 Reworked svcs slightly, improved error messages in AM and fsp_srv 2018-11-27 12:29:06 +11:00
David Marcec 9662ca918d Improved error messages for SVCs 2018-11-26 19:47:39 +11:00
David Marcec a2cc3b10bb Changed logging to be "Log before execution", Added more error logging, all services should now log on some level 2018-11-26 17:06:13 +11:00
Luke Street 94e8dfc0c7 svc: Return ERR_INVALID_ENUM_VALUE from svcGetInfo 2018-11-25 16:48:44 -05:00
Zach Hilman 820d81b9a5 scheduler: Add explanations for YieldWith and WithoutLoadBalancing 2018-11-22 00:33:53 -05:00
Lioncash 0e35f1bb18 kernel/handle_table: Move private static functions into the cpp file
These don't depend on class state, and are effectively implementation
details, so they can go into the cpp file .
2018-11-21 18:31:01 -05:00
Lioncash 568bcbc29d kernel/handle_table: Restrict handle table size to 1024 entries
The previous handle table size is a holdover from Citra. The actual
handle table construct on Horizon only allows for a maximum of 1024
entries.
2018-11-21 18:28:03 -05:00
Lioncash f5ce71793e kernel/handle_table: Default destructor in the cpp file
We don't need to potentially inline the teardown logic of all of the
handle instances.
2018-11-21 18:23:09 -05:00
bunnei aa7e53ab5c
Merge pull request #1734 from lioncash/shared
kernel/shared_memory: Make data members private, plus minor interface changes
2018-11-20 16:13:30 -08:00
Lioncash 31d1e06eb1 kernel/process: Move <random> include to the cpp file
<random> isn't necesary directly within the header and can be placed in
the cpp file where its needed. Avoids propagating random generation
utilities via a header file.
2018-11-20 17:46:20 -05:00
bunnei b6d2c64f4d
Merge pull request #1667 from DarkLordZach/swkbd
am: Implement HLE software keyboard applet
2018-11-20 08:24:11 -08:00
Lioncash 5d46038c5c kernel/resource_limit: Clean up interface
Cleans out the citra/3DS-specific implementation details that don't
apply to the Switch. Sets the stage for implementing ResourceLimit
instances properly.

While we're at it, remove the erroneous checks within CreateThread() and
SetThreadPriority(). While these are indeed checked in some capacity,
they are not checked via a ResourceLimit instance.

In the process of moving out Citra-specifics, this also replaces the
system ResourceLimit instance's values with ones from the Switch.
2018-11-19 18:16:39 -05:00
Lioncash 233e495c14 kernel/shared_memory: Make Map() and Unmap() take the target process by reference rather than as a pointer
Both member functions assume the passed in target process will not be
null. Instead of making this assumption implicit, we can change the
functions to be references and enforce this at the type-system level.
2018-11-19 09:20:29 -05:00
Lioncash fb5d4b17de kernel/shared_memory: Add a const qualified member function overload for GetPointer()
Given this doesn't mutate instance state, we can provide a
const-qualified variant as well.
2018-11-19 09:20:29 -05:00
Lioncash 2d37ca3726 kernel/shared_memory: Use 64-bit types for offset and size in CreateForApplet
Keeps the interface consistent with the regular Create() function.
2018-11-19 09:20:29 -05:00
Lioncash 76ac234bf6 kernel/shared_memory: Make GetPointer() take a std::size_t instead of a u32
Makes the interface nicer to use in terms of 64-bit code, as it makes it
less likely for one to get truncation warnings (and also makes sense in
the context of the rest of the interface where 64-bit types are used for
sizes and offsets
2018-11-19 09:20:29 -05:00
Lioncash f472232705 kernel/shared_memory: Make data members private
Rather than allow unfettered access to the class internals, we hide all
members by default and create and API that other code can operate
against.
2018-11-19 09:20:25 -05:00
Zach Hilman 409dcf0e0a svc: Implement yield types 0 and -1 2018-11-18 23:44:19 -05:00
bunnei e34d47e6e3
Merge pull request #1620 from DarkLordZach/ldr-ro
ldr_ro: Complete LDR:RO implementation
2018-11-18 19:23:38 -08:00
Mat M 9a1bac840e
Merge pull request #1728 from FearlessTobi/reset-signal
svc: ResetSignal is not stubbed
2018-11-18 15:51:32 -05:00
Tobias 13f79cc5bd
svc: ResetSignal is not stubbed
https://user-images.githubusercontent.com/20753089/48677874-b8e01c80-eb7b-11e8-8043-b99faa29022c.PNG
2018-11-18 21:49:17 +01:00
Zach Hilman e696ed1f4d am: Deglobalize software keyboard applet 2018-11-18 10:53:47 -05:00
Zach Hilman 7901de2b75 svc: Implement svcCreateTransferMemory
Seems to be used and created identically to SharedMemory, so just reuse that.
2018-11-18 10:53:47 -05:00
Zach Hilman 51af996854 ldr_ro: Add error check for memory allocation failure 2018-11-17 21:40:26 -05:00
Lioncash d21b2164e9 kernel/errors: Clean up error codes
Similar to PR 1706, which cleans up the error codes for the filesystem
code, but done for the kernel error codes. This removes the ErrCodes
namespace and specifies the errors directly. This also fixes up any
straggling lines of code that weren't using the named error codes where
applicable.
2018-11-16 14:32:30 -05:00
Mat M 14cede1a0c
Merge pull request #1638 from FreddyFunk/SetMemoryPermission-Stubbed
Implement SetMemoryPermission
2018-11-16 10:35:56 -05:00
bunnei f7319b0d3c
Merge pull request #1687 from lioncash/deduplication
kernel/thread: Deduplicate scheduler switching code
2018-11-15 14:47:42 -08:00
Zach Hilman 0276761a1e process: Make MirrorMemory take state to map new memory as
Credits to Subv
2018-11-15 12:48:09 -05:00
bunnei e1ea8cc721
Merge pull request #1679 from DarkLordZach/deterministic-rng-2
svc: Use proper random entropy generation algorithm
2018-11-14 11:52:27 -08:00
Lioncash f9db75fe40 kernel/thread: Deduplicate scheduler switching code
The code in both places was the same verbatim, so we can extract it to a
function to deduplicate the logic.
2018-11-14 00:02:42 -05:00
Lioncash 004277477a vm_manager: Unstub GetTotalHeapUsage()
Now that we've moved all of the heap-related stuff to the VMManager
class, we can unstub this function, as the necessary members are visible
now.
2018-11-13 13:08:26 -05:00
Lioncash b8e885c6e5 kernel/process: Migrate heap-related memory management out of the process class and into the vm manager
Avoids a breach of responsibilities in the interface and keeps the
direct code for memory management within the VMManager class.
2018-11-13 13:08:19 -05:00
Zach Hilman ab552e4a25 svc: Use proper random entropy generation algorithm 2018-11-13 12:26:03 -05:00
Zach Hilman cb1e63ef09 svc: Return random seed for svcGetInfo RandomEntropy 2018-11-12 21:46:21 -05:00
David 581406af18 svcBreak now dumps information from the debug buffer passed (#1646)
* svcBreak now dumps information from the debug buffer passed

info1 and info2 seem to somtimes hold an address to a buffer, this is usually 4 bytes or the size of the int and contains an error code. There's other circumstances where it can be something different so we hexdump these to examine them at a later date.

* Addressed comments
2018-11-07 20:43:54 -08:00
Frederic Laing ba2cdcdc5a Implement SetMemoryPermission 2018-11-06 10:21:01 +01:00
Frederic Laing ab7472345b Stubbed SetMemoryPermission 2018-11-03 16:01:34 +01:00
Lioncash 352b56367c general: Remove unused boost inclusions where applicable
Cleans up unused includes and trims off some dependencies on externals.
2018-10-30 00:09:46 -04:00
Frederic L 7a5eda5914 global: Use std::optional instead of boost::optional (#1578)
* get rid of boost::optional

* Remove optional references

* Use std::reference_wrapper for optional references

* Fix clang format

* Fix clang format part 2

* Adressed feedback

* Fix clang format and MacOS build
2018-10-30 00:03:25 -04:00
bunnei adf26ae668
Merge pull request #1621 from lioncash/ipc
hle_ipc: Make GetDomainMessageHeader return a regular pointer
2018-10-29 23:55:59 -04:00
Lioncash 6383653a8d hle_ipc: Add member function for querying the existence of a domain header
Gets rid of the need to call the getter and then check for null.
2018-10-29 23:28:04 -04:00
Lioncash 0cc347462d hle_ipc: Make GetDomainMessageHeader return a regular pointer
Nothing requires the shared owner ship here, so we can just return a
plain pointer.
2018-10-29 23:18:25 -04:00
Lioncash a973a049b7 core: Make System references const where applicable 2018-10-28 17:45:29 -04:00
Lioncash 7de8e36343 svc: Localize the GetInfo enum class to the function itself
Nothing from this enum is intended to be used outside of this function.
2018-10-26 12:49:14 -04:00
Lioncash 6594853eb1 svc: Implement svcGetInfo command 0xF0000002
This retrieves:

if (curr_thread == handle_thread) {
   result = total_thread_ticks + (hardware_tick_count - last_context_switch_ticks);
} else if (curr_thread == handle_thread && sub_id == current_core_index) {
   result = hardware_tick_count - last_context_switch_ticks;
}
2018-10-26 12:49:11 -04:00
bunnei c2049aa4e5 process: LoadModule should clear JIT instruction cache. 2018-10-25 18:03:54 -04:00
bunnei a609b6907a Kernel/Memory: Added a function to first a suitable guest address at which to allocate a region of a given size. 2018-10-25 18:03:54 -04:00
Lioncash 1fb4bebb63 kernel/errors: Remove now-unused, unnecessary, error codes
Now that we've gotten the innaccurate error codes out of the way, we can
finally toss away a bunch of these, trimming down the error codes to
ones that are actually used and knocking out two TODO comments.
2018-10-24 14:58:37 -04:00
Lioncash 239dfea34a kernel/shared_memory: Return ERR_INVALID_MEMORY_PERMISSIONS instead of ERR_INVALID_COMBINATION
This is more consistent with what the kernel does.
2018-10-24 14:54:36 -04:00
Lioncash 474bc29208 kernel/server_port: Simplify emptiness check within ShouldWait() 2018-10-24 14:24:36 -04:00
Lioncash b703aba622 kernel/server_port: Change error case return value in Accept() to ERR_NOT_FOUND
This is what the kernel does in this instance.
2018-10-24 14:23:38 -04:00
Lioncash afb7e5cc05 kernel/error: Remove leftover 3DS error codes
These are now entirely unused and can be removed.
2018-10-24 14:21:37 -04:00
Lioncash fcf8f53a63 kernel/svc: Amend returned error code for invalid priorities in CreateThread
Like with the previous change, the kernel doesn't return NOT_AUTHORIZED
here. It returns INVALID_THREAD_PRIORITY.
2018-10-24 14:11:11 -04:00
Lioncash 77328b0f19 kernel/svc: Move and correct returned error code for invalid thread priorities in SetThreadPriority()
All priority checks are supposed to occur before checking the validity
of the thread handle, we're also not supposed to return
ERR_NOT_AUTHORIZED here.
2018-10-24 14:10:48 -04:00
Lioncash c7c346a15d kernel/error: Add error code for invalid pointers
The kernel appears to return 0xE601 for this situation. Particularly in
svcWaitSynchronization, svcReplyAndReceive, and svcGetThreadContext
2018-10-24 13:41:32 -04:00
Lioncash 6df09f5b76 kernel/error: Add error code for closed sessions
The kernel appears to return 0xF601 for this case.
2018-10-24 13:38:39 -04:00
bunnei a94e5d9e68
Merge pull request #1551 from ogniK5377/improved-svcbreak
Added break types to svcBreak
2018-10-23 19:56:42 -04:00
bunnei e61a62066a
Merge pull request #1540 from lioncash/handle
kernel/process: Make the handle table per-process
2018-10-23 18:43:11 -04:00
David Marcec 38cdb6744d Added assertion failed, reworked logging levels 2018-10-23 15:17:13 +11:00
David Marcec 8042731da9 Added break types to svcBreak
There seems to be more such as type 1, and 2. Unsure what these currently are but when a game hits them we can investigate and add the rest
2018-10-23 15:03:59 +11:00
Lioncash 90a981a03a kernel/process: Make the handle table per-process
In the kernel, there isn't a singular handle table that everything gets
tossed into or used, rather, each process gets its own handle table that
it uses. This currently isn't an issue for us, since we only execute one
process at the moment, but we may as well get this out of the way so
it's not a headache later on.
2018-10-20 16:38:32 -04:00
Lioncash 896c0f61a0 svc: Fix vma boundary check in svcQueryMemory
This should be comparing against the queried process' vma_map, not the
current process'. The only reason this hasn't become an issue yet is we
currently only handle one process being active at any time.
2018-10-20 14:56:51 -04:00
bunnei 60317e6306
Merge pull request #1520 from lioncash/san
svc: Add missing sanitizing checks for MapSharedMemory/UnmapSharedMemory
2018-10-19 22:58:57 -04:00
Lioncash 4b5ae8dbaa svc: Check for word alignment of addresses within svcArbitrateLock/svcArbitrateUnlock
The kernel itself checks whether or not the provided addresses are word
aligned before continuing, so we should be doing the same.
2018-10-18 13:01:29 -04:00
Lioncash d27f4a4928 common: Move Is4KBAligned() to alignment.h
Aligning on 4KB pages isn't a Switch-specific thing, so this can be
moved to common so it can be used with other things as well.
2018-10-18 12:57:02 -04:00
Lioncash 33830aa65a svc: Add missing sanitizing checks for MapSharedMemory/UnmapSharedMemory
Now that the changes clarifying the address spaces has been merged, we
can wrap the checks that the kernel performs when mapping shared memory
(and other forms of memory) into its own helper function and then use
those within MapSharedMemory and UnmapSharedMemory to complete the
sanitizing checks that are supposed to be done.
2018-10-18 02:01:21 -04:00
bunnei 6e8752881c
Merge pull request #1498 from lioncash/aslr
svc: Clarify enum values for AddressSpaceBaseAddr and AddressSpaceSize in svcGetInfo()
2018-10-17 18:31:51 -04:00
Lioncash 5484742fda core_cpu: Make Cpu scheduler instances unique_ptrs instead of shared_ptrs 2018-10-15 14:15:56 -04:00
Lioncash 90f8474fc1 svc: Clarify enum values for AddressSpaceBaseAddr and AddressSpaceSize in svcGetInfo()
So, one thing that's puzzled me is why the kernel seemed to *not* use
the direct code address ranges in some cases for some service functions.
For example, in svcMapMemory, the full address space width is compared
against for validity, but for svcMapSharedMemory, it compares against
0xFFE00000, 0xFF8000000, and 0x7FF8000000 as upper bounds, and uses
either 0x200000 or 0x8000000 as the lower-bounds as the beginning of the
compared range. Coincidentally, these exact same values are also used in
svcGetInfo, and also when initializing the user address space, so this
is actually retrieving the ASLR extents, not the extents of the address
space in general.
2018-10-14 20:11:16 -04:00
bunnei 2f8ca32020
Merge pull request #1492 from lioncash/proc
svc: Implement svcGetProcessInfo
2018-10-14 14:37:58 -04:00
David Marcec 92fae7e1ab Stop all threads on svcBreak
This should help diagnose crashes easier and prevent many users thinking that a game is still running when in fact it's just an audio thread still running(this is typically not killed when svcBreak is hit since the game expects us to do this)
2018-10-14 18:14:51 +11:00
Lioncash 1c7a7ed79b svc: Implement svcGetProcessInfo
A fairly basic service function, which only appears to currently support
retrieving the process state. This also alters the ProcessStatus enum to
contain all of the values that a kernel process seems to be able of
reporting with regards to state.
2018-10-13 17:00:43 -04:00
bunnei c2aa4293ec
Merge pull request #1483 from lioncash/codeset
kernel/process: Make CodeSet a regular non-inherited object
2018-10-12 22:52:12 -04:00
bunnei ffcda6c08e
Merge pull request #1481 from lioncash/typo
svc: Fix typos in sanitizing checks for MapMemory/UnmapMemory
2018-10-12 20:46:55 -04:00
bunnei 2946d4bdbe
Merge pull request #1467 from ogniK5377/svcbreak-type-fix
Fixed incorrect types for svcBreak
2018-10-12 12:08:08 -04:00
Lioncash 1abed2f4c4 kernel/process: Make CodeSet a regular non-inherited object
These only exist to ferry data into a Process instance and end up going
out of scope quite early. Because of this, we can just make it a plain
struct for holding things and just std::move it into the relevant
function. There's no need to make this inherit from the kernel's Object
type.
2018-10-12 12:07:32 -04:00
Lioncash b492d43e63 thread: Remove unnecessary memset from ResetThreadContext()
Regular value initialization is adequate here for zeroing out data. It
also has the benefit of not invoking undefined behavior if a non-trivial
type is ever added to the struct for whatever reason.
2018-10-12 10:57:31 -04:00
Lioncash 4ccf30dfaa svc: Fix typos in sanitizing checks for MapMemory/UnmapMemory 2018-10-12 01:48:26 -04:00
Lioncash 72e9cb523e svc: Add missing address range sanitizing checks to MapMemory/UnmapMemory
This adds the missing address range checking that the service functions
do before attempting to map or unmap memory. Given that both service
functions perform the same set of checks in the same order, we can wrap
these into a function and just call it from both functions, which
deduplicates a little bit of code.
2018-10-10 20:30:49 -04:00
Lioncash 5c0408596f kernel/thread: Use a regular pointer for the owner/current process
There's no real need to use a shared pointer in these cases, and only
makes object management more fragile in terms of how easy it would be to
introduce cycles. Instead, just do the simple thing of using a regular
pointer. Much of this is just a hold-over from citra anyways.

It also doesn't make sense from a behavioral point of view for a
process' thread to prolong the lifetime of the process itself (the
process is supposed to own the thread, not the other way around).
2018-10-10 02:04:55 -04:00
David Marcec 2db37ddea9 Changed all casts in svc_wrap.h to be static_cast instead 2018-10-10 12:49:08 +11:00
David Marcec 09b6dda8f0 Use a better name than "dont_kill_application"
signal_debugger seems like a more fitting name
2018-10-10 12:27:44 +11:00
David Marcec a4412c8e22 Fixed incorrect types for svcBreak
svcBreak reason should be a u32, not a u64.
2018-10-10 12:23:50 +11:00
David Marcec f5631e78d1 Added bitfield instead of manually checking if the bit is set 2018-10-09 12:11:14 +11:00
David Marcec af3ba94b2a Actual kill execution when the bit isn't set, not the other way around 2018-10-09 11:14:48 +11:00
David Marcec c50f66a8eb svcBreak, Signalling to the debugger should not kill execution
When loading NROs, svcBreak is called to signal to the debugger that a new "module" is loaded. As no debugger is technically attached we shouldn't be killing the programs execution.
2018-10-09 11:10:30 +11:00
David Marcec 612ce89eca Added forward define for ServerPort 2018-10-06 17:47:33 +10:00
David Marcec f84b9ed4e8 Ported #4296 from citra
This will allow us to easily remove the use of "NFC" in "System"
2018-10-06 16:49:01 +10:00
Lioncash 6ddf8f34db
kernel/mutex: Amend behavior of TransferMutexOwnership()
This was the result of a typo accidentally introduced in
e51d715700. This restores the previous
correct behavior.

The behavior with the reference was incorrect and would cause some games
to fail to boot.
2018-10-06 01:13:02 -04:00
balika011 1a5d6de0d4 thread: Make the scheduler pointer a regular pointer
Conceptually, it doesn't make sense for a thread to be able to persist
the lifetime of a scheduler. A scheduler should be taking care of the
threads; the threads should not be taking care of the scheduler.

If the threads outlive the scheduler (or we simply don't actually
terminate/shutdown the threads), then it should be considered a bug
that we need to fix.

Attributing this to balika011, as they opened #1317 to attempt to fix
this in a similar way, but my refactoring of the kernel code caused
quite a few conflicts.
2018-10-05 14:53:01 -04:00
Lioncash baed7e1fba kernel/thread: Make all instance variables private
Many of the member variables of the thread class aren't even used
outside of the class itself, so there's no need to make those variables
public. This change follows in the steps of the previous changes that
made other kernel types' members private.

The main motivation behind this is that the Thread class will likely
change in the future as emulation becomes more accurate, and letting
random bits of the emulator access data members of the Thread class
directly makes it a pain to shuffle around and/or modify internals.
Having all data members public like this also makes it difficult to
reason about certain bits of behavior without first verifying what parts
of the core actually use them.

Everything being public also generally follows the tendency for changes
to be introduced in completely different translation units that would
otherwise be better introduced as an addition to the Thread class'
public interface.
2018-10-04 00:14:15 -04:00
Lioncash 541c550753 kernel/svc: Implement svcGetThreadContext()
Now that we have all of the rearranging and proper structure sizes in
place, it's fairly trivial to implement svcGetThreadContext(). In the
64-bit case we can more or less just write out the context as is, minus
some minor value sanitizing. In the 32-bit case we'll need to clear out
the registers that wouldn't normally be accessible from a 32-bit
AArch32 exectuable (or process).
2018-09-30 05:29:40 -04:00
Lioncash dccfe193a9 kernel/process: Add a data member to determine if a process is 64-bit or not.
This will be necessary for the implementation of svcGetThreadContext(),
as the kernel checks whether or not the process that owns the thread
that has it context being retrieved is a 64-bit or 32-bit process.

If the process is 32-bit, then the upper 15 general-purpose registers
and upper 16 vector registers are cleared to zero (as AArch32 only has
15 GPRs and 16 128-bit vector registers. not 31 general-purpose
registers and 32 128-bit vector registers like AArch64).
2018-09-30 05:29:40 -04:00
Lioncash cf9d6c6f52 kernel/process: Make data member variables private
Makes the public interface consistent in terms of how accesses are done
on a process object. It also makes it slightly nicer to reason about the
logic of the process class, as we don't want to expose everything to
external code.
2018-09-30 02:30:01 -04:00
bunnei 97c0ac3545
Merge pull request #1412 from lioncash/move
kernel/object: Remove unnecessary std::move from DynamicObjectCast()
2018-09-29 11:58:58 -04:00
bunnei f7b69d61f2
Merge pull request #1395 from lioncash/vm
process/vm_manager: Initial modifications to load NPDM metadata
2018-09-29 10:54:39 -04:00
Lioncash f4c24d0832 kernel/object: Remove unnecessary std::move from DynamicObjectCast()
boost::static_pointer_cast for boost::intrusive_ptr (what SharedPtr is),
takes its parameter by const reference. Given that, it means that this
std::move doesn't actually do anything other than obscure what the
function's actual behavior is, so we can remove this. To clarify, this
would only do something if the parameter was either taking its argument
by value, by non-const ref, or by rvalue-reference.
2018-09-28 02:17:57 -04:00
bunnei c0445006af
Merge pull request #1399 from lioncash/sched
kernel/scheduler: Take ARM_Interface instances by reference
2018-09-26 16:17:18 -04:00
Lioncash a58eefa7e4 kernel/scheduler: Take ARM_Interface instance by reference in the constructor
It doesn't make sense to allow a scheduler to be constructed around a
null pointer.
2018-09-25 16:00:17 -04:00
bunnei b67c1fdf38
Merge pull request #1393 from tech4me/svc
svc: Updated svc names
2018-09-25 10:47:12 -04:00
Lioncash 83377113bf memory: Dehardcode the use of fixed memory range constants
The locations of these can actually vary depending on the address space
layout, so we shouldn't be using these when determining where to map
memory or be using them as offsets for calculations. This keeps all the
memory ranges flexible and malleable based off of the virtual memory
manager instance state.
2018-09-24 22:16:03 -04:00
Lioncash 6c6f95d071 svc: Report correct memory-related values within some of the cases in svcGetInfo()
Previously, these were reporting hardcoded values, but given the regions
can change depending on the requested address spaces, these need to
report the values that the memory manager contains.
2018-09-24 22:16:03 -04:00
Lioncash 7fd598636e memory: Dehardcode the use of a 36-bit address space
Given games can also request a 32-bit or 39-bit address space, we
shouldn't be hardcoding the address space range as 36-bit.
2018-09-24 22:15:53 -04:00
Lioncash 75603b005b process/vm_manager: Amend API to allow reading parameters from NPDM metadata
Rather than hard-code the address range to be 36-bit, we can derive the
parameters from supplied NPDM metadata if the supplied exectuable
supports it. This is the bare minimum necessary for this to be possible.

The following commits will rework the memory code further to adjust to
this.
2018-09-24 17:24:50 -04:00
tech4me d42424ace0 svc: Updated svc names 2018-09-23 17:03:38 -07:00
Lioncash 48b2eda492 svc: Move most process termination code to its own function within Process
Reduces the use of Process class members externally and keeps most code
related to tearing down a process with the rest of the process code.
2018-09-21 06:07:41 -04:00
Lioncash acfc801d14 thread/process: Move TLS slot marking/freeing to the process class
Allows making several members of the process class private, it also
avoids going through Core::CurrentProcess() just to retrieve the owning
process.
2018-09-21 03:50:12 -04:00
bunnei 0285ddfbd4
Merge pull request #1372 from lioncash/thread
kernel/thread: Use owner_process when setting the page table in SetupMainThread()
2018-09-20 23:35:29 -04:00
Lioncash 05aa4aa01a kernel/thread: Use owner_process when setting the page table in SetupMainThread()
The owning process of a thread is required to exist before the thread,
so we can enforce this API-wise by using a reference. We can also avoid
the reliance on the system instance by using that parameter to access
the page table that needs to be set.
2018-09-20 21:10:00 -04:00
Lioncash 9b8fc2b689 arm_interface: Replace kernel vm_manager include with a forward declaration
Avoids an unnecessary inclusion and also uncovers three places where
indirect inclusions were relied upon, which allows us to also resolve
those.
2018-09-20 19:35:36 -04:00
bunnei c768535463
Merge pull request #1346 from lioncash/svc
svc_wrap: Convert the PARAM macro into a function
2018-09-18 22:12:47 -04:00
bunnei 733c47623b
Merge pull request #1343 from lioncash/mutex
kernel/svc: Handle invalid address cases within svcArbitrateLock() and svcArbitrateUnlock()
2018-09-18 14:25:00 -04:00
Lioncash f85ab0a123 svc_wrap: Convert the PARAM macro into a function
This can just be a regular function, getting rid of the need to also
explicitly undef the define at the end of the file. Given FuncReturn()
was already converted into a function, it's #undef can also be removed.
2018-09-18 04:27:38 -04:00
Lioncash b51e7e0288 arm_interface: Remove ARM11-isms from the CPU interface
This modifies the CPU interface to more accurately match an
AArch64-supporting CPU as opposed to an ARM11 one. Two of the methods
don't even make sense to keep around for this interface, as Adv Simd is
used, rather than the VFP in the primary execution state. This is
essentially a modernization change that should have occurred from the
get-go.
2018-09-18 03:20:04 -04:00
Lioncash 71b48cb00f kernel/mutex: Replace ResultCode construction for invalid addresses with the named variant
We already have a ResultCode constant for the case of an invalid
address, so we can just use it instead of re-rolling that ResultCode
type.
2018-09-17 23:27:53 -04:00
Lioncash b6867602ca kernel/svc: Handle error cases for svcArbitrateLock() and svcArbitrateUnlock()
The kernel does the equivalent of the following check before proceeding:

if (address + 0x8000000000 < 0x7FFFE00000) {
    return ERR_INVALID_MEMORY_STATE;
}

which is essentially what our IsKernelVirtualAddress() function does. So
we should also be checking for this.

The kernel also checks if the given input addresses are 4-byte aligned,
however our Mutex::TryAcquire() and Mutex::Release() functions already
handle this, so we don't need to add code for this case.
2018-09-17 23:27:53 -04:00
bunnei 2bfb9fd0e6
Merge pull request #1313 from lioncash/error
kernel/errors: Amend error code for ERR_NOT_FOUND
2018-09-17 12:28:40 -04:00
bunnei e6367ab955
Merge pull request #1315 from lioncash/size
kernel/svc: Handle a few error cases within memory-related functions
2018-09-17 10:11:26 -04:00
bunnei e561afdcd5
Merge pull request #1328 from FearlessTobi/port-4192
Port #4192 from Citra: "svc: change unknown to thread in CreateThread"
2018-09-17 09:56:48 -04:00
Valentin Vanelslande 54ddb37b3c Port # #4192 from Citra: "svc: change unknown to thread in CreateThread" 2018-09-15 15:28:35 +02:00
fearlessTobi 63c2e32e20 Port #4182 from Citra: "Prefix all size_t with std::" 2018-09-15 15:21:06 +02:00