diff --git a/SheepShaver/src/BeOS/main_beos.cpp b/SheepShaver/src/BeOS/main_beos.cpp index 542e266e..f994510f 100644 --- a/SheepShaver/src/BeOS/main_beos.cpp +++ b/SheepShaver/src/BeOS/main_beos.cpp @@ -219,6 +219,7 @@ uint32 DREmulatorAddr; // Address of DR Emulator uint32 PVR; // Theoretical PVR int64 CPUClockSpeed; // Processor clock speed (Hz) int64 BusClockSpeed; // Bus clock speed (Hz) +int64 TimebaseSpeed; // Timebase clock speed (Hz) system_info SysInfo; // System information static void *sig_stack = NULL; // Stack for signal handlers @@ -299,6 +300,7 @@ void SheepShaver::ReadyToRun(void) } CPUClockSpeed = SysInfo.cpu_clock_speed; BusClockSpeed = SysInfo.bus_clock_speed; + TimebaseSpeed = BusClockSpeed / 4; // Delete old areas area_id old_kernel_area = find_area(KERNEL_AREA_NAME); diff --git a/SheepShaver/src/Unix/configure.ac b/SheepShaver/src/Unix/configure.ac index 67a94eab..b3407d94 100644 --- a/SheepShaver/src/Unix/configure.ac +++ b/SheepShaver/src/Unix/configure.ac @@ -224,7 +224,7 @@ AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(mach/vm_map.h mach/mach_init.h sys/mman.h) AC_CHECK_HEADERS(sys/time.h sys/times.h sys/socket.h) -AC_CHECK_HEADERS(unistd.h fcntl.h byteswap.h) +AC_CHECK_HEADERS(unistd.h fcntl.h byteswap.h dirent.h) AC_CHECK_HEADERS(linux/if.h, [], [], [ #if HAVE_SYS_SOCKET_H # include diff --git a/SheepShaver/src/Unix/main_unix.cpp b/SheepShaver/src/Unix/main_unix.cpp index 2e536918..f8516e1a 100644 --- a/SheepShaver/src/Unix/main_unix.cpp +++ b/SheepShaver/src/Unix/main_unix.cpp @@ -127,6 +127,10 @@ #include "debug.h" +#ifdef HAVE_DIRENT_H +#include +#endif + #ifdef USE_SDL #include #endif @@ -275,6 +279,7 @@ uint32 DRCacheAddr; // Address of DR Cache uint32 PVR; // Theoretical PVR int64 CPUClockSpeed; // Processor clock speed (Hz) int64 BusClockSpeed; // Bus clock speed (Hz) +int64 TimebaseSpeed; // Timebase clock speed (Hz) // Global variables @@ -566,6 +571,7 @@ int main(int argc, char **argv) PVR = 0x00040000; // Default: 604 CPUClockSpeed = 100000000; // Default: 100MHz BusClockSpeed = 100000000; // Default: 100MHz + TimebaseSpeed = 25000000; // Default: 25MHz #if EMULATED_PPC PVR = 0x000c0000; // Default: 7400 (with AltiVec) #elif defined(__APPLE__) && defined(__MACH__) @@ -670,6 +676,27 @@ int main(int argc, char **argv) BusClockSpeed = value.l; fclose(proc_file); } + + // Get actual timebase frequency + TimebaseSpeed = BusClockSpeed / 4; + DIR *cpus_dir; + if ((cpus_dir = opendir("/proc/device-tree/cpus")) != NULL) { + struct dirent *cpu_entry; + while ((cpu_entry = readdir(cpus_dir)) != NULL) { + if (strstr(cpu_entry->d_name, "PowerPC,") == cpu_entry->d_name) { + char timebase_freq_node[256]; + sprintf(timebase_freq_node, "/proc/device-tree/cpus/%s/timebase-frequency", cpu_entry->d_name); + proc_file = fopen(timebase_freq_node, "r"); + if (proc_file) { + union { uint8 b[4]; uint32 l; } value; + if (fread(value.b, sizeof(value), 1, proc_file) == 1) + TimebaseSpeed = value.l; + fclose(proc_file); + } + } + } + closedir(cpus_dir); + } #endif D(bug("PVR: %08x (assumed)\n", PVR)); @@ -954,7 +981,7 @@ int main(int argc, char **argv) kernel_data->v[0xf60 >> 2] = htonl(PVR); kernel_data->v[0xf64 >> 2] = htonl(CPUClockSpeed); // clock-frequency kernel_data->v[0xf68 >> 2] = htonl(BusClockSpeed); // bus-frequency - kernel_data->v[0xf6c >> 2] = htonl(BusClockSpeed / 4); // timebase-frequency + kernel_data->v[0xf6c >> 2] = htonl(TimebaseSpeed); // timebase-frequency } else { kernel_data->v[0xc80 >> 2] = htonl(RAMSize); kernel_data->v[0xc84 >> 2] = htonl(RAMSize); @@ -968,7 +995,7 @@ int main(int argc, char **argv) kernel_data->v[0xf80 >> 2] = htonl(PVR); kernel_data->v[0xf84 >> 2] = htonl(CPUClockSpeed); // clock-frequency kernel_data->v[0xf88 >> 2] = htonl(BusClockSpeed); // bus-frequency - kernel_data->v[0xf8c >> 2] = htonl(BusClockSpeed / 4); // timebase-frequency + kernel_data->v[0xf8c >> 2] = htonl(TimebaseSpeed); // timebase-frequency } // Initialize extra low memory diff --git a/SheepShaver/src/include/main.h b/SheepShaver/src/include/main.h index b2ae6acf..fb8248f1 100644 --- a/SheepShaver/src/include/main.h +++ b/SheepShaver/src/include/main.h @@ -28,6 +28,7 @@ extern uint32 BootGlobsAddr; // Address of BootGlobs structure at top of Mac RAM extern uint32 PVR; // Theoretical PVR extern int64 CPUClockSpeed; // Processor clock speed (Hz) extern int64 BusClockSpeed; // Bus clock speed (Hz) +extern int64 TimebaseSpeed; // Timebase clock speed (Hz) #ifdef __BEOS__ extern system_info SysInfo; // System information diff --git a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp index bfb9eccb..a7bcac3f 100644 --- a/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp +++ b/SheepShaver/src/kpx_cpu/src/cpu/ppc/ppc-execute.cpp @@ -1145,7 +1145,7 @@ static inline uint64 get_tb_ticks(void) { uint64 ticks; #ifdef SHEEPSHAVER - const uint32 TBFreq = BusClockSpeed / 4; + const uint32 TBFreq = TimebaseSpeed; ticks = muldiv64(GetTicks_usec(), TBFreq, 1000000); #else const uint32 TBFreq = 25 * 1000 * 1000; // 25 MHz diff --git a/SheepShaver/src/name_registry.cpp b/SheepShaver/src/name_registry.cpp index e50a91a3..2830ad30 100644 --- a/SheepShaver/src/name_registry.cpp +++ b/SheepShaver/src/name_registry.cpp @@ -138,7 +138,7 @@ void DoPatchNameRegistry(void) RegistryPropertyCreate(power_pc.ptr(), "clock-frequency", u32.ptr(), 4); u32.set_value(BusClockSpeed); RegistryPropertyCreate(power_pc.ptr(), "bus-frequency", u32.ptr(), 4); - u32.set_value(BusClockSpeed / 4); + u32.set_value(TimebaseSpeed); RegistryPropertyCreate(power_pc.ptr(), "timebase-frequency", u32.ptr(), 4); u32.set_value(PVR); RegistryPropertyCreate(power_pc.ptr(), "cpu-version", u32.ptr(), 4);