FreeNOS
CoreServer.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <FreeNOS/User.h>
19#include <ExecutableFormat.h>
20#include <Lz4Decompressor.h>
21#include <stdio.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <sys/wait.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include "CoreServer.h"
28
29const char * CoreServer::kernelPath = "/boot/kernel";
30
33{
34 m_numRegions = 0;
35 m_kernel = ZERO;
38
39 m_cores = ZERO;
44
45 // Register IPC handlers
47
48 // Because of waitpid() we must send the reply manually before waitpid().
50}
51
53{
54 CoreMessage msg;
55
56 if (m_info.coreId == 0)
57 return run();
58
59 while (true)
60 {
61 // wait from a message of the master core
63
65 if (h)
66 {
67 const bool sendReply = h->sendReply;
68 (this->*h->exec) (&msg);
69
70 if (sendReply)
71 {
72 sendToMaster(&msg);
73 }
74 }
75 else
76 {
77 ERROR("invalid action " << (int)msg.action << " from master");
78 }
79 }
80}
81
83{
84 const Size maximumArguments = 64;
85 char cmd[128], *argv[maximumArguments], *arg = ZERO;
86 Memory::Range range;
88 Size argc = 0;
89
90 if (m_info.coreId == 0)
91 {
92 // Find physical address for program buffer
93 range.virt = msg->programAddr;
94 if ((result = VMCtl(msg->from, LookupVirtual, &range)) != API::Success)
95 {
96 ERROR("failed to lookup virtual address at " <<
97 (void *) msg->programAddr << ": " << (int)result);
99 return;
100 }
101 msg->programAddr = range.phys;
102
103 // Find physical address for command
104 range.virt = (Address) msg->programCmd;
105 if ((result = VMCtl(msg->from, LookupVirtual, &range)) != API::Success)
106 {
107 ERROR("failed to lookup virtual address at " <<
108 (void *) msg->programCmd << ": " << (int)result);
110 return;
111 }
112 msg->programCmd = (char *) range.phys;
113
114 // Forward message to slave core
115 if (sendToSlave(msg->coreNumber, msg) != Core::Success)
116 {
117 ERROR("failed to write channel on core"<<msg->coreNumber);
118 msg->result = Core::IOError;
119 return;
120 }
121 DEBUG("creating program at phys " << (void *) msg->programAddr << " on core" << msg->coreNumber);
122
123 // Wait until the slave created the program
124 if (receiveFromSlave(msg->coreNumber, msg) != Core::Success)
125 {
126 ERROR("failed to read channel on core" << msg->coreNumber);
127 msg->result = Core::IOError;
128 return;
129 }
130 DEBUG("program created with result " << (int)msg->result << " at core" << msg->coreNumber);
131 ChannelClient::instance()->syncSendTo(msg, sizeof(*msg), msg->from);
132 }
133 else
134 {
135 // Copy the program command
136 result = VMCopy(SELF, API::ReadPhys, (Address) cmd,
137 (Address) msg->programCmd, sizeof(cmd));
138 if (result != API::Success)
139 {
140 ERROR("failed to copy program command: result = " << (int) result);
142 sendToMaster(msg);
143 return;
144 }
145 // First argument points to start of command
146 arg = cmd;
147
148 // Translate space separated command to argv[]
149 for (Size i = 0; i < sizeof(cmd) && argc < maximumArguments - 1; i++)
150 {
151 if (cmd[i] == ' ')
152 {
153 cmd[i] = 0;
154 argv[argc++] = arg;
155 arg = &cmd[i+1];
156 }
157 else if (cmd[i] == 0)
158 {
159 argv[argc++] = arg;
160 break;
161 }
162 }
163 // Mark end of the argument list
164 argv[argc] = 0;
165
166 // Map the program buffer
167 range.phys = msg->programAddr;
168 range.virt = 0;
170 range.size = msg->programSize;
171 if ((result = VMCtl(SELF, MapContiguous, &range)) != API::Success)
172 {
173 ERROR("failed to map program data: " << (int)result);
174 msg->result = Core::IOError;
175 sendToMaster(msg);
176 return;
177 }
178
179 int pid = spawn(range.virt, msg->programSize, (const char **)argv);
180 if (pid == -1)
181 {
182 ERROR("failed to spawn() program: " << pid);
183 msg->result = Core::IOError;
184 sendToMaster(msg);
185 }
186 else
187 {
188 // reply to master before calling waitpid()
189 msg->result = Core::Success;
190 sendToMaster(msg);
191 }
192
193 if ((result = VMCtl(SELF, UnMap, &range)) != API::Success)
194 {
195 ERROR("failed to unmap program data: " << (int)result);
196 }
197
198 // Wait until the spawned process completes
199 if (pid != -1)
200 {
201 int status;
202 waitpid((pid_t)pid, &status, 0);
203 }
204 }
205}
206
208{
209 DEBUG("");
210
211 if (m_info.coreId == 0)
212 {
213 if (m_cores)
214 msg->coreNumber = m_cores->getCores().count();
215 else
216 msg->coreNumber = 1;
217
218 msg->result = Core::Success;
219 }
220 else
222}
223
225{
226 const Size pingPongNumber = 0x12345678;
227
228 if (m_info.coreId != 0)
229 {
230 CoreMessage msg;
233 msg.coreNumber = pingPongNumber;
234
235 sendToMaster(&msg);
236 }
237 else if (m_cores != NULL)
238 {
239 CoreMessage msg;
240 Size numCores = m_cores->getCores().count();
241
242 for (Size i = 1; i < numCores; i++)
243 {
244 receiveFromSlave(i, &msg);
245
246 if (msg.action == Core::PongResponse && msg.coreNumber == pingPongNumber)
247 {
248 NOTICE("core" << i << " send a Pong");
249 }
250 else
251 {
252 ERROR("invalid message received from core" << i);
253 }
254 }
255 }
256
257 return Core::Success;
258}
259
261{
262 // Only core0 needs to start other coreservers
263 if (m_info.coreId != 0)
264 {
266 {
267 ERROR("failed to setup IPC channels");
268 return IOError;
269 }
270 else
271 {
272 return Success;
273 }
274 }
275
276 if (loadKernel() != Core::Success)
277 {
278 ERROR("failed to load kernel program");
279 return IOError;
280 }
281
283 {
284 ERROR("failed to discover cores");
285 return IOError;
286 }
287
289 {
290 ERROR("failed to prepare CoreInfo data array");
291 return IOError;
292 }
293
295 {
296 ERROR("failed to setup IPC channels");
297 return IOError;
298 }
299
300 if (bootAll() != Core::Success)
301 {
302 ERROR("failed to boot all cores");
303 return IOError;
304 }
305
307 {
308 ERROR("failed to unload kernel program");
309 return IOError;
310 }
311
312 return Success;
313}
314
316{
317 struct stat st;
318 int fd, r;
319 API::Result result;
320
321 DEBUG("Opening : " << kernelPath);
322
323 // Stat the compressed program image
324 if ((r = stat(kernelPath, &st)) != 0)
325 {
326 ERROR("failed to stat() kernel on path: " << kernelPath <<
327 ": result " << r);
328 return Core::IOError;
329 }
330
331 // Map memory buffer for the compressed program image
332 Memory::Range compressed;
333 compressed.virt = ZERO;
334 compressed.phys = ZERO;
335 compressed.size = st.st_size;
337
338 // Allocate compressed memory buffer
339 result = VMCtl(SELF, MapContiguous, &compressed);
340 if (result != API::Success)
341 {
342 ERROR("failed to allocate compressed kernel image with VMCtl: result = " << (int) result);
343 return Core::IOError;
344 }
345
346 // Open the file
347 if ((fd = open(kernelPath, O_RDONLY)) < 0)
348 {
349 ERROR("failed to open() kernel on path: " << kernelPath <<
350 ": result " << fd);
351 return Core::IOError;
352 }
353
354 // Read the file
355 if ((r = read(fd, (void *) compressed.virt, st.st_size)) != st.st_size)
356 {
357 ERROR("failed to read() kernel on path: " << kernelPath <<
358 ": result " << r);
359 return Core::IOError;
360 }
361 close(fd);
362
363 // Initialize decompressor
364 Lz4Decompressor lz4((void *)compressed.virt, st.st_size);
365 Lz4Decompressor::Result decompResult = lz4.initialize();
366 if (decompResult != Lz4Decompressor::Success)
367 {
368 ERROR("failed to initialize LZ4 decompressor: result = " << (int) decompResult);
369 return Core::IOError;
370 }
371
372 // Map memory buffer for the uncompressed program image
377
378 // Allocate uncompressed memory buffer
380 if (result != API::Success)
381 {
382 ERROR("failed to allocate kernel image with VMCtl: result = " << (int) result);
383 return Core::IOError;
384 }
385
386 // Decompress the kernel program
387 decompResult = lz4.read((void *)m_kernelImage.virt, lz4.getUncompressedSize());
388 if (decompResult != Lz4Decompressor::Success)
389 {
390 ERROR("failed to decompress kernel image: result = " << (int) decompResult);
391 return Core::IOError;
392 }
393
394 // Attempt to read executable format
396 if (execResult != ExecutableFormat::Success)
397 {
398 ERROR("failed to find ExecutableFormat of kernel on path: " << kernelPath <<
399 ": result " << (int) execResult);
400 return Core::ExecError;
401 }
402
403 // Retrieve memory regions
404 m_numRegions = 16;
405 execResult = m_kernel->regions(m_regions, &m_numRegions);
406
407 if (execResult != ExecutableFormat::Success)
408 {
409 ERROR("failed to get ExecutableFormat regions of kernel on path: " << kernelPath <<
410 ": result " << (int) execResult);
411 return Core::ExecError;
412 }
413
414 // Release compressed kernel image
415 result = VMCtl(SELF, Release, &compressed);
416 if (result != API::Success)
417 {
418 ERROR("failed to release compressed kernel image with VMCtl: result = " << (int) result);
419 return Core::IOError;
420 }
421
422 DEBUG("kernel loaded");
423 return Core::Success;
424}
425
427{
428 // Cleanup program buffer
430 if (r != API::Success)
431 {
432 ERROR("failed to deallocate kernel image with VMCtl: result = " << (int) r);
433 return Core::IOError;
434 }
435
438 return Core::Success;
439}
440
443{
444 API::Result r;
445 SystemInformation sysInfo;
446
447 DEBUG("Reserving: " << (void *)info->memory.phys << " size=" <<
448 info->memory.size << " available=" << sysInfo.memoryAvail);
449
450 // Claim the core's memory
451 if ((r = VMCtl(SELF, ReserveMem, &info->memory)) != API::Success)
452 {
453 ERROR("VMCtl(ReserveMem) failed for core" << coreId <<
454 " at " << (void *)info->memory.phys << ": result " << (int) r);
455 return Core::OutOfMemory;
456 }
457
458 DEBUG("Starting core" << coreId << " with "
459 << info->memory.size / 1024 / 1024 << "MB");
460
461 // Map the kernel
462 for (Size i = 0; i < m_numRegions; i++)
463 {
464 Memory::Range range;
465 range.phys = info->memory.phys + (regions[i].virt - RAM_ADDR);
466 range.virt = 0;
467 range.size = regions[i].dataSize;
470
471 // Map the target kernel's memory for regions[i].size
472 if ((r = VMCtl(SELF, MapContiguous, &range)) != 0)
473 {
474 ERROR("VMCtl(Map) failed for kernel on core" << coreId <<
475 " at " << (void *)range.phys << ": result " << (int) r);
476 return Core::OutOfMemory;
477 }
478
479 // Copy the kernel to the target core's memory
481 range.virt, regions[i].dataSize);
482 if (r != API::Success)
483 {
484 ERROR("VMCopy failed for kernel regions[" << i << "].dataOffset" <<
485 " at " << (void *)regions[i].dataOffset << ": result " << (int) r);
486 return Core::MemoryError;
487 }
488
489 // Unmap the target kernel's memory
490 if ((r = VMCtl(SELF, UnMap, &range)) != API::Success)
491 {
492 ERROR("VMCtl(UnMap) failed for kernel on core" << coreId <<
493 " at " << (void *)range.phys << ": result " << (int) r);
494 return Core::MemoryError;
495 }
496
497 DEBUG(kernelPath << "[" << i << "] = " << (void *) m_regions[i].virt <<
498 " @ " << (void *) range.phys);
499 }
500
501 // Copy the BootImage after the kernel.
502 Memory::Range range;
503 range.phys = info->bootImageAddress;
504 range.virt = 0;
505 range.size = info->bootImageSize;
507
508 // Map BootImage buffer
509 if ((r = VMCtl(SELF, MapContiguous, &range)) != API::Success)
510 {
511 ERROR("VMCtl(Map) failed for BootImage on core" << coreId <<
512 " at " << (void *)range.phys << ": result " << (int) r);
513 return Core::OutOfMemory;
514 }
515
516 // Copy the BootImage
518 range.virt, sysInfo.bootImageSize);
519 if (r != API::Success)
520 {
521 ERROR("VMCopy failed for BootIage on core" << coreId <<
522 " at " << (void *)sysInfo.bootImageAddress <<
523 ": result " << (int) r);
524 return Core::MemoryError;
525 }
526
527 // Unmap the BootImage
528 if ((r = VMCtl(SELF, UnMap, &range)) != API::Success)
529 {
530 ERROR("VMCtl(UnMap) failed for BootImage on core" << coreId <<
531 " at " << (void *)range.phys << ": result " << (int) r);
532 return Core::MemoryError;
533 }
534
535 return Core::Success;
536}
537
538
540{
541 SystemInformation sysInfo;
542 Size memPerCore = 0;
543
544 List<uint> & cores = m_cores->getCores();
545 if (cores.count() == 0)
546 {
547 ERROR("no cores found");
548 return Core::NotFound;
549 }
550
551 memPerCore = sysInfo.memorySize / cores.count();
552 memPerCore /= MegaByte(4);
553 memPerCore *= MegaByte(4);
554
555 NOTICE("found " << cores.count() << " cores: " <<
556 (memPerCore / 1024 / 1024) << "MB per core");
557
558 // Allocate CoreInfo for each core
560
561 // Prepare CoreInfo for each core
562 for (ListIterator<uint> i(cores); i.hasCurrent(); i++)
563 {
564 uint coreId = i.current();
565
566 if (coreId != 0)
567 {
568 CoreInfo *info = new CoreInfo;
569 m_coreInfo->insertAt(coreId, info);
570 MemoryBlock::set(info, 0, sizeof(CoreInfo));
571
572 info->coreId = coreId;
573 info->memory.phys = RAM_ADDR + (memPerCore * coreId);
574 info->memory.size = memPerCore - PAGESIZE;
575 info->kernel.phys = sysInfo.kernelAddress + (memPerCore * coreId);
576 info->kernel.size = sysInfo.kernelSize;
577
578 info->bootImageAddress = info->kernel.phys + info->kernel.size;
579 info->bootImageAddress += PAGESIZE - (info->kernel.size % PAGESIZE);
580 info->bootImageSize = sysInfo.bootImageSize;
581
582 info->heapAddress = info->bootImageAddress + info->bootImageSize;
583 info->heapAddress += PAGESIZE - (info->bootImageSize % PAGESIZE);
584 info->heapSize = MegaByte(1);
585
586 info->coreChannelAddress = info->heapAddress + info->heapSize;
587 info->coreChannelAddress += PAGESIZE - (info->heapSize % PAGESIZE);
588 info->coreChannelSize = PAGESIZE * 4;
590
591 m_kernel->entry(&info->kernelEntry);
592 info->timerCounter = sysInfo.timerCounter;
594 }
595 }
596
597 return Core::Success;
598}
599
601{
602 List<uint> & cores = m_cores->getCores();
603 if (cores.count() == 0)
604 {
605 ERROR("no cores found");
606 return Core::NotFound;
607 }
608
609 // Boot each core
610 for (ListIterator<uint> i(cores); i.hasCurrent(); i++)
611 {
612 uint coreId = i.current();
613
614 if (coreId != 0)
615 {
618 }
619 }
620
621 return Core::Success;
622}
623
625{
626 Memory::Range range;
627
628 DEBUG("addr = " << (void*)addr << ", size = " << size);
629
630 range.phys = addr;
631 range.virt = ZERO;
632 range.size = size;
634 VMCtl(SELF, MapContiguous, &range);
635
636 MemoryBlock::set((void *) range.virt, 0, size);
637
638 VMCtl(SELF, UnMap, &range);
639 return Core::Success;
640}
641
643{
645
646 DEBUG("");
647
648 if (info.coreId == 0)
649 {
650 Size numCores = m_cores->getCores().count();
651
654
655 for (Size i = 1; i < numCores; i++)
656 {
661 m_toSlave->insertAt(i, ch);
662
666 m_fromSlave->insertAt(i, ch);
667 }
668 }
669 else
670 {
674
677 info.coreChannelAddress + (PAGESIZE * 3));
678 }
679
680 return Core::Success;
681}
682
684{
686
687 // wait from a message of the master core
688 while (result != Channel::Success)
689 {
690 for (uint i = 0; i < MaxMessageRetry && result != Channel::Success; i++)
691 {
692 result = m_fromMaster->read(msg);
693 }
694
695 // Wait for IPI which will wake us
696 waitIPI();
697 }
698
699 return Core::Success;
700}
701
703{
704 while (m_toMaster->write(msg) != Channel::Success)
705 ;
706
707 const MemoryChannel::Result result = m_toMaster->flush();
708 if (result != Channel::Success)
709 {
710 ERROR("failed to flush master channel: result = " << (int) result);
711 msg->result = Core::IOError;
712 return Core::IOError;
713 }
714
715 return Core::Success;
716}
717
719{
721 if (!ch)
722 return Core::IOError;
723
724 while (ch->read(msg) != Channel::Success)
725 ;
726
727 return Core::Success;
728}
729
731{
733 if (!ch)
734 {
735 ERROR("cannot retrieve MemoryChannel for core" << coreId);
736 msg->result = Core::NotFound;
737 return Core::IOError;
738 }
739
740 MemoryChannel::Result result = ch->write(msg);
741 if (result != Channel::Success)
742 {
743 ERROR("failed to write channel on core" << coreId << ": result = " << (int)result);
744 msg->result = Core::IOError;
745 return Core::IOError;
746 }
747
748 result = ch->flush();
749 if (result != Channel::Success)
750 {
751 ERROR("failed to flush channel on core" << coreId << ": result = " << (int)result);
752 msg->result = Core::IOError;
753 return Core::IOError;
754 }
755
756 // Send IPI to ensure the slave wakes up for the message
758 {
759 ERROR("failed to send IPI to core" << coreId);
760 return Core::IOError;
761 }
762
763 return Core::Success;
764}
u8 coreId
Definition IntelACPI.h:1
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ Success
Definition API.h:70
@ ReadPhys
Definition API.h:100
@ Write
Definition API.h:99
virtual Result syncSendTo(const void *buffer, const Size msgSize, const ProcessID pid)
Synchronous send to one process.
ProcessID from
Source process of the message.
Type type
Message type is either a request or response.
Template class which serves incoming messages from Channels using MessageHandlers.
Index< MessageHandler< IPCHandlerFunction >, MaximumHandlerCount > m_ipcHandlers
IPC handler functions.
int run()
Enters an infinite loop, serving incoming requests.
void addIPCHandler(const Size slot, IPCHandlerFunction h, const bool sendReply=true)
Register a new IPC message action handler.
@ Consumer
Definition Channel.h:59
@ Producer
Definition Channel.h:58
Result
Result codes.
Definition Channel.h:42
@ Success
Definition Channel.h:43
@ NotFound
Definition Channel.h:49
List< uint > & getCores()
Get list of core identities.
Represents a single Core in a Central Processing Unit (CPU).
Definition CoreServer.h:51
Core::Result sendToMaster(CoreMessage *msg)
Send message to master.
MemoryChannel * m_toMaster
Definition CoreServer.h:257
Core::Result bootAll()
Boot all processor cores.
Index< MemoryChannel, MaxCores > * m_fromSlave
Definition CoreServer.h:254
virtual Core::Result sendIPI(uint coreId)=0
Send Inter-Processor-Interrupt.
void getCoreCount(CoreMessage *msg)
Get and fill the number of processor cores.
SystemInformation m_info
Definition CoreServer.h:252
void createProcess(CoreMessage *msg)
Create a process on the current processor core.
virtual void waitIPI() const =0
Wait for Inter-Processor-Interrupt.
Memory::Range m_kernelImage
Definition CoreServer.h:245
Core::Result loadKernel()
Load operating system kernel program.
virtual Result initialize()
Initialize the server.
ExecutableFormat * m_kernel
Definition CoreServer.h:244
Index< MemoryChannel, MaxCores > * m_toSlave
Definition CoreServer.h:255
int runCore()
Routine for the slave processor core.
Core::Result receiveFromMaster(CoreMessage *msg)
Receive message from master.
virtual Core::Result bootCore(uint coreId, CoreInfo *info)=0
Boot a processor core.
Core::Result unloadKernel()
Unload operating system kernel program.
Core::Result prepareCore(uint coreId, CoreInfo *info, ExecutableFormat::Region *regions)
Prepare processor core for booting.
virtual Core::Result discoverCores()=0
Discover processor cores.
Index< CoreInfo, MaxCores > * m_coreInfo
Definition CoreServer.h:251
Core::Result sendToSlave(uint coreId, CoreMessage *msg)
Send message to slave.
Core::Result prepareCoreInfo()
Prepare the CoreInfo array.
CoreManager * m_cores
Definition CoreServer.h:240
Core::Result test()
Run a ping-pong test.
Core::Result receiveFromSlave(uint coreId, CoreMessage *msg)
Receive message from slave.
static const char * kernelPath
The default kernel for starting new cores.
Definition CoreServer.h:61
MemoryChannel * m_fromMaster
Definition CoreServer.h:258
static const Size MaxMessageRetry
Number of times to busy wait on receiving a message.
Definition CoreServer.h:58
Core::Result clearPages(Address addr, Size size)
Clear memory pages with zeroes.
Size m_numRegions
Definition CoreServer.h:249
ExecutableFormat::Region m_regions[16]
Definition CoreServer.h:247
Core::Result setupChannels()
Setup communication channels between CoreServers.
CoreServer()
Class constructor function.
virtual Result regions(Region *regions, Size *count) const =0
Memory regions a program needs at runtime.
static Result find(const u8 *image, const Size size, ExecutableFormat **fmt)
Find a ExecutableFormat which can handle the given format.
virtual Result entry(Address *entry) const =0
Lookup the program entry point.
Index is a N-sized array of pointers to items of type T.
Definition Index.h:37
virtual T * get(const Size position) const
Returns the item at the given position.
Definition Index.h:187
virtual bool insertAt(const Size position, T *item)
Inserts the given item at the given position.
Definition Index.h:113
Iterate through a List.
virtual bool hasCurrent() const
Check if there is a current item on the List.
Simple linked list template class.
Definition List.h:37
Size count() const
Get the number of items on the list.
Definition List.h:402
Decompress data using the LZ4 algorithm created by Yann Collet.
Result initialize()
Initialize the decompressor.
u64 getUncompressedSize() const
Get size of the uncompressed data.
Result
Result codes.
Result read(void *buffer, const Size size) const
Reads compressed data.
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
Unidirectional point-to-point channel using shared memory.
Result setPhysical(const Address data, const Address feedback, const bool hardReset=true)
Set memory pages by physical address.
virtual Result flush()
Flush message buffers.
virtual Result read(void *buffer)
Read a message.
virtual Result write(const void *buffer)
Write a message.
static ChannelClient * instance()
Retrieve the instance.
Definition Singleton.h:53
API::Result VMCopy(const ProcessID proc, const API::Operation how, const Address ours, const Address theirs, const Size sz)
Prototype for user applications.
Definition VMCopy.h:42
#define SELF
Definition ProcessID.h:35
API::Result VMCtl(const ProcessID procID, const MemoryOperation op, Memory::Range *range=ZERO)
Prototype for user applications.
Definition VMCtl.h:61
@ Release
Definition VMCtl.h:40
@ ReserveMem
Definition VMCtl.h:44
@ LookupVirtual
Definition VMCtl.h:42
@ UnMap
Definition VMCtl.h:39
@ MapContiguous
Definition VMCtl.h:37
#define PAGESIZE
ARM uses 4K pages.
Definition ARMConstant.h:97
CoreInfo coreInfo
Local CoreInfo instance.
#define KERNEL_PATHLEN
Definition CoreInfo.h:29
C size_t strlcpy(char *dst, const char *src, size_t siz)
Copy src to string dst of size siz.
Definition strlcpy.cpp:19
C int open(const char *path, int oflag,...)
Open file relative to directory file descriptor.
Definition open.cpp:26
C int close(int fildes)
Close a file descriptor.
Definition close.cpp:22
#define O_RDONLY
Open for reading only.
Definition fcntl.h:81
ProcessID pid_t
Used for process IDs and process group IDs.
Definition types.h:32
C ssize_t read(int fildes, void *buf, size_t nbyte)
Read from a file.
Definition read.cpp:22
C int spawn(Address program, Size programSize, const char *argv[])
Create a new process using in-memory image.
Definition spawn.cpp:29
C pid_t waitpid(pid_t pid, int *stat_loc, int options)
Wait for a child process to stop or terminate.
Definition waitpid.cpp:23
#define NULL
NULL means zero.
Definition Macros.h:39
unsigned long Address
A memory address.
Definition Types.h:131
#define MegaByte(v)
Convert megabytes to bytes.
Definition Macros.h:57
#define ERROR(msg)
Output an error message.
Definition Log.h:61
#define NOTICE(msg)
Output a notice message.
Definition Log.h:75
unsigned int uint
Unsigned integer number.
Definition Types.h:44
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define ZERO
Zero value.
Definition Macros.h:43
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
unsigned char u8
Unsigned 8-bit number.
Definition Types.h:59
@ GetCoreCount
Definition Core.h:38
@ PongResponse
Definition Core.h:41
@ CreateProcess
Definition Core.h:39
Result
Result code for Actions.
Definition Core.h:48
@ InvalidArgument
Definition Core.h:50
@ IOError
Definition Core.h:55
@ Success
Definition Core.h:49
@ NotFound
Definition Core.h:51
@ MemoryError
Definition Core.h:56
@ OutOfMemory
Definition Core.h:54
@ ExecError
Definition Core.h:53
@ User
Definition Memory.h:44
@ Readable
Definition Memory.h:41
@ Writable
Definition Memory.h:42
Per-Core information structure.
Definition CoreInfo.h:61
uint timerCounter
Arch-specific timer counter.
Definition CoreInfo.h:99
Address bootImageSize
Boot image size in bytes.
Definition CoreInfo.h:84
Memory::Range kernel
Kernel memory range.
Definition CoreInfo.h:75
Size coreChannelSize
Size of the IPC channel in bytes.
Definition CoreInfo.h:90
uint coreId
Core identifier.
Definition CoreInfo.h:66
Address coreChannelAddress
Physical memory address of IPC channel for CoreServer of this core.
Definition CoreInfo.h:87
Address bootImageAddress
Boot image physical memory address.
Definition CoreInfo.h:81
Memory::Range memory
Defines the physical memory available to the core.
Definition CoreInfo.h:69
Size heapSize
Size in bytes of the kernel heap.
Definition CoreInfo.h:96
Address heapAddress
Physical memory address of the kernel heap.
Definition CoreInfo.h:93
Address kernelEntry
Kernel entry point.
Definition CoreInfo.h:72
char kernelCommand[KERNEL_PATHLEN]
Kernel command.
Definition CoreInfo.h:78
Message format for communication with the CoreServer.
Definition CoreMessage.h:39
Size programSize
Contains the size of a loaded program.
Definition CoreMessage.h:44
Size coreNumber
Indicates a number of cores or a specific coreId.
Definition CoreMessage.h:42
Core::Result result
Result code.
Definition CoreMessage.h:41
Core::Action action
Action to perform.
Definition CoreMessage.h:40
const char * programCmd
Command-line string for a loaded program.
Definition CoreMessage.h:45
Address programAddr
Contains the virtual address of a loaded program.
Definition CoreMessage.h:43
Memory range.
Definition Memory.h:56
Size size
Size in number of bytes.
Definition Memory.h:59
Address phys
Physical address.
Definition Memory.h:58
Address virt
Virtual address.
Definition Memory.h:57
Access access
Page access flags.
Definition Memory.h:60
Message handler function (dummy) container.
const Func exec
Handler function.
const bool sendReply
Whether to send a reply or not.
System information structure.
Definition SystemInfo.h:80
Size memorySize
Total and available memory in bytes.
Definition SystemInfo.h:102
Address bootImageAddress
BootImage physical address.
Definition SystemInfo.h:108
Address kernelAddress
Physical start address of the kernel program.
Definition SystemInfo.h:96
Size bootImageSize
BootImage size.
Definition SystemInfo.h:111
Size kernelSize
Size of the kernel program in bytes.
Definition SystemInfo.h:99
uint coreId
Core Identifier.
Definition SystemInfo.h:105
Address coreChannelAddress
Definition SystemInfo.h:113
uint timerCounter
Timer counter.
Definition SystemInfo.h:117
The <sys/stat.h> header shall define the stat structure.
Definition stat.h:177
off_t st_size
For regular files, the file size in bytes.
Definition stat.h:226