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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [rtos_ex.c] - Diff between revs 407 and 416

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 407 Rev 416
/*--------------------------------------------------------------------
/*--------------------------------------------------------------------
 * TITLE: Plasma Real Time Operating System Extensions
 * TITLE: Plasma Real Time Operating System Extensions
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
 * DATE CREATED: 12/17/05
 * DATE CREATED: 12/17/05
 * FILENAME: rtos_ex.c
 * FILENAME: rtos_ex.c
 * PROJECT: Plasma CPU core
 * PROJECT: Plasma CPU core
 * COPYRIGHT: Software placed into the public domain by the author.
 * COPYRIGHT: Software placed into the public domain by the author.
 *    Software 'as is' without warranty.  Author liable for nothing.
 *    Software 'as is' without warranty.  Author liable for nothing.
 * DESCRIPTION:
 * DESCRIPTION:
 *    Support simulation under Windows.
 *    Support simulation under Windows.
 *    Support simulating multiple CPUs using symmetric multiprocessing.
 *    Support simulating multiple CPUs using symmetric multiprocessing.
 *--------------------------------------------------------------------*/
 *--------------------------------------------------------------------*/
#include "plasma.h"
#include "plasma.h"
#include "rtos.h"
#include "rtos.h"
 
 
/************** WIN32 Simulation Support *************/
/************** WIN32 Simulation Support *************/
#ifdef WIN32
#ifdef WIN32
#include <conio.h>
#include <conio.h>
#define kbhit _kbhit
#define kbhit _kbhit
#define getch _getch
#define getch _getch
#define putch _putch
#define putch _putch
extern void __stdcall Sleep(unsigned long value);
extern void __stdcall Sleep(unsigned long value);
 
 
#if OS_CPU_COUNT > 1
#if OS_CPU_COUNT > 1
unsigned int __stdcall GetCurrentThreadId(void);
unsigned int __stdcall GetCurrentThreadId(void);
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
   LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
   LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
   unsigned int dwCreationFlags, unsigned int *pdwThreadId);
   unsigned int dwCreationFlags, unsigned int *pdwThreadId);
 
 
static unsigned int ThreadId[OS_CPU_COUNT];
static unsigned int ThreadId[OS_CPU_COUNT];
 
 
//PC simulation of multiple CPUs
//PC simulation of multiple CPUs
void OS_InitSimulation(void)
void OS_InitSimulation(void)
{
{
 
 
   int i;
   int i;
   ThreadId[0] = GetCurrentThreadId();
   ThreadId[0] = GetCurrentThreadId();
   for(i = 1; i < OS_CPU_COUNT; ++i)
   for(i = 1; i < OS_CPU_COUNT; ++i)
      CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OS_Start, NULL, 0, &ThreadId[i]);
      CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OS_Start, NULL, 0, &ThreadId[i]);
}
}
#endif  //OS_CPU_COUNT > 1
#endif  //OS_CPU_COUNT > 1
 
 
static uint32 Memory[8];
static uint32 Memory[8];
 
 
//Simulates device register memory reads
//Simulates device register memory reads
uint32 MemoryRead(uint32 address)
uint32 MemoryRead(uint32 address)
{
{
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
   switch(address)
   switch(address)
   {
   {
   case UART_READ:
   case UART_READ:
      if(kbhit())
      if(kbhit())
         Memory[0] = getch();                //UART_READ
         Memory[0] = getch();                //UART_READ
      Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
      Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
      return Memory[0];
      return Memory[0];
   case IRQ_MASK:
   case IRQ_MASK:
      return Memory[1];                      //IRQ_MASK
      return Memory[1];                      //IRQ_MASK
   case IRQ_MASK + 4:
   case IRQ_MASK + 4:
      Sleep(10);
      Sleep(10);
      return 0;
      return 0;
   case IRQ_STATUS:
   case IRQ_STATUS:
      if(kbhit())
      if(kbhit())
         Memory[2] |= IRQ_UART_READ_AVAILABLE;
         Memory[2] |= IRQ_UART_READ_AVAILABLE;
      return Memory[2];
      return Memory[2];
   }
   }
   return 0;
   return 0;
}
}
 
 
//Simulates device register memory writes
//Simulates device register memory writes
void MemoryWrite(uint32 address, uint32 value)
void MemoryWrite(uint32 address, uint32 value)
{
{
   switch(address)
   switch(address)
   {
   {
   case UART_WRITE:
   case UART_WRITE:
      putch(value);
      putch(value);
      break;
      break;
   case IRQ_MASK:
   case IRQ_MASK:
      Memory[1] = value;
      Memory[1] = value;
      break;
      break;
   case IRQ_STATUS:
   case IRQ_STATUS:
      Memory[2] = value;
      Memory[2] = value;
      break;
      break;
   }
   }
}
}
 
 
uint32 OS_AsmInterruptEnable(uint32 enableInterrupt)
uint32 OS_AsmInterruptEnable(uint32 enableInterrupt)
{
{
   return enableInterrupt;
   return enableInterrupt;
}
}
 
 
void OS_AsmInterruptInit(void)
void OS_AsmInterruptInit(void)
{
{
}
}
 
 
 
void UartInit(void) {}
 
uint8 UartRead(void) {return getch();}
 
int OS_kbhit(void) {return kbhit();}
 
void UartPrintf(const char *format,
 
                int arg0, int arg1, int arg2, int arg3,
 
                int arg4, int arg5, int arg6, int arg7)
 
{
 
   char buffer[256], *ptr = buffer;
 
 
 
   sprintf(buffer, format, arg0, arg1, arg2, arg3,
 
           arg4, arg5, arg6, arg7);
 
   while(ptr[0])
 
      putchar(*ptr++);
 
}
 
 
#endif  //WIN32
#endif  //WIN32
 
 
 
 
#if OS_CPU_COUNT > 1
#if OS_CPU_COUNT > 1
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
/******************************************/
/******************************************/
uint32 OS_CpuIndex(void)
uint32 OS_CpuIndex(void)
{
{
#ifdef WIN32
#ifdef WIN32
   int i;
   int i;
   unsigned int threadId=GetCurrentThreadId();
   unsigned int threadId=GetCurrentThreadId();
   for(i = 0; i < OS_CPU_COUNT; ++i)
   for(i = 0; i < OS_CPU_COUNT; ++i)
   {
   {
      if(threadId == ThreadId[i])
      if(threadId == ThreadId[i])
         return i;
         return i;
   }
   }
#endif
#endif
   //return MemoryRead(GPIO_CPU_INDEX);
   //return MemoryRead(GPIO_CPU_INDEX);
   return 0; //0 to OS_CPU_COUNT-1
   return 0; //0 to OS_CPU_COUNT-1
}
}
 
 
 
 
/******************************************/
/******************************************/
//Symmetric Multiprocessing Spin Lock Mutex
//Symmetric Multiprocessing Spin Lock Mutex
uint32 OS_SpinLock(void)
uint32 OS_SpinLock(void)
{
{
   uint32 state, cpuIndex, i, ok, delay;
   uint32 state, cpuIndex, i, ok, delay;
   volatile uint32 keepVar;
   volatile uint32 keepVar;
 
 
   cpuIndex = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   state = OS_AsmInterruptEnable(0);    //disable interrupts
   state = OS_AsmInterruptEnable(0);    //disable interrupts
   if(SpinLockArray[cpuIndex])
   if(SpinLockArray[cpuIndex])
      return (uint32)-1;                //already locked
      return (uint32)-1;                //already locked
   delay = (4 + cpuIndex) << 2;
   delay = (4 + cpuIndex) << 2;
 
 
   //Spin until only this CPU has the spin lock
   //Spin until only this CPU has the spin lock
   for(;;)
   for(;;)
   {
   {
      ok = 1;
      ok = 1;
      SpinLockArray[cpuIndex] = 1;
      SpinLockArray[cpuIndex] = 1;
      for(i = 0; i < OS_CPU_COUNT; ++i)
      for(i = 0; i < OS_CPU_COUNT; ++i)
      {
      {
         if(i != cpuIndex && SpinLockArray[i])
         if(i != cpuIndex && SpinLockArray[i])
            ok = 0;   //Another CPU has the spin lock
            ok = 0;   //Another CPU has the spin lock
      }
      }
      if(ok)
      if(ok)
         return state;
         return state;
      SpinLockArray[cpuIndex] = 0;
      SpinLockArray[cpuIndex] = 0;
      OS_AsmInterruptEnable(state);     //re-enable interrupts
      OS_AsmInterruptEnable(state);     //re-enable interrupts
      for(i = 0; i < delay; ++i)        //wait a bit
      for(i = 0; i < delay; ++i)        //wait a bit
         ++ok;
         ++ok;
      keepVar = ok;    //don't optimize away the delay loop
      keepVar = ok;    //don't optimize away the delay loop
      if(delay < 128)
      if(delay < 128)
         delay <<= 1;
         delay <<= 1;
      state = OS_AsmInterruptEnable(0); //disable interrupts
      state = OS_AsmInterruptEnable(0); //disable interrupts
   }
   }
}
}
 
 
 
 
/******************************************/
/******************************************/
void OS_SpinUnlock(uint32 state)
void OS_SpinUnlock(uint32 state)
{
{
   uint32 cpuIndex;
   uint32 cpuIndex;
   if(state == (uint32)-1)
   if(state == (uint32)-1)
      return;                           //nested lock call
      return;                           //nested lock call
   cpuIndex = OS_CpuIndex();
   cpuIndex = OS_CpuIndex();
   SpinLockArray[cpuIndex] = 0;
   SpinLockArray[cpuIndex] = 0;
}
}
#endif  //OS_CPU_COUNT > 1
#endif  //OS_CPU_COUNT > 1
 
 
 
 

powered by: WebSVN 2.1.0

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