big commit

This commit is contained in:
Taku Shimosawa
2011-11-28 13:00:13 +09:00
parent ea0e1327c8
commit 480e1b12ef
21 changed files with 1866 additions and 89 deletions

View File

@@ -1,5 +1,6 @@
AALDIR=$(AALBASE)/$(TARGET)
OBJS=init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o
OBJS = init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o host.o
OBJS += process.o
DEPSRCS=$(wildcard $(SRC)/*.c)
include $(SRC)/configs/config.$(TARGET)

View File

@@ -47,6 +47,7 @@ void ap_init(void)
kprintf("BSP HW ID = %d, ", bsp_hw_id);
kprintf("AP Booting :");
for (i = 0; i < cpu_info->ncpus; i++) {
if (cpu_info->hw_ids[i] == bsp_hw_id) {
continue;

184
kernel/host.c Normal file
View File

@@ -0,0 +1,184 @@
#include <types.h>
#include <kmsg.h>
#include <aal/cpu.h>
#include <aal/mm.h>
#include <aal/debug.h>
#include <aal/ikc.h>
#include <ikc/master.h>
#include <syscall.h>
#include <cls.h>
#include <process.h>
#include <page.h>
/*
* Communication with host
*/
static void process_msg_prepare_process(unsigned long rphys)
{
unsigned long phys, sz, s, e, up;
struct program_load_desc *p, *pn;
int i, npages, n;
struct process *proc;
sz = sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * 16;
npages = (sz + PAGE_SIZE - 1) >> PAGE_SHIFT;
phys = aal_mc_map_memory(NULL, rphys, sz);
p = aal_mc_map_virtual(phys, npages, PTATTR_WRITABLE);
n = p->num_sections;
kprintf("# of sections: %d\n", n);
pn = aal_mc_allocate(sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * n, 0);
memcpy_long(pn, p, sizeof(struct program_load_desc)
+ sizeof(struct program_image_section) * n);
proc = create_process(p->entry);
proc->pid = p->pid;
for (i = 0; i < n; i++) {
s = (pn->sections[i].vaddr) & PAGE_MASK;
e = (pn->sections[i].vaddr + pn->sections[i].len
+ PAGE_SIZE - 1) & PAGE_MASK;
up = virt_to_phys(aal_mc_alloc_pages((e - s) >> PAGE_SHIFT, 0));
add_process_memory_range(proc, s, e, up, 0);
p->sections[i].remote_pa = up;
/* TODO: Maybe we need flag */
if (i == 0) {
proc->region.text_start = s;
proc->region.text_end = e;
} else if (i == 1) {
proc->region.data_start = s;
proc->region.data_end = e;
} else {
proc->region.data_start =
(s < proc->region.data_start ?
s : proc->region.data_start);
proc->region.data_end =
(e > proc->region.data_end ?
e : proc->region.data_end);
}
}
proc->region.brk_start = proc->region.brk_end = proc->region.data_end;
proc->region.map_start = proc->region.map_end =
(USER_END / 3) & PAGE_MASK;
p->rprocess = (unsigned long)proc;
init_process_stack(proc);
kprintf("new process : %p [%d] / table : %p\n", proc, proc->pid,
proc->page_table);
aal_mc_free(pn);
aal_mc_unmap_virtual(p, npages);
aal_mc_unmap_memory(NULL, phys, sz);
}
static void process_msg_init(struct ikc_scd_init_param *pcp)
{
struct syscall_params *lparam;
lparam = &cpu_local_var(scp);
lparam->response_va = allocate_pages(1, 0);
lparam->response_pa = virt_to_phys(lparam->response_va);
pcp->request_page = 0;
pcp->doorbell_page = 0;
pcp->response_page = lparam->response_pa;
}
static void process_msg_init_acked(unsigned long pphys)
{
struct ikc_scd_init_param *param = (void *)pphys;
struct syscall_params *lparam;
lparam = &cpu_local_var(scp);
lparam->request_rpa = param->request_page;
lparam->request_pa = aal_mc_map_memory(NULL, param->request_page,
PAGE_SIZE);
lparam->request_va = aal_mc_map_virtual(lparam->request_pa, 1,
PTATTR_WRITABLE);
lparam->doorbell_rpa = param->doorbell_page;
lparam->doorbell_pa = aal_mc_map_memory(NULL, param->doorbell_page,
PAGE_SIZE);
lparam->doorbell_va = aal_mc_map_virtual(lparam->doorbell_pa, 1,
PTATTR_WRITABLE);
kprintf("Syscall parameters:\n");
kprintf(" Response: %lx, %p\n",
lparam->response_pa, lparam->response_va);
kprintf(" Request : %lx, %lx, %p\n",
lparam->request_pa, lparam->request_rpa, lparam->request_va);
kprintf(" Doorbell: %lx, %lx, %p\n",
lparam->doorbell_pa, lparam->doorbell_rpa, lparam->doorbell_va);
}
static void syscall_channel_send(struct aal_ikc_channel_desc *c,
struct ikc_scd_packet *packet)
{
aal_ikc_send(c, packet, 0);
}
static int syscall_packet_handler(struct aal_ikc_channel_desc *c,
void *__packet, void *aal_os)
{
struct ikc_scd_packet *packet = __packet;
struct ikc_scd_packet pckt;
switch (packet->msg) {
case SCD_MSG_INIT_CHANNEL_ACKED:
kprintf("init channel acked!\n");
process_msg_init_acked(packet->arg);
return 0;
case SCD_MSG_PREPARE_PROCESS:
process_msg_prepare_process(packet->arg);
pckt.msg = SCD_MSG_PREPARE_PROCESS_ACKED;
pckt.ref = packet->ref;
pckt.arg = packet->arg;
syscall_channel_send(c, &pckt);
return 0;
case SCD_MSG_SCHEDULE_PROCESS:
kprintf("next one : %lx\n", packet->arg);
cpu_local_var(next) = (struct process *)packet->arg;
return 0;
}
return 0;
}
void init_host_syscall_channel(void)
{
struct aal_ikc_connect_param param;
struct ikc_scd_packet pckt;
param.port = 501;
param.pkt_size = sizeof(struct ikc_scd_packet);
param.queue_size = PAGE_SIZE;
param.magic = 0x1129;
param.handler = syscall_packet_handler;
kprintf("(syscall) Trying to connect host ...");
while (aal_ikc_connect(NULL, &param) != 0) {
kprintf(".");
aal_mc_delay_us(1000 * 1000);
}
kprintf("connected.\n");
get_this_cpu_local_var()->syscall_channel = param.channel;
process_msg_init(&cpu_local_var(iip));
pckt.msg = SCD_MSG_INIT_CHANNEL;
pckt.ref = aal_mc_get_processor_id();
pckt.arg = virt_to_phys(&cpu_local_var(iip));
syscall_channel_send(param.channel, &pckt);
}

View File

@@ -1,5 +1,8 @@
#ifndef __HEADER_CLS_H
#define __HEADER_CLS_H
#include <process.h>
#include <syscall.h>
/*
* CPU Local Storage (cls)
*/
@@ -12,7 +15,16 @@ struct malloc_header {
struct cpu_local_var {
/* malloc */
struct malloc_header free_list;
/* Align to 64-byte */
struct process idle;
struct process *current;
struct process *next;
struct aal_ikc_channel_desc *syscall_channel;
struct syscall_params scp;
struct ikc_scd_init_param iip;
} __attribute__((aligned(64)));

52
kernel/include/process.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef HEADER_PROCESS_H
#define HEADER_PROCESS_H
#include <aal/context.h>
#include <aal/cpu.h>
#include <aal/mm.h>
#include <list.h>
#define VR_STACK 1
struct vm_range {
struct list_head list;
unsigned long start, end;
unsigned long phys;
unsigned long flag;
};
struct vm_regions {
unsigned long text_start, text_end;
unsigned long data_start, data_end;
unsigned long brk_start, brk_end;
unsigned long map_start, map_end;
unsigned long stack_start, stack_end;
};
struct process {
int pid;
int status;
struct page_table *page_table;
struct list_head vm_range_list;
struct vm_regions region;
aal_mc_kernel_context_t ctx;
aal_mc_user_context_t *uctx;
};
struct process *create_process(unsigned long user_pc);
int add_process_memory_range(struct process *process,
unsigned long start, unsigned long end,
unsigned long phys, unsigned long flag);
int remove_process_region(struct process *proc,
unsigned long start, unsigned long end);
void init_process_stack(struct process *process);
unsigned long extend_process_region(struct process *proc,
unsigned long start, unsigned long end,
unsigned long address);
void schedule(void);
#endif

65
kernel/include/syscall.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef __HEADER_SYSCALL_H
#define __HEADER_SYSCALL_H
#define NUM_SYSCALLS 255
#define SCD_MSG_PREPARE_PROCESS 0x1
#define SCD_MSG_PREPARE_PROCESS_ACKED 0x2
#define SCD_MSG_SCHEDULE_PROCESS 0x3
#define SCD_MSG_INIT_CHANNEL 0x5
#define SCD_MSG_INIT_CHANNEL_ACKED 0x6
#define SCD_MSG_SYSCALL_ONESIDE 0x4
struct ikc_scd_packet {
int msg;
int ref;
unsigned long arg;
};
struct program_image_section {
unsigned long vaddr;
unsigned long len;
unsigned long remote_pa;
unsigned long filesz, offset;
void *source;
};
struct program_load_desc {
int num_sections;
int status;
int cpu;
int pid;
unsigned long entry;
unsigned long rprocess;
struct program_image_section sections[0];
};
struct ikc_scd_init_param {
unsigned long request_page;
unsigned long response_page;
unsigned long doorbell_page;
};
struct syscall_request {
unsigned long number;
unsigned long args[5];
};
struct syscall_response {
unsigned long status;
long ret;
};
struct syscall_params {
unsigned long request_rpa, request_pa;
struct syscall_request *request_va;
unsigned long response_pa;
struct syscall_response *response_va;
unsigned long doorbell_rpa, doorbell_pa;
unsigned long *doorbell_va;
};
#endif

View File

@@ -4,6 +4,9 @@
#include <aal/cpu.h>
#include <aal/mm.h>
#include <aal/debug.h>
#include <aal/dma.h>
#include <aal/perfctr.h>
#include <process.h>
#include <cls.h>
extern struct aal_kmsg_buf kmsg_buf;
@@ -18,36 +21,98 @@ extern void mc_ikc_init(void);
extern void cpu_local_var_init(void);
extern void kmalloc_init(void);
extern void ap_start(void);
extern void aal_mc_dma_init(void);
extern void init_host_syscall_channel(void);
extern void sched_init(void);
static aal_mc_kernel_context_t idle_ctx;
static void idle(void)
{
while (1) {
cpu_enable_interrupt();
cpu_halt();
}
}
extern int syscall(int, aal_mc_user_context_t *);
extern long syscall(int, aal_mc_user_context_t *);
static void handler_init(void)
{
aal_mc_set_syscall_handler(syscall);
}
unsigned long data[1024] __attribute__((aligned(64)));
static void dma_test(void)
{
struct aal_dma_request req;
unsigned long fin = 0;
memset(&req, 0, sizeof(req));
req.src_phys = virt_to_phys(data);
req.dest_phys = virt_to_phys(data + 256);
req.size = 64;
req.notify = (void *)virt_to_phys(&fin);
req.priv = (void *)0x2984;
aal_mc_dma_request(0, &req);
while (!fin) {
barrier();
}
}
static void pc_test(void)
{
int i;
int kmode = PERFCTR_USER_MODE;
int x[2][4] = { { APT_TYPE_L1D_MISS, APT_TYPE_L1I_MISS,
APT_TYPE_L2_MISS, APT_TYPE_INSTRUCTIONS, },
{ APT_TYPE_STALL, APT_TYPE_L1I_MISS,
APT_TYPE_L2_MISS, APT_TYPE_INSTRUCTIONS, }};
for (i = 0; i < 4; i++) {
aal_mc_perfctr_init(i, x[1][i], kmode);
}
aal_mc_perfctr_start(0xf);
/*
aal_mc_perfctr_read_mask(0x0f, st);
for (i = 0; i < 100000; i++) {
data[i & 1023] += i;
asm volatile("" : : : "memory");
}
aal_mc_perfctr_read_mask(0x0f, ed);
aal_mc_perfctr_stop(1);
kprintf("INS = %ld, %ld, %ld\n", st[0], ed[0], ed[0] - st[0]);
kprintf("L2M = %ld, %ld, %ld\n", st[1], ed[1], ed[1] - st[1]);
*/
}
static void rest_init(void)
{
handler_init();
aal_mc_dma_init();
dma_test();
pc_test();
ap_init();
cpu_local_var_init();
kmalloc_init();
ikc_master_init();
mc_ikc_init();
sched_init();
ap_start();
}
int host_ikc_inited = 0;
static void post_init(void)
{
cpu_enable_interrupt();
while (!host_ikc_inited) {
barrier();
cpu_pause();
}
init_host_syscall_channel();
}
int main(void)
{
kmsg_init();
@@ -58,16 +123,15 @@ int main(void)
mem_init();
ikc_master_init();
rest_init();
arch_ready();
post_init();
kputs("MCK/AAL booted.\n");
aal_mc_init_context(&idle_ctx, NULL, idle);
aal_mc_switch_context(NULL, &idle_ctx);
schedule();
return 0;
}

View File

@@ -40,6 +40,7 @@ static int test_packet_handler(struct aal_ikc_channel_desc *c,
{
struct ikc_test_packet *packet = __packet;
struct ikc_test_packet p;
int i;
unsigned long a, pp, *v;
if (packet->msg == 0x11110011) {
@@ -56,7 +57,9 @@ static int test_packet_handler(struct aal_ikc_channel_desc *c,
aal_mc_unmap_memory(NULL, pp, 4 * 1024 * 1024);
} else if (packet->msg == 0x11110012) {
p.msg = 0x11110013;
aal_ikc_send(c, &p, 0);
for (i = 0; i < 10; i++) {
aal_ikc_send(c, &p, 0);
}
}
return 0;

View File

@@ -100,7 +100,10 @@ void *aal_mc_map_virtual(unsigned long phys, int npages,
enum aal_mc_pt_attribute attr)
{
void *p;
unsigned long i;
unsigned long i, offset;
offset = (phys & (PAGE_SIZE - 1));
phys = phys & PAGE_MASK;
p = (void *)aal_pagealloc_alloc(vmap_allocator, npages);
if (!p) {
@@ -110,13 +113,14 @@ void *aal_mc_map_virtual(unsigned long phys, int npages,
aal_mc_pt_set_page(NULL, (char *)p + (i << PAGE_SHIFT),
phys + (i << PAGE_SHIFT), attr);
}
return p;
return (char *)p + offset;
}
void aal_mc_unmap_virtual(void *va, int npages)
{
unsigned long i;
va = (void *)((unsigned long)va & PAGE_MASK);
for (i = 0; i < npages; i++) {
aal_mc_pt_clear_page(NULL, (char *)va + (i << PAGE_SHIFT));
}

189
kernel/process.c Normal file
View File

@@ -0,0 +1,189 @@
#include <process.h>
#include <string.h>
#include <errno.h>
#include <kmalloc.h>
#include <cls.h>
#include <aal/debug.h>
#include <page.h>
struct process *create_process(unsigned long user_pc)
{
struct process *proc;
proc = aal_mc_alloc_pages(1, 0);
memset(proc, 0, sizeof(struct process));
aal_mc_init_user_process(&proc->ctx, &proc->uctx,
((char *)proc) + PAGE_SIZE, user_pc, 0);
INIT_LIST_HEAD(&proc->vm_range_list);
proc->page_table = aal_mc_pt_create();
return proc;
}
void update_process_page_table(struct process *process, struct vm_range *range)
{
unsigned long p, pa = range->phys;
p = range->start;
while (p < range->end) {
aal_mc_pt_set_page(process->page_table, (void *)p,
pa, PTATTR_WRITABLE | PTATTR_USER);
pa += PAGE_SIZE;
p += PAGE_SIZE;
}
}
int add_process_memory_range(struct process *process,
unsigned long start, unsigned long end,
unsigned long phys, unsigned long flag)
{
struct vm_range *range;
range = kmalloc(sizeof(struct vm_range), 0);
if (!range) {
return -ENOMEM;
}
INIT_LIST_HEAD(&range->list);
range->start = start;
range->end = end;
range->phys = phys;
range->flag = flag;
kprintf("range: %lx - %lx => %lx - %lx\n",
range->start, range->end, range->phys, range->phys +
range->end - range->start);
update_process_page_table(process, range);
list_add_tail(&range->list, &process->vm_range_list);
return 0;
}
void init_process_stack(struct process *process)
{
char *stack = aal_mc_alloc_pages(1, 0);
unsigned long *p = (unsigned long *)(stack + PAGE_SIZE);
memset(stack, 0, PAGE_SIZE);
add_process_memory_range(process, USER_END - PAGE_SIZE,
USER_END,
virt_to_phys(p), VR_STACK);
/* TODO: fill with actual value of argc, argv, envp */
p[-1] = 0; /* env: "" */
p[-2] = 0x41; /* argv(0): "a" */
p[-3] = USER_END - sizeof(unsigned long); /* envp: END - 8 */
p[-4] = 0; /* argv[1] = NULL */
p[-5] = USER_END - sizeof(unsigned long) * 2; /* argv[0] = END - 16 */
p[-6] = 1; /* argc */
aal_mc_modify_user_context(process->uctx, AAL_UCR_STACK_POINTER,
USER_END - sizeof(unsigned long) * 6);
process->region.stack_end = USER_END;
process->region.stack_start = USER_END - PAGE_SIZE;
}
unsigned long extend_process_region(struct process *proc,
unsigned long start, unsigned long end,
unsigned long address)
{
unsigned long aligned_end, aligned_new_end;
void *p;
if (!address || address < start || address >= USER_END) {
return end;
}
aligned_end = ((end + PAGE_SIZE - 1) & PAGE_MASK);
if (aligned_end >= address) {
return address;
}
aligned_new_end = (address + PAGE_SIZE - 1) & PAGE_MASK;
p = allocate_pages((aligned_new_end - aligned_end) >> PAGE_SHIFT,
0);
if (!p) {
return end;
}
add_process_memory_range(proc, aligned_end, aligned_new_end,
virt_to_phys(p), 0);
return address;
}
int remove_process_region(struct process *proc,
unsigned long start, unsigned long end)
{
if ((start & (PAGE_SIZE - 1)) || (end & (PAGE_SIZE - 1))) {
return -EINVAL;
}
while (start < end) {
aal_mc_pt_clear_page(proc->page_table, (void *)start);
start += PAGE_SIZE;
}
return 0;
}
static void idle(void)
{
while (1) {
cpu_enable_interrupt();
schedule();
cpu_halt();
}
}
void sched_init(void)
{
struct process *idle_process = &cpu_local_var(idle);
memset(idle_process, 0, sizeof(struct process));
aal_mc_init_context(&idle_process->ctx, NULL, idle);
cpu_local_var(next) = idle_process;
}
void schedule(void)
{
struct cpu_local_var *v = get_this_cpu_local_var();
struct process *next, *prev;
int switch_ctx = 0;
cpu_disable_interrupt();
if (v->next && v->next != v->current) {
prev = v->current;
next = v->next;
switch_ctx = 1;
v->current = next;
v->next = NULL;
}
cpu_enable_interrupt();
if (switch_ctx) {
kprintf("schedule: %p => %p \n", prev, next);
aal_mc_load_page_table(next->page_table);
if (prev) {
aal_mc_switch_context(&prev->ctx, &next->ctx);
} else {
aal_mc_switch_context(NULL, &next->ctx);
}
}
}

View File

@@ -5,6 +5,8 @@ set -e
O=`pwd`
make -C $3/../kboot O=$O clean
make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x3a001000
#make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x101001000
make -C $3/../kboot O=$O KIMAGE="$O/$1" LOAD_PA=0x901001000
cat $3/../elfboot/elfboot kboot/kboot.elf > $2

View File

@@ -3,11 +3,308 @@
#include <aal/cpu.h>
#include <aal/mm.h>
#include <aal/debug.h>
#include <aal/ikc.h>
#include <errno.h>
#include <cls.h>
#include <syscall.h>
#include <page.h>
int syscall(int num, aal_mc_user_context_t *ctx)
static void send_syscall(struct syscall_request *req)
{
kprintf("System call #%d\n", num);
struct ikc_scd_packet packet;
struct syscall_response *res = cpu_local_var(scp).response_va;
return -ENOSYS;
res->status = 0;
/* TODO: copy by DMA */
memcpy_long(cpu_local_var(scp).request_va, req, sizeof(*req));
packet.msg = SCD_MSG_SYSCALL_ONESIDE;
packet.ref = aal_mc_get_processor_id();
packet.arg = cpu_local_var(scp).request_rpa;
aal_ikc_send(cpu_local_var(syscall_channel), &packet, 0);
}
static int do_syscall(struct syscall_request *req)
{
struct syscall_response *res = cpu_local_var(scp).response_va;
send_syscall(req);
while (!res->status) {
cpu_pause();
}
return res->ret;
}
long sys_brk(int n, aal_mc_user_context_t *ctx)
{
unsigned long address = aal_mc_syscall_arg0(ctx);
struct vm_regions *region = &cpu_local_var(current)->region;
region->brk_end =
extend_process_region(cpu_local_var(current),
region->brk_start, region->brk_end,
address);
return region->brk_end;
}
#define SYSCALL_DECLARE(name) long sys_##name(int n, aal_mc_user_context_t *ctx)
#define SYSCALL_HEADER struct syscall_request request; \
request.number = n
#define SYSCALL_ARG_D(n) request.args[n] = aal_mc_syscall_arg##n(ctx)
#define SYSCALL_ARG_MO(n) \
do { \
unsigned long __phys; \
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \
(void *)aal_mc_syscall_arg##n(ctx),\
&__phys)) { \
return -EFAULT; \
}\
request.args[n] = __phys; \
} while(0)
#define SYSCALL_ARG_MI(n) \
do { \
unsigned long __phys; \
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table, \
(void *)aal_mc_syscall_arg##n(ctx),\
&__phys)) { \
return -EFAULT; \
}\
request.args[n] = __phys; \
} while(0)
#define SYSCALL_ARGS_1(a0) SYSCALL_ARG_##a0(0)
#define SYSCALL_ARGS_2(a0, a1) SYSCALL_ARG_##a0(0); SYSCALL_ARG_##a1(1)
#define SYSCALL_ARGS_3(a0, a1, a2) SYSCALL_ARG_##a0(0); SYSCALL_ARG_##a1(1); \
SYSCALL_ARG_##a2(2)
#define SYSCALL_ARGS_4(a0, a1, a2, a3) \
SYSCALL_ARG_##a0(0); SYSCALL_ARG_##a1(1); \
SYSCALL_ARG_##a2(2); SYSCALL_ARG_##a3(3)
#define SYSCALL_FOOTER return do_syscall(&request)
SYSCALL_DECLARE(fstat)
{
SYSCALL_HEADER;
SYSCALL_ARGS_2(D, MO);
SYSCALL_FOOTER;
}
static int stop(void)
{
while(1);
return 0;
}
SYSCALL_DECLARE(open)
{
SYSCALL_HEADER;
SYSCALL_ARGS_3(MI, D, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(ioctl)
{
SYSCALL_HEADER;
/* Very ad-hoc for termios */
switch(aal_mc_syscall_arg1(ctx)) {
case 0x5401:
SYSCALL_ARGS_3(D, D, MO);
SYSCALL_FOOTER;
}
return -EINVAL;
}
SYSCALL_DECLARE(read)
{
SYSCALL_HEADER;
SYSCALL_ARGS_3(D, MO, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(pread)
{
SYSCALL_HEADER;
SYSCALL_ARGS_4(D, MO, D, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(write)
{
SYSCALL_HEADER;
SYSCALL_ARGS_3(D, MI, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(pwrite)
{
SYSCALL_HEADER;
SYSCALL_ARGS_4(D, MI, D, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(close)
{
SYSCALL_HEADER;
SYSCALL_ARGS_1(D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(lseek)
{
SYSCALL_HEADER;
SYSCALL_ARGS_3(D, D, D);
SYSCALL_FOOTER;
}
SYSCALL_DECLARE(exit_group)
{
SYSCALL_HEADER;
send_syscall(&request);
cpu_local_var(current) = NULL;
cpu_local_var(next) = &cpu_local_var(idle);
schedule();
return 0;
}
SYSCALL_DECLARE(mmap)
{
unsigned long address, ret;
struct vm_regions *region = &cpu_local_var(current)->region;
/* anonymous */
if (aal_mc_syscall_arg3(ctx) & 0x22) {
ret = region->map_end;
address = region->map_end + aal_mc_syscall_arg1(ctx);
region->map_end =
extend_process_region(cpu_local_var(current),
region->map_start,
region->map_end,
address);
if (region->map_end == address) {
return ret;
} else {
return -EINVAL;
}
}
kprintf("Non-anonymous mmap: fd = %lx, %lx\n",
aal_mc_syscall_arg4(ctx), aal_mc_syscall_arg5(ctx));
while(1);
}
SYSCALL_DECLARE(munmap)
{
unsigned long address, len;
address = aal_mc_syscall_arg0(ctx);
len = aal_mc_syscall_arg1(ctx);
return remove_process_region(cpu_local_var(current), address,
address + len);
}
SYSCALL_DECLARE(getpid)
{
return cpu_local_var(current)->pid;
}
long sys_uname(int n, aal_mc_user_context_t *ctx)
{
struct syscall_request request;
unsigned long phys;
if (aal_mc_pt_virt_to_phys(cpu_local_var(current)->page_table,
(void *)aal_mc_syscall_arg0(ctx), &phys)) {
return -EFAULT;
}
request.number = n;
request.args[0] = phys;
return do_syscall(&request);
}
long sys_getxid(int n, aal_mc_user_context_t *ctx)
{
struct syscall_request request;
request.number = n;
return do_syscall(&request);
}
long sys_arch_prctl(int n, aal_mc_user_context_t *ctx)
{
unsigned long code = aal_mc_syscall_arg0(ctx);
unsigned long address = aal_mc_syscall_arg1(ctx);
switch (code) {
case 0x1002:
return aal_mc_arch_set_special_register(AAL_ASR_X86_FS,
address);
case 0x1003:
return aal_mc_arch_get_special_register(AAL_ASR_X86_FS,
(unsigned long *)
address);
}
return -EINVAL;
}
static long (*syscall_table[])(int, aal_mc_user_context_t *) = {
[0] = sys_read,
[1] = sys_write,
[2] = sys_open,
[3] = sys_close,
[5] = sys_fstat,
[8] = sys_lseek,
[9] = sys_mmap,
[11] = sys_munmap,
[12] = sys_brk,
[16] = sys_ioctl,
[17] = sys_pread,
[18] = sys_pwrite,
[39] = sys_getpid,
[63] = sys_uname,
[102] = sys_getxid,
[104] = sys_getxid,
[107] = sys_getxid,
[108] = sys_getxid,
[110] = sys_getxid,
[111] = sys_getxid,
[158] = sys_arch_prctl,
[231] = sys_exit_group,
};
long syscall(int num, aal_mc_user_context_t *ctx)
{
long l;
cpu_enable_interrupt();
if (syscall_table[num]) {
l = syscall_table[num](num, ctx);
return l;
} else {
kprintf("USC[%3d](%lx, %lx, %lx, %lx, %lx) @ %lx | %lx\n", num,
aal_mc_syscall_arg0(ctx), aal_mc_syscall_arg1(ctx),
aal_mc_syscall_arg2(ctx), aal_mc_syscall_arg3(ctx),
aal_mc_syscall_arg4(ctx), aal_mc_syscall_pc(ctx),
aal_mc_syscall_sp(ctx));
while(1);
return -ENOSYS;
}
}