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

Subversion Repositories plasma

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

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 436 rhoads
#define NO_ELLIPSIS2
15 405 rhoads
#include "rtos.h"
16
 
17
/************** WIN32 Simulation Support *************/
18
#ifdef WIN32
19 407 rhoads
#include <conio.h>
20
#define kbhit _kbhit
21
#define getch _getch
22
#define putch _putch
23
extern void __stdcall Sleep(unsigned long value);
24
 
25
#if OS_CPU_COUNT > 1
26 405 rhoads
unsigned int __stdcall GetCurrentThreadId(void);
27
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
28
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
29
   LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
30
   unsigned int dwCreationFlags, unsigned int *pdwThreadId);
31 407 rhoads
 
32 405 rhoads
static unsigned int ThreadId[OS_CPU_COUNT];
33
 
34
//PC simulation of multiple CPUs
35
void OS_InitSimulation(void)
36
{
37
 
38
   int i;
39
   ThreadId[0] = GetCurrentThreadId();
40
   for(i = 1; i < OS_CPU_COUNT; ++i)
41
      CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OS_Start, NULL, 0, &ThreadId[i]);
42
}
43 407 rhoads
#endif  //OS_CPU_COUNT > 1
44 436 rhoads
#else   //NWIN32
45
#include <unistd.h>
46
#define kbhit() 1
47
#define getch getchar
48
#define putch putchar
49
#define Sleep(X) usleep(X*1000)
50
#endif  //WIN32
51 405 rhoads
 
52 436 rhoads
 
53 405 rhoads
static uint32 Memory[8];
54
 
55
//Simulates device register memory reads
56
uint32 MemoryRead(uint32 address)
57
{
58
   Memory[2] |= IRQ_UART_WRITE_AVAILABLE;    //IRQ_STATUS
59
   switch(address)
60
   {
61
   case UART_READ:
62
      if(kbhit())
63
         Memory[0] = getch();                //UART_READ
64
      Memory[2] &= ~IRQ_UART_READ_AVAILABLE; //clear bit
65
      return Memory[0];
66
   case IRQ_MASK:
67
      return Memory[1];                      //IRQ_MASK
68
   case IRQ_MASK + 4:
69
      Sleep(10);
70
      return 0;
71
   case IRQ_STATUS:
72
      if(kbhit())
73
         Memory[2] |= IRQ_UART_READ_AVAILABLE;
74
      return Memory[2];
75
   }
76
   return 0;
77
}
78
 
79
//Simulates device register memory writes
80
void MemoryWrite(uint32 address, uint32 value)
81
{
82
   switch(address)
83
   {
84
   case UART_WRITE:
85
      putch(value);
86
      break;
87
   case IRQ_MASK:
88
      Memory[1] = value;
89
      break;
90
   case IRQ_STATUS:
91
      Memory[2] = value;
92
      break;
93
   }
94
}
95
 
96
uint32 OS_AsmInterruptEnable(uint32 enableInterrupt)
97
{
98
   return enableInterrupt;
99
}
100
 
101
void OS_AsmInterruptInit(void)
102
{
103
}
104 416 rhoads
 
105
void UartInit(void) {}
106
uint8 UartRead(void) {return getch();}
107
int OS_kbhit(void) {return kbhit();}
108
void UartPrintf(const char *format,
109
                int arg0, int arg1, int arg2, int arg3,
110
                int arg4, int arg5, int arg6, int arg7)
111
{
112
   char buffer[256], *ptr = buffer;
113
 
114
   sprintf(buffer, format, arg0, arg1, arg2, arg3,
115
           arg4, arg5, arg6, arg7);
116
   while(ptr[0])
117
      putchar(*ptr++);
118
}
119
 
120 405 rhoads
 
121
#if OS_CPU_COUNT > 1
122
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
123
/******************************************/
124
uint32 OS_CpuIndex(void)
125
{
126
#ifdef WIN32
127
   int i;
128
   unsigned int threadId=GetCurrentThreadId();
129
   for(i = 0; i < OS_CPU_COUNT; ++i)
130
   {
131
      if(threadId == ThreadId[i])
132
         return i;
133
   }
134
#endif
135 407 rhoads
   //return MemoryRead(GPIO_CPU_INDEX);
136
   return 0; //0 to OS_CPU_COUNT-1
137 405 rhoads
}
138
 
139
 
140
/******************************************/
141
//Symmetric Multiprocessing Spin Lock Mutex
142
uint32 OS_SpinLock(void)
143
{
144
   uint32 state, cpuIndex, i, ok, delay;
145
   volatile uint32 keepVar;
146
 
147
   cpuIndex = OS_CpuIndex();
148
   state = OS_AsmInterruptEnable(0);    //disable interrupts
149 407 rhoads
   if(SpinLockArray[cpuIndex])
150
      return (uint32)-1;                //already locked
151 405 rhoads
   delay = (4 + cpuIndex) << 2;
152
 
153
   //Spin until only this CPU has the spin lock
154
   for(;;)
155
   {
156
      ok = 1;
157 407 rhoads
      SpinLockArray[cpuIndex] = 1;
158 405 rhoads
      for(i = 0; i < OS_CPU_COUNT; ++i)
159
      {
160
         if(i != cpuIndex && SpinLockArray[i])
161
            ok = 0;   //Another CPU has the spin lock
162
      }
163
      if(ok)
164
         return state;
165
      SpinLockArray[cpuIndex] = 0;
166
      OS_AsmInterruptEnable(state);     //re-enable interrupts
167
      for(i = 0; i < delay; ++i)        //wait a bit
168
         ++ok;
169
      keepVar = ok;    //don't optimize away the delay loop
170
      if(delay < 128)
171
         delay <<= 1;
172
      state = OS_AsmInterruptEnable(0); //disable interrupts
173
   }
174
}
175
 
176
 
177
/******************************************/
178
void OS_SpinUnlock(uint32 state)
179
{
180
   uint32 cpuIndex;
181 407 rhoads
   if(state == (uint32)-1)
182
      return;                           //nested lock call
183 405 rhoads
   cpuIndex = OS_CpuIndex();
184 407 rhoads
   SpinLockArray[cpuIndex] = 0;
185 405 rhoads
}
186
#endif  //OS_CPU_COUNT > 1
187
 

powered by: WebSVN 2.1.0

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