mirror of
https://github.com/drasko/codezero.git
synced 2026-02-08 16:03:14 +01:00
Updated LICENSE/README files, removed unused code from tasks.
This commit is contained in:
@@ -1,130 +0,0 @@
|
||||
#
|
||||
# User space application build script
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from string import split
|
||||
from os.path import join
|
||||
from glob import glob
|
||||
|
||||
task_name = "blkdev0"
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = join(project_root, "tools")
|
||||
prev_image = join(project_root, "tasks/mm0/mm0.axf")
|
||||
libs_path = join(project_root, "libs")
|
||||
ld_script = "include/linker.lds"
|
||||
physical_base_ld_script = "include/physical_base.lds"
|
||||
|
||||
# libc paths:
|
||||
libc_variant = "userspace"
|
||||
libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
|
||||
libc_incpath = join(libc_libpath, "include")
|
||||
libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
|
||||
libc_name = "c-%s" % libc_variant
|
||||
|
||||
# libl4 paths:
|
||||
libl4_path = "../libl4"
|
||||
libl4_incpath = join(libl4_path, "include")
|
||||
|
||||
#libmem paths:
|
||||
libmem_path = "../libmem"
|
||||
libmem_incpath = "../libmem"
|
||||
|
||||
# kernel paths:
|
||||
kernel_incpath = join(project_root, "include")
|
||||
|
||||
# Kernel config header.
|
||||
config_h = join(project_root, "include/l4/config.h")
|
||||
|
||||
|
||||
# If crt0 is in its library path, it becomes hard to link with it.
|
||||
# For instance the linker script must use an absolute path for it.
|
||||
def copy_crt0(source, target, env):
|
||||
os.system("cp " + str(source[0]) + " " + str(target[0]))
|
||||
|
||||
def get_physical_base(source, target, env):
|
||||
os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
|
||||
prev_image +" >> " + physical_base_ld_script))
|
||||
|
||||
# The kernel build environment:
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, "-L" + libmem_path],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', \
|
||||
'gcc', libc_name], # libgcc.a - This is required for division routines.
|
||||
CPPFLAGS = "-D__USERSPACE__",
|
||||
CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, libmem_incpath])
|
||||
|
||||
def extract_arch_subarch_plat(config_header):
|
||||
'''
|
||||
From the autogenerated kernel config.h, extracts platform, archictecture,
|
||||
subarchitecture information. This is used to include the relevant headers
|
||||
from the kernel directories.
|
||||
'''
|
||||
arch = None
|
||||
subarch = None
|
||||
plat = None
|
||||
|
||||
if not os.path.exists(config_header):
|
||||
print "\n\nconfig.h does not exist. "\
|
||||
"Please run: `scons configure' first\n\n"
|
||||
sys.exit()
|
||||
f = open(config_h, "r")
|
||||
while True:
|
||||
line = f.readline()
|
||||
if line == "":
|
||||
break
|
||||
parts = split(line)
|
||||
if len(parts) > 0:
|
||||
if parts[0] == "#define":
|
||||
if parts[1] == "__ARCH__":
|
||||
arch = parts[2]
|
||||
elif parts[1] == "__PLATFORM__":
|
||||
plat = parts[2]
|
||||
elif parts[1] == "__SUBARCH__":
|
||||
subarch = parts[2]
|
||||
f.close()
|
||||
if arch == None:
|
||||
print "Error: No config symbol found for architecture"
|
||||
sys.exit()
|
||||
if subarch == None:
|
||||
print "Error: No config symbol found for subarchitecture"
|
||||
sys.exit()
|
||||
if plat == None:
|
||||
print "Error: No config symbol found for platform"
|
||||
sys.exit()
|
||||
return arch, subarch, plat
|
||||
|
||||
def create_symlinks(arch):
|
||||
arch_path = "include/arch"
|
||||
arch_path2 ="src/arch"
|
||||
if os.path.exists(arch_path):
|
||||
os.system("rm %s" % (arch_path))
|
||||
os.system("ln -s %s %s" % ("arch-" + arch, arch_path))
|
||||
if os.path.exists(arch_path2):
|
||||
os.system("rm %s" % (arch_path2))
|
||||
os.system("ln -s %s %s" % ("arch-" + arch, arch_path2))
|
||||
|
||||
arch, subarch, plat = extract_arch_subarch_plat(config_h)
|
||||
|
||||
create_symlinks(arch) # Creates symlinks to architecture specific directories.
|
||||
|
||||
src = [glob("src/*.c"), glob("fsbin/*.S"), glob("*.c"), glob("src/arch/*.c")]
|
||||
objs = env.Object(src)
|
||||
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
|
||||
crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
|
||||
|
||||
task = env.Program(task_name, objs + [crt0_copied])
|
||||
env.Alias(task_name, task)
|
||||
env.Depends(task, physical_base)
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# Binary to elf build script
|
||||
# Works by including a binary in an assembler file and linking it.
|
||||
#
|
||||
# Copyright (C) 2007 Bahadir Balban
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from os.path import join
|
||||
from glob import glob
|
||||
|
||||
elfimg_name = "romfs"
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = join(project_root, "tools")
|
||||
prev_image = join(project_root, "tasks/test0/test0.axf")
|
||||
ld_script = "include/linker.lds"
|
||||
physical_base_ld_script = "include/physical_base.lds"
|
||||
|
||||
def get_physical_base(source, target, env):
|
||||
os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
|
||||
prev_image + " >> " + physical_base_ld_script))
|
||||
|
||||
# The kernel build environment:
|
||||
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
||||
# We don't use -nostdinc because sometimes we need standard headers,
|
||||
# such as stdarg.h e.g. for variable args, as in printk().
|
||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script],
|
||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||
CPPFLAGS = "-D__USERSPACE__",
|
||||
CPPPATH = ['#include'])
|
||||
|
||||
src = [glob("*.S")]
|
||||
objs = env.Object(src)
|
||||
physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
|
||||
task = env.Program(elfimg_name, objs)
|
||||
env.Alias(elfimg_name, task)
|
||||
env.Depends(task, physical_base)
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
|
||||
/* This is used to place a binary file into an elf section */
|
||||
.section .data.fs
|
||||
|
||||
.incbin "fsbin/romfs.bin"
|
||||
.align 4
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
arch-arm
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef __BLKDEV_H__
|
||||
#define __BLKDEV_H__
|
||||
|
||||
#include <l4lib/types.h>
|
||||
|
||||
struct block_device;
|
||||
|
||||
struct block_device_ops {
|
||||
int (*init)(struct block_device *bdev);
|
||||
int (*open)(struct block_device *bdev);
|
||||
int (*read)(struct block_device *bdev, unsigned long offset,
|
||||
int size, void *buf);
|
||||
int (*write)(struct block_device *bdev, unsigned long offset,
|
||||
int size, void *buf);
|
||||
int (*read_page)(struct block_device *bdev,
|
||||
unsigned long pfn, void *buf);
|
||||
int (*write_page)(struct block_device *bdev,
|
||||
unsigned long pfn, void *buf);
|
||||
};
|
||||
|
||||
struct block_device {
|
||||
char *name;
|
||||
void *private; /* Low-level device specific data */
|
||||
u64 size;
|
||||
struct block_device_ops ops;
|
||||
};
|
||||
|
||||
|
||||
void init_blkdev(void);
|
||||
|
||||
#endif /* __BLKDEV_H__ */
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Simple linker script for userspace or svc tasks.
|
||||
*
|
||||
* Copyright (C) 2007 Bahadir Balban
|
||||
*/
|
||||
|
||||
/*
|
||||
* The only catch with this linker script is that everything
|
||||
* is linked starting at virtual_base, and loaded starting
|
||||
* at physical_base. virtual_base is the predefined region
|
||||
* of virtual memory for userland applications. physical_base
|
||||
* is determined at build-time, it is one of the subsequent pages
|
||||
* that come after the kernel image's load area.
|
||||
*/
|
||||
/* USER_AREA_START, see memlayout.h */
|
||||
virtual_base = 0x10000000;
|
||||
__stack = 0x20000000;
|
||||
INCLUDE "include/physical_base.lds"
|
||||
|
||||
/* physical_base = 0x228000; */
|
||||
offset = virtual_base - physical_base;
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = virtual_base;
|
||||
_start_text = .;
|
||||
.text : AT (ADDR(.text) - offset) { crt0.o(.text) *(.text) }
|
||||
/* rodata is needed else your strings will link at physical! */
|
||||
.rodata : AT (ADDR(.rodata) - offset) { *(.rodata) }
|
||||
.rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) }
|
||||
.data : AT (ADDR(.data) - offset)
|
||||
{
|
||||
. = ALIGN(4K);
|
||||
_start_ramdisk0 = .;
|
||||
*(.data.romfs)
|
||||
_end_ramdisk0 = .;
|
||||
. = ALIGN(4K);
|
||||
_start_ramdisk1 = .;
|
||||
*(.data.sfs)
|
||||
_end_ramdisk1 = .;
|
||||
*(.data)
|
||||
}
|
||||
.bss : AT (ADDR(.bss) - offset) { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef __RAMDISK_H__
|
||||
#define __RAMDISK_H__
|
||||
|
||||
extern struct block_device ramdisk[];
|
||||
extern struct block_device ramdisk[];
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* High-level block device handling.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <blkdev.h>
|
||||
|
||||
/*
|
||||
* Handles block device requests from fs0 using a combination of
|
||||
* server-specific and posix shm semantics
|
||||
*/
|
||||
void handle_block_device_request()
|
||||
{
|
||||
u32 mr[MR_UNUSED_TOTAL];
|
||||
l4id_t sender;
|
||||
int err;
|
||||
u32 tag;
|
||||
|
||||
printf("%s: Listening requests.\n", __TASKNAME__);
|
||||
|
||||
if ((err = l4_receive(L4_ANYTHREAD)) < 0) {
|
||||
printf("%s: %s: IPC Error: %d. Quitting...\n", __TASKNAME__,
|
||||
__FUNCTION__, err);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/* Read conventional ipc data */
|
||||
tag = l4_get_tag();
|
||||
sender = l4_get_sender();
|
||||
|
||||
/* Read mrs not used by syslib */
|
||||
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
|
||||
mr[i] = read_mr(i);
|
||||
|
||||
switch(tag) {
|
||||
case L4_IPC_TAG_WAIT:
|
||||
printf("%s: Synced with waiting thread.\n", __TASKNAME__);
|
||||
break;
|
||||
case L4_IPC_TAG_BLOCK_OPEN:
|
||||
sys_open(sender, (void *)mr[0], (int)mr[1], (u32)mr[2]);
|
||||
break;
|
||||
default:
|
||||
printf("%s: Unrecognised ipc tag (%d)"
|
||||
"received. Ignoring.\n", __TASKNAME__, mr[MR_TAG]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/* Initialise the block devices */
|
||||
init_blkdev();
|
||||
|
||||
while (1) {
|
||||
handle_block_device_request();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
#include <blkdev.h>
|
||||
#include <ramdisk.h>
|
||||
|
||||
|
||||
void init_blkdev(void)
|
||||
{
|
||||
ramdisk[0].ops.init(&ramdisk[0]);
|
||||
ramdisk[1].ops.init(&ramdisk[1]);
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* A basic ramdisk implementation.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||
*
|
||||
* The ramdisk binary is embedded in the data section of the ramdisk device
|
||||
* executable. Read/writes simply occur to this area. The disk area could
|
||||
* have any filesystem layout e.g. romfs, which is irrelevant for this code.
|
||||
*/
|
||||
#include <blkdev.h>
|
||||
#include <ramdisk.h>
|
||||
#include <l4/macros.h>
|
||||
#include <l4/config.h>
|
||||
#include <l4/types.h>
|
||||
#include <string.h>
|
||||
#include INC_SUBARCH(mm.h)
|
||||
#include INC_GLUE(memory.h)
|
||||
|
||||
/* Ramdisk section markers for ramdisk inside this executable image */
|
||||
extern char _start_ramdisk0[];
|
||||
extern char _end_ramdisk0[];
|
||||
extern char _start_ramdisk1[];
|
||||
extern char _end_ramdisk1[];
|
||||
|
||||
struct ramdisk_data {
|
||||
u64 base;
|
||||
u64 end;
|
||||
};
|
||||
|
||||
struct ramdisk_data rddata[2];
|
||||
|
||||
__attribute__((section(".data.sfs"))) char sfsdisk[SZ_16MB];
|
||||
|
||||
int ramdisk_init(struct block_device *ramdisk)
|
||||
{
|
||||
struct ramdisk_data *rddata = ramdisk->private;
|
||||
|
||||
if (!strcmp("ramdisk0", ramdisk->name)) {
|
||||
rddata->base = (u64)(unsigned long)_start_ramdisk0;
|
||||
rddata->end = (u64)(unsigned long)_end_ramdisk0;
|
||||
ramdisk->size = (u64)((unsigned long)_end_ramdisk0 -
|
||||
(unsigned long)_start_ramdisk0);
|
||||
} else if (!strcmp("ramdisk1", ramdisk->name)) {
|
||||
rddata->base = (u64)(unsigned long)_start_ramdisk1;
|
||||
rddata->end = (u64)(unsigned long)_end_ramdisk1;
|
||||
ramdisk->size = (u64)((unsigned long)_end_ramdisk1 -
|
||||
(unsigned long)_start_ramdisk1);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ramdisk_open(struct block_device *ramdisk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ramdisk_read(struct block_device *b, unsigned long offset, int size, void *buf)
|
||||
{
|
||||
struct ramdisk_data *data = b->private;
|
||||
void *src = (void *)(unsigned long)(data->base + offset);
|
||||
|
||||
memcpy(buf, src, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ramdisk_write(struct block_device *b, unsigned long offset,
|
||||
int size, void *buf)
|
||||
{
|
||||
struct ramdisk_data *data = b->private;
|
||||
void *dst = (void *)(unsigned long)(data->base + offset);
|
||||
|
||||
memcpy(dst, buf, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ramdisk_readpage(struct block_device *b, unsigned long pfn, void *buf)
|
||||
{
|
||||
ramdisk_read(b, __pfn_to_addr(pfn), PAGE_SIZE, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ramdisk_writepage(struct block_device *b, unsigned long pfn, void *buf)
|
||||
{
|
||||
ramdisk_write(b, __pfn_to_addr(pfn), PAGE_SIZE, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct block_device ramdisk[2] = {
|
||||
[0] = {
|
||||
.name = "ramdisk0",
|
||||
.private = &rddata[0],
|
||||
.ops = {
|
||||
.init = ramdisk_init,
|
||||
.open = ramdisk_open,
|
||||
.read = ramdisk_read,
|
||||
.write = ramdisk_write,
|
||||
.read_page = ramdisk_readpage,
|
||||
.write_page = ramdisk_writepage,
|
||||
},
|
||||
},
|
||||
[1] = {
|
||||
.name = "ramdisk1",
|
||||
.private = &rddata[1],
|
||||
.ops = {
|
||||
.init = ramdisk_init,
|
||||
.open = ramdisk_open,
|
||||
.read = ramdisk_read,
|
||||
.write = ramdisk_write,
|
||||
.read_page = ramdisk_readpage,
|
||||
.write_page = ramdisk_writepage,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import sys
|
||||
|
||||
compiler_prefix = "arm-none-linux-gnueabi-"
|
||||
objdump = "objdump"
|
||||
command = "-t"
|
||||
image_name = "inittask.axf"
|
||||
linkoutput_file_suffix = "-linkinfo.txt"
|
||||
linkoutput_file = image_name + linkoutput_file_suffix
|
||||
|
||||
def generate_bootdesc():
|
||||
command = compiler_prefix + objdump + " -t " + image_name + " > " + linkoutput_file
|
||||
print command
|
||||
os.system(command)
|
||||
f = open(linkoutput_file, "r")
|
||||
|
||||
while True:
|
||||
line = f.readline()
|
||||
if len(line) is 0:
|
||||
break
|
||||
if "_start" in line or "_end" in line:
|
||||
print line
|
||||
f.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
generate_bootdesc()
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
struct channel {
|
||||
int dir; /* Direction */
|
||||
char *name; /* Name */
|
||||
int cd; /* Channel descriptor */
|
||||
};
|
||||
|
||||
|
||||
struct interface {
|
||||
struct channel chan[];
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *buf = malloc(sizeof(struct channel)*10);
|
||||
struct interface *intf = buf;
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Lightweight and simple RPC primitives.
|
||||
*
|
||||
* Copyright (c) 2007 Bahadir Balban
|
||||
*
|
||||
* Some methodology is needed for efficient and functional message passing
|
||||
* among processes, particulary when shared memory or same address space
|
||||
* messaging is available. The rpc primitives here attempt to fill this gap.
|
||||
*
|
||||
* The idea is to generate as little bloat as possible. To that end we don't
|
||||
* need encryption, marshalling, type tracking and discovery. Also Very minor
|
||||
* boilerplated code is produced from C macros rather than a notorious rpc tool.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* What default value arg0 is given for rpc calls */
|
||||
#define ARG0 8
|
||||
#define PAGE_SIZE 0x1000
|
||||
char pagebuf[PAGE_SIZE];
|
||||
|
||||
struct ipc_shmem {
|
||||
unsigned long vaddr;
|
||||
};
|
||||
|
||||
struct tlmsg {
|
||||
struct ipc_shmem shmem;
|
||||
unsigned long arg[3];
|
||||
unsigned long ret;
|
||||
unsigned long method_num;
|
||||
};
|
||||
|
||||
typedef int (*remote_call_t)(struct tlmsg *m);
|
||||
|
||||
int square(int i)
|
||||
{
|
||||
printf("%s: Entering...\n", __FUNCTION__);
|
||||
return i*i;
|
||||
}
|
||||
|
||||
/* Hand coded wrapper for non-complex argument types. */
|
||||
int rpc_square(struct tlmsg *m)
|
||||
{
|
||||
printf("%s: Entering...\n", __FUNCTION__);
|
||||
return square(m->arg[0]);
|
||||
}
|
||||
|
||||
struct complex_struct {
|
||||
int item;
|
||||
int item2;
|
||||
};
|
||||
|
||||
/* Use this to declare an RPC wrapper for your function. Your function
|
||||
* must return a primitive type (e.g, int, float, long etc.) and can
|
||||
* have a ref to a single argument of complex type (e.g. a struct). Apart
|
||||
* from these limitations it is essentially a regular C function. Note
|
||||
* that one can pass a lot of data back and forth using a single struct.
|
||||
* The wrappers are very lightweight, and thanks to many possibilities of
|
||||
* shared memory (e.g. same address-space, shared pages) data need not be
|
||||
* copied when passed back and forth. */
|
||||
#define DECLARE_RPC_BYREF(ret, func, type0) \
|
||||
static inline ret rpc_byref_##func(struct tlmsg *m) \
|
||||
{ /* Find struct address */ \
|
||||
unsigned long multiword_struct = m->arg[0] + \
|
||||
m->shmem.vaddr; /* Data passed by a shared entity */ \
|
||||
return func((type0 *)multiword_struct); /* Call real function */\
|
||||
}
|
||||
|
||||
/* Same as above, but passing a structure by value instead of reference.
|
||||
* This is much slower due to lots of copying involved. It is not
|
||||
* recommended but included for completion. */
|
||||
#define DECLARE_RPC_BYVAL(ret, func, type0) \
|
||||
static inline ret rpc_byval_##func(struct tlmsg *m) \
|
||||
{ /* Find struct address */ \
|
||||
unsigned long multiword_struct = m->arg[0] + \
|
||||
m->shmem.vaddr; /* Data passed by a shared entity */ \
|
||||
/* Call real function, by value */ \
|
||||
return func((type0)(*(type0 *)multiword_struct)); \
|
||||
}
|
||||
/* Use these directly to declare the function, *and* its RPC wrapper. */
|
||||
#define RPC_FUNC_BYREF(ret, func, type0) \
|
||||
ret func(type0 *); \
|
||||
DECLARE_RPC_BYREF(ret, func, type0) \
|
||||
ret func(type0 *arg0)
|
||||
|
||||
#define RPC_FUNC_BYVAL(ret, func, type0) \
|
||||
ret func(type0); \
|
||||
DECLARE_RPC_BYVAL(ret, func, type0) \
|
||||
ret func(type0 arg0)
|
||||
|
||||
RPC_FUNC_BYVAL(int, complex_byval, struct complex_struct)
|
||||
{
|
||||
printf("%s: Entering...\n", __FUNCTION__);
|
||||
arg0.item++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RPC_FUNC_BYREF(int, complex_byref, struct complex_struct)
|
||||
{
|
||||
printf("%s: Entering...\n", __FUNCTION__);
|
||||
arg0->item++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RPC_NAME(func, by) rpc_##by##_##func
|
||||
remote_call_t remote_call_array[] = {
|
||||
rpc_square,
|
||||
RPC_NAME(complex_byval, byval),
|
||||
RPC_NAME(complex_byref, byref),
|
||||
};
|
||||
|
||||
struct tlmsg *getmsg(int x)
|
||||
{
|
||||
struct tlmsg *m = (struct tlmsg *)malloc(sizeof(struct tlmsg));
|
||||
m->method_num = x;
|
||||
m->arg[0] = ARG0;
|
||||
m->shmem.vaddr = (unsigned long)&pagebuf;
|
||||
return m;
|
||||
}
|
||||
|
||||
void putmsg(struct tlmsg *m)
|
||||
{
|
||||
free((void *)m);
|
||||
}
|
||||
|
||||
void check_rpc_success()
|
||||
{
|
||||
struct complex_struct *cs = (struct complex_struct *)(pagebuf + ARG0);
|
||||
|
||||
printf("complex struct at offset 0x%x. cs->item: %d, expected: 1.\n", ARG0, cs->item);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct tlmsg *m[3];
|
||||
unsigned int ret;
|
||||
remote_call_t call[3];
|
||||
memset((void *)pagebuf, 0, PAGE_SIZE);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
m[i] = getmsg(i);
|
||||
printf("Calling remote function %d according to incoming msg.\n", i);
|
||||
call[i] = remote_call_array[m[i]->method_num];
|
||||
ret = call[i](m[i]); /* i.e. call rpc function number i, with
|
||||
* message number i as argument */
|
||||
printf("Call returned %d\n", ret);
|
||||
m[i]->ret = ret;
|
||||
putmsg(m[i]);
|
||||
}
|
||||
check_rpc_success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
BIN
tasks/sigma0/rpc
BIN
tasks/sigma0/rpc
Binary file not shown.
Reference in New Issue
Block a user