process.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/assert.h"
  5. #include "common/common_funcs.h"
  6. #include "common/logging/log.h"
  7. #include "core/hle/kernel/process.h"
  8. #include "core/hle/kernel/resource_limit.h"
  9. #include "core/hle/kernel/thread.h"
  10. #include "core/memory.h"
  11. namespace Kernel {
  12. u32 Process::next_process_id;
  13. SharedPtr<Process> Process::Create(std::string name, u64 program_id) {
  14. SharedPtr<Process> process(new Process);
  15. process->name = std::move(name);
  16. process->program_id = program_id;
  17. process->flags.raw = 0;
  18. process->flags.memory_region = MemoryRegion::APPLICATION;
  19. return process;
  20. }
  21. void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) {
  22. for (int i = 0; i < len; ++i) {
  23. u32 descriptor = kernel_caps[i];
  24. u32 type = descriptor >> 20;
  25. if (descriptor == 0xFFFFFFFF) {
  26. // Unused descriptor entry
  27. continue;
  28. } else if ((type & 0xF00) == 0xE00) { // 0x0FFF
  29. // Allowed interrupts list
  30. LOG_WARNING(Loader, "ExHeader allowed interrupts list ignored");
  31. } else if ((type & 0xF80) == 0xF00) { // 0x07FF
  32. // Allowed syscalls mask
  33. unsigned int index = ((descriptor >> 24) & 7) * 24;
  34. u32 bits = descriptor & 0xFFFFFF;
  35. while (bits && index < svc_access_mask.size()) {
  36. svc_access_mask.set(index, bits & 1);
  37. ++index; bits >>= 1;
  38. }
  39. } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF
  40. // Handle table size
  41. handle_table_size = descriptor & 0x3FF;
  42. } else if ((type & 0xFF8) == 0xFF0) { // 0x007F
  43. // Misc. flags
  44. flags.raw = descriptor & 0xFFFF;
  45. } else if ((type & 0xFFE) == 0xFF8) { // 0x001F
  46. // Mapped memory range
  47. if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) {
  48. LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored.");
  49. continue;
  50. }
  51. u32 end_desc = kernel_caps[i+1];
  52. ++i; // Skip over the second descriptor on the next iteration
  53. AddressMapping mapping;
  54. mapping.address = descriptor << 12;
  55. mapping.size = (end_desc << 12) - mapping.address;
  56. mapping.writable = descriptor & (1 << 20);
  57. mapping.unk_flag = end_desc & (1 << 20);
  58. address_mappings.push_back(mapping);
  59. } else if ((type & 0xFFF) == 0xFFE) { // 0x000F
  60. // Mapped memory page
  61. AddressMapping mapping;
  62. mapping.address = descriptor << 12;
  63. mapping.size = Memory::PAGE_SIZE;
  64. mapping.writable = true; // TODO: Not sure if correct
  65. mapping.unk_flag = false;
  66. } else if ((type & 0xFE0) == 0xFC0) { // 0x01FF
  67. // Kernel version
  68. int minor = descriptor & 0xFF;
  69. int major = (descriptor >> 8) & 0xFF;
  70. LOG_INFO(Loader, "ExHeader kernel version ignored: %d.%d", major, minor);
  71. } else {
  72. LOG_ERROR(Loader, "Unhandled kernel caps descriptor: 0x%08X", descriptor);
  73. }
  74. }
  75. }
  76. void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
  77. Kernel::SetupMainThread(entry_point, main_thread_priority);
  78. }
  79. Kernel::Process::Process() {}
  80. Kernel::Process::~Process() {}
  81. SharedPtr<Process> g_current_process;
  82. }