OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [glue/] [arm/] [systable.c] - Blame information for rev 5

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * System Calls
3
 *
4
 * Copyright (C) 2007 Bahadir Balban
5
 */
6
#include <l4/lib/mutex.h>
7
#include <l4/lib/printk.h>
8
#include <l4/generic/space.h>
9
#include <l4/generic/scheduler.h>
10
#include <l4/generic/debug.h>
11
#include <l4/generic/tcb.h>
12
#include <l4/api/errno.h>
13
#include INC_GLUE(memlayout.h)
14
#include INC_GLUE(syscall.h)
15
#include INC_GLUE(mapping.h)
16
#include INC_GLUE(debug.h)
17
#include INC_SUBARCH(mm.h)
18
#include INC_SUBARCH(perfmon.h)
19
#include INC_API(syscall.h)
20
#include INC_API(kip.h)
21
 
22
void kip_init_syscalls(void)
23
{
24
        kip.irq_control = ARM_SYSCALL_PAGE + sys_irq_control_offset;
25
        kip.thread_control = ARM_SYSCALL_PAGE + sys_thread_control_offset;
26
        kip.ipc_control = ARM_SYSCALL_PAGE + sys_ipc_control_offset;
27
        kip.map = ARM_SYSCALL_PAGE + sys_map_offset;
28
        kip.ipc = ARM_SYSCALL_PAGE + sys_ipc_offset;
29
        kip.capability_control = ARM_SYSCALL_PAGE + sys_capability_control_offset;
30
        kip.unmap = ARM_SYSCALL_PAGE + sys_unmap_offset;
31
        kip.exchange_registers = ARM_SYSCALL_PAGE + sys_exchange_registers_offset;
32
        kip.thread_switch = ARM_SYSCALL_PAGE + sys_thread_switch_offset;
33
        kip.schedule = ARM_SYSCALL_PAGE + sys_schedule_offset;
34
        kip.getid = ARM_SYSCALL_PAGE + sys_getid_offset;
35
        kip.container_control = ARM_SYSCALL_PAGE + sys_container_control_offset;
36
        kip.time = ARM_SYSCALL_PAGE + sys_time_offset;
37
        kip.mutex_control = ARM_SYSCALL_PAGE + sys_mutex_control_offset;
38
        kip.cache_control = ARM_SYSCALL_PAGE + sys_cache_control_offset;
39
}
40
 
41
/* Jump table for all system calls. */
42
syscall_fn_t syscall_table[SYSCALLS_TOTAL];
43
 
44
 
45
int arch_sys_ipc(syscall_context_t *regs)
46
{
47
        return sys_ipc((l4id_t)regs->r0, (l4id_t)regs->r1,
48
                       (unsigned int)regs->r2);
49
}
50
 
51
int arch_sys_thread_switch(syscall_context_t *regs)
52
{
53
        return sys_thread_switch();
54
}
55
 
56
int arch_sys_thread_control(syscall_context_t *regs)
57
{
58
        return sys_thread_control((unsigned int)regs->r0,
59
                                  (struct task_ids *)regs->r1);
60
}
61
 
62
int arch_sys_exchange_registers(syscall_context_t *regs)
63
{
64
        return sys_exchange_registers((struct exregs_data *)regs->r0,
65
                                      (l4id_t)regs->r1);
66
}
67
 
68
int arch_sys_schedule(syscall_context_t *regs)
69
{
70
        return sys_schedule();
71
}
72
 
73
int arch_sys_getid(syscall_context_t *regs)
74
{
75
        return sys_getid((struct task_ids *)regs->r0);
76
}
77
 
78
int arch_sys_unmap(syscall_context_t *regs)
79
{
80
        return sys_unmap((unsigned long)regs->r0, (unsigned long)regs->r1,
81
                         (unsigned int)regs->r2);
82
}
83
 
84
int arch_sys_irq_control(syscall_context_t *regs)
85
{
86
        return sys_irq_control((unsigned int)regs->r0,
87
                               (unsigned int)regs->r1,
88
                               (l4id_t)regs->r2);
89
}
90
 
91
int arch_sys_ipc_control(syscall_context_t *regs)
92
{
93
        return sys_ipc_control();
94
}
95
 
96
int arch_sys_map(syscall_context_t *regs)
97
{
98
        return sys_map((unsigned long)regs->r0, (unsigned long)regs->r1,
99
                       (unsigned long)regs->r2, (unsigned long)regs->r3,
100
                       (l4id_t)regs->r4);
101
}
102
 
103
int arch_sys_capability_control(syscall_context_t *regs)
104
{
105
        return sys_capability_control((unsigned int)regs->r0,
106
                                      (unsigned int)regs->r1,
107
                                      (void *)regs->r2);
108
}
109
 
