3 Copyright (C) 2006-2009 Jörg Pfähler
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <kernel/syscall.hpp>
20 #include <kernel/scheduler.hpp>
21 #include <kernel/kernel.hpp>
22 #include <kernel/page_allocator.hpp>
23 #include <kernel/range_allocator.hpp>
24 #include <kernel/process.hpp>
25 #include <kernel/port_manager.hpp>
26 #include <kernel/sharedMemoryManager.hpp>
27 #include <kernel/elf.hpp>
28 #include <kernel/event_manager.hpp>
29 #include <kernel/x86_shared/dma.hpp>
30 #include <kernel/x86_shared/cmos.hpp>
31 #include <kernel/x86_shared/serial.hpp>
32 #include <kernel/processor.hpp>
33 #include <lightOS/lightOS.hpp>
35 #include <kernel/log.hpp>
37 #include <kernel/x86/vbe.hpp>
39 #include <kernel/virtual_memory.hpp>
41 using namespace kernel
;
43 size_t monthnumbers
[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5};
45 systemcall
kernel::systemcalls
[] =
47 syscall::get_kernel_version
, // 0
48 syscall::heap_allocate
, // 1
49 syscall::get_memory_info
, // 2
50 syscall::get_commandline
, // 3
51 syscall::get_time
, // 4
52 syscall::get_date
, // 5
53 syscall::create_port
, // 6
54 syscall::destroy_port
, // 7
55 syscall::peek_message
, // 8
56 syscall::get_message
, // 9
57 syscall::wait_message
, // 10
58 syscall::send_message
, // 11
59 syscall::port_info
, // 12
60 syscall::standard_port
, // 13
61 syscall::transfer_port
, // 14
62 syscall::add_wait_message
, // 15
63 syscall::create_thread
, // 16
64 syscall::suspend_thread
, // 17
65 syscall::resume_thread
, // 18
66 syscall::destroy_thread
, // 19
67 syscall::destroy_process
, // 20
68 syscall::get_pid
, // 21
69 syscall::get_tid
, // 22
70 syscall::get_process_count
, // 23
71 syscall::get_process_list
, // 24
72 syscall::get_process_info
, // 25
73 syscall::register_event
, // 26
74 syscall::acknoledge_event
, // 27
75 syscall::unregister_event
, // 28
76 syscall::get_tick_count
, // 29
77 syscall::create_shared_memory
, // 30
78 syscall::destroy_shared_memory
, // 31
79 syscall::range_allocator_count
, // 32
80 syscall::enum_range_allocator
, // 33
84 syscall::create_specific_port
, // 37
85 syscall::get_kernel_log
, // 38
86 syscall::get_vbe_version
, // 39
87 syscall::get_vbe_mode_count
, // 40
88 syscall::get_vbe_mode
, // 41
89 syscall::set_vbe_mode
, // 42
90 syscall::request_io
, // 43
92 syscall::execute
, // 45
93 syscall::get_physical_address
, // 46
94 syscall::allocate_region
, // 47
95 syscall::free_region
, // 48
96 syscall::get_system_configuration
, // 49
97 syscall::get_library_count
, // 50
98 syscall::get_library_info
, // 51
99 syscall::signal_handler
, // 52
100 syscall::signal
, // 53
101 syscall::signal_end
, // 54
103 syscall::get_log_entry
, // 55
106 static void server_check(interrupt_stackframe
&frame
)
108 process
&Process
= *scheduler::get_process();
110 if (Process
.server() == false)
112 ERROR(Process
.getName().c_str() << ": not a server (syscall: 0x" << hex(frame
.syscall_number()) << ")");
113 process::destroy(Process
.getId());
114 scheduler::schedule(0);
118 void syscall::get_kernel_version(interrupt_stackframe
&frame
)
120 frame
.param0() = version_major
;
121 frame
.param1() = version_minor
;
124 void syscall::heap_allocate(interrupt_stackframe
&frame
)
126 process
&Process
= *scheduler::get_process();
127 frame
.param0() = reinterpret_cast<uintptr_t>(Process
.heapAlloc(frame
.param1()));
130 void syscall::get_memory_info(interrupt_stackframe
&frame
)
132 page_allocator
&PageAllocator
= page_allocator::instance();
133 frame
.param0() = PageAllocator
.capacity() * virtual_memory::page_size
;
134 frame
.param1() = PageAllocator
.size() * virtual_memory::page_size
;
137 void syscall::get_commandline(interrupt_stackframe
&frame
)
139 process
&Process
= *scheduler::get_process();
140 frame
.param0() = Process
.getCommandLine().length();
141 if (frame
.param1() != 0)
143 strcpy(reinterpret_cast<char*>(frame
.param1()), Process
.getCommandLine().c_str());
147 void syscall::get_time(interrupt_stackframe
&frame
)
149 x86_shared::cmos
&Cmos
= x86_shared::cmos::instance();
150 frame
.param0() = Cmos
.second();
151 frame
.param1() = Cmos
.minute();
152 frame
.param2() = Cmos
.hour();
155 void syscall::get_date(interrupt_stackframe
&frame
)
157 x86_shared::cmos
&Cmos
= x86_shared::cmos::instance();
158 frame
.param1() = Cmos
.dayofmonth();
159 frame
.param2() = Cmos
.month();
160 frame
.param3() = Cmos
.year();
161 frame
.param4() = static_cast<size_t>(Cmos
.summertime());
163 // Calculate day of week
164 frame
.param0() = frame
.param1() % 7;
165 frame
.param0() += monthnumbers
[frame
.param2() - 1];
166 frame
.param0() += ((frame
.param3() % 100) + ((frame
.param3() % 100) / 4)) % 7;
167 frame
.param0() -= ((frame
.param3() / 100) % 4 - 3) * 2;
168 if (frame
.param2() < 3)frame
.param0()--;
172 void syscall::create_port(interrupt_stackframe
&frame
)
174 port_manager
&PortManager
= port_manager::instance();
175 frame
.param0() = PortManager
.create(*scheduler::get_process());
178 void syscall::destroy_port(interrupt_stackframe
&frame
)
180 port_manager
&PortManager
= port_manager::instance();
181 frame
.param0() = static_cast<size_t>(PortManager
.destroy(frame
.param1()));
184 void syscall::peek_message(interrupt_stackframe
&frame
)
186 libkernel::message_t msg
;
187 port_manager
&PortManager
= port_manager::instance();
188 frame
.param0() = static_cast<size_t>(PortManager
.peek( static_cast<libkernel::port_id_t
>(frame
.param1()),
190 *scheduler::get_process()));
191 frame
.param1() = msg
.port
;
192 frame
.param2() = msg
.type
;
193 frame
.param3() = msg
.param1
;
194 frame
.param4() = msg
.param2
;
195 frame
.param5() = msg
.param3
;
198 void syscall::get_message(interrupt_stackframe
&frame
)
200 libkernel::message_t msg
;
201 port_manager
&PortManager
= port_manager::instance();
202 frame
.param0() = frame
.param1();
203 if (PortManager
.get(static_cast<libkernel::port_id_t
>(frame
.param1()),
205 *scheduler::get_thread())
208 scheduler::schedule(&frame
);
211 frame
.param1() = msg
.port
;
212 frame
.param2() = msg
.type
;
213 frame
.param3() = msg
.param1
;
214 frame
.param4() = msg
.param2
;
215 frame
.param5() = msg
.param3
;
218 void syscall::wait_message(interrupt_stackframe
&frame
)
220 libkernel::message_t msg
;
221 port_manager
&PortManager
= port_manager::instance();
222 if (PortManager
.wait( reinterpret_cast<libkernel::port_id_t
&>(frame
.param0()),
224 *scheduler::get_thread())
227 scheduler::schedule(&frame
);
230 frame
.param1() = msg
.port
;
231 frame
.param2() = msg
.type
;
232 frame
.param3() = msg
.param1
;
233 frame
.param4() = msg
.param2
;
234 frame
.param5() = msg
.param3
;
237 void syscall::send_message(interrupt_stackframe
&frame
)
239 process
&Process
= *scheduler::get_process();
240 port_manager
&PortManager
= port_manager::instance();
241 sharedMemoryManager
&SharedMemoryManager
= sharedMemoryManager::instance();
243 if (frame
.param2() == libkernel::message_port::kernel
&&
244 frame
.param3() == libkernel::message::event
&&
245 frame
.param4() == libkernel::event::irq
)
247 libkernel::process_id_t pid
= PortManager
.get_processId(frame
.param1());
248 if (Process
.getId() == pid
)
250 // TODO HACK reenableIRQ(frame.param5(), frame.param1());
254 ERROR(Process
.getName().c_str() << ": not the port owner");
255 Process
.destroyThread(scheduler::get_thread()->getId());
256 scheduler::schedule(0);
261 size_t flags
= frame
.param3() >> 29;
264 size_t flags
= frame
.param3() >> 61;
268 process
*dest
= process::get_process(PortManager
.get_processId(frame
.param2()));
271 pair
<void*, size_t> result
= SharedMemoryManager
.transfer(*dest
, Process
, frame
.param5(), flags
);
272 if (result
.first
== 0)
274 ERROR("syscall: Unable to transfer shared memory #" << dec(frame
.param5()) << " (sender: \"" <<
275 Process
.getName().c_str() << "\" on port " << dec(frame
.param1()) << " to port " <<
276 dec(frame
.param2()) << ", receiver: \"" << dest
->getName().c_str() << "\")");
277 frame
.param0() = static_cast<size_t>(false);
280 frame
.param6() = reinterpret_cast<uintptr_t>(result
.first
) | result
.second
;
284 ERROR("syscall: Cannot find receiving process (sender: \"" << Process
.getName().c_str() <<
285 "\" on port " << dec(frame
.param1()) << " to port " << dec(frame
.param2()) << ")");
286 frame
.param0() = static_cast<size_t>(false);
291 libkernel::message_t msg
;
292 msg
.port
= frame
.param2();
293 msg
.type
= frame
.param3();
294 msg
.param1
= frame
.param4();
295 msg
.param2
= frame
.param5();
296 msg
.param3
= frame
.param6();
297 frame
.param0() = static_cast<size_t>(PortManager
.send(frame
.param1(), msg
, scheduler::get_process()));
300 void syscall::port_info(interrupt_stackframe
&frame
)
302 port_manager
&PortManager
= port_manager::instance();
303 libkernel::process_id_t pid
= PortManager
.get_processId(frame
.param1());
304 libkernel::thread_id_t tid
= PortManager
.get_waiting_threadId(frame
.param1());
306 frame
.param0() = static_cast<size_t>(pid
!= 0);
307 frame
.param1() = pid
;
308 frame
.param2() = tid
;
311 void syscall::standard_port(interrupt_stackframe
&frame
)
315 if (frame
.param1() == 0)Process
= scheduler::get_process();
316 else Process
= process::get_process(frame
.param1());
319 if (frame
.param2() == 0)
321 frame
.param0() = static_cast<size_t>(false);
324 frame
.param0() = static_cast<size_t>(Process
->set_standard_port(frame
.param3(), frame
.param4(), frame
.param5()));
328 else if (frame
.param2() == 1)
334 std::pair
<libkernel::port_id_t
,libkernel::port_id_t
> ports
= Process
->get_standard_port(frame
.param3());
335 frame
.param0() = ports
.first
;
336 frame
.param1() = ports
.second
;
341 void syscall::transfer_port(interrupt_stackframe
& frame
)
343 port_manager
&PortManager
= port_manager::instance();
344 frame
.param0() = static_cast<size_t>(PortManager
.transfer( frame
.param1(),
345 *scheduler::get_process(),
349 void syscall::add_wait_message(interrupt_stackframe
&frame
)
351 libkernel::message_t
msg(frame
.param2(), frame
.param3(), frame
.param4(), frame
.param5(), frame
.param6());
352 port_manager
&PortManager
= port_manager::instance();
353 frame
.param0() = static_cast<size_t>(PortManager
.add_wait(frame
.param1(), msg
, *scheduler::get_thread()));
356 void syscall::create_thread(interrupt_stackframe
&frame
)
358 frame
.param0() = static_cast<size_t>(scheduler::get_process()->createThread(frame
.param1(), frame
.param2(), frame
.param3(), frame
.param4()));
361 void syscall::suspend_thread(interrupt_stackframe
&frame
)
363 if (frame
.param1() == 0)frame
.param1() = scheduler::get_thread()->getId();
364 thread
*Thread
= process::get_thread(frame
.param1());
365 frame
.param0() = static_cast<size_t>(false);
367 if (Thread
->status() == thread::run
)
369 Thread
->block(thread::suspended
);
370 frame
.param0() = static_cast<size_t>(true);
372 scheduler::schedule(&frame
);
375 void syscall::resume_thread(interrupt_stackframe
&frame
)
377 thread
*Thread
= process::get_thread(frame
.param1());
378 frame
.param0() = static_cast<size_t>(false);
380 if (Thread
->status() == thread::suspended
)
383 frame
.param0() = static_cast<size_t>(true);
387 void syscall::destroy_thread(interrupt_stackframe
&frame
)
389 libkernel::thread_id_t tid
= scheduler::get_thread()->getId();
390 if (frame
.param1() == 0)frame
.param1() = tid
;
391 frame
.param0() = static_cast<size_t>(scheduler::get_process()->destroyThread(frame
.param1()));
392 if (tid
== frame
.param1())scheduler::schedule(0);
395 void syscall::destroy_process(interrupt_stackframe
&frame
)
397 libkernel::process_id_t thispid
= scheduler::get_process()->getId();
398 if (frame
.param1() == 0)frame
.param1() = thispid
;
399 frame
.param0() = static_cast<size_t>(process::destroy(frame
.param1()));
400 if (frame
.param1() == thispid
)scheduler::schedule(0);
401 scheduler::schedule(&frame
);
404 void syscall::get_pid(interrupt_stackframe
&frame
)
406 frame
.param0() = scheduler::get_process()->getId();
409 void syscall::get_tid(interrupt_stackframe
&frame
)
411 frame
.param0() = scheduler::get_thread()->getId();
414 void syscall::get_process_count(interrupt_stackframe
&frame
)
416 frame
.param0() = process::size();
419 void syscall::get_process_list(interrupt_stackframe
&frame
)
421 if (frame
.param1() >= process::size())frame
.param0() = 0;
424 process
*Process
= process::get_process_by_index(frame
.param1());
425 frame
.param0() = Process
->getId();
429 void syscall::get_process_info(interrupt_stackframe
&frame
)
431 process
*Process
= process::get_process(frame
.param1());
434 if (frame
.param2() == 0) // Get process name (length)
436 string name
= Process
->getName();
437 if (frame
.param3() == 0)frame
.param0() = name
.length();
438 else strcpy(reinterpret_cast<char*>(frame
.param3()), name
.c_str());
440 else if (frame
.param2() == 1) // Get process used memory
442 frame
.param0() = Process
->used_page_count() * virtual_memory::page_size
;
444 //TODO: more process information
448 void syscall::register_event(interrupt_stackframe
&frame
)
450 event_manager
&EventManager
= event_manager::instance();
452 if (frame
.param2() == libkernel::event::irq
||
453 frame
.param2() == libkernel::event::log_update
)
457 if (frame
.param2() == libkernel::event::irq
)
458 frame
.param0() = EventManager
.register_irq( frame
.param1(),
461 else if (frame
.param2() == libkernel::event::log_update
)
463 // TODO NOTE HACK frame.param0() = static_cast<size_t>(video::instance().registerEvent(frame.param1()));
464 FATAL("No log_update event");
468 else if ( frame
.param2() == libkernel::event::create_process
||
469 frame
.param2() == libkernel::event::destroy_process
)
471 process::registerEvent( frame
.param1(),
472 static_cast<libkernel::event
>(frame
.param2()),
475 frame
.param0() = static_cast<size_t>(true);
477 else if (frame
.param2() == libkernel::event::timer
)
478 EventManager
.register_timer(frame
.param1(),
479 static_cast<uint64_t>(frame
.param3()),
480 static_cast<bool>(frame
.param4()));
483 ERROR("error: trying to register unknown event");
484 process
&Process
= *scheduler::get_process();
485 process::destroy(Process
.getId());
486 scheduler::schedule(0);
490 void syscall::acknoledge_event(interrupt_stackframe
&frame
)
492 event_manager
&EventManager
= event_manager::instance();
493 if (frame
.param2() == libkernel::event::irq
)
494 EventManager
.acknoledge_irq(frame
.param1(), frame
.param3());
497 ERROR("error: trying to acknoledge unknown event");
498 process
&Process
= *scheduler::get_process();
499 process::destroy(Process
.getId());
500 scheduler::schedule(0);
504 void syscall::unregister_event(interrupt_stackframe
&frame
)
506 event_manager
&EventManager
= event_manager::instance();
509 if (frame.param2() == lightOS::event::irq ||
510 frame.param2() == lightOS::event::log_update)
514 if (frame.param2() == lightOS::event::irq)
515 frame.param0() = EventManager.register_irq( frame.param1(),
518 else if (frame.param2() == lightOS::event::log_update)
520 // TODO NOTE HACK frame.param0() = static_cast<size_t>(video::instance().registerEvent(frame.param1()));
521 FATAL("No log_update event");
525 else if ( frame.param2() == lightOS::event::create_process ||
526 frame.param2() == lightOS::event::destroy_process)
528 process::registerEvent( frame.param1(),
529 static_cast<lightOS::event::type>(frame.param2()),
532 frame.param0() = static_cast<size_t>(true);
534 else*/ if (frame
.param2() == libkernel::event::timer
)
535 EventManager
.unregister_timer(frame
.param1());
538 ERROR("error: trying to unregister unknown event");
539 process
&Process
= *scheduler::get_process();
540 process::destroy(Process
.getId());
541 scheduler::schedule(0);
545 void syscall::get_tick_count(interrupt_stackframe
&frame
)
547 event_manager
&EventManager
= event_manager::instance();
548 frame
.param0() = EventManager
.get_ticks();
551 void syscall::create_shared_memory(interrupt_stackframe
&frame
)
553 sharedMemoryManager
&SharedMemoryManager
= sharedMemoryManager::instance();
554 pair
<libkernel::shared_memory_id_t
, void*> result
= SharedMemoryManager
.create(*scheduler::get_process(), frame
.param1());
555 frame
.param0() = result
.first
;
556 frame
.param1() = reinterpret_cast<uintptr_t>(result
.second
);
559 void syscall::destroy_shared_memory(interrupt_stackframe
&frame
)
561 sharedMemoryManager
&SharedMemoryManager
= sharedMemoryManager::instance();
562 frame
.param0() = static_cast<size_t>(SharedMemoryManager
.destroy(*scheduler::get_process(), frame
.param1()));
565 void syscall::range_allocator_count(interrupt_stackframe
&frame
)
567 range_allocator
&RangeAllocator
= range_allocator::instance();
568 frame
.param0() = RangeAllocator
.count();
569 frame
.param1() = RangeAllocator
.capacity() * virtual_memory::page_size
;
572 void syscall::enum_range_allocator(interrupt_stackframe
&frame
)
574 range_allocator
&RangeAllocator
= range_allocator::instance();
575 range_allocator::range Range
= RangeAllocator
.get_range(frame
.param1());
576 frame
.param0() = Range
.address
;
577 frame
.param1() = Range
.size
* virtual_memory::page_size
;
580 void syscall::create_specific_port(interrupt_stackframe
&frame
)
584 process
&Process
= *scheduler::get_process();
585 port_manager
&PortManager
= port_manager::instance();
586 frame
.param0() = static_cast<size_t>(PortManager
.create(Process
, frame
.param1()));
589 void syscall::get_kernel_log(interrupt_stackframe
&frame
)
593 FATAL("not get_kernel_log()");
596 std::string &log = video::instance().log();
597 if (frame.param1() == 0)
599 frame.param0() = log.length();
603 if (log.length() != 0)
605 strncpy(reinterpret_cast<char*>(frame.param1()), log.c_str(), frame.param2() + 1);
606 log.erase(log.begin(), log.begin() + frame.param2());
611 void syscall::get_vbe_version(interrupt_stackframe
&frame
)
616 vbe
&Vbe
= vbe::instance();
617 frame
.param0() = Vbe
.majorVersion();
618 frame
.param1() = Vbe
.minorVersion();
623 scheduler::schedule(&frame
);
626 void syscall::get_vbe_mode_count(interrupt_stackframe
&frame
)
631 vbe
&Vbe
= vbe::instance();
632 frame
.param0() = Vbe
.modeCount();
636 scheduler::schedule(&frame
);
639 void syscall::get_vbe_mode(interrupt_stackframe
&frame
)
644 vbe
&Vbe
= vbe::instance();
645 vbe::videoMode VideoMode
;
646 if (Vbe
.getModeInfo(frame
.param1(), VideoMode
) == true)
648 frame
.param0() = VideoMode
.width
;
649 frame
.param1() = VideoMode
.height
;
650 frame
.param2() = VideoMode
.bpp
;
654 frame
.param0() = frame
.param1() = frame
.param2() = 0;
657 frame
.param0() = frame
.param1() = frame
.param2() = 0;
659 scheduler::schedule(&frame
);
662 void syscall::set_vbe_mode(interrupt_stackframe
&frame
)
668 vbe
&Vbe
= vbe::instance();
669 if (Vbe
.setMode(frame
.param1()) == true)
671 vbe::videoMode VideoMode
;
672 if (Vbe
.getModeInfo(frame
.param1(), VideoMode
) == true)
673 frame
.param0() = reinterpret_cast<size_t>(VideoMode
.framebuffer
);
676 scheduler::schedule(&frame
);
679 void syscall::request_io(interrupt_stackframe
&frame
)
683 thread
&Thread
= *scheduler::get_thread();
684 frame
.param0() = static_cast<size_t>(true);
685 Thread
.set_cpu_state(frame
);
686 Thread
.grantIOAccess();
687 scheduler::schedule(0);
690 void syscall::dma(interrupt_stackframe
&frame
)
694 x86_shared::dma
&Dma
= x86_shared::dma::instance();
695 frame
.param0() = static_cast<size_t>(Dma
.setup( frame
.param1(),
701 void syscall::execute(interrupt_stackframe
&frame
)
707 string
name(reinterpret_cast<char*>(frame
.param3()));
710 // NOTE: We have to copy the elf image into the kernel space
711 size_t pages
= frame
.param2() / virtual_memory::page_size
;
712 if ((frame
.param2() % virtual_memory::page_size
) != 0)++pages
;
713 void *image
= kernel_context::instance().allocate_memory_region(pages
, lightOS::context::write
);
714 memcpy(image
, reinterpret_cast<void*>(frame
.param1()), frame
.param2());
716 KERNEL_CONTEXT_START
;
717 elf
Elf(image
, frame
.param2());
719 elf
Elf(reinterpret_cast<void*>(frame
.param1()), frame
.param2());
723 if (Elf
.valid() == true)
725 if (Elf
.is_library() == true)
727 Elf
.create_library_image(name
.c_str());
728 frame
.param0() = static_cast<size_t>(-1);
734 bool result
= Elf
.create_process_image(Context
, Pages
, libName
);
738 frame
.param0() = process::create( Context
,
749 KernelContext
.free_memory_region(image
, pages
);
752 if (frame
.param0() == 0 &&
753 libName
.length() != 0)
754 strcpy(reinterpret_cast<char*>(frame
.param5()), libName
.c_str());
757 void syscall::get_physical_address(interrupt_stackframe
&frame
)
761 context
&Context
= scheduler::get_process()->getContext();
762 frame
.param0() = reinterpret_cast<size_t>(Context
.physical_address(reinterpret_cast<void*>(frame
.param1())));
765 void syscall::allocate_region(interrupt_stackframe
&frame
)
769 process
&Process
= *scheduler::get_process();
770 frame
.param0() = reinterpret_cast<size_t>(Process
.create_memory_region( frame
.param1(),
772 reinterpret_cast<void*>(frame
.param3())));
775 void syscall::free_region(interrupt_stackframe
&frame
)
779 scheduler::get_process()->free_memory_region(reinterpret_cast<void*>(frame
.param1()));
782 void syscall::get_system_configuration(interrupt_stackframe
&frame
)
786 // Get the information from the serial driver
787 uint16_t ser0
, ser1
, ser2
, ser3
, usedSer
;
789 serial &Serial = serial::instance();
790 usedSer = Serial.get();
791 Serial.get(ser0, ser1, ser2, ser3);
794 // Pack this info into the registers
795 frame
.param0() = (ser1
<< 16) | ser0
;
796 frame
.param1() = (ser3
<< 16) | ser2
;
797 frame
.param2() = usedSer
;
800 void syscall::get_library_count(interrupt_stackframe
&frame
)
802 frame
.param0() = elf::library_count();
805 void syscall::get_library_info(interrupt_stackframe
&frame
)
807 size_t index
= frame
.param1();
808 frame
.param0() = elf::get_library_name(index
, reinterpret_cast<char*>(frame
.param2()));
809 pair
<uintptr_t,size_t> result
= elf::get_library_address(index
);
810 frame
.param1() = result
.first
;
811 frame
.param2() = result
.second
;
814 void syscall::signal_handler(interrupt_stackframe
&frame
)
816 process
*Process
= scheduler::get_process();
817 if (frame
.param1() == 0)
818 frame
.param1() = reinterpret_cast<size_t>(Process
->signal_handler());
820 Process
->signal_handler(reinterpret_cast<void*>(frame
.param1()));
823 void syscall::signal(interrupt_stackframe
&frame
)
825 libkernel::process_id_t pid
= scheduler::get_process()->getId();
826 if (frame
.param1() == 0)frame
.param1() = pid
;
827 if (frame
.param1() == pid
)
828 scheduler::get_thread()->set_cpu_state(frame
);
830 process
*Dest
= process::get_process(frame
.param1());
831 frame
.param0() = Dest
->signal(frame
.param2());
833 if (frame
.param1() == pid
)
834 scheduler::schedule(0);
837 void syscall::signal_end(interrupt_stackframe
&frame
)
839 process
*Process
= scheduler::get_process();
840 thread
*Thread
= scheduler::get_thread();
841 Thread
->set_cpu_state(frame
);
842 Process
->signal_end();
843 scheduler::schedule(0);
849 * param2 - size of param3's array
850 * param3 - pointer to the array
855 void syscall::get_log_entry(interrupt_stackframe
& frame
)
857 log
& Log
= log::instance();
858 libkernel::log_level lvl
;
859 frame
.param0() = Log
.get_entry(frame
.param1(),
861 reinterpret_cast<char*>(frame
.param3()),
863 frame
.param1() = lvl
;