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

Subversion Repositories plasma

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

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
#undef kbhit
19
#undef getch
20
#undef putch
21
extern int kbhit(void);
22
extern int getch(void);
23
extern int putch(int);
24
unsigned int __stdcall GetCurrentThreadId(void);
25
typedef void (*LPTHREAD_START_ROUTINE)(void *lpThreadParameter);
26
void * __stdcall CreateThread(void *lpsa, unsigned int dwStackSize,
27
   LPTHREAD_START_ROUTINE pfnThreadProc, void *pvParam,
28
   unsigned int dwCreationFlags, unsigned int *pdwThreadId);
29
 
30
#if OS_CPU_COUNT > 1
31
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
#endif
43
 
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
   return 0; //0 to OS_CPU_COUNT-1; Read a CPU specific GPIO value
113
}
114
 
115
 
116
/******************************************/
117
//Symmetric Multiprocessing Spin Lock Mutex
118
uint32 OS_SpinLock(void)
119
{
120
   uint32 state, cpuIndex, i, ok, delay;
121
   volatile uint32 keepVar;
122
 
123
   cpuIndex = OS_CpuIndex();
124
   state = OS_AsmInterruptEnable(0);    //disable interrupts
125
   if(++SpinLockArray[cpuIndex] > 1)    //check for nesting
126
      return state;
127
   delay = (4 + cpuIndex) << 2;
128
 
129
   //Spin until only this CPU has the spin lock
130
   for(;;)
131
   {
132
      ok = 1;
133
      for(i = 0; i < OS_CPU_COUNT; ++i)
134
      {
135
         if(i != cpuIndex && SpinLockArray[i])
136
            ok = 0;   //Another CPU has the spin lock
137
      }
138
      if(ok)
139
         return state;
140
      SpinLockArray[cpuIndex] = 0;
141
      OS_AsmInterruptEnable(state);     //re-enable interrupts
142
      for(i = 0; i < delay; ++i)        //wait a bit
143
         ++ok;
144
      keepVar = ok;    //don't optimize away the delay loop
145
      if(delay < 128)
146
         delay <<= 1;
147
      state = OS_AsmInterruptEnable(0); //disable interrupts
148
      SpinLockArray[cpuIndex] = 1;
149
   }
150
}
151
 
152
 
153
/******************************************/
154
void OS_SpinUnlock(uint32 state)
155
{
156
   uint32 cpuIndex;
157
   cpuIndex = OS_CpuIndex();
158
   if(--SpinLockArray[cpuIndex] == 0)
159
      OS_AsmInterruptEnable(state);
160
 
161
   assert(SpinLockArray[cpuIndex] < 10);
162
}
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.