| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| | |
Revert PR #11806 and do a proper fix to the memory handling.
|
| | |
|
|/
|
|
| |
Co-authored-by: Kelebek1 <eeeedddccc@hotmail.co.uk>
|
|\
| |
| | |
memory: check page against address space size
|
| | |
|
|\ \
| |/
|/| |
Fixes and workarounds to make UBSan happier on macOS
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
There are still some other issues not addressed here, but it's a start.
Workarounds for false-positive reports:
- `RasterizerAccelerated`: Put a gigantic array behind a `unique_ptr`,
because UBSan has a [hardcoded limit](https://stackoverflow.com/questions/64531383/c-runtime-error-using-fsanitize-undefined-object-has-a-possibly-invalid-vp)
of how big it thinks objects can be, specifically when dealing with
offset-to-top values used with multiple inheritance. Hopefully this
doesn't have a performance impact.
- `QueryCacheBase::QueryCacheBase`: Avoid an operation that UBSan thinks
is UB even though it at least arguably isn't. See the link in the
comment for more information.
Fixes for correct reports:
- `PageTable`, `Memory`: Use `uintptr_t` values instead of pointers to
avoid UB from pointer overflow (when pointer arithmetic wraps around
the address space).
- `KScheduler::Reload`: `thread->GetOwnerProcess()` can be `nullptr`;
avoid calling methods on it in this case. (The existing code returns
a garbage reference to a field, which is then passed into
`LoadWatchpointArray`, and apparently it's never used, so it's
harmless in practice but still triggers UBSan.)
- `KAutoObject::Close`: This function calls `this->Destroy()`, which
overwrites the beginning of the object with junk (specifically a free
list pointer). Then it calls `this->UnregisterWithKernel()`. UBSan
complains about a type mismatch because the vtable has been
overwritten, and I believe this is indeed UB. `UnregisterWithKernel`
also loads `m_kernel` from the 'freed' object, which seems to be
technically safe (the overwriting doesn't extend as far as that
field), but seems dubious. Switch to a `static` method and load
`m_kernel` in advance.
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
This reverts commit af5ecb0b15d4449f58434e70eed835cf71fc5527.
|
| |
|
| |
|
|\
| |
| | |
memory: correct semantics of data cache management operations
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Some header files, specifically for OSX and Musl libc define PAGE_SIZE to be a number
This is great except in yuzu we're using PAGE_SIZE as a variable
Specific example
`static constexpr u64 PAGE_SIZE = u64(1) << PAGE_BITS;`
PAGE_SIZE PAGE_BITS PAGE_MASK are all similar variables.
Simply deleted the underscores, and then added YUZU_ prefix
Might be worth noting that there are multiple uses in different classes/namespaces
This list may not be exhaustive
Core::Memory 12 bits (4096)
QueryCacheBase 12 bits
ShaderCache 14 bits (16384)
TextureCache 20 bits (1048576, or 1MB)
Fixes #8779
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[REUSE] is a specification that aims at making file copyright
information consistent, so that it can be both human and machine
readable. It basically requires that all files have a header containing
copyright and licensing information. When this isn't possible, like
when dealing with binary assets, generated files or embedded third-party
dependencies, it is permitted to insert copyright information in the
`.reuse/dep5` file.
Oh, and it also requires that all the licenses used in the project are
present in the `LICENSES` folder, that's why the diff is so huge.
This can be done automatically with `reuse download --all`.
The `reuse` tool also contains a handy subcommand that analyzes the
project and tells whether or not the project is (still) compliant,
`reuse lint`.
Following REUSE has a few advantages over the current approach:
- Copyright information is easy to access for users / downstream
- Files like `dist/license.md` do not need to exist anymore, as
`.reuse/dep5` is used instead
- `reuse lint` makes it easy to ensure that copyright information of
files like binary assets / images is always accurate and up to date
To add copyright information of files that didn't have it I looked up
who committed what and when, for each file. As yuzu contributors do not
have to sign a CLA or similar I couldn't assume that copyright ownership
was of the "yuzu Emulator Project", so I used the name and/or email of
the commit author instead.
[REUSE]: https://reuse.software
Follow-up to 01cf05bc75b1e47beb08937439f3ed9339e7b254
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
- That way, we can consolidate the memory layout to one place.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
This makes it by far harder to crash yuzu.
Also implement the 48bit masking of AARCH64 while touching this code.
|
|
|
|
| |
- There are some issues with the current workaround, we will just use host memory until we have a complete kernel memory implementation.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Squash attributes into the pointer's integer, making them an uintptr_t
pair containing 2 bits at the bottom and then the pointer. These bits
are currently unused thanks to alignment requirements.
Configure Dynarmic to mask out these bits on pointer reads.
While we are at it, remove some unused attributes carried over from
Citra.
Read/Write and other hot functions use a two step unpacking process that
is less readable to stop MSVC from emitting an extra AND instruction in
the hot path:
mov rdi,rcx
shr rdx,0Ch
mov r8,qword ptr [rax+8]
mov rax,qword ptr [r8+rdx*8]
mov rdx,rax
-and al,3
and rdx,0FFFFFFFFFFFFFFFCh
je Core::Memory::Memory::Impl::Read<unsigned char>
mov rax,qword ptr [vaddr]
movzx eax,byte ptr [rdx+rax]
|
|
|
| |
* core: memory: Ensure thread safe access when pages are rasterizer cached.
|
|
|
|
|
| |
Write() doesn't return anything, so the @returns tag shouldn't be
present.
|
| |
|
|
|
|
|
|
|
| |
Recent changes to the build system that made more warnings be flagged as
errors caused building via clang to break.
Fixes #4795
|
|
|
|
|
|
|
|
|
| |
Makes our error coverage a little more consistent across the board by
applying it to Linux side of things as well. This also makes it more
consistent with the warning settings in other libraries in the project.
This also updates httplib to 0.7.9, as there are several warning
cleanups made that allow us to enable several warnings as errors.
|
|
|
|
| |
memory doesn't exist as a parameter any more.
|
|
|
|
| |
Preserves the volatility of the pointers being casted.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
This commit: Implements CPU Interrupts, Replaces Cycle Timing for Host
Timing, Reworks the Kernel's Scheduler, Introduce Idle State and
Suspended State, Recreates the bootmanager, Initializes Multicore
system.
|
|
|
|
| |
- Fixes Super Smash Bros. Ultimate.
|
| |
|
|
|
|
| |
- helpful to disambiguate Kernel::Memory namespace.
|
| |
|
| |
|
|
|
|
| |
This allows us to create a fastmem arena within the memory.cpp helpers.
|
|
|
|
|
|
| |
This saves us two x64 instructions per load/store instruction.
TODO: Clean up our memory code. We can use this optimization here as well.
|
|
|
|
|
|
|
| |
Now that literally every other API function is converted over to the
Memory class, we can just move the file-local page table into the Memory
implementation class, finally getting rid of global state within the
memory code.
|
|
|
|
|
|
|
|
| |
Now that everything else is migrated over, this is essentially just code
relocation and conversion of a global accessor to the class member
variable.
All that remains is to migrate over the page table.
|
|
|
|
|
|
|
|
|
| |
The Write functions are used slightly less than the Read functions,
which make these a bit nicer to move over.
The only adjustments we really need to make here are to Dynarmic's
exclusive monitor instance. We need to keep a reference to the currently
active memory instance to perform exclusive read/write operations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
With all of the trivial parts of the memory interface moved over, we can
get right into moving over the bits that are used.
Note that this does require the use of GetInstance from the global
system instance to be used within hle_ipc.cpp and the gdbstub. This is
fine for the time being, as they both already rely on the global system
instance in other functions. These will be removed in a change directed
at both of these respectively.
For now, it's sufficient, as it still accomplishes the goal of
de-globalizing the memory code.
|
|
|
|
|
| |
These currently aren't used anywhere in the codebase, so these are very
trivial to move over to the Memory class.
|
|
|
|
|
| |
This is only used within the accelerated rasterizer in two places, so
this is also a very trivial migration.
|
|
|
|
|
| |
This only had one usage spot, so this is fairly straightforward to
convert over.
|
|
|
|
|
| |
With all of the interfaces ready for migration, it's trivial to migrate
over GetPointer().
|
|
|
|
|
|
| |
These will eventually be migrated into the main Memory class, but for
now, we put them in an anonymous namespace, so that the other functions
that use them, can be migrated over separately.
|
|
|
|
|
|
|
|
|
| |
A fairly straightforward migration. These member functions can just be
mostly moved verbatim with minor changes. We already have the necessary
plumbing in places that they're used.
IsKernelVirtualAddress() can remain a non-member function, since it
doesn't rely on class state in any form.
|
|
|
|
|
|
| |
Migrates all of the direct mapping facilities over to the new memory
class. In the process, this also obsoletes the need for memory_setup.h,
so we can remove it entirely from the project.
|
|
|
|
|
|
|
|
|
| |
Currently, the main memory management code is one of the remaining
places where we have global state. The next series of changes will aim
to rectify this.
This change simply introduces the main skeleton of the class that will
contain all the necessary state.
|
|
|
|
|
|
| |
This only encourages the use of the global system instance (which will
be phased out long-term). Instead, we use the direct system function
call directly to remove the appealing but discouraged short-hand.
|
|
|
|
|
| |
This commit avoids Invalidating and Flushing the GPU if the page is not
marked as a RasterizerCache Page.
|
|
|
|
|
| |
These aren't used within the central memory management code, so they can
be removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Our initialization process is a little wonky than one would expect when
it comes to code flow. We initialize the CPU last, as opposed to
hardware, where the CPU obviously needs to be first, otherwise nothing
else would work, and we have code that adds checks to get around this.
For example, in the page table setting code, we check to see if the
system is turned on before we even notify the CPU instances of a page
table switch. This results in dead code (at the moment), because the
only time a page table switch will occur is when the system is *not*
running, preventing the emulated CPU instances from being notified of a
page table switch in a convenient manner (technically the code path
could be taken, but we don't emulate the process creation svc handlers
yet).
This moves the threads creation into its own member function of the core
manager and restores a little order (and predictability) to our
initialization process.
Previously, in the multi-threaded cases, we'd kick off several threads
before even the main kernel process was created and ready to execute (gross!).
Now the initialization process is like so:
Initialization:
1. Timers
2. CPU
3. Kernel
4. Filesystem stuff (kind of gross, but can be amended trivially)
5. Applet stuff (ditto in terms of being kind of gross)
6. Main process (will be moved into the loading step in a following
change)
7. Telemetry (this should be initialized last in the future).
8. Services (4 and 5 should ideally be alongside this).
9. GDB (gross. Uses namespace scope state. Needs to be refactored into a
class or booted altogether).
10. Renderer
11. GPU (will also have its threads created in a separate step in a
following change).
Which... isn't *ideal* per-se, however getting rid of the wonky
intertwining of CPU state initialization out of this mix gets rid of
most of the footguns when it comes to our initialization process.
|
|
|
|
|
| |
Now that nothing actually touches the internal page table aside from the
memory subsystem itself, we can remove the accessor to it.
|
|
|
|
|
| |
- GPU will be released on shutdown, before pages are unmapped.
- On subsequent runs, current_page_table will be not nullptr, but GPU might not be valid yet.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
The comment already invalidates itself: neither MMIO nor rasterizer cache belongsHLE kernel state. This mutex has a too large scope if MMIO or cache is included, which is prone to dead lock when multiple thread acquires these resource at the same time. If necessary, each MMIO component or rasterizer should have their own lock.
|
|
|
|
| |
- Memory::MapPages total samplecount was reduced from 4.6% to 1.06%.
- From main menu into the game from 1.03% to 0.35%
|
|
|
|
| |
Functions which are suppose to crash on non canary builds usually don't return anything which lead to uninitialized memory being used.
|
|
|
|
|
|
| |
Given memory should always be expected to be valid during normal
execution, this should be a debug assertion, rather than a check in
regular builds.
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
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.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Makes the class interface consistent and provides accessors for
obtaining a reference to the memory manager instance.
Given we also return references, this makes our more flimsy uses of
const apparent, given const doesn't propagate through pointers in the
way one would typically expect. This makes our mutable state more
apparent in some places.
|
|
|
|
|
|
|
| |
All calling code assumes that the rasterizer will be in a valid state,
which is a totally fine assumption. The only way the rasterizer wouldn't
be is if initialization is done incorrectly or fails, which is checked
against in System::Init().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We move the initialization of the renderer to the core class, while
keeping the creation of it and any other specifics in video_core. This
way we can ensure that the renderer is initialized and doesn't give
unfettered access to the renderer. This also makes dependencies on types
more explicit.
For example, the GPU class doesn't need to depend on the
existence of a renderer, it only needs to care about whether or not it
has a rasterizer, but since it was accessing the global variable, it was
also making the renderer a part of its dependency chain. By adjusting
the interface, we can get rid of this dependency.
|
|
|
|
| |
This is just unused code, so we may as well get rid of it.
|
|
|
|
| |
Removes leftover code from citra that isn't needed.
|
|\
| |
| | |
core/memory, core/hle/kernel: Use std::move where applicable
|
| |
| |
| |
| | |
Avoids pointless copies
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
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).
|
| |
|
|\
| |
| | |
GPU: Partially implemented the 2D surface copy engine
|
| | |
|
| |
| |
| |
| | |
Addresses are 64-bit, these formatting specifiers are simply holdovers from citra. Adjust them to be the correct width.
|
|/
|
|
| |
While we're at it, correct addresses to print all 64 bits where applicable, which were holdovers from citra.
|
| |
|
| |
|
| |
|
|\
| |
| | |
Tegra progress 2
|
| | |
|
| | |
|
| | |
|
| | |
|
|/ |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
# Conflicts:
# src/core/CMakeLists.txt
# src/core/arm/dynarmic/arm_dynarmic.cpp
# src/core/arm/dyncom/arm_dyncom.cpp
# src/core/hle/kernel/process.cpp
# src/core/hle/kernel/thread.cpp
# src/core/hle/kernel/thread.h
# src/core/hle/kernel/vm_manager.cpp
# src/core/loader/3dsx.cpp
# src/core/loader/elf.cpp
# src/core/loader/ncch.cpp
# src/core/memory.cpp
# src/core/memory.h
# src/core/memory_setup.h
|
| | |
|
| | |
|
| | |
|
| |\
| | |
| | | |
Loaders: Don't automatically set the current process every time we load an application.
|
| | |
| | |
| | |
| | | |
There is still an overload of IsValidVirtualAddress that only takes the VAddr and will default to the current process.
|
| |\ \
| | |/
| |/| |
Memory/RasterizerCache: Ignore unmapped memory regions when caching physical regions
|
| | |
| | |
| | |
| | |
| | |
| | | |
Not all physical regions need to be mapped into the address space of every process, for example, system modules do not have a VRAM mapping.
This fixes a crash when loading applets and system modules.
|
| | | |
|
| | | |
|
| |/
| |
| |
| | |
Don't expose Memory::current_page_table as a global.
|
| |\
| | |
| | | |
Kernel/Memory: Give each process its own page table and allow switching the current page table upon reschedule
|
| | | |
|
| | | |
|
| | |
| | |
| | |
| | | |
The loader is in charge of setting the newly created process's page table as the main one during the loading process.
|
| | | |
|
| |\ \
| | |/
| |/| |
Kernel/HLE: Use a mutex to synchronize access to the HLE kernel state between the cpu thread and any other possible threads that might touch the kernel (network thread, etc).
|
| | | |
|
| | | |
|
|/ / |
|
|\ \
| |/
|/| |
Add address conversion functions returning optional, Add function to flush virtual region from rasterizer cache
|
| |
| |
| |
| |
| |
| | |
This is slightly more ergonomic to use, correctly handles virtual
regions which are disjoint in physical addressing space, and checks only
regions which can be cached by the rasterizer.
|
| | |
|
| |
| |
| |
| | |
And fix a few places in the code to take advantage of that.
|
|/
|
|
|
|
|
|
|
|
| |
Unmapping pages tries to flush any cached GPU surfaces touching that
region. When a cached page is invalidated, GetPointerFromVMA() is used
to restore the original pagetable pointer. However, since that VMA has
already been deleted, this hits an UNREACHABLE case in that function.
Now when this happens, just set the page type to Unmapped and continue,
which arrives at the correct end result.
|
|
|
|
| |
This is 4MB of extra, separate memory that was added on the New 3DS.
|
| |
|
|
|
|
|
| |
This prevents individual writes touching a cached page, but which don't
overlap the surface, from constantly hitting the surface cache lookup.
|
| |
|
|
|
|
| |
RasterizerCachedMemory doesn't has pointer but should be considered as valid
|
| |
|
|
|
|
|
|
|
| |
This makes clang-format useful on those.
Also add a bunch of forgotten transitive includes, which otherwise
prevented compilation.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
This adds some structures necessary to support multiple memory regions
in the future. It also adds support for different system memory types
and the new linear heap mapping at 0x30000000.
|
|
|
|
|
| |
These helpers aren't really part of the kernel, and mem_map.cpp/h is
going to be moved there next.
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
This enables more dynamic management of the process address space,
compared to just directly configuring the page table for major areas.
This will serve as the foundation upon which the rest of the Kernel
memory management functions will be built.
|
| |
|
| |
|
| |
|
|
memory.cpp/h contains definitions related to acessing memory and
configuring the address space
mem_map.cpp/h contains higher-level definitions related to configuring
the address space accoording to the kernel and allocating memory.
|