The Pedigree Project  0.1
NativeSyscallManager.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/Log.h"
21 #include "pedigree/kernel/process/Scheduler.h"
22 #include "pedigree/kernel/processor/Processor.h"
23 #include "pedigree/kernel/processor/SyscallManager.h"
24 #include "pedigree/kernel/processor/state.h"
25 
26 #include "pedigree/native/ipc/Ipc.h"
27 #include <native-ipc.h>
28 
29 #include "NativeSyscallManager.h"
30 #include "pedigree/native/nativeSyscallNumbers.h"
31 
32 class Foo : public NativeBase
33 {
34  public:
35  virtual ReturnState
36  syscall(uint64_t subid, void *params, size_t params_size);
37 };
38 
40 {
41 }
42 
44 {
45 }
46 
47 void NativeSyscallManager::initialise()
48 {
50 }
51 
53  uintptr_t function, uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4,
54  uintptr_t p5)
55 {
56  if (function >= serviceEnd)
57  {
58  ERROR(
59  "NativeSyscallManager: invalid function called: "
60  << Dec << static_cast<int>(function));
61  return 0;
62  }
63 
64  uintptr_t ret = SyscallManager::instance().syscall(
65  native, function, p1, p2, p3, p4, p5);
66  return ret;
67 }
68 
69 uintptr_t NativeSyscallManager::syscall(SyscallState &state)
70 {
71  uintptr_t p1 = state.getSyscallParameter(0);
72  uintptr_t p2 = state.getSyscallParameter(1);
73  uintptr_t p3 = state.getSyscallParameter(2);
74  uintptr_t p4 = state.getSyscallParameter(3);
75  uintptr_t p5 = state.getSyscallParameter(4);
76 
77  // We're interruptible.
79 
80  // NOTICE("Native syscall " << state.getSyscallNumber() << " (" << p1 << ",
81  // " << p2 << ", " << p3 << ", " << p4 << ", " << p5);
82 
83  switch (state.getSyscallNumber())
84  {
85  case IPC_CREATE_STANDARD_MESSAGE:
86  return createStandardMessage(
87  reinterpret_cast<PedigreeIpc::IpcMessage *>(p1));
88  case IPC_CREATE_SHARED_MESSAGE:
89  return createSharedMessage(
90  reinterpret_cast<PedigreeIpc::IpcMessage *>(p1), p2, p3);
91  case IPC_GET_SHARED_REGION:
92  return reinterpret_cast<uintptr_t>(getIpcSharedRegion(
93  reinterpret_cast<PedigreeIpc::IpcMessage *>(p1)));
94  case IPC_DESTROY_MESSAGE:
95  destroyMessage(reinterpret_cast<PedigreeIpc::IpcMessage *>(p1));
96  break;
97 
98  case IPC_SEND_IPC:
99  return static_cast<uintptr_t>(sendIpc(
100  reinterpret_cast<PedigreeIpc::IpcEndpoint *>(p1),
101  reinterpret_cast<PedigreeIpc::IpcMessage *>(p2),
102  static_cast<bool>(p3)));
103  case IPC_RECV_PHASE1:
104  return reinterpret_cast<uintptr_t>(recvIpcPhase1(
105  reinterpret_cast<PedigreeIpc::IpcEndpoint *>(p1),
106  static_cast<bool>(p2)));
107  case IPC_RECV_PHASE2:
108  return recvIpcPhase2(
109  reinterpret_cast<PedigreeIpc::IpcMessage *>(p1),
110  reinterpret_cast<void *>(p2));
111 
112  case IPC_CREATE_ENDPOINT:
113  createEndpoint(reinterpret_cast<const char *>(p1));
114  break;
115  case IPC_REMOVE_ENDPOINT:
116  removeEndpoint(reinterpret_cast<const char *>(p1));
117  break;
118  case IPC_GET_ENDPOINT:
119  return reinterpret_cast<uintptr_t>(
120  getEndpoint(reinterpret_cast<const char *>(p1)));
121 
123  case NATIVE_REGISTER_OBJECT:
124  NOTICE("NativeSyscallManager: register object");
125  {
126  uint64_t guid = p1;
127  void *ptr = reinterpret_cast<void *>(p2);
128 
129  NativeBase *kptr = factory(guid);
130  if (kptr)
131  {
132  m_NativeObjects.insert(ptr, kptr);
133  return true;
134  }
135 
136  return false;
137  }
138  case NATIVE_UNREGISTER_OBJECT:
139  NOTICE("NativeSyscallManager: unregister object");
140  {
141  void *ptr = reinterpret_cast<void *>(p1);
142  NativeBase *kptr = m_NativeObjects.lookup(ptr);
143  if (kptr)
144  {
145  delete kptr;
146  m_NativeObjects.remove(ptr);
147  }
148  }
149  return true;
150  case NATIVE_CALL:
151  NOTICE("NativeSyscallManager: call");
152  {
153  void *ptr = reinterpret_cast<void *>(p1);
154  uint64_t subid = p2;
155  void *params = reinterpret_cast<void *>(p3);
156  size_t params_size = p4;
157  ReturnState *adjustedState =
158  reinterpret_cast<ReturnState *>(p5);
159 
161 
162  NativeBase *kptr = m_NativeObjects.lookup(ptr);
163  if (kptr)
164  {
165  *adjustedState = kptr->syscall(subid, params, params_size);
166  }
167  else
168  {
169  adjustedState->success = false;
170  adjustedState->meta = META_ERROR_BADOBJECT;
171  }
172  }
173  break;
174 
175  default:
176  ERROR(
177  "NativeSyscallManager: invalid syscall received: "
178  << Dec << state.getSyscallNumber());
179  return 0;
180  }
181 
182  return 0;
183 }
184 
186 {
187  NOTICE("NativeSyscallManager::factory(" << guid << ")");
188  if (guid == 0xdeadbeef)
189  return new Foo();
190  return 0;
191 }
192 
193 ReturnState Foo::syscall(uint64_t subid, void *params, size_t params_size)
194 {
195  NOTICE("syscall subid=" << subid);
196 
197  ReturnState ret;
198  switch (subid)
199  {
200  case 0x1234:
201  ret.success = true;
202  ret.value = 0x4321;
203  break;
204  default:
205  ret.success = false;
206  ret.meta = 0;
207  }
208 
209  return ret;
210 }
uint64_t value
NativeBase * factory(uint64_t guid)
static EXPORTED_PUBLIC SyscallManager & instance()
uint64_t meta
uintptr_t call(uintptr_t function, uintptr_t p1=0, uintptr_t p2=0, uintptr_t p3=0, uintptr_t p4=0, uintptr_t p5=0)
virtual uintptr_t syscall(SyscallState &state)
#define NOTICE(text)
Definition: Log.h:74
virtual ReturnState syscall(uint64_t subid, void *params, size_t params_size)
static void setInterrupts(bool bEnable)
#define ERROR(text)
Definition: Log.h:82
Definition: Log.h:138
virtual bool registerSyscallHandler(Service_t Service, SyscallHandler *pHandler)=0
virtual ReturnState syscall(uint64_t subid, void *params, size_t params_size)=0
virtual uintptr_t syscall(Service_t service, uintptr_t function, uintptr_t p1=0, uintptr_t p2=0, uintptr_t p3=0, uintptr_t p4=0, uintptr_t p5=0)=0