| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
|
|
|
| |
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.
|