| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| | |
kernel/process: Start the main thread using the specified 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.
|
|\ \
| | |
| | | |
Print backtrace on svcBreak
|
| | | |
|
| | |
| | |
| | |
| | | |
When we get an svcBreak we get a backtrace now
|
| |/
|/|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
|\ \
| | |
| | | |
svc: Implement SetThreadActivity (thread suspension)
|
| | | |
|
|\ \ \
| | | |
| | | | |
kernel/{process, thread}: Amend behavior related to IDs
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
The service call uses a 64-bit value, just like svcGetProcessId. This
amends the function signature accordingly.
|
| | | |
| | | |
| | | |
| | | |
| | | | |
svcGetProcessId's out parameter is a pointer to a 64-bit value, not a
32-bit one.
|
|/ / /
| | |
| | |
| | |
| | | |
With all the basic backing functionality implemented, we can now unstub
svcSetMemoryAttribute.
|
|\ \ \
| | | |
| | | | |
svc: Implement yield types 0 and -1
|
| | | | |
|
| | | |
| | | |
| | | | |
This will automatically occur anyway when PrepareReschedule is called
|
| | | | |
|
| | | | |
|
| | | | |
|
| | | | |
|
|\ \ \ \
| | | | |
| | | | | |
vm_manager/svc: Modify MemoryState enum, and correct error handling for svcQueryMemory
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
svcQueryProcessMemory is trivial to implement, given all the behavior
necessary for it is present, it just needs a handler for it.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Gets rid of the need to directly access the managed VMAs outside of the
memory manager itself just for querying memory.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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.
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
|\ \ \ \
| | | | |
| | | | | |
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.
|
|/ / / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
| | | | |
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
|\ \ \ \
| | | | |
| | | | | |
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.
|
|/ / /
| | |
| | |
| | |
| | | |
Allows a process to register the resource limit as part of its handle
table.
|
| | | |
|
|\ \ \
| | | |
| | | | |
svc: Reorganize svcGetInfo, handle more error cases for existing implemented info categories
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
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.
|
| | |/
| |/|
| | |
| | |
| | |
| | | |
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.
|
|\ \ \
| |/ /
|/| | |
kernel: Divide Event into ReadableEvent and WritableEvent
|
| | | |
|
| | | |
|
|/ /
| |
| |
| |
| | |
A non-existent parameter was left in some formatting calls (the logging
macro for which only does anything meaningful on debug builds)
|
|\ \
| | |
| | | |
Changed logging to be "Log before execution", Added more error logging, all services/svc should now log on some level
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
| | |
|
|\ \
| | |
| | | |
kernel/shared_memory: Make data members private, plus minor interface changes
|
| |/
| |
| |
| |
| |
| | |
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.
|
|\ \
| | |
| | | |
am: Implement HLE software keyboard applet
|
| | | |
|
| | |
| | |
| | | |
Seems to be used and created identically to SharedMemory, so just reuse that.
|
| |/
|/|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
|\ \
| |/
|/| |
svc: ResetSignal is not stubbed
|
| |
| |
| | |
https://user-images.githubusercontent.com/20753089/48677874-b8e01c80-eb7b-11e8-8043-b99faa29022c.PNG
|
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
|\ \
| | |
| | | |
Implement SetMemoryPermission
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
|/ /
| |
| |
| |
| |
| |
| |
| | |
* 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
|
|/ |
|
|
|
|
| |
Nothing from this enum is intended to be used outside of this function.
|
|
|
|
|
|
|
|
|
|
| |
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;
}
|
|
|
|
|
| |
Like with the previous change, the kernel doesn't return NOT_AUTHORIZED
here. It returns INVALID_THREAD_PRIORITY.
|
|
|
|
|
|
| |
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.
|
|\
| |
| | |
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
|
|\ \
| |/
|/| |
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.
|
|/
|
|
|
|
| |
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.
|
|\
| |
| | |
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.
|
| |
| |
| |
| |
| | |
The kernel itself checks whether or not the provided addresses are word
aligned before continuing, so we should be doing the same.
|
|/
|
|
|
| |
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.
|
|\
| |
| | |
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.
|
|/ |
|
|\
| |
| | |
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.
|
|/
|
|
| |
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)
|
|\
| |
| | |
svc: Fix typos in sanitizing checks for MapMemory/UnmapMemory
|
| | |
|
|\ \
| |/
|/| |
Fixed incorrect types for svcBreak
|
| |
| |
| |
| | |
signal_debugger seems like a more fitting name
|
| |
| |
| |
| | |
svcBreak reason should be a u32, not a u64.
|
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
|/
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
| |
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
|
|
|
|
| |
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.
|
|\
| |
| | |
process/vm_manager: Initial modifications to load NPDM metadata
|
| |
| |
| |
| |
| |
| |
| |
| | |
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.
|
| |
| |
| |
| |
| |
| | |
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.
|
|\ \
| |/
|/| |
svc: Updated svc names
|
| | |
|
|/
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|\
| |
| | |
kernel/svc: Handle a few error cases within memory-related functions
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The kernel caps the size limit of shared memory to 8589930496 bytes (or
(1GB - 512 bytes) * 8), so approximately 8GB, where every GB has a 512
byte sector taken off of it.
It also ensures the shared memory is created with either read or
read/write permissions for both permission types passed in, allowing the
remote permissions to also be set as "don't care".
|
| |
| |
| |
| |
| |
| |
| |
| | |
Part of the checking done by the kernel is to check if the given
address and size are 4KB aligned, as well as checking if the size isn't
zero. It also only allows mapping shared memory as readable or
read/write, but nothing else, and so we shouldn't allow mapping as
anything else either.
|
| |
| |
| |
| |
| | |
The kernel checks if the addresses and given size is 4KB aligned before
continuing onwards to map the memory.
|
| |
| |
| |
| |
| | |
The kernel checks if the given size is a multiple of 2MB and <= to 4GB
before going ahead and attempting to allocate that much memory.
|
|\ \
| | |
| | | |
Port #4192 from Citra: "svc: change unknown to thread in CreateThread"
|
| |/ |
|
|/ |
|
|\
| |
| | |
kernel/errors: Amend invalid thread priority and invalid processor ID error codes
|
| |
| |
| |
| | |
This is what the kernel does for an out-of-range processor ID.
|
| | |
|
| |
| |
| |
| |
| |
| | |
While unlikely, it does avoid constructing a std::string and
unnecessarily calling into the memory code if a game or executable
decides to be really silly about their logging.
|
|/
|
|
| |
This should be a u64 to represent size.
|
|
|
|
|
|
| |
Now that we have a class representing the kernel in some capacity, we
now have a place to put the named port map, so we move it over and get
rid of another piece of global state within the core.
|
|
|
|
|
|
|
|
|
|
|
| |
The follow-up to e2457418dae19b889b2ad85255bb95d4cd0e4bff, which
replaces most of the includes in the core header with forward declarations.
This makes it so that if any of the headers the core header was
previously including change, then no one will need to rebuild the bulk
of the core, due to core.h being quite a prevalent inclusion.
This should make turnaround for changes much faster for developers.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As means to pave the way for getting rid of global state within core,
This eliminates kernel global state by removing all globals. Instead
this introduces a KernelCore class which acts as a kernel instance. This
instance lives in the System class, which keeps its lifetime contained
to the lifetime of the System class.
This also forces the kernel types to actually interact with the main
kernel instance itself instead of having transient kernel state placed
all over several translation units, keeping everything together. It also
has a nice consequence of making dependencies much more explicit.
This also makes our initialization a tad bit more correct. Previously we
were creating a kernel process before the actual kernel was initialized,
which doesn't really make much sense.
The KernelCore class itself follows the PImpl idiom, which allows
keeping all the implementation details sealed away from everything else,
which forces the use of the exposed API and allows us to avoid any
unnecessary inclusions within the main kernel header.
|
|
|
|
|
|
| |
We already have the variable itself set up to perform this task, so we
can just return its value from the currently executing process instead
of always stubbing it to zero.
|
|
|
|
|
|
| |
Given if we hit here all is lost, we should probably be logging the
break reason code and associated information to distinguish between the
causes.
|
|\
| |
| | |
Use an approximated amortized amount of ticks when advancing timing.
|
| |
| |
| |
| | |
The current core may have nothing to do with the core where the new thread was scheduled to run. In case it's the same core, then the following PrepareReshedule call will take care of that.
|
|/
|
|
|
|
|
|
|
|
| |
Exit from AddMutexWaiter early if the thread is already waiting for a mutex owned by the owner thread.
This accounts for the possibility of a thread that is waiting on a condition variable being awakened twice in a row.
Also added more validation asserts.
This should fix one of the random crashes in Breath Of The Wild.
|
|
|
|
| |
Makes our immutable state explicit.
|
|\
| |
| | |
kernel: Remove unused object_address_table.cpp/.h
|
| |
| |
| |
| |
| |
| | |
These source files were entirely unused throughout the rest of the
codebase. This also has the benefit of getting rid of a global variable
as well.
|
|/
|
|
|
| |
Removes unnecessary direct dependencies in some headers and also gets
rid of indirect dependencies that were being relied on to be included.
|
|\
| |
| | |
svc: Log parameters in SetMemoryAttribute()
|
| |
| |
| |
| | |
Provides slightly more context than only logging out the address value.
|
|/
|
|
|
| |
The loop's induction variable was signed, but we were comparing against
an unsigned variable.
|
| |
|
|
|
|
|
| |
Makes the thread status strongly typed, so implicit conversions can't
happen. It also makes it easier to catch mistakes at compile time.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The reason this would never be true is that ideal_processor is a u8 and
THREADPROCESSORID_DEFAULT is an s32. In this case, it boils down to how
arithmetic conversions are performed before performing the comparison.
If an unsigned value has a lesser conversion rank (aka smaller size)
than the signed type being compared, then the unsigned value is promoted
to the signed value (i.e. u8 -> s32 happens before the comparison). No
sign-extension occurs here either.
An alternative phrasing:
Say we have a variable named core and it's given a value of -2.
u8 core = -2;
This becomes 254 due to the lack of sign. During integral promotion to
the signed type, this still remains as 254, and therefore the condition
will always be true, because no matter what value the u8 is given it
will never be -2 in terms of 32 bits.
Now, if one type was a s32 and one was a u32, this would be entirely
different, since they have the same bit width (and the signed type would
be converted to unsigned instead of the other way around) but would
still have its representation preserved in terms of bits, allowing the
comparison to be false in some cases, as opposed to being true all the
time.
---
We also get rid of two signed/unsigned comparison warnings while we're
at it.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|\
| |
| | |
svc: Add a stub for UserExceptionContextAddr.
|
| | |
|
| |
| |
| |
| | |
Also added some proper error handling.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
| |
| |
| |
| |
| | |
This makes the formatting expectations more obvious (e.g. any zero padding specified
is padding that's entirely dedicated to the value being printed, not any pretty-printing
that also gets tacked on).
|
| |
| |
| |
| | |
Given we utilize fmt, we don't need to provide our own functions for formatting anymore
|
| | |
|
| | |
|
|\ \
| | |
| | | |
Kernel: Reworked the new kernel synchronization primitives.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Verified with a hwtest and implemented based on reverse engineering.
Thread A's priority will get bumped to the highest priority among all the threads that are waiting for a mutex that A holds.
Once A releases the mutex and ownership is transferred to B, A's priority will return to normal and B's priority will be bumped.
|
| | | |
|
| | |
| | |
| | |
| | | |
They work in tandem with guest code to provide synchronization primitives along with svcArbitrateLock/Unlock
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Switch mutexes are no longer kernel objects, they are managed in userland and only use the kernel to handle the contention case.
Mutex addresses store a special flag value (0x40000000) to notify the guest code that there are still some threads waiting for the mutex to be released. This flag is updated when a thread calls ArbitrateUnlock.
TODO:
* Fix svcWaitProcessWideKey
* Fix svcSignalProcessWideKey
* Remove the Mutex class.
|
|/ /
| |
| |
| | |
Prevents enum identifiers from leaking into the surrounding scope.
|
| |
| |
| |
| | |
C++17 has non-member size() which we can just call where necessary.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
* Updated ACC with more service names
* Updated SVC with more service names
* Updated set with more service names
* Updated sockets with more service names
* Updated SPL with more service names
* Updated time with more service names
* Updated vi with more service names
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
|/ |
|
|\
| |
| | |
UnmapSharedMemory
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| | |
C++11 requires spaces on the Identifier
Add inttypes include
clang
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Added svcCreateSharedMemory
* Services which are not implemented now throw UNIMPLEMENTED()
* clang-format
* changed perms to u32
* removed camelcase
|
| |
|
|
|
|
| |
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.
|
|
|
|
| |
Makes the table match SwitchBrew for these entries
|
| |
|
|
|
|
|
| |
# Conflicts:
# src/core/hle/kernel/svc.cpp
|
|\
| |
| | |
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
|
| | |
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
Also properly keep track of data in guest memory, this fixes managing the semaphore from userland.
It was found that Semaphores are actually Condition Variables, with Release(1) and Release(-1) being equivalent to notify_one and notify_all. We should change the name of the class to reflect this.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|