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.3 by gbeauche, 2002-04-21T15:07:08Z vs.
Revision 1.8 by gbeauche, 2003-09-29T15:46:07Z

# Line 107 | Line 107
107   #include "macos_util.h"
108   #include "rom_patches.h"
109   #include "user_strings.h"
110 + #include "vm_alloc.h"
111 + #include "sigsegv.h"
112  
113   #define DEBUG 0
114   #include "debug.h"
# Line 143 | 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
147 < const uint32 ROM_END = ROM_BASE + ROM_SIZE;     // End of ROM
148 <
149 < const uint32 KERNEL_DATA_BASE = 0x68ffe000;     // Address of Kernel Data
150 < const uint32 KERNEL_DATA2_BASE = 0x5fffe000;    // Alternate address of Kernel Data
151 < const uint32 KERNEL_AREA_SIZE = 0x2000;         // Size of Kernel Data area
152 <
148 > const uint32 RAM_BASE = 0x20000000;                     // Base address of RAM
149   const uint32 SIG_STACK_SIZE = 0x10000;          // Size of signal stack
150  
151  
156 // 68k Emulator Data
157 struct EmulatorData {
158        uint32  v[0x400];      
159 };
160
161
162 // Kernel Data
163 struct KernelData {
164        uint32  v[0x400];
165        EmulatorData ed;
166 };
167
168
152   #if !EMULATED_PPC
153   // Structure in which registers are saved in a signal handler;
154   // sigcontext->regs points to it
# Line 189 | 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 201 | Line 187 | static char *x_display_name = NULL;                    //
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
208 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 220 | 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  
223 #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 236 | 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 > #else
228   static void sigusr2_handler(int sig, sigcontext_struct *sc);
229   static void sigsegv_handler(int sig, sigcontext_struct *sc);
230   static void sigill_handler(int sig, sigcontext_struct *sc);
# Line 291 | Line 279 | int main(int argc, char **argv)
279  
280          // Initialize variables
281          RAMBase = 0;
294        mmap_RAMBase = NULL;
282          tzset();
283  
284          // Print some info
# Line 420 | Line 407 | int main(int argc, char **argv)
407          }
408  
409          // Create Low Memory area (0x0000..0x3000)
410 <        if (mmap((char *)0x0000, 0x3000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) == (void *)-1) {
410 >        if (vm_acquire_fixed((char *)0, 0x3000) < 0) {
411                  sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
412                  ErrorAlert(str);
413                  goto quit;
# Line 449 | Line 436 | int main(int argc, char **argv)
436          KernelDataAddr = (uint32)kernel_data;
437          D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data));
438  
439 +        // Create area for SheepShaver data
440 +        if (vm_acquire_fixed((char *)SHEEP_BASE, SHEEP_SIZE) < 0) {
441 +                sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
442 +                ErrorAlert(str);
443 +                goto quit;
444 +        }
445 +        SheepStack1Base = SHEEP_BASE + 0x10000;
446 +        SheepStack2Base = SheepStack1Base + 0x10000;
447 +        SheepThunksBase = SheepStack2Base + 0x1000;
448 +        sheep_area_mapped = true;
449 +
450          // Create area for Mac ROM
451 <        if (mmap((char *)ROM_BASE, ROM_AREA_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0) == (void *)-1) {
451 >        if (vm_acquire_fixed((char *)ROM_BASE, ROM_AREA_SIZE) < 0) {
452 >                sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
453 >                ErrorAlert(str);
454 >                goto quit;
455 >        }
456 > #if !EMULATED_PPC || defined(__powerpc__)
457 >        if (vm_protect((char *)ROM_BASE, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
458                  sprintf(str, GetString(STR_ROM_MMAP_ERR), strerror(errno));
459                  ErrorAlert(str);
460                  goto quit;
461          }
462 + #endif
463          rom_area_mapped = true;
464          D(bug("ROM area at %08x\n", ROM_BASE));
465  
# Line 465 | Line 470 | int main(int argc, char **argv)
470                  RAMSize = 8*1024*1024;
471          }
472  
473 <        mmap_RAMBase = mmap((void *)0x20000000, RAMSize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, zero_fd, 0);
469 <        if (mmap_RAMBase == (void *)-1) {
473 >        if (vm_acquire_fixed((char *)RAM_BASE, RAMSize) < 0) {
474                  sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
475                  ErrorAlert(str);
476                  goto quit;
477          }
478 <        RAMBase = (uint32)mmap_RAMBase;
478 > #if !EMULATED_PPC
479 >        if (vm_protect((char *)RAM_BASE, RAMSize, VM_PAGE_READ | VM_PAGE_WRITE | VM_PAGE_EXECUTE) < 0) {
480 >                sprintf(str, GetString(STR_RAM_MMAP_ERR), strerror(errno));
481 >                ErrorAlert(str);
482 >                goto quit;
483 >        }
484 > #endif
485 >        RAMBase = RAM_BASE;
486          ram_area_mapped = true;
487          D(bug("RAM area at %08x\n", RAMBase));
488  
# Line 567 | Line 578 | int main(int argc, char **argv)
578   #if !EMULATED_PPC
579          MakeExecutable(0, (void *)ROM_BASE, ROM_AREA_SIZE);
580   #endif
581 <        mprotect((char *)ROM_BASE, ROM_AREA_SIZE, PROT_EXEC | PROT_READ);
581 >        vm_protect((char *)ROM_BASE, ROM_AREA_SIZE, VM_PAGE_READ | VM_PAGE_EXECUTE);
582  
583          // Initialize Kernel Data
584          memset(kernel_data, 0, sizeof(KernelData));
# Line 621 | Line 632 | int main(int argc, char **argv)
632          WriteMacInt32(XLM_PVR, PVR);                                                                    // Theoretical PVR
633          WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed);                                    // For DriverServicesLib patch
634          WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN);                // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
635 < #if !EMULATED_PPC
635 > #if EMULATED_PPC
636 >        WriteMacInt32(XLM_ETHER_INIT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_INIT));
637 >        WriteMacInt32(XLM_ETHER_TERM, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_TERM));
638 >        WriteMacInt32(XLM_ETHER_OPEN, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_OPEN));
639 >        WriteMacInt32(XLM_ETHER_CLOSE, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_CLOSE));
640 >        WriteMacInt32(XLM_ETHER_WPUT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_WPUT));
641 >        WriteMacInt32(XLM_ETHER_RSRV, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_RSRV));
642 >        WriteMacInt32(XLM_VIDEO_DOIO, POWERPC_NATIVE_OP_FUNC(NATIVE_VIDEO_DO_DRIVER_IO));
643 > #else
644          WriteMacInt32(XLM_TOC, (uint32)TOC);                                                    // TOC pointer of emulator
645          WriteMacInt32(XLM_ETHER_INIT, (uint32)InitStreamModule);                // DLPI ethernet driver functions
646          WriteMacInt32(XLM_ETHER_TERM, (uint32)TerminateStreamModule);
# Line 691 | Line 710 | int main(int argc, char **argv)
710                  ErrorAlert(str);
711                  goto quit;
712          }
713 + #endif
714  
715          // Install interrupt signal handler
716          sigemptyset(&sigusr2_action.sa_mask);
717          sigusr2_action.sa_handler = (__sighandler_t)sigusr2_handler;
718 +        sigusr2_action.sa_flags = 0;
719 + #if !EMULATED_PPC
720          sigusr2_action.sa_flags = SA_ONSTACK | SA_RESTART;
721 + #endif
722          sigusr2_action.sa_restorer = NULL;
723          if (sigaction(SIGUSR2, &sigusr2_action, NULL) < 0) {
724                  sprintf(str, GetString(STR_SIGUSR2_INSTALL_ERR), strerror(errno));
725                  ErrorAlert(str);
726                  goto quit;
727          }
705 #endif
728  
729          // Get my thread ID and execute MacOS thread function
730          emul_thread = pthread_self();
# Line 779 | Line 801 | static void Quit(void)
801  
802          // Delete RAM area
803          if (ram_area_mapped)
804 <                munmap(mmap_RAMBase, RAMSize);
804 >                vm_release((char *)RAM_BASE, RAMSize);
805  
806          // Delete ROM area
807          if (rom_area_mapped)
808 <                munmap((char *)ROM_BASE, ROM_AREA_SIZE);
808 >                vm_release((char *)ROM_BASE, ROM_AREA_SIZE);
809  
810          // Delete Kernel Data area
811          if (kernel_area >= 0) {
# Line 890 | Line 912 | void Execute68kTrap(uint16 trap, M68kReg
912          uint16 proc[2] = {trap, M68K_RTS};
913          Execute68k((uint32)proc, r);
914   }
893 #endif
915  
916  
917   /*
# Line 904 | Line 925 | void ExecutePPC(void (*func)())
925          M68kRegisters r;
926          Execute68k((uint32)&desc, &r);
927   }
928 + #endif
929  
930  
931   /*
# Line 979 | Line 1001 | void MakeExecutable(int dummy, void *sta
1001  
1002   void PatchAfterStartup(void)
1003   {
1004 + #if EMULATED_PPC
1005 +        ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
1006 + #else
1007          ExecutePPC(VideoInstallAccel);
1008 + #endif
1009          InstallExtFS();
1010   }
1011  
# Line 1090 | Line 1116 | void Set_pthread_attr(pthread_attr_t *at
1116   *  Mutexes
1117   */
1118  
1119 + #ifdef HAVE_PTHREADS
1120 +
1121 + struct B2_mutex {
1122 +        B2_mutex() {
1123 +            pthread_mutexattr_t attr;
1124 +            pthread_mutexattr_init(&attr);
1125 +            // Initialize the mutex for priority inheritance --
1126 +            // required for accurate timing.
1127 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
1128 +            pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
1129 + #endif
1130 + #if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL)
1131 +            pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
1132 + #endif
1133 + #ifdef HAVE_PTHREAD_MUTEXATTR_SETPSHARED
1134 +            pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
1135 + #endif
1136 +            pthread_mutex_init(&m, &attr);
1137 +            pthread_mutexattr_destroy(&attr);
1138 +        }
1139 +        ~B2_mutex() {
1140 +            pthread_mutex_trylock(&m); // Make sure it's locked before
1141 +            pthread_mutex_unlock(&m);  // unlocking it.
1142 +            pthread_mutex_destroy(&m);
1143 +        }
1144 +        pthread_mutex_t m;
1145 + };
1146 +
1147 + B2_mutex *B2_create_mutex(void)
1148 + {
1149 +        return new B2_mutex;
1150 + }
1151 +
1152 + void B2_lock_mutex(B2_mutex *mutex)
1153 + {
1154 +        pthread_mutex_lock(&mutex->m);
1155 + }
1156 +
1157 + void B2_unlock_mutex(B2_mutex *mutex)
1158 + {
1159 +        pthread_mutex_unlock(&mutex->m);
1160 + }
1161 +
1162 + void B2_delete_mutex(B2_mutex *mutex)
1163 + {
1164 +        delete mutex;
1165 + }
1166 +
1167 + #else
1168 +
1169   struct B2_mutex {
1170          int dummy;
1171   };
# Line 1112 | Line 1188 | void B2_delete_mutex(B2_mutex *mutex)
1188          delete mutex;
1189   }
1190  
1191 + #endif
1192 +
1193  
1194   /*
1195   *  Trigger signal USR2 from another thread
1196   */
1197  
1198 + #if !EMULATED_PPC || ASYNC_IRQ
1199   void TriggerInterrupt(void)
1200   {
1122 #if EMULATED_PPC
1123        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1124 #else
1125 #if 0
1126        WriteMacInt32(0x16a, ReadMacInt32(0x16a) + 1);
1127 #else
1201          if (ready_for_signals)
1202                  pthread_kill(emul_thread, SIGUSR2);
1130 #endif
1131 #endif
1203   }
1204 + #endif
1205  
1206  
1207   /*
# Line 1169 | Line 1241 | void EnableInterrupt(void)
1241   }
1242  
1243  
1172 #if !EMULATED_PPC
1244   /*
1245   *  USR2 handler
1246   */
1247  
1248 + #if EMULATED_PPC
1249 + static void sigusr2_handler(int sig)
1250 + {
1251 + #if ASYNC_IRQ
1252 +        extern void HandleInterrupt(void);
1253 +        HandleInterrupt();
1254 + #endif
1255 + }
1256 + #else
1257   static void sigusr2_handler(int sig, sigcontext_struct *sc)
1258   {
1259          pt_regs *r = sc->regs;
# Line 1255 | Line 1335 | static void sigusr2_handler(int sig, sig
1335                          }
1336                          break;
1337   #endif
1258
1338          }
1339   }
1340 + #endif
1341  
1342  
1343   /*
1344   *  SIGSEGV handler
1345   */
1346  
1347 + #if !EMULATED_PPC
1348   static void sigsegv_handler(int sig, sigcontext_struct *sc)
1349   {
1350          pt_regs *r = sc->regs;
1351 +
1352 +        // Get effective address
1353 +        uint32 addr = r->dar;
1354 +        
1355 + #if ENABLE_VOSF
1356 +        // Handle screen fault.
1357 +        extern bool Screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction);
1358 +        if (Screen_fault_handler((sigsegv_address_t)addr, (sigsegv_address_t)r->nip))
1359 +                return;
1360 + #endif
1361 +
1362          num_segv++;
1363  
1364          // Fault in Mac ROM or RAM?
1365          bool mac_fault = (r->nip >= ROM_BASE) && (r->nip < (ROM_BASE + ROM_AREA_SIZE)) || (r->nip >= RAMBase) && (r->nip < (RAMBase + RAMSize));
1366          if (mac_fault) {
1367  
1276                // Get opcode and divide into fields
1277                uint32 opcode = *((uint32 *)r->nip);
1278                uint32 primop = opcode >> 26;
1279                uint32 exop = (opcode >> 1) & 0x3ff;
1280                uint32 ra = (opcode >> 16) & 0x1f;
1281                uint32 rb = (opcode >> 11) & 0x1f;
1282                uint32 rd = (opcode >> 21) & 0x1f;
1283                int32 imm = (int16)(opcode & 0xffff);
1284
1368                  // "VM settings" during MacOS 8 installation
1369                  if (r->nip == ROM_BASE + 0x488160 && r->gpr[20] == 0xf8000000) {
1370                          r->nip += 4;
# Line 1309 | Line 1392 | static void sigsegv_handler(int sig, sig
1392                          return;
1393                  }
1394  
1395 +                // Get opcode and divide into fields
1396 +                uint32 opcode = *((uint32 *)r->nip);
1397 +                uint32 primop = opcode >> 26;
1398 +                uint32 exop = (opcode >> 1) & 0x3ff;
1399 +                uint32 ra = (opcode >> 16) & 0x1f;
1400 +                uint32 rb = (opcode >> 11) & 0x1f;
1401 +                uint32 rd = (opcode >> 21) & 0x1f;
1402 +                int32 imm = (int16)(opcode & 0xffff);
1403 +
1404                  // Analyze opcode
1405                  enum {
1406                          TYPE_UNKNOWN,
# Line 1392 | Line 1484 | static void sigsegv_handler(int sig, sig
1484                                  transfer_type = TYPE_STORE; transfer_size = SIZE_HALFWORD; addr_mode = MODE_U; break;
1485                  }
1486          
1395                // Calculate effective address
1396                uint32 addr = 0;
1397                switch (addr_mode) {
1398                        case MODE_X:
1399                        case MODE_UX:
1400                                if (ra == 0)
1401                                        addr = r->gpr[rb];
1402                                else
1403                                        addr = r->gpr[ra] + r->gpr[rb];
1404                                break;
1405                        case MODE_NORM:
1406                        case MODE_U:
1407                                if (ra == 0)
1408                                        addr = (int32)(int16)imm;
1409                                else
1410                                        addr = r->gpr[ra] + (int32)(int16)imm;
1411                                break;
1412                        default:
1413                                break;
1414                }
1415
1487                  // Ignore ROM writes
1488                  if (transfer_type == TYPE_STORE && addr >= ROM_BASE && addr < ROM_BASE + ROM_SIZE) {
1489   //                      D(bug("WARNING: %s write access to ROM at %08lx, pc %08lx\n", transfer_size == SIZE_BYTE ? "Byte" : transfer_size == SIZE_HALFWORD ? "Halfword" : "Word", addr, r->nip));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines