mirror of
https://github.com/darlinghq/darling-newlkm.git
synced 2024-12-04 10:03:32 +00:00
8f105c7be5
All the files that were building with the previous version of XNU are now building again (with Clang), however, the module does not link yet (due to missing symbols; *lots* of them). A lot of them are probably new additions to XNU, but some of them are probably from me not knowing the `ifdef` certain things that should be. Also, I completely overhauled the Makefile to make it simpler to manage settings and flags across files, folders, modules, and Linux/KBuild versions. I didn't add this feature (because I don't need it yet), but it can be easily extended to easily allow per-compiler flags Full list of all missing symbols reported by `MODPOST`: task_is_driver thread_get_state_to_user machine_exception catch_mach_exception_raise_state_identity turnstile_has_waiters mach_vm_allocate_kernel processor_start_from_user catch_mach_exception_raise_state task_violated_guard hw_atomic_test_and_set32 task_is_importance_donor catch_mach_exception_raise ipc_importance_task_reference work_interval_port_notify random_bool_init os_ref_retain_try_internal mach_zone_info_for_zone processor_exit_from_user pqueue_pair_meld mach_vm_page_range_query turnstile_complete mach_vm_wire_external mach_vm_allocate_external vm_allocate_kernel ux_handler_init uext_server turnstile_waitq_add_thread_priority_queue thread_depress_abort_from_user turnstile_deallocate _Block_object_assign turnstile_cleanup turnstile_kernel_update_inheritor_on_wake_locked _pthread_priority_normalize_for_ipc filt_ipc_kqueue_turnstile lck_spin_assert IOTaskHasEntitlement thread_get_requested_qos task_watchport_elem_deallocate os_ref_init_count_internal lck_mtx_lock_spin_always turnstile_update_inheritor_complete task_inspect thread_bootstrap_return thread_setstatus_from_user turnstile_recompute_priority_locked mach_vm_remap_external zone_require thread_getstatus_to_user turnstile_hash_bucket_unlock _NSConcreteGlobalBlock filt_machport_kqueue_has_turnstile mach_continuous_time ipc_importance_init turnstile_update_inheritor_locked turnstile_alloc ipc_importance_send ipc_importance_thread_call_init bank_get_bank_ledger_thread_group_and_persona turnstile_hash_bucket_lock filt_machport_turnstile_prepare_lazily turnstile_deallocate_safe os_ref_release_barrier_internal turnstile_reference vm_map_wire_kernel thread_deallocate_safe turnstile_stats_update thread_set_pending_block_hint task_info_from_user thread_inspect_deallocate catch_exc_subsystem ux_handler_stop lck_mtx_assert mach_vm_map_external filt_machport_stash_port ipc_importance_task_hold_internal_assertion lck_spin_lock_grp _Block_object_dispose ipc_importance_check_circularity task_restartable_subsystem ipc_importance_task_drop_internal_assertion random_bool_gen_bits turnstile_update_inheritor lck_spin_try_lock_grp ipc_importance_task_release kdp_lck_spin_is_acquired ipc_importance_receive os_ref_retain_internal task_inspect_deallocate _NSConcreteStackBlock task_get_exc_guard_behavior pid_from_task sched_thread_unpromote_reason memory_entry_subsystem turnstile_prepare act_get_state_to_user sched_thread_promote_reason task_set_exc_guard_behavior ipc_importance_task_is_any_receiver_type knote_vanish thread_user_promotion_qos_for_pri
175 lines
4.1 KiB
C
175 lines
4.1 KiB
C
/*
|
|
* Darling Mach Linux Kernel Module
|
|
* Copyright (C) 2017 Lubos Dolezel
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <duct/compiler/clang/asm-inline.h>
|
|
#include <linux/string.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/cpumask.h>
|
|
#include <linux/mm.h>
|
|
#include <asm/processor.h>
|
|
#include "commpage.h"
|
|
|
|
// Include commpage definitions
|
|
#include "../osfmk/i386/cpu_capabilities.h"
|
|
|
|
static const char* SIGNATURE32 = "commpage 32-bit";
|
|
static const char* SIGNATURE64 = "commpage 64-bit";
|
|
|
|
static uint64_t get_cpu_caps(void);
|
|
|
|
#define CGET(p) (commpage + ((p)-_COMM_PAGE_START_ADDRESS))
|
|
#define __cpuid(level, eax, ebx, ecx, edx) \
|
|
eax = level; \
|
|
native_cpuid(&(eax), &(ebx), &(ecx), &(edx))
|
|
|
|
void* commpage_setup(bool _64bit)
|
|
{
|
|
uint8_t* commpage;
|
|
uint64_t* cpu_caps64;
|
|
uint32_t* cpu_caps;
|
|
uint16_t* version;
|
|
char* signature;
|
|
uint64_t my_caps;
|
|
uint8_t *ncpus, *nactivecpus;
|
|
uint8_t *physcpus, *logcpus;
|
|
|
|
commpage = vmalloc_user(_64bit ? _COMM_PAGE64_AREA_LENGTH : _COMM_PAGE32_AREA_LENGTH);
|
|
if (!commpage)
|
|
return NULL;
|
|
|
|
signature = (char*)CGET(_COMM_PAGE_SIGNATURE);
|
|
version = (uint16_t*)CGET(_COMM_PAGE_VERSION);
|
|
cpu_caps64 = (uint64_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES64);
|
|
cpu_caps = (uint32_t*)CGET(_COMM_PAGE_CPU_CAPABILITIES);
|
|
|
|
strcpy(signature, _64bit ? SIGNATURE64 : SIGNATURE32);
|
|
*version = _COMM_PAGE_THIS_VERSION;
|
|
|
|
ncpus = (uint8_t*)CGET(_COMM_PAGE_NCPUS);
|
|
*ncpus = num_online_cpus();
|
|
|
|
nactivecpus = (uint8_t*)CGET(_COMM_PAGE_ACTIVE_CPUS);
|
|
*nactivecpus = num_active_cpus();
|
|
|
|
// Better imprecise information than no information
|
|
physcpus = (uint8_t*)CGET(_COMM_PAGE_PHYSICAL_CPUS);
|
|
logcpus = (uint8_t*)CGET(_COMM_PAGE_LOGICAL_CPUS);
|
|
*physcpus = *logcpus = *ncpus;
|
|
|
|
my_caps = get_cpu_caps();
|
|
if (*ncpus == 1)
|
|
my_caps |= kUP;
|
|
|
|
*cpu_caps = (uint32_t) my_caps;
|
|
*cpu_caps64 = my_caps;
|
|
|
|
uint64_t* memsize = (uint64_t*)CGET(_COMM_PAGE_MEMORY_SIZE);
|
|
*memsize = get_num_physpages() * PAGE_SIZE;
|
|
|
|
return commpage;
|
|
}
|
|
|
|
unsigned long commpage_length(bool _64bit)
|
|
{
|
|
return _64bit ? _COMM_PAGE64_AREA_LENGTH : _COMM_PAGE32_AREA_LENGTH;
|
|
}
|
|
|
|
unsigned long commpage_address(bool _64bit)
|
|
{
|
|
return _64bit ? _COMM_PAGE64_BASE_ADDRESS : _COMM_PAGE32_BASE_ADDRESS;
|
|
}
|
|
|
|
void commpage_free(void* p)
|
|
{
|
|
vfree(p);
|
|
}
|
|
|
|
uint64_t get_cpu_caps(void)
|
|
{
|
|
uint64_t caps = 0;
|
|
|
|
{
|
|
union cpu_flags1 eax;
|
|
union cpu_flags2 ecx;
|
|
union cpu_flags3 edx;
|
|
uint32_t ebx;
|
|
|
|
eax.reg = ecx.reg = edx.reg = 0;
|
|
__cpuid(1, eax.reg, ebx, ecx.reg, edx.reg);
|
|
|
|
if (ecx.mmx)
|
|
caps |= kHasMMX;
|
|
if (ecx.sse)
|
|
caps |= kHasSSE;
|
|
if (ecx.sse2)
|
|
caps |= kHasSSE2;
|
|
if (edx.sse3)
|
|
caps |= kHasSSE3;
|
|
if (ecx.ia64)
|
|
caps |= k64Bit;
|
|
if (edx.ssse3)
|
|
caps |= kHasSupplementalSSE3;
|
|
if (edx.sse41)
|
|
caps |= kHasSSE4_1;
|
|
if (edx.sse42)
|
|
caps |= kHasSSE4_2;
|
|
if (edx.aes)
|
|
caps |= kHasAES;
|
|
if (edx.avx)
|
|
caps |= kHasAVX1_0;
|
|
if (edx.rdrnd)
|
|
caps |= kHasRDRAND;
|
|
if (edx.fma)
|
|
caps |= kHasFMA;
|
|
if (edx.f16c)
|
|
caps |= kHasF16C;
|
|
}
|
|
{
|
|
union cpu_flags4 ebx;
|
|
union cpu_flags5 ecx;
|
|
uint32_t edx = 0, eax = 7;
|
|
|
|
__cpuid(7, eax, ebx.reg, ecx.reg, edx);
|
|
|
|
if (ebx.erms)
|
|
caps |= kHasENFSTRG;
|
|
if (ebx.avx2)
|
|
caps |= kHasAVX2_0;
|
|
if (ebx.bmi1)
|
|
caps |= kHasBMI1;
|
|
if (ebx.bmi2)
|
|
caps |= kHasBMI2;
|
|
if (ebx.rtm)
|
|
caps |= kHasRTM;
|
|
if (ebx.hle)
|
|
caps |= kHasHLE;
|
|
if (ebx.rdseed)
|
|
caps |= kHasRDSEED;
|
|
if (ebx.adx)
|
|
caps |= kHasADX;
|
|
if (ebx.mpx)
|
|
caps |= kHasMPX;
|
|
if (ebx.sgx)
|
|
caps |= kHasSGX;
|
|
}
|
|
|
|
return caps;
|
|
}
|
|
|