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.13 by gbeauche, 2003-11-03T21:28:25Z vs.
Revision 1.22 by gbeauche, 2004-01-04T05:45:50Z

# Line 109 | Line 109
109   #include "user_strings.h"
110   #include "vm_alloc.h"
111   #include "sigsegv.h"
112 + #include "thunks.h"
113  
114   #define DEBUG 0
115   #include "debug.h"
# Line 145 | Line 146
146   const char ROM_FILE_NAME[] = "ROM";
147   const char ROM_FILE_NAME2[] = "Mac OS ROM";
148  
149 < const uint32 RAM_BASE = 0x20000000;                     // Base address of RAM
149 > const uintptr RAM_BASE = 0x20000000;            // Base address of RAM
150   const uint32 SIG_STACK_SIZE = 0x10000;          // Size of signal stack
151  
152  
# Line 172 | Line 173 | void *TOC;                             // Small data pointer (r13
173   #endif
174   uint32 RAMBase;                 // Base address of Mac RAM
175   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
176   uint32 KernelDataAddr;  // Address of Kernel Data
177   uint32 BootGlobsAddr;   // Address of BootGlobs structure at top of Mac RAM
178   uint32 PVR;                             // Theoretical PVR
# Line 185 | Line 183 | int64 BusClockSpeed;   // Bus clock speed
183   // Global variables
184   char *x_display_name = NULL;                            // X11 display name
185   Display *x_display = NULL;                                      // X11 display handle
186 + #ifdef X11_LOCK_TYPE
187 + X11_LOCK_TYPE x_display_lock = X11_LOCK_INIT; // X11 display lock
188 + #endif
189  
190   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
# Line 207 | Line 207 | static bool ready_for_signals = false;
207   static int64 num_segv = 0;                                      // Number of handled SEGV signals
208  
209   static struct sigaction sigusr2_action;         // Interrupt signal (of emulator thread)
210 < #if !EMULATED_PPC
210 > #if EMULATED_PPC
211 > static uintptr sig_stack = 0;                           // Stack for PowerPC interrupt routine
212 > #else
213   static struct sigaction sigsegv_action;         // Data access exception signal (of emulator thread)
214   static struct sigaction sigill_action;          // Illegal instruction signal (of emulator thread)
215   static void *sig_stack = NULL;                          // Stack for signal handlers
# Line 216 | Line 218 | static bool emul_thread_fatal = false;
218   static sigregs sigsegv_regs;                            // Register dump when crashed
219   #endif
220  
221 + uintptr SheepMem::zero_page = 0;                        // Address of ro page filled in with zeros
222 + uintptr SheepMem::base = 0x60000000;            // Address of SheepShaver data
223 + uintptr SheepMem::top = 0;                                      // Top of SheepShaver data (stack like storage)
224 +
225  
226   // Prototypes
227   static void Quit(void);
# Line 252 | Line 258 | extern void paranoia_check(void);
258  
259   #if EMULATED_PPC
260   /*
261 + *  Return signal stack base
262 + */
263 +
264 + uintptr SignalStackBase(void)
265 + {
266 +        return sig_stack + SIG_STACK_SIZE;
267 + }
268 +
269 +
270 + /*
271   *  Atomic operations
272   */
273  
# Line 470 | Line 486 | int main(int argc, char **argv)
486                  ErrorAlert(str);
487                  goto quit;
488          }
489 <        kernel_data = (KernelData *)0x68ffe000;
489 >        kernel_data = (KernelData *)KERNEL_DATA_BASE;
490          emulator_data = &kernel_data->ed;
491 <        KernelDataAddr = (uint32)kernel_data;
491 >        KernelDataAddr = KERNEL_DATA_BASE;
492          D(bug("Kernel Data at %p, Emulator Data at %p\n", kernel_data, emulator_data));
493  
494          // Create area for SheepShaver data
495 <        if (vm_acquire_fixed((char *)SHEEP_BASE, SHEEP_SIZE) < 0) {
495 >        if (!SheepMem::Init()) {
496                  sprintf(str, GetString(STR_SHEEP_MEM_MMAP_ERR), strerror(errno));
497                  ErrorAlert(str);
498                  goto quit;
499          }
484        SheepStack1Base = SHEEP_BASE + 0x10000;
485        SheepStack2Base = SheepStack1Base + 0x10000;
486        SheepThunksBase = SheepStack2Base + 0x1000;
487        sheep_area_mapped = true;
500  
501          // Create area for Mac ROM
502          if (vm_acquire_fixed((char *)ROM_BASE, ROM_AREA_SIZE) < 0) {
# Line 579 | Line 591 | int main(int argc, char **argv)
591          boot_globs[1] = htonl(RAMSize);
592          boot_globs[2] = htonl((uint32)-1);                      // End of bank table
593  
594 +        // Init thunks
595 +        if (!ThunksInit())
596 +                goto quit;
597 +
598          // Init drivers
599          SonyInit();
600          DiskInit();
# Line 588 | Line 604 | int main(int argc, char **argv)
604          // Init external file system
605          ExtFSInit();
606  
607 +        // Init ADB
608 +        ADBInit();
609 +
610          // Init audio
611          AudioInit();
612  
# Line 622 | Line 641 | int main(int argc, char **argv)
641          // Initialize Kernel Data
642          memset(kernel_data, 0, sizeof(KernelData));
643          if (ROMType == ROMTYPE_NEWWORLD) {
644 <                static uint32 of_dev_tree[4] = {0, 0, 0, 0};
645 <                static uint8 vector_lookup_tbl[128];
646 <                static uint8 vector_mask_tbl[64];
644 >                uintptr of_dev_tree = SheepMem::Reserve(4 * sizeof(uint32));
645 >                memset((void *)of_dev_tree, 0, 4 * sizeof(uint32));
646 >                uintptr vector_lookup_tbl = SheepMem::Reserve(128);
647 >                uintptr vector_mask_tbl = SheepMem::Reserve(64);
648                  memset((uint8 *)kernel_data + 0xb80, 0x3d, 0x80);
649 <                memset(vector_lookup_tbl, 0, 128);
650 <                memset(vector_mask_tbl, 0, 64);
649 >                memset((void *)vector_lookup_tbl, 0, 128);
650 >                memset((void *)vector_mask_tbl, 0, 64);
651                  kernel_data->v[0xb80 >> 2] = htonl(ROM_BASE);
652 <                kernel_data->v[0xb84 >> 2] = htonl((uint32)of_dev_tree);        // OF device tree base
653 <                kernel_data->v[0xb90 >> 2] = htonl((uint32)vector_lookup_tbl);
654 <                kernel_data->v[0xb94 >> 2] = htonl((uint32)vector_mask_tbl);
652 >                kernel_data->v[0xb84 >> 2] = htonl(of_dev_tree);                        // OF device tree base
653 >                kernel_data->v[0xb90 >> 2] = htonl(vector_lookup_tbl);
654 >                kernel_data->v[0xb94 >> 2] = htonl(vector_mask_tbl);
655                  kernel_data->v[0xb98 >> 2] = htonl(ROM_BASE);                           // OpenPIC base
656                  kernel_data->v[0xbb0 >> 2] = htonl(0);                                          // ADB base
657                  kernel_data->v[0xc20 >> 2] = htonl(RAMSize);
# Line 667 | Line 687 | int main(int argc, char **argv)
687          D(bug("Initializing Low Memory...\n"));
688          memset(NULL, 0, 0x3000);
689          WriteMacInt32(XLM_SIGNATURE, FOURCC('B','a','a','h'));                  // Signature to detect SheepShaver
690 <        WriteMacInt32(XLM_KERNEL_DATA, (uint32)kernel_data);                    // For trap replacement routines
690 >        WriteMacInt32(XLM_KERNEL_DATA, KernelDataAddr);                                 // For trap replacement routines
691          WriteMacInt32(XLM_PVR, PVR);                                                                    // Theoretical PVR
692          WriteMacInt32(XLM_BUS_CLOCK, BusClockSpeed);                                    // For DriverServicesLib patch
693          WriteMacInt16(XLM_EXEC_RETURN_OPCODE, M68K_EXEC_RETURN);                // For Execute68k() (RTS from the executed 68k code will jump here and end 68k mode)
694 < #if EMULATED_PPC
695 <        WriteMacInt32(XLM_ETHER_INIT, POWERPC_NATIVE_OP_FUNC(NATIVE_ETHER_INIT));
696 <        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);
686 <        WriteMacInt32(XLM_ETHER_OPEN, (uint32)ether_open);
687 <        WriteMacInt32(XLM_ETHER_CLOSE, (uint32)ether_close);
688 <        WriteMacInt32(XLM_ETHER_WPUT, (uint32)ether_wput);
689 <        WriteMacInt32(XLM_ETHER_RSRV, (uint32)ether_rsrv);
690 <        WriteMacInt32(XLM_VIDEO_DOIO, (uint32)VideoDoDriverIO);
694 >        WriteMacInt32(XLM_ZERO_PAGE, SheepMem::ZeroPage());                             // Pointer to read-only page with all bits set to 0
695 > #if !EMULATED_PPC
696 >        WriteMacInt32(XLM_TOC, (uint32)TOC);                                                            // TOC pointer of emulator
697   #endif
698 +        WriteMacInt32(XLM_ETHER_INIT, NativeFunction(NATIVE_ETHER_INIT));       // DLPI ethernet driver functions
699 +        WriteMacInt32(XLM_ETHER_TERM, NativeFunction(NATIVE_ETHER_TERM));
700 +        WriteMacInt32(XLM_ETHER_OPEN, NativeFunction(NATIVE_ETHER_OPEN));
701 +        WriteMacInt32(XLM_ETHER_CLOSE, NativeFunction(NATIVE_ETHER_CLOSE));
702 +        WriteMacInt32(XLM_ETHER_WPUT, NativeFunction(NATIVE_ETHER_WPUT));
703 +        WriteMacInt32(XLM_ETHER_RSRV, NativeFunction(NATIVE_ETHER_RSRV));
704 +        WriteMacInt32(XLM_VIDEO_DOIO, NativeFunction(NATIVE_VIDEO_DO_DRIVER_IO));
705          D(bug("Low Memory initialized\n"));
706  
707          // Start 60Hz thread
# Line 831 | Line 844 | static void Quit(void)
844          // Exit audio
845          AudioExit();
846  
847 +        // Exit ADB
848 +        ADBExit();
849 +
850          // Exit video
851          VideoExit();
852  
# Line 843 | Line 859 | static void Quit(void)
859          DiskExit();
860          SonyExit();
861  
862 +        // Delete SheepShaver globals
863 +        SheepMem::Exit();
864 +
865          // Delete RAM area
866          if (ram_area_mapped)
867                  vm_release((char *)RAM_BASE, RAMSize);
# Line 954 | Line 973 | void Execute68kTrap(uint16 trap, M68kReg
973          uint16 proc[2] = {trap, M68K_RTS};
974          Execute68k((uint32)proc, r);
975   }
957
958
959 /*
960 *  Execute PPC code from EMUL_OP routine (real mode switch)
961 */
962
963 void ExecutePPC(void (*func)())
964 {
965        uint32 tvect[2] = {(uint32)func, 0};    // Fake TVECT
966        RoutineDescriptor desc = BUILD_PPC_ROUTINE_DESCRIPTOR(0, tvect);
967        M68kRegisters r;
968        Execute68k((uint32)&desc, &r);
969 }
976   #endif
977  
978  
# Line 1045 | Line 1051 | void MakeExecutable(int dummy, void *sta
1051  
1052   void PatchAfterStartup(void)
1053   {
1048 #if EMULATED_PPC
1054          ExecuteNative(NATIVE_VIDEO_INSTALL_ACCEL);
1050 #else
1051        ExecutePPC(VideoInstallAccel);
1052 #endif
1055          InstallExtFS();
1056   }
1057  
# Line 1152 | Line 1154 | static void *tick_func(void *arg)
1154  
1155   void Set_pthread_attr(pthread_attr_t *attr, int priority)
1156   {
1157 <        // nothing to do
1157 > #ifdef HAVE_PTHREADS
1158 >        pthread_attr_init(attr);
1159 > #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
1160 >        // Some of these only work for superuser
1161 >        if (geteuid() == 0) {
1162 >                pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
1163 >                pthread_attr_setschedpolicy(attr, SCHED_FIFO);
1164 >                struct sched_param fifo_param;
1165 >                fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) +
1166 >                                              sched_get_priority_max(SCHED_FIFO)) / 2 +
1167 >                                             priority);
1168 >                pthread_attr_setschedparam(attr, &fifo_param);
1169 >        }
1170 >        if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) {
1171 > #ifdef PTHREAD_SCOPE_BOUND_NP
1172 >            // If system scope is not available (eg. we're not running
1173 >            // with CAP_SCHED_MGT capability on an SGI box), try bound
1174 >            // scope.  It exposes pthread scheduling to the kernel,
1175 >            // without setting realtime priority.
1176 >            pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP);
1177 > #endif
1178 >        }
1179 > #endif
1180 > #endif
1181   }
1182  
1183  
# Line 1367 | Line 1392 | static void sigusr2_handler(int sig, sig
1392                                          if (InterruptFlags & INTFLAG_VIA) {
1393                                                  ClearInterruptFlag(INTFLAG_VIA);
1394                                                  ADBInterrupt();
1395 <                                                ExecutePPC(VideoVBL);
1395 >                                                ExecuteNative(NATIVE_VIDEO_VBL);
1396                                          }
1397                                  }
1398   #endif
# Line 1764 | Line 1789 | rti:;
1789  
1790  
1791   /*
1792 + *  Helpers to share 32-bit addressable data with MacOS
1793 + */
1794 +
1795 + bool SheepMem::Init(void)
1796 + {
1797 +        const int page_size = getpagesize();
1798 +
1799 +        // Allocate SheepShaver globals
1800 +        if (vm_acquire_fixed((char *)base, size) < 0)
1801 +                return false;
1802 +
1803 +        // Allocate page with all bits set to 0
1804 +        zero_page = base + size;
1805 +        if (vm_acquire_fixed((char *)zero_page, page_size) < 0)
1806 +                return false;
1807 +        memset((char *)zero_page, 0, page_size);
1808 +        if (vm_protect((char *)zero_page, page_size, VM_PAGE_READ) < 0)
1809 +                return false;
1810 +
1811 + #if EMULATED_PPC
1812 +        // Allocate alternate stack for PowerPC interrupt routine
1813 +        sig_stack = zero_page + page_size;
1814 +        if (vm_acquire_fixed((char *)sig_stack, SIG_STACK_SIZE) < 0)
1815 +                return false;
1816 + #endif
1817 +
1818 +        top = base + size;
1819 +        return true;
1820 + }
1821 +
1822 + void SheepMem::Exit(void)
1823 + {
1824 +        if (top) {
1825 +                const int page_size = getpagesize();
1826 +
1827 +                // Delete SheepShaver globals
1828 +                vm_release((void *)base, size);
1829 +
1830 +                // Delete zero page
1831 +                vm_release((void *)zero_page, page_size);
1832 +
1833 + #if EMULATED_PPC
1834 +                // Delete alternate stack for PowerPC interrupt routine
1835 +                vm_release((void *)sig_stack, SIG_STACK_SIZE);
1836 + #endif
1837 +        }
1838 + }
1839 +
1840 +
1841 + /*
1842   *  Display alert
1843   */
1844  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines