process.cpp 3.4 KB

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