|
|
|
@ -1,3 +1,6 @@ |
|
|
|
#!/usr/bin/python3 |
|
|
|
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project |
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later |
|
|
|
# SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later |
|
|
|
|
|
|
|
@ -378,7 +381,7 @@ def emit_gather(sources, name, type_name, reg_size): |
|
|
|
|
|
|
|
if len(sources) == 1: |
|
|
|
s, = sources |
|
|
|
line = f"{name} = Convert<{type_name}>({get_fn}(args, {s}));" |
|
|
|
line = f"{type_name} {name} = Convert<{type_name}>({get_fn}(args, {s}));" |
|
|
|
return [line] |
|
|
|
|
|
|
|
var_type = f"std::array<uint{reg_size*8}_t, {len(sources)}>" |
|
|
|
@ -386,10 +389,9 @@ def emit_gather(sources, name, type_name, reg_size): |
|
|
|
f"{var_type} {name}_gather{{}};" |
|
|
|
] |
|
|
|
for i in range(0, len(sources)): |
|
|
|
lines.append( |
|
|
|
f"{name}_gather[{i}] = {get_fn}(args, {sources[i]});") |
|
|
|
lines.append(f"{name}_gather[{i}] = {get_fn}(args, {sources[i]});") |
|
|
|
|
|
|
|
lines.append(f"{name} = Convert<{type_name}>({name}_gather);") |
|
|
|
lines.append(f"{type_name} {name} = Convert<{type_name}>({name}_gather);") |
|
|
|
return lines |
|
|
|
|
|
|
|
|
|
|
|
@ -405,14 +407,9 @@ def emit_scatter(destinations, name, reg_size): |
|
|
|
return [line] |
|
|
|
|
|
|
|
var_type = f"std::array<{reg_type}, {len(destinations)}>" |
|
|
|
lines = [ |
|
|
|
f"auto {name}_scatter = Convert<{var_type}>({name});" |
|
|
|
] |
|
|
|
|
|
|
|
lines = [f"auto {name}_scatter = Convert<{var_type}>({name});"] |
|
|
|
for i in range(0, len(destinations)): |
|
|
|
lines.append( |
|
|
|
f"{set_fn}(args, {destinations[i]}, {name}_scatter[{i}]);") |
|
|
|
|
|
|
|
lines.append(f"{set_fn}(args, {destinations[i]}, {name}_scatter[{i}]);") |
|
|
|
return lines |
|
|
|
|
|
|
|
|
|
|
|
@ -436,25 +433,8 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size): |
|
|
|
f"static void SvcWrap_{wrapped_fn}{suffix}(Core::System& system, std::span<uint64_t, 8> args) {{" |
|
|
|
] |
|
|
|
|
|
|
|
# Get everything ready. |
|
|
|
for return_type, _ in return_write: |
|
|
|
lines.append(f"{return_type} ret{{}};") |
|
|
|
if return_write: |
|
|
|
lines.append("") |
|
|
|
|
|
|
|
for output_type, var_name, _, is_address in output_writes: |
|
|
|
output_type = "uint64_t" if is_address else output_type |
|
|
|
lines.append(f"{output_type} {var_name}{{}};") |
|
|
|
for input_type, var_name, _ in input_reads: |
|
|
|
lines.append(f"{input_type} {var_name}{{}};") |
|
|
|
|
|
|
|
if output_writes or input_reads: |
|
|
|
lines.append("") |
|
|
|
|
|
|
|
for input_type, var_name, sources in input_reads: |
|
|
|
lines += emit_gather(sources, var_name, input_type, byte_size) |
|
|
|
if input_reads: |
|
|
|
lines.append("") |
|
|
|
|
|
|
|
# Build the call. |
|
|
|
call_arguments = ["system"] |
|
|
|
@ -464,16 +444,18 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size): |
|
|
|
else: |
|
|
|
call_arguments.append(arg.var_name) |
|
|
|
|
|
|
|
# Get everything ready. |
|
|
|
for output_type, var_name, _, is_address in output_writes: |
|
|
|
output_type = "uint64_t" if is_address else output_type |
|
|
|
lines.append(f"{output_type} {var_name}{{}};") |
|
|
|
|
|
|
|
line = "" |
|
|
|
if return_write: |
|
|
|
line += "ret = " |
|
|
|
for return_type, _ in return_write: |
|
|
|
line += f"{return_type} ret = " |
|
|
|
|
|
|
|
line += f"{wrapped_fn}{suffix}({', '.join(call_arguments)});" |
|
|
|
lines.append(line) |
|
|
|
|
|
|
|
if return_write or output_writes: |
|
|
|
lines.append("") |
|
|
|
|
|
|
|
# Write back the return value and outputs. |
|
|
|
for _, destinations in return_write: |
|
|
|
lines += emit_scatter(destinations, "ret", byte_size) |
|
|
|
@ -485,10 +467,13 @@ def emit_wrapper(wrapped_fn, suffix, register_info, arguments, byte_size): |
|
|
|
|
|
|
|
|
|
|
|
COPYRIGHT = """\ |
|
|
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project |
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later |
|
|
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later |
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-late |
|
|
|
|
|
|
|
// This file is automatically generated using svc_generator.py. |
|
|
|
// DO NOT MODIFY IT MANUALLY |
|
|
|
""" |
|
|
|
|
|
|
|
PROLOGUE_H = """ |
|
|
|
@ -505,13 +490,9 @@ class System; |
|
|
|
#include "core/hle/result.h" |
|
|
|
|
|
|
|
namespace Kernel::Svc { |
|
|
|
|
|
|
|
// clang-format off |
|
|
|
""" |
|
|
|
|
|
|
|
EPILOGUE_H = """ |
|
|
|
// clang-format on |
|
|
|
|
|
|
|
// Custom ABI. |
|
|
|
Result ReplyAndReceiveLight(Core::System& system, Handle handle, uint32_t* args); |
|
|
|
Result ReplyAndReceiveLight64From32(Core::System& system, Handle handle, uint32_t* args); |
|
|
|
@ -553,7 +534,7 @@ PROLOGUE_CPP = """ |
|
|
|
namespace Kernel::Svc { |
|
|
|
|
|
|
|
static uint32_t GetArg32(std::span<uint64_t, 8> args, int n) { |
|
|
|
return static_cast<uint32_t>(args[n]); |
|
|
|
return uint32_t(args[n]); |
|
|
|
} |
|
|
|
|
|
|
|
static void SetArg32(std::span<uint64_t, 8> args, int n, uint32_t result) { |
|
|
|
@ -574,37 +555,27 @@ template <typename To, typename From> |
|
|
|
requires(std::is_trivial_v<To> && std::is_trivially_copyable_v<From>) |
|
|
|
static To Convert(const From& from) { |
|
|
|
To to{}; |
|
|
|
|
|
|
|
if constexpr (sizeof(To) >= sizeof(From)) { |
|
|
|
if constexpr (sizeof(To) >= sizeof(From)) |
|
|
|
std::memcpy(std::addressof(to), std::addressof(from), sizeof(From)); |
|
|
|
} else { |
|
|
|
else |
|
|
|
std::memcpy(std::addressof(to), std::addressof(from), sizeof(To)); |
|
|
|
} |
|
|
|
|
|
|
|
return to; |
|
|
|
} |
|
|
|
|
|
|
|
// clang-format off |
|
|
|
""" |
|
|
|
|
|
|
|
EPILOGUE_CPP = """ |
|
|
|
// clang-format on |
|
|
|
|
|
|
|
void Call(Core::System& system, u32 imm) { |
|
|
|
auto& kernel = system.Kernel(); |
|
|
|
auto& process = GetCurrentProcess(kernel); |
|
|
|
|
|
|
|
std::array<uint64_t, 8> args; |
|
|
|
kernel.CurrentPhysicalCore().SaveSvcArguments(process, args); |
|
|
|
kernel.EnterSVCProfile(); |
|
|
|
|
|
|
|
if (process.Is64Bit()) { |
|
|
|
//kernel.EnterSVCProfile(); |
|
|
|
if (process.Is64Bit()) |
|
|
|
Call64(system, imm, args); |
|
|
|
} else { |
|
|
|
else |
|
|
|
Call32(system, imm, args); |
|
|
|
} |
|
|
|
|
|
|
|
kernel.ExitSVCProfile(); |
|
|
|
//kernel.ExitSVCProfile(); |
|
|
|
kernel.CurrentPhysicalCore().LoadSvcArguments(process, args); |
|
|
|
} |
|
|
|
|
|
|
|
@ -617,12 +588,11 @@ def emit_call(bitness, names, suffix): |
|
|
|
indent = " " |
|
|
|
lines = [ |
|
|
|
f"static void Call{bit_size}(Core::System& system, u32 imm, std::span<uint64_t, 8> args) {{", |
|
|
|
f"{indent}switch (static_cast<SvcId>(imm)) {{" |
|
|
|
f"{indent}switch (SvcId(imm)) {{" |
|
|
|
] |
|
|
|
|
|
|
|
for _, name in names: |
|
|
|
lines.append(f"{indent}case SvcId::{name}:") |
|
|
|
lines.append(f"{indent*2}return SvcWrap_{name}{suffix}(system, args);") |
|
|
|
lines.append(f"{indent}case SvcId::{name}: return SvcWrap_{name}{suffix}(system, args);") |
|
|
|
|
|
|
|
lines.append(f"{indent}default:") |
|
|
|
lines.append( |
|
|
|
@ -692,7 +662,7 @@ def main(): |
|
|
|
call_64 = emit_call(BIT_64, names, SUFFIX_NAMES[BIT_64]) |
|
|
|
enum_decls = build_enum_declarations() |
|
|
|
|
|
|
|
with open("svc.h", "w") as f: |
|
|
|
with open("src/core/hle/kernel/svc.h", "w") as f: |
|
|
|
f.write(COPYRIGHT) |
|
|
|
f.write(PROLOGUE_H) |
|
|
|
f.write("\n".join(svc_fw_declarations)) |
|
|
|
@ -704,7 +674,7 @@ def main(): |
|
|
|
f.write(enum_decls) |
|
|
|
f.write(EPILOGUE_H) |
|
|
|
|
|
|
|
with open("svc.cpp", "w") as f: |
|
|
|
with open("src/core/hle/kernel/svc.cpp", "w") as f: |
|
|
|
f.write(COPYRIGHT) |
|
|
|
f.write(PROLOGUE_CPP) |
|
|
|
f.write(emit_size_check()) |