↑ Back to main site.

EPOS

Experimental Protected-mode Operating System

service.c
/*
EPOS
http://www.atanaslaskov.com/epos/

FILE:          service.c
DESCRIPTION:   Kernel Service Dispatcher

BSD LICENSE
Copyright (c) 2006, Atanas Laskov
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
   1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
   2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "service.h"

#include "..\access\access.h"
#include "..\gdt\gdt.h"
#include "..\memory\memory.h"
#include "..\process\process.h"

#include "specmem\specmem.h"
#include "ports\ports.h"
#include "irq\irq.h"
#include "process\process.h"
#include "ipc\ipc.h"
#include "ipc_thoth\ipc_thoth.h"
#include "sync\sync.h"
#include "mem\mem.h"
#include "..\paging\paging.h"
#include "debug\debug.h"
#include "bios\bios.h"

/*
    Some debug information
*/

unsigned long g_dwLastServiceN=0;
unsigned long g_pidLastService=0;
char g_bCompleted=0;

/*
    Initialization
*/

void srvinit() {
    k_debugInit();
    k_smInit();
    k_portInit();
    k_pInit();
    k_ipcInit();
    k_syInit();
    k_memInit();
    k_thothInit();
}

/*
    Kernel Service Dispatcher ( interrupt 48h )
*/

void kservice(unsigned long nService, void* pLocalArg)
{
    // Extract agrument structure form the data segment
    // of the current process
    void *pArg;

    //
    // Attantion: The commented code is no longer valid.
    // Paging is enabled and we are in the kernel directory.
    // The pointer recived here is in process space.
    //
    // pDescLDTData = gdtGetDescriptorLDT(tmGetCrProcessID(), INDEX_LDT_DATA);
    // gdtFormPointer(pDescLDTData, pLocalArg, &pArg);
    //
   
    pageDirectorySwitch(PAGING_DIR_KERNEL);
   
    // Get process base memory pointer + local argument pointer
    //
    pArg = (void*)(tmGetProcessMembase(
        tmGetCrProcessID()) + (unsigned long)pLocalArg - 0x600
    );
   
    // Remember stuff about this call (for debug usage)
    //
    g_dwLastServiceN = nService;
    g_pidLastService = tmGetCrProcessID();
    g_bCompleted     = 0;

    // Dispatch call
    //
    // NOTE: These calls probably should be distributed
    // to the corresponding sub-systems but it's simpler to just
    // keep them all at one place.
    //
    switch(nService)
    {
    // Specmem
    /*case 0:  smLockArea((struct SMArea*)pArg); break;
    case 1:  smFreeArea((struct SMHandle*)pArg); break;
    case 2:  smPutb((struct SMTransfer*)pArg); break; // obsolete
    case 3:  smGetb((struct SMTransfer*)pArg); break; // obsolete*/


    // Ports
    case 10: pLockPorts((struct PArea*)pArg); break;
    case 11: pFreePorts((struct PHandle*)pArg); break;
    case 12: pPutb((struct PTransfer*)pArg); break; // obsolete
    case 13: pGetb((struct PTransfer*)pArg); break; // obsolete

    // IRQ
    case 20: irqLock((struct IRQ*)pArg); break;
    case 21: irqFree((struct IRQ*)pArg); break;
    case 22: irqLockEx((IRQEX*)pArg); break;

    // Dynamic Memory
    case 30: mAlloc((MALLOC*)pArg); break;
    case 31: mFree((MFREE*)pArg); break;
    case 32: mInfo((MINFO*)pArg); break;

    // Process Management
    case 40:  pCreate((struct PCreate*)pArg); break;
    case 41:  pPut((struct PTransferByte*)pArg); break; // obsolete
    case 42:  pRun((struct PPID*)pArg); break;
    case 43:  pKill((struct PPID*)pArg); break;
    case 44:  pAllocateName((struct PAllocName*)pArg); break;
    case 45:  pFreeName((struct PAllocName*)pArg); break;
    case 46:  pGetKernelLine((struct PHLine*)pArg); break;
    case 47:  pSelfKill(); break;
    case 48:  pInfo((struct PInfo*)pArg); break;
    case 49:  pGetProcessID((struct PPID *)pArg); break;

    // Inter Process Communication
    case 50: ipcOpenLine((struct IPCOpenLine*)pArg); break;
    case 51: ipcGetLineInfo((struct IPCPID*)pArg); break;
    case 52: ipcAcceptOpen((struct IPCHLine*)pArg); break;
    case 53: ipcDenyOpen((struct IPCHLine*)pArg); break;
    case 54: ipcCloseLine((struct IPCHLine*)pArg); break;
    case 55: ipcSend((struct IPCTransfer*)pArg); break;
    case 56: ipcRecive((struct IPCTransfer*)pArg); break;
    case 57: ipcReciveMem((struct IPCTransfer *)pArg); break;
    case 58: ipcReciveB((struct IPCTransfer*)pArg); break;
    case 59: ipcWaitMessage(); break;

    // Process Syncronisation
    case 60: syCreateEvent((struct SYEvent*)pArg); break;
    case 61: syDeleteEvent((struct SYEventHandle*)pArg); break;
    case 62: syWaitEvent((struct SYEvent*)pArg); break;
    case 63: syRaiseEvent((struct SYEventHandle*)pArg);  break;
    case 64: syResetEvent((struct SYEventHandle*)pArg);  break;
    case 65: syGetMiliseconds((struct SYCount*)pArg); break;

    // Debug
    case 70: debugSend(); break;
    case 71: debugDontSend(); break;
    case 72: debugGetOSVersion((OSVER*)pArg); break;
    case 73: debugMemInfo((MEMINFO*)pArg); break;

    // BIOS
    case 80: biosCall((BIOSREGS*)pArg); break;

    // Thoth style IPC
    /*case 90: thothSend((struct ThothMsg*)pArg); break;
    case 91: thothReceive((struct ThothMsg*)pArg); break;
    case 92: thothReply((struct ThothMsg*)pArg); break;*/

    }
   
    g_bCompleted     = 1;
    if(tmGetCharge()) tmirq(7);

    // Don't forget to restore memory mapping for the client process
    //
    pageDirectorySwitch(PAGING_DIR_PROCESS0 + tmGetCrProcessID());
}