The Pedigree Project  0.1
hosted/SyscallManager.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 "SyscallManager.h"
21 #include "pedigree/kernel/LockGuard.h"
22 #include "pedigree/kernel/compiler.h"
23 #include "pedigree/kernel/processor/Processor.h"
24 
26 
28 {
30 }
31 
33  Service_t Service, SyscallHandler *pHandler)
34 {
35  // Lock the class until the end of the function
36  LockGuard<Spinlock> lock(m_Lock);
37 
38  if (UNLIKELY(Service >= serviceEnd))
39  return false;
40  if (UNLIKELY(pHandler != 0 && m_pHandler[Service] != 0))
41  return false;
42  if (UNLIKELY(pHandler == 0 && m_pHandler[Service] == 0))
43  return false;
44 
45  m_pHandler[Service] = pHandler;
46  return true;
47 }
48 
49 void HostedSyscallManager::syscall(SyscallState &syscallState)
50 {
51  SyscallHandler *pHandler;
52  size_t serviceNumber = syscallState.getSyscallService();
53 
54  if (UNLIKELY(serviceNumber >= serviceEnd))
55  {
56  // TODO: We should return an error here
57  return;
58  }
59 
60  // Get the syscall handler
61  {
62  LockGuard<Spinlock> lock(m_Instance.m_Lock);
63  pHandler = m_Instance.m_pHandler[serviceNumber];
64  }
65 
66  if (LIKELY(pHandler != 0))
67  {
68  syscallState.setSyscallReturnValue(pHandler->syscall(syscallState));
69  syscallState.setSyscallErrno(
70  Processor::information().getCurrentThread()->getErrno());
71 
72  if (Processor::information().getCurrentThread()->getUnwindState() ==
74  {
75  NOTICE("Unwind state exit, in interrupt handler");
77  .getCurrentThread()
78  ->getParent()
79  ->getSubsystem()
80  ->exit(0);
81  }
82  }
83 }
84 
86  Service_t service, uintptr_t function, uintptr_t p1, uintptr_t p2,
87  uintptr_t p3, uintptr_t p4, uintptr_t p5)
88 {
89  return 0;
90 }
91 
92 //
93 // Functions only usable in the kernel initialisation phase
94 //
95 
97 {
98 }
99 
101 {
102  // Initialise the pointers to the handler
103  for (size_t i = 0; i < serviceEnd; i++)
104  m_pHandler[i] = 0;
105 }
106 
108 {
109 }
static EXPORTED_PUBLIC SyscallManager & instance()
static HostedSyscallManager & instance()
static void initialiseProcessor() INITIALISATION_ONLY
virtual uintptr_t syscall(SyscallState &State)=0
virtual bool registerSyscallHandler(Service_t Service, SyscallHandler *pHandler)
static ProcessorInformation & information()
Definition: Processor.cc:45
#define NOTICE(text)
Definition: Log.h:74
HostedSyscallManager() INITIALISATION_ONLY
(b) below.
Definition: Thread.h:245
uintptr_t syscall(Service_t service, uintptr_t function, uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4, uintptr_t p5)