ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/main_unix.cpp
(Generate patch)

Comparing SheepShaver/src/Unix/main_unix.cpp (file contents):
Revision 1.5 by gbeauche, 2003-05-22T22:12:04Z vs.
Revision 1.14 by gbeauche, 2003-11-10T16:05:52Z

# Line 145 | Line 145
145   const char ROM_FILE_NAME[] = "ROM";
146   const char ROM_FILE_NAME2[] = "Mac OS ROM";
147  
148 < const uint32 ROM_AREA_SIZE = 0x500000;          // Size of ROM area
149 < const uint32 ROM_END = ROM_BASE + ROM_SIZE;     // End of ROM
150 <
151 < const uint32 KERNEL_DATA_BASE = 0x68ffe000;     // Address of Kernel Data
152 < const uint32 KERNEL_DATA2_BASE = 0x5fffe000;    // Alternate address of Kernel Data
153 < const uint32 KERNEL_AREA_SIZE = 0x2000;         // Size of Kernel Data area
154 <
148 > const uint32 RAM_BASE = 0x20000000;                     // Base address of RAM
149   const uint32 SIG_STACK_SIZE = 0x10000;          // Size of signal stack
150  
151  
158 // 68k Emulator Data
159 struct EmulatorData {
160        uint32  v[0x400];      
161 };
162
163
164 // Kernel Data
165 struct KernelData {
166        uint32  v[0x400];
167        EmulatorData ed;
168 };
169
170
152   #if !EMULATED_PPC
153   // Structure in which registers are saved in a signal handler;
154   // sigcontext->regs points to it
# Line 191 | Line 172 | void *TOC;                             // Small data pointer (r13
172   #endif
173   uint32 RAMBase;                 // Base address of Mac RAM
174   uint32 RAMSize;                 // Size of Mac RAM
175 + uint32 SheepStack1Base; // SheepShaver first alternate stack base
176 + uint32 SheepStack2Base; // SheepShaver second alternate stack base
177 + uint32 SheepThunksBase; // SheepShaver thunks base
178   uint32 KernelDataAddr;  // Address of Kernel Data
179   uint32 BootGlobsAddr;   // Address of BootGlobs structure at top of Mac RAM
180   uint32 PVR;                             // Theoretical PVR
# Line 199 | Line 183 | int64 BusClockSpeed;   // Bus clock speed
183  
184  
185   // Global variables
186 < static char *x_display_name = NULL;                     // X11 display name
186 > char *x_display_name = NULL;                            // X11 display name
187   Display *x_display = NULL;                                      // X11 display handle
188  
189   static int zero_fd = 0;                                         // FD of /dev/zero
190 + static bool sheep_area_mapped = false;          // Flag: SheepShaver data area mmap()ed
191   static bool lm_area_mapped = false;                     // Flag: Low Memory area mmap()ped
192   static int kernel_area = -1;                            // SHM ID of Kernel Data area
193   static bool rom_area_mapped = false;            // Flag: Mac ROM mmap()ped
194   static bool ram_area_mapped = false;            // Flag: Mac RAM mmap()ped
210 static void *mmap_RAMBase = NULL;                       // Base address of mmap()ed RAM area
195   static KernelData *kernel_data;                         // Pointer to Kernel Data
196   static EmulatorData *emulator_data;
197  
# Line 222 | Line 206 | static pthread_t emul_thread;                          // MacO
206   static bool ready_for_signals = false;          // Handler installed, signals can be sent
207   static int64 num_segv = 0;                                      // Number of handled SEGV signals
208  
225 #if !EMULATED_PPC
209   static struct sigaction sigusr2_action;         // Interrupt signal (of emulator thread)
210 + #if !EMULATED_PPC
211   static struct sigaction sigsegv_action;         // Data access exception signal (of emulator thread)
212   static struct sigaction sigill_action;          // Illegal instruction signal (of emulator thread)
213   static void *sig_stack = NULL;                          // Stack for signal handlers
# Line 238 | Line 222 | static void Quit(void);
222   static void *emul_func(void *arg);
223   static void *nvram_func(void *arg);
224   static void *tick_func(void *arg);
225 < #if !EMULATED_PPC
225 > #if EMULATED_PPC
226 > static void sigusr2_handler(int sig);
227 > extern void emul_ppc(uint32 start);
228 > extern void init_emul_ppc(void);
229 > extern void exit_emul_ppc(void);
230 > #else
231   static void sigusr2_handler(int sig, sigcontext_struct *sc);
232   static void sigsegv_handler(int sig, sigcontext_struct *sc);
233   static void sigill_handler(int sig, sigcontext_struct *sc);
# Line 246 | Line 235 | static void sigill_handler(int sig, sigc
235  
236  
237   // From asm_linux.S
238 < #if EMULATED_PPC
250 < extern int atomic_add(int *var, int v);
251 < extern int atomic_and(int *var, int v);
252 < extern int atomic_or(int *var, int v);
253 < #else
238 > #if !EMULATED_PPC
239   extern "C" void *get_toc(void);
240   extern "C" void *get_sp(void);
241   extern "C" void flush_icache_range(void *start, void *end);
# Line 265 | Line 250 | extern void paranoia_check(void);
250   #endif
251  
252  
253 + #if EMULATED_PPC
254 + /*
255 + *  Atomic operations
256 + */
257 +
258 + #if HAVE_SPINLOCKS
259 + static spinlock_t atomic_ops_lock = SPIN_LOCK_UNLOCKED;
260 + #else
261 + #define spin_lock(LOCK)
262 + #define spin_unlock(LOCK)
263 + #endif
264 +
265 + int atomic_add(int *var, int v)
266 + {
267 +        spin_lock(&atomic_ops_lock);
268 +        int ret = *var;
269 +        *var += v;
270 +        spin_unlock(&atomic_ops_lock);
271 +        return ret;
272 + }
273 +
274 + int atomic_and(int *var, int v)
275 + {
276 +        spin_lock(&atomic_ops_lock);
277 +        int ret = *var;
278 +        *var &= v;
279 +        spin_unlock(&atomic_ops_lock);
280 +        return ret;
281 + }
282 +
283 + int atomic_or(int *var, int v)
284 + {
285 +        spin_lock(&atomic_ops_lock);
286 +        int ret = *var;
287 +        *var |= v;
288 +        spin_unlock(&atomic_ops_lock);
289 +        return ret;
290 + }
291 + #endif
292 +
293 +
294   /*
295   *  Main program
296   */
# Line 283 | Line 309 | int main(int argc, char **argv)
309          char str[256];
310          uint32 *boot_globs;
311          int16 i16;
286        int drive, driver;
312          int rom_fd;
313          FILE *proc_file;
314          const char *rom_path;
# Line 293 | Line 318 | int main(int argc, char **argv)
318  
319          // Initialize variables
320          RAMBase = 0;
296        mmap_RAMBase = NULL;
321          tzset();
322  
323          // Print some info
# Line 451 | Line 475 | int main(int argc, char **argv)
475          KernelDataAddr = (uint32)kernel_data;
476          D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data));
477  
478 +        // Create area for SheepShaver data
479 +        if (vm_acquire_fixed((char *)SHEEP_BASE, SHEEP_SIZE) < 0) {
480 +                sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
481 +                ErrorAlert(str);
482 +                goto quit;
483 +        }
484 +        SheepStack1Base = SHEEP_BASE + 0x10000;
485 +        SheepStack2Base = SheepStack1Base + 0x10000;
486 +        SheepThunksBase = SheepStack2Base + 0x1000;
487 +        sheep_area_mapped = true;
488 +
489          // Create area for Mac ROM
490          if (vm_acquire_fixed((char *)ROM_BASE, ROM_AREA_SIZE) < 0) {
491                  sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
492                  ErrorAlert(str);
493                  goto quit;
494          }
495 < #if !EMULATED_PPC
495 > #if !EMULATED_PPC || defined(__powerpc__)
496          if (vm_protect((char *)ROM_BASE, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
497                  sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
498                  ErrorAlert(str);
# Line 474 | Line 509 | int main(int argc, char **argv)
509                  RAMSize = 8*1024*1024;
510          }
511  
512 <        mmap_RAMBase = (void *)0x20000000;
478 <        if (vm_acquire_fixed(mmap_RAMBase, RAMSize) < 0) {
512 >        if (vm_acquire_fixed((char *)RAM_BASE, RAMSize) < 0) {
513                  sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
514                  ErrorAlert(str);
515                  goto quit;
516          }
517   #if !EMULATED_PPC
518 <        if (vm_protect(mmap_RAMBase, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
518 >        if (vm_protect((char *)RAM_BASE, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
519                  sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
520                  ErrorAlert(str);
521                  goto quit;
522          }
523   #endif
524 <        RAMBase = (uint32)mmap_RAMBase;
524 >        RAMBase = RAM_BASE;
525          ram_area_mapped = true;
526          D(bug("RAM area at %08x\n", RAMBase));
527  
# Line 529 | Line 563 | int main(int argc, char **argv)
563          XPRAMInit();
564  
565          // Set boot volume
566 <        drive = PrefsFindInt32("bootdrive");
566 >        i16 = PrefsFindInt32("bootdrive");
567          XPRAM[0x1378] = i16 >> 8;
568          XPRAM[0x1379] = i16 & 0xff;
569 <        driver = PrefsFindInt32("bootdriver");
569 >        i16 = PrefsFindInt32("bootdriver");
570          XPRAM[0x137a] = i16 >> 8;
571          XPRAM[0x137b] = i16 & 0xff;
572  
# Line 637 | Line 671 | int main(int argc, char **argv)
671          WriteMacInt32(XLM_PVR, PVR);                                                                    // Theoretical PVR
672          WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed);                                    // For DriverServicesLib patch
673          WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN);                // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
674 < #if !EMULATED_PPC
674 > #if EMULATED_PPC
675 >        WriteMacInt32(XLM_ETHER_INIT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_INIT));
676 >        WriteMacInt32(XLM_ETHER_TERM, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_TERM));
677 >        WriteMacInt32(XLM_ETHER_OPEN, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_OPEN));
678 >        WriteMacInt32(XLM_ETHER_CLOSE, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_CLOSE));
679 >        WriteMacInt32(XLM_ETHER_WPUT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_WPUT));
680 >        WriteMacInt32(XLM_ETHER_RSRV, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_RSRV));
681 >        WriteMacInt32(XLM_VIDEO_DOIO, POWERPC_NATIVE_OP_FUNC(NATIVE_VIDEO_DO_DRIVER_IO));
682 > #else
683          WriteMacInt32(XLM_TOC, (uint32)TOC);                                                    // TOC pointer of emulator
684          WriteMacInt32(XLM_ETHER_INIT, (uint32)InitStreamModule);                // DLPI ethernet driver functions
685          WriteMacInt32(XLM_ETHER_TERM, (uint32)TerminateStreamModule);
# Line 707 | Line 749 | int main(int argc, char **argv)
749                  ErrorAlert(str);
750                  goto quit;
751          }
752 + #endif
753  
754          // Install interrupt signal handler
755          sigemptyset(&sigusr2_action.sa_mask);
756          sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler;
757 +        sigusr2_action.sa_flags = 0;
758 + #if !EMULATED_PPC
759          sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
760 + #endif
761          sigusr2_action.sa_restorer = NULL;
762          if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) {
763                  sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
764                  ErrorAlert(str);
765                  goto quit;
766          }
721 #endif
767  
768          // Get my thread ID and execute MacOS thread function
769          emul_thread = pthread_self();
# Line 737 | Line 782 | quit:
782  
783   static void Quit(void)
784   {
785 + #if EMULATED_PPC
786 +        // Exit PowerPC emulation
787 +        exit_emul_ppc();
788 + #endif
789 +
790          // Stop 60Hz thread
791          if (tick_thread_active) {
792                  pthread_cancel(tick_thread);
# Line 795 | Line 845 | static void Quit(void)
845  
846          // Delete RAM area
847          if (ram_area_mapped)
848 <                vm_release(mmap_RAMBase, RAMSize);
848 >                vm_release((char *)RAM_BASE, RAMSize);
849  
850          // Delete ROM area
851          if (rom_area_mapped)
# Line 840 | Line 890 | static void Quit(void)
890   */
891  
892   #if EMULATED_PPC
843 extern void emul_ppc(uint32 start);
844 extern void init_emul_ppc(void);
893   void jump_to_rom(uint32 entry)
894   {
895          init_emul_ppc();
# Line 906 | Line 954 | void Execute68kTrap(uint16 trap, M68kReg
954          uint16 proc[2] = {trap, M68K_RTS};
955          Execute68k((uint32)proc, r);
956   }
909 #endif
957  
958  
959   /*
# Line 920 | Line 967 | void ExecutePPC(void (*func)())
967          M68kRegisters r;
968          Execute68k((uint32)&desc, &r);
969   }
970 + #endif
971  
972  
973   /*
# Line 981 | Line 1029 | void Dump68kRegs(M68kRegisters *r)
1029  
1030   void MakeExecutable(int dummy, void *start, uint32 length)
1031   {
1032 < #if !EMULATED_PPC
985 <        if (((uint32)start >= ROM_BASE) && ((uint32)start < (ROM_BASE + ROM_SIZE)))
1032 >        if (((uintptr)start >= ROM_BASE) && ((uintptr)start < (ROM_BASE + ROM_SIZE)))
1033                  return;
1034 <        flush_icache_range(start, (void *)((uint32)start + length));
1034 > #if EMULATED_PPC
1035 >        FlushCodeCache((uintptr)start, (uintptr)start + length);
1036 > #else
1037 >        flush_icache_range(start, (void *)((uintptr)start + length));
1038   #endif
1039   }
1040  
# Line 995 | Line 1045 | void MakeExecutable(int dummy, void *sta
1045  
1046   void PatchAfterStartup(void)
1047   {
1048 + #if EMULATED_PPC
1049 +        ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
1050 + #else
1051          ExecutePPC(VideoInstallAccel);
1052 + #endif
1053          InstallExtFS();
1054   }
1055  
# Line 1098 | Line 1152 | static void *tick_func(void *arg)
1152  
1153   void Set_pthread_attr(pthread_attr_t *attr, int priority)
1154   {
1155 <        // nothing to do
1155 > #ifdef HAVE_PTHREADS
1156 >        pthread_attr_init(attr);
1157 > #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
1158 >        // Some of these only work for superuser
1159 >        if (geteuid() == 0) {
1160 >                pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
1161 >                pthread_attr_setschedpolicy(attr, SCHED_FIFO);
1162 >                struct sched_param fifo_param;
1163 >                fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) +
1164 >                                              sched_get_priority_max(SCHED_FIFO)) / 2 +
1165 >                                             priority);
1166 >                pthread_attr_setschedparam(attr, &fifo_param);
1167 >        }
1168 >        if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) {
1169 > #ifdef PTHREAD_SCOPE_BOUND_NP
1170 >            // If system scope is not available (eg. we're not running
1171 >            // with CAP_SCHED_MGT capability on an SGI box), try bound
1172 >            // scope.  It exposes pthread scheduling to the kernel,
1173 >            // without setting realtime priority.
1174 >            pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP);
1175 > #endif
1176 >        }
1177 > #endif
1178 > #endif
1179   }
1180  
1181  
# Line 1106 | Line 1183 | void Set_pthread_attr(pthread_attr_t *at
1183   *  Mutexes
1184   */
1185  
1186 + #ifdef HAVE_PTHREADS
1187 +
1188 + struct B2_mutex {
1189 +        B2_mutex() {
1190 +            pthread_mutexattr_t attr;
1191 +            pthread_mutexattr_init(&attr);
1192 +            // Initialize the mutex for priority inheritance --
1193 +            // required for accurate timing.
1194 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
1195 +            pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
1196 + #endif
1197 + #if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
1198 +            pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
1199 + #endif
1200 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
1201 +            pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
1202 + #endif
1203 +            pthread_mutex_init(&m, &attr);
1204 +            pthread_mutexattr_destroy(&attr);
1205 +        }
1206 +        ~B2_mutex() {
1207 +            pthread_mutex_trylock(&m); // Make sure it's locked before
1208 +            pthread_mutex_unlock(&m);  // unlocking it.
1209 +            pthread_mutex_destroy(&m);
1210 +        }
1211 +        pthread_mutex_t m;
1212 + };
1213 +
1214 + B2_mutex *B2_create_mutex(void)
1215 + {
1216 +        return new B2_mutex;
1217 + }
1218 +
1219 + void B2_lock_mutex(B2_mutex *mutex)
1220 + {
1221 +        pthread_mutex_lock(&mutex->m);
1222 + }
1223 +
1224 + void B2_unlock_mutex(B2_mutex *mutex)
1225 + {
1226 +        pthread_mutex_unlock(&mutex->m);
1227 + }
1228 +
1229 + void B2_delete_mutex(B2_mutex *mutex)
1230 + {
1231 +        delete mutex;
1232 + }
1233 +
1234 + #else
1235 +
1236   struct B2_mutex {
1237          int dummy;
1238   };
# Line 1128 | Line 1255 | void B2_delete_mutex(B2_mutex *mutex)
1255          delete mutex;
1256   }
1257  
1258 + #endif
1259 +
1260  
1261   /*
1262   *  Trigger signal USR2 from another thread
1263   */
1264  
1265 + #if !EMULATED_PPC || ASYNC_IRQ
1266   void TriggerInterrupt(void)
1267   {
1138 #if EMULATED_PPC
1139        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1140 #else
1141 #if 0
1142        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1143 #else
1268          if (ready_for_signals)
1269                  pthread_kill(emul_thread, SIGUSR2);
1146 #endif
1147 #endif
1270   }
1271 + #endif
1272  
1273  
1274   /*
# Line 1185 | Line 1308 | void EnableInterrupt(void)
1308   }
1309  
1310  
1188 #if !EMULATED_PPC
1311   /*
1312   *  USR2 handler
1313   */
1314  
1315 + #if EMULATED_PPC
1316 + static void sigusr2_handler(int sig)
1317 + {
1318 + #if ASYNC_IRQ
1319 +        extern void HandleInterrupt(void);
1320 +        HandleInterrupt();
1321 + #endif
1322 + }
1323 + #else
1324   static void sigusr2_handler(int sig, sigcontext_struct *sc)
1325   {
1326          pt_regs *r = sc->regs;
# Line 1271 | Line 1402 | static void sigusr2_handler(int sig, sig
1402                          }
1403                          break;
1404   #endif
1274
1405          }
1406   }
1407 + #endif
1408  
1409  
1410   /*
1411   *  SIGSEGV handler
1412   */
1413  
1414 + #if !EMULATED_PPC
1415   static void sigsegv_handler(int sig, sigcontext_struct *sc)
1416   {
1417          pt_regs *r = sc->regs;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines