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

Subversion Repositories plasma

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

Only display areas with differences | Details | Blame | View Log

Rev 416 Rev 436
/*--------------------------------------------------------------------
/*--------------------------------------------------------------------
 * 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"
 
#define NO_ELLIPSIS2
#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
 
#else   //NWIN32
 
#include <unistd.h>
 
#define kbhit() 1
 
#define getch getchar
 
#define putch putchar
 
#define Sleep(X) usleep(X*1000)
 
#endif  //WIN32
 
 
 
 
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) {}
void UartInit(void) {}
uint8 UartRead(void) {return getch();}
uint8 UartRead(void) {return getch();}
int OS_kbhit(void) {return kbhit();}
int OS_kbhit(void) {return kbhit();}
void UartPrintf(const char *format,
void UartPrintf(const char *format,
                int arg0, int arg1, int arg2, int arg3,
                int arg0, int arg1, int arg2, int arg3,
                int arg4, int arg5, int arg6, int arg7)
                int arg4, int arg5, int arg6, int arg7)
{
{
   char buffer[256], *ptr = buffer;
   char buffer[256], *ptr = buffer;
 
 
   sprintf(buffer, format, arg0, arg1, arg2, arg3,
   sprintf(buffer, format, arg0, arg1, arg2, arg3,
           arg4, arg5, arg6, arg7);
           arg4, arg5, arg6, arg7);
   while(ptr[0])
   while(ptr[0])
      putchar(*ptr++);
      putchar(*ptr++);
}
}
 
 
#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.