110
int arch_sys_container_control(syscall_context_t *regs)
111
{
112
        return sys_container_control((unsigned int)regs->r0,
113
                                     (unsigned int)regs->r1,
114
                                     (void *)regs->r2);
115
}
116
 
117
int arch_sys_time(syscall_context_t *regs)
118
{
119
        return sys_time((struct timeval *)regs->r0, (int)regs->r1);
120
}
121
 
122
int arch_sys_mutex_control(syscall_context_t *regs)
123
{
124
        return sys_mutex_control((unsigned long)regs->r0, (int)regs->r1);
125
}
126
 
127
int arch_sys_cache_control(syscall_context_t *regs)
128
{
129
        return sys_cache_control((unsigned long)regs->r0,
130
                                 (unsigned long)regs->r1,
131
                                 (unsigned int)regs->r2);
132
}
133
 
134
/*
135
 * Initialises the system call jump table, for kernel to use.
136
 * Also maps the system call page into userspace.
137
 */
138
void syscall_init()
139
{
140
        syscall_table[sys_ipc_offset >> 2]                      = (syscall_fn_t)arch_sys_ipc;
141
        syscall_table[sys_thread_switch_offset >> 2]            = (syscall_fn_t)arch_sys_thread_switch;
142
        syscall_table[sys_thread_control_offset >> 2]           = (syscall_fn_t)arch_sys_thread_control;
143
        syscall_table[sys_exchange_registers_offset >> 2]       = (syscall_fn_t)arch_sys_exchange_registers;
144
        syscall_table[sys_schedule_offset >> 2]                 = (syscall_fn_t)arch_sys_schedule;
145
        syscall_table[sys_getid_offset >> 2]                    = (syscall_fn_t)arch_sys_getid;
146
        syscall_table[sys_unmap_offset >> 2]                    = (syscall_fn_t)arch_sys_unmap;
147
        syscall_table[sys_irq_control_offset >> 2]              = (syscall_fn_t)arch_sys_irq_control;
148
        syscall_table[sys_ipc_control_offset >> 2]              = (syscall_fn_t)arch_sys_ipc_control;
149
        syscall_table[sys_map_offset >> 2]                      = (syscall_fn_t)arch_sys_map;
150
        syscall_table[sys_capability_control_offset >> 2]       = (syscall_fn_t)arch_sys_capability_control;
151
        syscall_table[sys_container_control_offset >> 2]        = (syscall_fn_t)arch_sys_container_control;
152
        syscall_table[sys_time_offset >> 2]                     = (syscall_fn_t)arch_sys_time;
153
        syscall_table[sys_mutex_control_offset >> 2]            = (syscall_fn_t)arch_sys_mutex_control;
154
        syscall_table[sys_cache_control_offset >> 2]            = (syscall_fn_t)arch_sys_cache_control;
155
 
156
        add_boot_mapping(virt_to_phys(&__syscall_page_start),
157
                         ARM_SYSCALL_PAGE, PAGE_SIZE, MAP_USR_RX);
158
}
159
 
160
/* Checks a syscall is legitimate and dispatches to appropriate handler. */
161
int syscall(syscall_context_t *regs, unsigned long swi_addr)
162
{
163
        int ret = 0;
164
 
165
        /* Check if genuine system call, coming from the syscall page */
166
        if ((swi_addr & ARM_SYSCALL_PAGE) == ARM_SYSCALL_PAGE) {
167
                /* Check within syscall offset boundary */
168
                if (((swi_addr & syscall_offset_mask) >= 0) &&
169
                    ((swi_addr & syscall_offset_mask) <= syscalls_end_offset)) {
170
 
171
                        /* Do system call accounting, if enabled */
172
                        system_account_syscall();
173
                        system_account_syscall_type(swi_addr);
174
 
175
                        /* Start measure syscall timing, if enabled */
176
                        system_measure_syscall_start();
177
 
178
                        /* Quick jump, rather than compare each */
179
                        ret = (*syscall_table[(swi_addr & 0xFF) >> 2])(regs);
180
 
181
                        /* End measure syscall timing, if enabled */
182
                        system_measure_syscall_end(swi_addr);
183
 
184
                } else {
185
                        printk("System call received from call @ 0x%lx."
186
                               "Instruction: 0x%lx.\n", swi_addr,
187
                               *((unsigned long *)swi_addr));
188
                        return -ENOSYS;
189
                }
190
        } else {
191
                printk("System call exception from unknown location 0x%lx."
192
                       "Discarding.\n", swi_addr);
193
                return -ENOSYS;
194
        }
195
 
196
        if (current->flags & TASK_SUSPENDING) {
197
                BUG_ON(current->nlocks);
198
                sched_suspend_sync();
199
        }
200
 
201
        return ret;
202
}
203
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.