openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

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