Nugget
Loading...
Searching...
No Matches
kernel.hh
Go to the documentation of this file.
1/*
2
3MIT License
4
5Copyright (c) 2022 PCSX-Redux authors
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26
27#pragma once
28
29#include <EASTL/functional.h>
30#include <stdint.h>
31
32#include <source_location>
33
34namespace psyqo {
35
36class Application;
37
47namespace Kernel {
48
49#ifdef PSYQO_RELEASE
50static constexpr bool debugMode = false;
51#else
52static constexpr bool debugMode = true;
53#endif
54
55namespace Internal {
56static inline uint32_t getCop0Status() {
57#ifndef PS1_PC_PORT
58 uint32_t r;
59 asm("mfc0 %0, $12 ; nop" : "=r"(r));
60 return r;
61#else
62 return 0;
63#endif
64}
65
66static inline void setCop0Status(uint32_t r) {
67#ifndef PS1_PC_PORT
68 asm("mtc0 %0, $12 ; nop" : : "r"(r));
69#endif
70}
71
72[[noreturn]] void abort(const char* msg, std::source_location location = std::source_location::current());
73[[noreturn]] void abort();
74
75} // namespace Internal
76
83static inline void fastEnterCriticalSection() {
84#ifndef PS1_PC_PORT
85 asm volatile("mtc0 %0, $12 ; nop ; nop" : : "r"(0x40000000));
86#endif
87}
88
94static inline void fastLeaveCriticalSection() {
95#ifndef PS1_PC_PORT
96 asm volatile("mtc0 %0, $12" : : "r"(0x40000401));
97#endif
98}
99
100enum class DMA : unsigned {
101 MDECin,
102 MDECout,
103 GPU,
104 CDRom,
105 SPU,
106 EXP1,
107 OTC,
108 Max,
109};
110
111enum class IRQ : unsigned {
112 VBlank,
113 GPU,
114 CDRom,
115 DMA,
116 Timer0,
117 Timer1,
118 Timer2,
120 SIO,
121 SPU,
122 PIO,
123 Max,
124};
125
129[[noreturn]] static inline void abort(const char* msg,
130 std::source_location location = std::source_location::current()) {
131 if constexpr (debugMode) {
132 Internal::abort(msg, location);
133 } else if constexpr (!debugMode) {
134 (void)msg;
135 (void)location;
137 }
138}
139
171void takeOverKernel();
172
176bool isKernelTakenOver();
177
195
213void queueIRQHandler(IRQ irq, eastl::function<void()>&& lambda);
214
224uint32_t openEvent(uint32_t classId, uint32_t spec, uint32_t mode, eastl::function<void()>&& lambda);
225
239unsigned registerDmaEvent(DMA channel, eastl::function<void()>&& lambda);
240
248
255void enableDma(DMA channel, unsigned priority = 7);
256
262void disableDma(DMA channel);
263
269void unregisterDmaEvent(unsigned slot);
270
281void queueCallback(eastl::function<void()>&& lambda);
282
292void queueCallbackFromISR(eastl::function<void()>&& lambda);
293
314void setBreakHandler(unsigned category, eastl::function<bool(uint32_t)>&& handler);
315
321void queuePsyqoBreakHandler(eastl::function<bool(uint32_t)>&& handler);
322
323namespace Internal {
324void pumpCallbacks();
325void prepare(Application&);
326void addInitializer(eastl::function<void(Application&)>&& lambda);
327void addOnFrame(eastl::function<void()>&& lambda);
328void beginFrame();
329[[noreturn]] void crashHandler(uint32_t exceptionCode, uint32_t* kernelRegisters);
330} // namespace Internal
331
335inline void assert(bool condition, const char* message,
336 std::source_location location = std::source_location::current()) {
337 if constexpr (debugMode) {
338 if (!condition) {
339 Internal::abort(message, location);
341 }
342 } else if constexpr (!debugMode) {
343 (void)message;
344 (void)location;
345 if (!condition) {
348 }
349 }
350}
351
352} // namespace Kernel
353
354} // namespace psyqo
The application class.
Definition application.hh:49
uint32_t r
Definition cpu.c:222
IRQ
Definition irq.h:31
void pumpCallbacks()
Definition kernel.cpp:407
void prepare(Application &)
Definition kernel.cpp:319
void crashHandler(uint32_t exceptionCode, uint32_t *kernelRegisters)
Definition crash-handler.cpp:145
void addOnFrame(eastl::function< void()> &&lambda)
Definition kernel.cpp:427
void beginFrame()
Definition kernel.cpp:431
void addInitializer(eastl::function< void(Application &)> &&lambda)
Definition kernel.cpp:285
void abort()
Definition kernel.cpp:202
uint32_t openEvent(uint32_t classId, uint32_t spec, uint32_t mode, eastl::function< void()> &&lambda)
A C++ wrapper around the openEvent syscall.
Definition kernel.cpp:209
void queueCallbackFromISR(eastl::function< void()> &&lambda)
Queues a callback to be called from the main thead.
Definition kernel.cpp:401
void assert(bool condition, const char *message, std::source_location location=std::source_location::current())
A simple assert macro.
Definition kernel.hh:335
unsigned registerDmaEvent(DMA channel, eastl::function< void()> &&lambda)
Sets an ISR callback for a given DMA channel.
Definition kernel.cpp:218
DMA
Definition kernel.hh:100
void queuePsyqoBreakHandler(eastl::function< bool(uint32_t)> &&handler)
Queues a break handler for psyqo's reserved category.
Definition kernel.cpp:111
void disableDma(DMA channel)
Disables the given DMA channel.
Definition kernel.cpp:254
void installCrashHandler()
Installs a crash handler for the application.
Definition kernel.cpp:173
void setBreakHandler(unsigned category, eastl::function< bool(uint32_t)> &&handler)
Sets a break handler for a given category.
Definition kernel.cpp:105
void flushCache()
Flushes the i-cache.
IRQ
Definition kernel.hh:111
void queueCallback(eastl::function< void()> &&lambda)
Queues a callback to be called from the main thead.
Definition kernel.cpp:394
void unregisterDmaEvent(unsigned slot)
Frees the given DMA callback slot.
Definition kernel.cpp:267
bool isKernelTakenOver()
Returns whether the kernel has been taken over.
Definition kernel.cpp:115
void enableDma(DMA channel, unsigned priority=7)
Enables the given DMA channel.
Definition kernel.cpp:236
void queueIRQHandler(IRQ irq, eastl::function< void()> &&lambda)
Queues an IRQ handler to be called from the exception handler.
Definition kernel.cpp:185
void takeOverKernel()
Takes over the kernel. Can only be called once inside the main function.
Definition kernel.cpp:140
Definition lua.hh:38
__builtin_unreachable()
static uint32_t spec
Definition syscalls.h:364
static uint32_t uint32_t void(* handler)())
Definition syscalls.h:371
void void(ptr, size)
static void uint32_t mode
Definition syscalls.h:231
void uint32_t(classId, spec)