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

Subversion Repositories plasma

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /plasma/trunk
    from Rev 404 to Rev 405
    Reverse comparison

Rev 404 → Rev 405

/kernel/rtos_ex.c
0,0 → 1,164
/*--------------------------------------------------------------------
* TITLE: Plasma Real Time Operating System Extensions
* AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
* DATE CREATED: 12/17/05
* FILENAME: rtos_ex.c
* PROJECT: Plasma CPU core
* COPYRIGHT: Software placed into the public domain by the author.
* Software 'as is' without warranty. Author liable for nothing.
* DESCRIPTION:
* Support simulation under Windows.
* Support simulating multiple CPUs using symmetric multiprocessing.
*--------------------------------------------------------------------*/
#include "plasma.h"
#include "rtos.h"
 
/************** WIN32 Simulation Support *************/
#ifdef WIN32
#undef kbhit
#undef getch
#undef putch
extern int kbhit(void);
extern int getch(void);
extern int putch(int);
unsigned int __stdcall GetCurrentThreadId(void);
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
unsigned int dwCreationFlags, unsigned int *pdwThreadId);
 
#if OS_CPU_COUNT > 1
static unsigned int ThreadId[OS_CPU_COUNT];
 
//PC simulation of multiple CPUs
void OS_InitSimulation(void)
{
 
int i;
ThreadId[0] = GetCurrentThreadId();
for(i = 1; i < OS_CPU_COUNT; ++i)
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OS_Start, NULL, 0, &ThreadId[i]);
}
#endif
 
static uint32 Memory[8];
 
//Simulates device register memory reads
uint32 MemoryRead(uint32 address)
{
Memory[2] |= IRQ_UART_WRITE_AVAILABLE; //IRQ_STATUS
switch(address)
{
case UART_READ:
if(kbhit())
Memory[0] = getch(); //UART_READ
Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
return Memory[0];
case IRQ_MASK:
return Memory[1]; //IRQ_MASK
case IRQ_MASK + 4:
Sleep(10);
return 0;
case IRQ_STATUS:
if(kbhit())
Memory[2] |= IRQ_UART_READ_AVAILABLE;
return Memory[2];
}
return 0;
}
 
//Simulates device register memory writes
void MemoryWrite(uint32 address, uint32 value)
{
switch(address)
{
case UART_WRITE:
putch(value);
break;
case IRQ_MASK:
Memory[1] = value;
break;
case IRQ_STATUS:
Memory[2] = value;
break;
}
}
 
uint32 OS_AsmInterruptEnable(uint32 enableInterrupt)
{
return enableInterrupt;
}
 
void OS_AsmInterruptInit(void)
{
}
#endif //WIN32
 
 
#if OS_CPU_COUNT > 1
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
/******************************************/
uint32 OS_CpuIndex(void)
{
#ifdef WIN32
int i;
unsigned int threadId=GetCurrentThreadId();
for(i = 0; i < OS_CPU_COUNT; ++i)
{
if(threadId == ThreadId[i])
return i;
}
#endif
return 0; //0 to OS_CPU_COUNT-1; Read a CPU specific GPIO value
}
 
 
/******************************************/
//Symmetric Multiprocessing Spin Lock Mutex
uint32 OS_SpinLock(void)
{
uint32 state, cpuIndex, i, ok, delay;
volatile uint32 keepVar;
 
cpuIndex = OS_CpuIndex();
state = OS_AsmInterruptEnable(0); //disable interrupts
if(++SpinLockArray[cpuIndex] > 1) //check for nesting
return state;
delay = (4 + cpuIndex) << 2;
 
//Spin until only this CPU has the spin lock
for(;;)
{
ok = 1;
for(i = 0; i < OS_CPU_COUNT; ++i)
{
if(i != cpuIndex && SpinLockArray[i])
ok = 0; //Another CPU has the spin lock
}
if(ok)
return state;
SpinLockArray[cpuIndex] = 0;
OS_AsmInterruptEnable(state); //re-enable interrupts
for(i = 0; i < delay; ++i) //wait a bit
++ok;
keepVar = ok; //don't optimize away the delay loop
if(delay < 128)
delay <<= 1;
state = OS_AsmInterruptEnable(0); //disable interrupts
SpinLockArray[cpuIndex] = 1;
}
}
 
 
/******************************************/
void OS_SpinUnlock(uint32 state)
{
uint32 cpuIndex;
cpuIndex = OS_CpuIndex();
if(--SpinLockArray[cpuIndex] == 0)
OS_AsmInterruptEnable(state);
 
assert(SpinLockArray[cpuIndex] < 10);
}
#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.