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

Subversion Repositories plasma

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

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 416 rhoads
 
96
void UartInit(void) {}
97
uint8 UartRead(void) {return getch();}
98
int OS_kbhit(void) {return kbhit();}
99
void UartPrintf(const char *format,
100
                int arg0, int arg1, int arg2, int arg3,
101
                int arg4, int arg5, int arg6, int arg7)
102
{
103
   char buffer[256], *ptr = buffer;
104
 
105
   sprintf(buffer, format, arg0, arg1, arg2, arg3,
106
           arg4, arg5, arg6, arg7);
107
   while(ptr[0])
108
      putchar(*ptr++);
109
}
110
 
111 405 rhoads
#endif  //WIN32
112
 
113
 
114
#if OS_CPU_COUNT > 1
115
static volatile uint8 SpinLockArray[OS_CPU_COUNT];
116
/******************************************/
117
uint32 OS_CpuIndex(void)
118
{
119
#ifdef WIN32
120
   int i;
121
   unsigned int threadId=GetCurrentThreadId();
122
   for(i = 0; i < OS_CPU_COUNT; ++i)
123
   {
124
      if(threadId == ThreadId[i])
125
         return i;
126
   }
127
#endif
128 407 rhoads
   //return MemoryRead(GPIO_CPU_INDEX);
129
   return 0; //0 to OS_CPU_COUNT-1
130 405 rhoads
}
131
 
132
 
133
/******************************************/
134
//Symmetric Multiprocessing Spin Lock Mutex
135
uint32 OS_SpinLock(void)
136
{
137
   uint32 state, cpuIndex, i, ok, delay;
138
   volatile uint32 keepVar;
139
 
140
   cpuIndex = OS_CpuIndex();
141
   state = OS_AsmInterruptEnable(0);    //disable interrupts
142 407 rhoads
   if(SpinLockArray[cpuIndex])
143
      return (uint32)-1;                //already locked
144 405 rhoads
   delay = (4 + cpuIndex) << 2;
145
 
146
   //Spin until only this CPU has the spin lock
147
   for(;;)
148
   {
149
      ok = 1;
150 407 rhoads
      SpinLockArray[cpuIndex] = 1;
151 405 rhoads
      for(i = 0; i < OS_CPU_COUNT; ++i)
152
      {
153
         if(i != cpuIndex && SpinLockArray[i])
154
            ok = 0;   //Another CPU has the spin lock
155
      }
156
      if(ok)
157
         return state;
158
      SpinLockArray[cpuIndex] = 0;
159
      OS_AsmInterruptEnable(state);     //re-enable interrupts
160
      for(i = 0; i < delay; ++i)        //wait a bit
161
         ++ok;
162
      keepVar = ok;    //don't optimize away the delay loop
163
      if(delay < 128)
164
         delay <<= 1;
165
      state = OS_AsmInterruptEnable(0); //disable interrupts
166
   }
167
}
168
 
169
 
170
/******************************************/
171
void OS_SpinUnlock(uint32 state)
172
{
173
   uint32 cpuIndex;
174 407 rhoads
   if(state == (uint32)-1)
175
      return;                           //nested lock call
176 405 rhoads
   cpuIndex = OS_CpuIndex();
177 407 rhoads
   SpinLockArray[cpuIndex] = 0;
178 405 rhoads
}
179
#endif  //OS_CPU_COUNT > 1
180
 

powered by: WebSVN 2.1.0

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