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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [rtos_ex.c] - Blame information for rev 407

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 405 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: Plasma Real Time Operating System Extensions
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 12/17/05
5
 * FILENAME: rtos_ex.c
6
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    Support simulation under Windows.
11
 *    Support simulating multiple CPUs using symmetric multiprocessing.
12
 *--------------------------------------------------------------------*/
13
#include "plasma.h"
14
#include "rtos.h"
15
 
16
/************** WIN32 Simulation Support *************/
17
#ifdef WIN32
18 407 rhoads
#include <conio.h>
19
#define kbhit _kbhit
20
#define getch _getch
21
#define putch _putch
22
extern void __stdcall Sleep(unsigned long value);
23
 
24
#if OS_CPU_COUNT > 1
25 405 rhoads
unsigned int __stdcall GetCurrentThreadId(void);
26
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
27
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
28
   LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
29
   unsigned int dwCreationFlags, unsigned int *pdwThreadId);
30 407 rhoads
 
31 405 rhoads
static unsigned int ThreadId[OS_CPU_COUNT];
32
 
33
//PC simulation of multiple CPUs
34
void OS_InitSimulation(void)
35
{
36
 
37
   int i;
38
   ThreadId[0] = GetCurrentThreadId();
39
   for(i = 1; i < OS_CPU_COUNT; ++i)
40
      CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OS_Start, NULL, 0, &ThreadId[i]);
41
}
42 407 rhoads
#endif  //OS_CPU_COUNT > 1
43 405 rhoads
 
44
static uint32 Memory[8];
45
 
46
//Simulates device register memory reads
47
uint32 MemoryRead(uint32 address)
48
{
49
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
50
   switch(address)
51
   {
52
   case UART_READ:
53
      if(kbhit())
54
         Memory[0] = getch();                //UART_READ
55
      Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
56
      return Memory[0];
57
   case IRQ_MASK:
58
      return Memory[1];                      //IRQ_MASK
59
   case IRQ_MASK + 4:
60
      Sleep(10);
61
      return 0;
62
   case IRQ_STATUS:
63
      if(kbhit())
64
         Memory[2] |= IRQ_UART_READ_AVAILABLE;
65
      return Memory[2];
66
   }
67
   return 0;
68
}
69
 
70
//Simulates device register memory writes
71
void MemoryWrite(uint32 address, uint32 value)
72
{
73
   switch(address)
74
   {
75
   case UART_WRITE:
76
      putch(value);
77
      break;
78
   case IRQ_MASK:
79
      Memory[1] = value;
80
      break;
81
   case IRQ_STATUS:
82
      Memory[2] = value;
83
      break;
84
   }
85
}
86
 
87
uint32 OS_AsmInterruptEnable(uint32 enableInterrupt)
88
{
89
   return enableInterrupt;
90
}
91
 
92
void OS_AsmInterruptInit(void)
93
{
94
}
95
#endif  //WIN32
96
 
97
 
98
#if OS_CPU_COUNT > 1
99
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
100
/******************************************/
101
uint32 OS_CpuIndex(void)
102
{
103
#ifdef WIN32
104
   int i;
105
   unsigned int threadId=GetCurrentThreadId();
106
   for(i = 0; i < OS_CPU_COUNT; ++i)
107
   {
108
      if(threadId == ThreadId[i])
109
         return i;
110
   }
111
#endif
112 407 rhoads
   //return MemoryRead(GPIO_CPU_INDEX);
113
   return 0; //0 to OS_CPU_COUNT-1
114 405 rhoads
}
115
 
116
 
117
/******************************************/
118
//Symmetric Multiprocessing Spin Lock Mutex
119
uint32 OS_SpinLock(void)
120
{
121
   uint32 state, cpuIndex, i, ok, delay;
122
   volatile uint32 keepVar;
123
 
124
   cpuIndex = OS_CpuIndex();
125
   state = OS_AsmInterruptEnable(0);    //disable interrupts
126 407 rhoads
   if(SpinLockArray[cpuIndex])
127
      return (uint32)-1;                //already locked
128 405 rhoads
   delay = (4 + cpuIndex) << 2;
129
 
130
   //Spin until only this CPU has the spin lock
131
   for(;;)
132
   {
133
      ok = 1;
134 407 rhoads
      SpinLockArray[cpuIndex] = 1;
135 405 rhoads
      for(i = 0; i < OS_CPU_COUNT; ++i)
136
      {
137
         if(i != cpuIndex && SpinLockArray[i])
138
            ok = 0;   //Another CPU has the spin lock
139
      }
140
      if(ok)
141
         return state;
142
      SpinLockArray[cpuIndex] = 0;
143
      OS_AsmInterruptEnable(state);     //re-enable interrupts
144
      for(i = 0; i < delay; ++i)        //wait a bit
145
         ++ok;
146
      keepVar = ok;    //don't optimize away the delay loop
147
      if(delay < 128)
148
         delay <<= 1;
149
      state = OS_AsmInterruptEnable(0); //disable interrupts
150
   }
151
}
152
 
153
 
154
/******************************************/
155
void OS_SpinUnlock(uint32 state)
156
{
157
   uint32 cpuIndex;
158 407 rhoads
   if(state == (uint32)-1)
159
      return;                           //nested lock call
160 405 rhoads
   cpuIndex = OS_CpuIndex();
161 407 rhoads
   SpinLockArray[cpuIndex] = 0;
162 405 rhoads
}
163
#endif  //OS_CPU_COUNT > 1
164
 

powered by: WebSVN 2.1.0

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