- kdevelop3 project files
[lightOS.git] / kernel / syscall.cpp
blobba4c9e1aed4a91b9c99a772c6c3cd6afb0f96bc1
1 /*
2 lightOS kernel
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>
34 #include <string>
35 #include <kernel/log.hpp>
36 #ifdef X86
37 #include <kernel/x86/vbe.hpp>
38 #endif
39 #include <kernel/virtual_memory.hpp>
40 using namespace std;
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
81 0, // 34
82 0, // 35
83 0, // 36
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
91 syscall::dma, // 44
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()--;
169 frame.param0() %= 7;
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()),
189 msg,
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()),
204 msg,
205 *scheduler::get_thread())
206 == false)
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()),
223 msg,
224 *scheduler::get_thread())
225 == true)
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());
252 else
254 ERROR(Process.getName().c_str() << ": not the port owner");
255 Process.destroyThread(scheduler::get_thread()->getId());
256 scheduler::schedule(0);
260 #ifdef X86
261 size_t flags = frame.param3() >> 29;
262 #endif
263 #ifdef X86_64
264 size_t flags = frame.param3() >> 61;
265 #endif
266 if (flags != 0)
268 process *dest = process::get_process(PortManager.get_processId(frame.param2()));
269 if (dest != 0)
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);
278 return;
280 frame.param6() = reinterpret_cast<uintptr_t>(result.first) | result.second;
282 else
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);
287 return;
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)
313 // Get the process
314 process *Process;
315 if (frame.param1() == 0)Process = scheduler::get_process();
316 else Process = process::get_process(frame.param1());
318 // set_standard_port
319 if (frame.param2() == 0)
321 frame.param0() = static_cast<size_t>(false);
322 if (Process != 0)
324 frame.param0() = static_cast<size_t>(Process->set_standard_port(frame.param3(), frame.param4(), frame.param5()));
327 // get_standard_port
328 else if (frame.param2() == 1)
330 frame.param0() = 0;
331 frame.param1() = 0;
332 if (Process != 0)
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(),
346 frame.param2()));
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);
366 if (Thread != 0)
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);
379 if (Thread != 0)
380 if (Thread->status() == thread::suspended)
382 Thread->unblock();
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;
422 else
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());
432 if (Process != 0)
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)
455 server_check(frame);
457 if (frame.param2() == libkernel::event::irq)
458 frame.param0() = EventManager.register_irq( frame.param1(),
459 frame.param3(),
460 frame.param4());
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");
465 processor::halt();
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()),
473 frame.param3(),
474 frame.param4());
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()));
481 else
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());
495 else
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();
508 /* TODO
509 if (frame.param2() == lightOS::event::irq ||
510 frame.param2() == lightOS::event::log_update)
512 server_check(frame);
514 if (frame.param2() == lightOS::event::irq)
515 frame.param0() = EventManager.register_irq( frame.param1(),
516 frame.param3(),
517 frame.param4());
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");
522 processor::halt();
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()),
530 frame.param3(),
531 frame.param4());
532 frame.param0() = static_cast<size_t>(true);
534 else*/ if (frame.param2() == libkernel::event::timer)
535 EventManager.unregister_timer(frame.param1());
536 else
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)
582 server_check(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)
591 server_check(frame);
593 FATAL("not get_kernel_log()");
594 processor::halt();
596 std::string &log = video::instance().log();
597 if (frame.param1() == 0)
599 frame.param0() = log.length();
601 else
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)
613 server_check(frame);
615 #ifdef _LIGHTOS_V86
616 vbe &Vbe = vbe::instance();
617 frame.param0() = Vbe.majorVersion();
618 frame.param1() = Vbe.minorVersion();
619 #else
620 frame.param0() = 0;
621 frame.param1() = 0;
622 #endif
623 scheduler::schedule(&frame);
626 void syscall::get_vbe_mode_count(interrupt_stackframe &frame)
628 server_check(frame);
630 #ifdef _LIGHTOS_V86
631 vbe &Vbe = vbe::instance();
632 frame.param0() = Vbe.modeCount();
633 #else
634 frame.param0() = 0;
635 #endif
636 scheduler::schedule(&frame);
639 void syscall::get_vbe_mode(interrupt_stackframe &frame)
641 server_check(frame);
643 #ifdef _LIGHTOS_V86
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;
652 else
654 frame.param0() = frame.param1() = frame.param2() = 0;
656 #else
657 frame.param0() = frame.param1() = frame.param2() = 0;
658 #endif
659 scheduler::schedule(&frame);
662 void syscall::set_vbe_mode(interrupt_stackframe &frame)
664 server_check(frame);
666 frame.param0() = 0;
667 #ifdef _LIGHTOS_V86
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);
675 #endif
676 scheduler::schedule(&frame);
679 void syscall::request_io(interrupt_stackframe &frame)
681 server_check(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)
692 server_check(frame);
694 x86_shared::dma &Dma = x86_shared::dma::instance();
695 frame.param0() = static_cast<size_t>(Dma.setup( frame.param1(),
696 frame.param2(),
697 frame.param3(),
698 frame.param4()));
701 void syscall::execute(interrupt_stackframe &frame)
703 server_check(frame);
705 frame.param0() = 0;
706 string libName;
707 string name(reinterpret_cast<char*>(frame.param3()));
709 #ifdef X86
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());
718 #else
719 elf Elf(reinterpret_cast<void*>(frame.param1()), frame.param2());
720 #endif
722 frame.param0() = 0;
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);
730 else
732 context Context;
733 vector<void*> Pages;
734 bool result = Elf.create_process_image(Context, Pages, libName);
736 if (result == true)
738 frame.param0() = process::create( Context,
739 Pages,
740 name,
741 Elf.entry_point(),
742 frame.param4());
747 #ifdef X86
748 KERNEL_CONTEXT_END;
749 KernelContext.free_memory_region(image, pages);
750 #endif
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)
759 server_check(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)
767 server_check(frame);
769 process &Process = *scheduler::get_process();
770 frame.param0() = reinterpret_cast<size_t>(Process.create_memory_region( frame.param1(),
771 frame.param2(),
772 reinterpret_cast<void*>(frame.param3())));
775 void syscall::free_region(interrupt_stackframe &frame)
777 server_check(frame);
779 scheduler::get_process()->free_memory_region(reinterpret_cast<void*>(frame.param1()));
782 void syscall::get_system_configuration(interrupt_stackframe &frame)
784 server_check(frame);
786 // Get the information from the serial driver
787 uint16_t ser0, ser1, ser2, ser3, usedSer;
788 /* TODO FIXME HACK
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());
819 else
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);
847 * in:
848 * param1 - index
849 * param2 - size of param3's array
850 * param3 - pointer to the array
851 * out:
852 * param1 - real size
853 * param2 - log level
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(),
860 lvl,
861 reinterpret_cast<char*>(frame.param3()),
862 frame.param2());
863 frame.param1() = lvl;