syscall.c (6318B)
1 /* Copyright 1998-1999, Brian J. Swetland. All rights reserved. 2 ** Distributed under the terms of the OpenBLT License 3 */ 4 5 #include <i386/io.h> 6 #include "kernel.h" 7 #include "memory.h" 8 #include "resource.h" 9 #include "boot.h" 10 #include "aspace.h" 11 #include "task.h" 12 #include "smp.h" 13 #include "rights.h" 14 15 #include <blt/syscall_id.h> 16 17 extern task_t *irq_task_map[16]; 18 19 void k_debugger(regs *r, uint32 eip, uint32 cs, uint32 eflags); 20 21 extern int live_tasks; 22 extern int reaper_sem; 23 24 extern boot_dir *bdir; 25 26 /* HACK: sem_release will cause a reschedule which would not be good */ 27 void wake_the_reaper(void) 28 { 29 task_t *task; 30 sem_t *sem = rsrc_find_sem(reaper_sem); 31 sem->count++; 32 if((task = rsrc_dequeue(&sem->rsrc)) != NULL) task_wake(task,ERR_NONE); 33 } 34 35 void terminate(void) 36 { 37 task_t *t = current, *t0; 38 39 //kprintf("Task %X terminated.",current->rsrc.id); 40 live_tasks--; 41 rsrc_enqueue(reaper_queue,current); 42 current->flags = tDEAD; 43 44 /* wake all blocking objects */ 45 while((t0 = list_detach_head(&t->rsrc.queue)) != NULL) 46 task_wake(t0,ERR_RESOURCE); 47 48 wake_the_reaper(); 49 50 swtch(); 51 kprintf("panic: HUH? Back from the dead? %x / %x",t,current); 52 asm("hlt"); 53 } 54 55 void sleep(int ticks) 56 { 57 /* convert from microseconds to 3ms ticks - round up slightly */ 58 ticks = ((ticks + 2000) / 3000); 59 60 if(ticks) { 61 rsrc_enqueue_ordered(timer_queue, current, kernel_timer + ticks); 62 } 63 swtch(); 64 } 65 66 #define p_uint32(n) (esp[n]) 67 #define p_int(n) ((int) esp[n]) 68 #define p_voidptr(n) ((void *) esp[n]) 69 #define p_charptr(n) ((char *) esp[n]) 70 #define p_sizet(n) ((size_t) esp[n]) 71 #define p_pint(n) ((int*) esp[n]) 72 #define p_puint32(n) ((uint32*) esp[n]) 73 74 #define res r.eax 75 int metacall (volatile uint32 *esp); 76 77 void syscall(regs r, volatile uint32 eip, uint32 cs, uint32 eflags, 78 volatile uint32 *esp) 79 { 80 #if 0 81 kprintf("* %d %x #%d@%x",current->rsrc.id,eip,r.eax,(uint32)esp); 82 #endif 83 84 switch(r.eax){ 85 case BLT_SYS_os_terminate : 86 terminate(); 87 break; 88 89 case BLT_SYS_os_console : 90 kprintf("task %X> %s",current->rsrc.id,p_charptr(1)); 91 break; 92 93 case BLT_SYS_os_brk : 94 res = brk(p_uint32(1)); 95 break; 96 97 case BLT_SYS_os_handle_irq : 98 /* thread wants to listen to irq in eax */ 99 if(p_uint32(1) > 0 && p_uint32(1) < 16) { 100 current->irq = p_uint32(1); 101 irq_task_map[p_uint32(1)] = current; 102 }; 103 104 eflags |= 2<<12 | 2<<13; 105 break; 106 107 case BLT_SYS_os_sleep_irq : 108 if(current->irq){ 109 /* sleep */ 110 current->flags = tSLEEP_IRQ; 111 unmask_irq(current->irq); 112 } 113 swtch(); 114 break; 115 116 case BLT_SYS_os_debug : 117 #ifdef __SMP__ 118 if (smp_configured) 119 { 120 config = apic_read (APIC_LVTT); 121 apic_write (APIC_LVTT, config | 0x10000); 122 smp_begun = 0; 123 ipi_all_but_self (IPI_STOP); 124 } 125 #endif 126 k_debugger(&r, eip, cs, eflags); 127 kprintf("bye bye debugger"); 128 129 #ifdef __SMP__ 130 if (smp_configured) 131 { 132 smp_begin (); 133 apic_write (APIC_LVTT, config); 134 } 135 #endif 136 break; 137 138 case BLT_SYS_os_sleep : 139 sleep(p_uint32(1)); 140 break; 141 142 case BLT_SYS_os_identify : 143 res = rsrc_identify(p_uint32(1)); 144 break; 145 146 case BLT_SYS_os_meta : 147 res = metacall(esp); 148 break; 149 150 case BLT_SYS_sem_create : 151 res = sem_create(p_uint32(1),p_charptr(2)); 152 break; 153 154 case BLT_SYS_sem_destroy : 155 res = sem_destroy(p_uint32(1)); 156 break; 157 158 case BLT_SYS_sem_acquire : 159 res = sem_acquire(p_uint32(1)); 160 break; 161 162 case BLT_SYS_sem_release : 163 res = sem_release(p_uint32(1)); 164 break; 165 166 case BLT_SYS_port_create : 167 res = port_create(p_uint32(1),p_charptr(2)); 168 break; 169 170 case BLT_SYS_port_destroy : 171 res = port_destroy(p_uint32(1)); 172 break; 173 174 case BLT_SYS_port_option : 175 res = port_option(p_uint32(1), p_uint32(2), p_uint32(3)); 176 break; 177 178 case BLT_SYS_port_send : 179 res = port_send(p_int(1), p_int(2), p_voidptr(3), p_sizet(4), p_uint32(5)); 180 break; 181 182 case BLT_SYS_port_recv : 183 res = port_recv(p_int(1), p_pint(2), p_voidptr(3), p_sizet(4), p_puint32(5)); 184 break; 185 186 case BLT_SYS_right_create : 187 res = right_create(p_uint32(1), p_uint32(1)); 188 break; 189 190 case BLT_SYS_right_destroy : 191 res = right_destroy(p_uint32(1)); 192 break; 193 194 case BLT_SYS_right_revoke : 195 res = right_revoke(p_uint32(1), p_uint32(2)); 196 break; 197 198 case BLT_SYS_right_grant : 199 res = right_grant(p_uint32(1), p_uint32(2)); 200 break; 201 202 case BLT_SYS_area_create : 203 res = area_create(current->rsrc.owner->aspace, p_uint32(1), p_uint32(2), (void **)p_voidptr(3), p_uint32(4)); 204 break; 205 206 case BLT_SYS_area_clone : 207 res = area_clone(current->rsrc.owner->aspace, p_uint32(1), p_uint32(2), (void **)p_voidptr(3), p_uint32(4)); 208 break; 209 210 case BLT_SYS_area_destroy : 211 res = area_destroy(current->rsrc.owner->aspace, p_uint32(1)); 212 break; 213 214 case BLT_SYS_area_resize : 215 res = area_resize(current->rsrc.owner->aspace, p_uint32(1), p_uint32(2)); 216 break; 217 218 case BLT_SYS_thr_create : { 219 char *name; 220 int i; 221 task_t *t; 222 t = new_thread(current->rsrc.owner, p_uint32(1), 0); 223 if(t) { 224 *((unsigned int *) (t->ustack + 0xfec)) = p_uint32(2); 225 name = p_charptr(3); 226 if (name == NULL) 227 { 228 for(i=0;current->rsrc.name[i] && i<31;i++) { 229 t->rsrc.name[i] = current->rsrc.name[i]; 230 } 231 if(i<30) t->rsrc.name[i++] = '+'; 232 t->rsrc.name[i] = 0; 233 } else { 234 rsrc_set_name((resource_t *)t, name); 235 } 236 res = t->rsrc.id; 237 } else { 238 res = -1; 239 } 240 } 241 break; 242 243 case BLT_SYS_thr_resume : 244 break; 245 246 case BLT_SYS_thr_suspend : 247 break; 248 249 case BLT_SYS_thr_spawn : 250 res = thr_spawn(p_uint32(1), p_uint32(2), 251 p_uint32(3), p_uint32(4), 252 p_uint32(5), p_uint32(6), 253 p_charptr(7)); 254 break; 255 256 case BLT_SYS_thr_kill : 257 break; 258 259 case BLT_SYS_thr_wait : 260 res = thr_wait(p_uint32(1)); 261 break; 262 263 default: 264 res = -1; 265 } 266 } 267 268 int metacall (volatile uint32 *esp) 269 { 270 switch (p_uint32 (0)) 271 { 272 case META_NULL_REQUEST : 273 return 0; 274 275 default: 276 return -1; 277 } 278 } 279