From f6c059f962f86aa50a8217048a320f40d2ce3ec9 Mon Sep 17 00:00:00 2001 From: Balakrishnan Unnithan Date: Tue, 4 Feb 2025 21:59:13 +0530 Subject: [PATCH 1/2] tlb refactor. tlb variables are moved into a struct for clean and readable code. Signed-off-by: Balakrishnan Unnithan --- src/x86/api.h | 63 +++++++--------------- src/x86/cache/descriptor.c | 106 ++++++++++++++++--------------------- src/x86/cache/init.c | 38 ++----------- src/x86/init.c | 22 +------- 4 files changed, 74 insertions(+), 155 deletions(-) diff --git a/src/x86/api.h b/src/x86/api.h index 1331ed04..3d276347 100644 --- a/src/x86/api.h +++ b/src/x86/api.h @@ -33,6 +33,22 @@ struct cpuinfo_x86_caches { uint32_t prefetch_size; }; +struct cpuinfo_x86_tlbs { + struct cpuinfo_tlb itlb_4KB; + struct cpuinfo_tlb itlb_2MB; + struct cpuinfo_tlb itlb_4MB; + struct cpuinfo_tlb dtlb0_4KB; + struct cpuinfo_tlb dtlb0_2MB; + struct cpuinfo_tlb dtlb0_4MB; + struct cpuinfo_tlb dtlb_4KB; + struct cpuinfo_tlb dtlb_2MB; + struct cpuinfo_tlb dtlb_4MB; + struct cpuinfo_tlb dtlb_1GB; + struct cpuinfo_tlb stlb2_4KB; + struct cpuinfo_tlb stlb2_2MB; + struct cpuinfo_tlb stlb2_1GB; +}; + struct cpuinfo_x86_model_info { uint32_t model; uint32_t family; @@ -61,21 +77,7 @@ struct cpuinfo_x86_processor { int linux_id; #endif struct cpuinfo_x86_caches cache; - struct { - struct cpuinfo_tlb itlb_4KB; - struct cpuinfo_tlb itlb_2MB; - struct cpuinfo_tlb itlb_4MB; - struct cpuinfo_tlb dtlb0_4KB; - struct cpuinfo_tlb dtlb0_2MB; - struct cpuinfo_tlb dtlb0_4MB; - struct cpuinfo_tlb dtlb_4KB; - struct cpuinfo_tlb dtlb_2MB; - struct cpuinfo_tlb dtlb_4MB; - struct cpuinfo_tlb dtlb_1GB; - struct cpuinfo_tlb stlb2_4KB; - struct cpuinfo_tlb stlb2_2MB; - struct cpuinfo_tlb stlb2_1GB; - } tlb; + struct cpuinfo_x86_tlbs tlb; struct cpuinfo_x86_topology topology; char brand_string[CPUINFO_PACKAGE_NAME_MAX]; }; @@ -109,40 +111,15 @@ CPUINFO_INTERNAL void cpuinfo_x86_detect_cache( enum cpuinfo_vendor vendor, const struct cpuinfo_x86_model_info* model_info, struct cpuinfo_x86_caches* cache, - struct cpuinfo_tlb* itlb_4KB, - struct cpuinfo_tlb* itlb_2MB, - struct cpuinfo_tlb* itlb_4MB, - struct cpuinfo_tlb* dtlb0_4KB, - struct cpuinfo_tlb* dtlb0_2MB, - struct cpuinfo_tlb* dtlb0_4MB, - struct cpuinfo_tlb* dtlb_4KB, - struct cpuinfo_tlb* dtlb_2MB, - struct cpuinfo_tlb* dtlb_4MB, - struct cpuinfo_tlb* dtlb_1GB, - struct cpuinfo_tlb* stlb2_4KB, - struct cpuinfo_tlb* stlb2_2MB, - struct cpuinfo_tlb* stlb2_1GB, - uint32_t* log2_package_cores_max); + struct cpuinfo_x86_tlbs* tlb, + struct cpuinfo_x86_topology* topology); CPUINFO_INTERNAL void cpuinfo_x86_decode_cache_descriptor( uint8_t descriptor, enum cpuinfo_vendor vendor, const struct cpuinfo_x86_model_info* model_info, struct cpuinfo_x86_caches* cache, - struct cpuinfo_tlb* itlb_4KB, - struct cpuinfo_tlb* itlb_2MB, - struct cpuinfo_tlb* itlb_4MB, - struct cpuinfo_tlb* dtlb0_4KB, - struct cpuinfo_tlb* dtlb0_2MB, - struct cpuinfo_tlb* dtlb0_4MB, - struct cpuinfo_tlb* dtlb_4KB, - struct cpuinfo_tlb* dtlb_2MB, - struct cpuinfo_tlb* dtlb_4MB, - struct cpuinfo_tlb* dtlb_1GB, - struct cpuinfo_tlb* stlb2_4KB, - struct cpuinfo_tlb* stlb2_2MB, - struct cpuinfo_tlb* stlb2_1GB, - uint32_t* prefetch_size); + struct cpuinfo_x86_tlbs* tlb); CPUINFO_INTERNAL bool cpuinfo_x86_decode_deterministic_cache_parameters( struct cpuid_regs regs, diff --git a/src/x86/cache/descriptor.c b/src/x86/cache/descriptor.c index 93d855ae..404c0235 100644 --- a/src/x86/cache/descriptor.c +++ b/src/x86/cache/descriptor.c @@ -8,20 +8,8 @@ void cpuinfo_x86_decode_cache_descriptor( enum cpuinfo_vendor vendor, const struct cpuinfo_x86_model_info* model_info, struct cpuinfo_x86_caches* cache, - struct cpuinfo_tlb* itlb_4KB, - struct cpuinfo_tlb* itlb_2MB, - struct cpuinfo_tlb* itlb_4MB, - struct cpuinfo_tlb* dtlb0_4KB, - struct cpuinfo_tlb* dtlb0_2MB, - struct cpuinfo_tlb* dtlb0_4MB, - struct cpuinfo_tlb* dtlb_4KB, - struct cpuinfo_tlb* dtlb_2MB, - struct cpuinfo_tlb* dtlb_4MB, - struct cpuinfo_tlb* dtlb_1GB, - struct cpuinfo_tlb* stlb2_4KB, - struct cpuinfo_tlb* stlb2_2MB, - struct cpuinfo_tlb* stlb2_1GB, - uint32_t* prefetch_size) { + struct cpuinfo_x86_tlbs* tlb) +{ /* * Descriptors are parsed according to: * - Application Note 485: Intel Processor Indentification and CPUID @@ -41,7 +29,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-KB Pages, 4-way set * associative, 32 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -55,7 +43,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-MB Pages, fully associative, * 2 entries" */ - *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 2, .associativity = 2, .pages = CPUINFO_PAGE_SIZE_4MB, @@ -68,7 +56,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 64 entries" Application Note 485: "Data TLB: 4-KB * Pages, 4-way set associative, 64 entries" */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -81,7 +69,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 8 entries" Application Note 485: "Data TLB: 4-MB * Pages, 4-way set associative, 8 entries" */ - *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 8, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4MB, @@ -94,7 +82,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 32 entries" Application Note 485: "Data TLB: 4-MB * Pages, 4-way set associative, 32 entries" */ - *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4MB, @@ -172,7 +160,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-MB pages, 4-way set * associative, 4 entries" */ - *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 4, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4MB, @@ -710,7 +698,7 @@ void cpuinfo_x86_decode_cache_descriptor( * Application Note 485: * "Instruction TLB: 4-KB pages, 32 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 32, /* Assume full associativity from nearby * entries: manual lacks detail @@ -727,7 +715,7 @@ void cpuinfo_x86_decode_cache_descriptor( * TLB: 4-KB, 2-MB or 4-MB pages, fully associative, 64 * entries" */ - *itlb_4KB = *itlb_2MB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = tlb->itlb_2MB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 64, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -741,7 +729,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-KB, 2-MB or 4-MB pages, fully * associative, 128 entries" */ - *itlb_4KB = *itlb_2MB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = tlb->itlb_2MB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 128, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -755,7 +743,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-KB, 2-MB or 4-MB pages, fully * associative, 256 entries" */ - *itlb_4KB = *itlb_2MB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = tlb->itlb_2MB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 256, .associativity = 256, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -769,7 +757,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 2-MB or 4-MB pages, fully * associative, 7 entries" */ - *itlb_2MB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_2MB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 7, .associativity = 7, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -782,7 +770,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 16 entries" Application Note 485: "L1 Data TLB: 4-MB * pages, 4-way set associative, 16 entries" */ - *dtlb0_4MB = (struct cpuinfo_tlb){ + tlb->dtlb0_4MB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4MB, @@ -795,7 +783,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "L1 Data TLB: 4-KB * pages, 4-way set associative, 16 entries" */ - *dtlb0_4KB = (struct cpuinfo_tlb){ + tlb->dtlb0_4KB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -808,7 +796,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "Data TLB0: 4-KB * pages, fully associative, 16 entries" */ - *dtlb0_4KB = (struct cpuinfo_tlb){ + tlb->dtlb0_4KB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 16, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -822,7 +810,7 @@ void cpuinfo_x86_decode_cache_descriptor( * TLB0: 2-MB or 4-MB pages, 4-way associative, 32 * entries" */ - *dtlb0_2MB = *dtlb0_4MB = (struct cpuinfo_tlb){ + tlb->dtlb0_2MB = tlb->dtlb0_4MB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -836,7 +824,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Data TLB: 4-KB or 4-MB pages, fully associative, * 64 entries" */ - *dtlb_4KB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 64, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_4MB, @@ -849,7 +837,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "Data TLB: 4-KB or * 4-MB pages, fully associative, 128 entries" */ - *dtlb_4KB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 128, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_4MB, @@ -862,7 +850,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "Data TLB: 4-KB or * 4-MB pages, fully associative, 256 entries" */ - *dtlb_4KB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 256, .associativity = 256, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_4MB, @@ -888,7 +876,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4 KByte pages, fully * associative, 48 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 48, .associativity = 48, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -901,12 +889,12 @@ void cpuinfo_x86_decode_cache_descriptor( * associative, 32 entries and a separate array with 1 * GByte pages, 4-way set associative, 4 entries" */ - *dtlb_2MB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_2MB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, }; - *dtlb_1GB = (struct cpuinfo_tlb){ + tlb->dtlb_1GB = (struct cpuinfo_tlb) { .entries = 4, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_1GB, @@ -919,7 +907,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 512 entries" * */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 512, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -977,7 +965,7 @@ void cpuinfo_x86_decode_cache_descriptor( /* uTLB is, an fact, a normal 1-level DTLB on Silvermont * & Knoghts Landing */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -989,7 +977,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "DTLB: 4 KByte pages, 8-way set associative, 256 * entries" */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 256, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1001,7 +989,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "DTLB: 2M/4M pages, 8-way set associative, 128 * entries" */ - *dtlb_2MB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_2MB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -1013,7 +1001,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "DTLB: 1 GByte pages, fully associative, 16 * entries" */ - *dtlb_1GB = (struct cpuinfo_tlb){ + tlb->dtlb_1GB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 16, .pages = CPUINFO_PAGE_SIZE_1GB, @@ -1033,7 +1021,7 @@ void cpuinfo_x86_decode_cache_descriptor( #if CPUINFO_ARCH_X86 case cpuinfo_vendor_cyrix: case cpuinfo_vendor_nsc: - *dtlb_4KB = *itlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1085,7 +1073,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 8 entries" Application Note 485: "Instruction TLB: * 2M/4M pages, fully associative, 8 entries" */ - *itlb_2MB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_2MB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 8, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -1352,7 +1340,7 @@ void cpuinfo_x86_decode_cache_descriptor( * Intel ISA Reference: * "DTLB: 4k pages, fully associative, 32 entries" */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 32, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1366,7 +1354,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-KB Pages, 4-way set associative, * 128 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1380,12 +1368,12 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 2-MB pages, 4-way, 8 entries or 4M * pages, 4-way, 4 entries" */ - *itlb_2MB = (struct cpuinfo_tlb){ + tlb->itlb_2MB = (struct cpuinfo_tlb) { .entries = 8, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, }; - *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 4, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -1399,7 +1387,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4-KB pages, 4-way set * associative, 64 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1412,7 +1400,7 @@ void cpuinfo_x86_decode_cache_descriptor( * 128 entries" Application Note 485: "Data TLB: 4-KB * Pages, 4-way set associative, 128 entries" */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1425,7 +1413,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "Data TLB: 4-KB Pages, * 4-way set associative, 256 entries" */ - *dtlb_4KB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = (struct cpuinfo_tlb) { .entries = 256, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1437,7 +1425,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4KByte pages, 8-way set * associative, 64 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1449,7 +1437,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Instruction TLB: 4KByte pages, 8-way set * associative, 128 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 128, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1462,7 +1450,7 @@ void cpuinfo_x86_decode_cache_descriptor( * entries" Application Note 485: "Data TLB: 4-KB Pages, * 4-way set associative, 64 entries" */ - *itlb_4KB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = (struct cpuinfo_tlb) { .entries = 64, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, @@ -1476,7 +1464,7 @@ void cpuinfo_x86_decode_cache_descriptor( * TLB: 4-KB or 4-MB Pages, 4-way set associative, 8 * entries" */ - *itlb_4KB = *itlb_4MB = (struct cpuinfo_tlb){ + tlb->itlb_4KB = tlb->itlb_4MB = (struct cpuinfo_tlb) { .entries = 8, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_4MB, @@ -1488,7 +1476,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Shared 2nd-Level TLB: 4 KByte/2MByte pages, * 8-way associative, 1024 entries" */ - *stlb2_4KB = *stlb2_2MB = (struct cpuinfo_tlb){ + tlb->stlb2_4KB = tlb->stlb2_2MB = (struct cpuinfo_tlb) { .entries = 1024, .associativity = 8, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB, @@ -1500,7 +1488,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "DTLB: 4 KByte/2 MByte pages, 4-way associative, * 16 entries" */ - *dtlb_4KB = *dtlb_2MB = (struct cpuinfo_tlb){ + tlb->dtlb_4KB = tlb->dtlb_2MB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB, @@ -1513,12 +1501,12 @@ void cpuinfo_x86_decode_cache_descriptor( * 6-way associative, 1536 entries. Also 1GBbyte pages, * 4-way, 16 entries." */ - *stlb2_4KB = *stlb2_2MB = (struct cpuinfo_tlb){ + tlb->stlb2_4KB = tlb->stlb2_2MB = (struct cpuinfo_tlb) { .entries = 1536, .associativity = 6, .pages = CPUINFO_PAGE_SIZE_4KB | CPUINFO_PAGE_SIZE_2MB, }; - *stlb2_1GB = (struct cpuinfo_tlb){ + tlb->stlb2_1GB = (struct cpuinfo_tlb) { .entries = 16, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_1GB, @@ -1530,7 +1518,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "DTLB: 2M/4M Byte pages, 4-way associative, 32 * entries" */ - *dtlb_2MB = *dtlb_4MB = (struct cpuinfo_tlb){ + tlb->dtlb_2MB = tlb->dtlb_4MB = (struct cpuinfo_tlb) { .entries = 32, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_2MB | CPUINFO_PAGE_SIZE_4MB, @@ -1544,7 +1532,7 @@ void cpuinfo_x86_decode_cache_descriptor( * "Shared 2nd-level TLB: 4 KB pages, 4-way set * associative, 512 entries" */ - *stlb2_4KB = (struct cpuinfo_tlb){ + tlb->stlb2_4KB = (struct cpuinfo_tlb) { .entries = 512, .associativity = 4, .pages = CPUINFO_PAGE_SIZE_4KB, diff --git a/src/x86/cache/init.c b/src/x86/cache/init.c index 34af90e7..04d95491 100644 --- a/src/x86/cache/init.c +++ b/src/x86/cache/init.c @@ -25,20 +25,9 @@ void cpuinfo_x86_detect_cache( enum cpuinfo_vendor vendor, const struct cpuinfo_x86_model_info* model_info, struct cpuinfo_x86_caches* cache, - struct cpuinfo_tlb* itlb_4KB, - struct cpuinfo_tlb* itlb_2MB, - struct cpuinfo_tlb* itlb_4MB, - struct cpuinfo_tlb* dtlb0_4KB, - struct cpuinfo_tlb* dtlb0_2MB, - struct cpuinfo_tlb* dtlb0_4MB, - struct cpuinfo_tlb* dtlb_4KB, - struct cpuinfo_tlb* dtlb_2MB, - struct cpuinfo_tlb* dtlb_4MB, - struct cpuinfo_tlb* dtlb_1GB, - struct cpuinfo_tlb* stlb2_4KB, - struct cpuinfo_tlb* stlb2_2MB, - struct cpuinfo_tlb* stlb2_1GB, - uint32_t* log2_package_cores_max) { + struct cpuinfo_x86_tlbs* tlb, + struct cpuinfo_x86_topology* topology) +{ if (max_base_index >= 2) { union cpuinfo_x86_cache_descriptors descriptors; descriptors.regs = cpuid(2); @@ -49,24 +38,7 @@ void cpuinfo_x86_detect_cache( const uint8_t descriptor = descriptors.as_bytes[i]; if (descriptor != 0) { cpuinfo_x86_decode_cache_descriptor( - descriptor, - vendor, - model_info, - cache, - itlb_4KB, - itlb_2MB, - itlb_4MB, - dtlb0_4KB, - dtlb0_2MB, - dtlb0_4MB, - dtlb_4KB, - dtlb_2MB, - dtlb_4MB, - dtlb_1GB, - stlb2_4KB, - stlb2_2MB, - stlb2_1GB, - &cache->prefetch_size); + descriptor, vendor, model_info, cache, tlb); } } if (--iterations != 0) { @@ -83,7 +55,7 @@ void cpuinfo_x86_detect_cache( leaf4 = cpuidex(4, input_ecx++); } while (cpuinfo_x86_decode_deterministic_cache_parameters(leaf4, cache, &package_cores_max)); if (package_cores_max != 0) { - *log2_package_cores_max = bit_length(package_cores_max); + topology->core_bits_length = bit_length(package_cores_max); } } } diff --git a/src/x86/init.c b/src/x86/init.c index adc5d361..c87c27a1 100644 --- a/src/x86/init.c +++ b/src/x86/init.c @@ -41,26 +41,8 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { const bool amd_topology_extensions = !!(leaf0x80000001.ecx & UINT32_C(0x00400000)); cpuinfo_x86_detect_cache( - max_base_index, - max_extended_index, - amd_topology_extensions, - vendor, - &model_info, - &processor->cache, - &processor->tlb.itlb_4KB, - &processor->tlb.itlb_2MB, - &processor->tlb.itlb_4MB, - &processor->tlb.dtlb0_4KB, - &processor->tlb.dtlb0_2MB, - &processor->tlb.dtlb0_4MB, - &processor->tlb.dtlb_4KB, - &processor->tlb.dtlb_2MB, - &processor->tlb.dtlb_4MB, - &processor->tlb.dtlb_1GB, - &processor->tlb.stlb2_4KB, - &processor->tlb.stlb2_2MB, - &processor->tlb.stlb2_1GB, - &processor->topology.core_bits_length); + max_base_index, max_extended_index, amd_topology_extensions, vendor, + &model_info, &processor->cache, &processor->tlb, &processor->topology); cpuinfo_x86_detect_topology(max_base_index, max_extended_index, leaf1, &processor->topology); From 085a58dc1cf90d30fa251f8648968ab90e490bcf Mon Sep 17 00:00:00 2001 From: Balakrishnan Unnithan Date: Tue, 4 Feb 2025 22:27:35 +0530 Subject: [PATCH 2/2] cache cpu info in a file at boot Instrumented cpuinfo to read the populated cpu info data from cpuid.info file during initialization. Consumers of the library or OEMs can trigger a oneshot service - cpuinfo-svc - during device boot to link libcpuinfo and dump all cpu info related to processor, model, arch and isa capabilities into cpuid.info file. This arrangement will limit cpuid() intrinsic calls (which causes VM-Exit events and performance overhead) to only once during init of libcpuinfo at boot by cpuinfo-svc. Signed-off-by: Balakrishnan Unnithan --- deps/clog/include/clog.h | 6 +- include/cpuinfo.h | 27 +++++++++ src/x86/init.c | 39 ++++++++++++- src/x86/isa.c | 18 ++++++ src/x86/linux/api.h | 17 ++++++ src/x86/linux/cpuinfo.c | 123 +++++++++++++++++++++++++++++++++++++++ tools/cpuinfo-svc.c | 94 ++++++++++++++++++++++++++++++ 7 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 tools/cpuinfo-svc.c diff --git a/deps/clog/include/clog.h b/deps/clog/include/clog.h index 41437611..3186c552 100644 --- a/deps/clog/include/clog.h +++ b/deps/clog/include/clog.h @@ -12,7 +12,11 @@ #define CLOG_DEBUG 5 #ifndef CLOG_VISIBILITY - #if defined(__ELF__) + #if defined(__GNUC__) + // ld.lld: error: undefined hidden symbol: clog_vlog_error + // referenced by log.h:16 (external/cpuinfo/src/cpuinfo/log.h) + #define CLOG_VISIBILITY + #elif defined(__ELF__) #define CLOG_VISIBILITY __attribute__((__visibility__("internal"))) #elif defined(__MACH__) #define CLOG_VISIBILITY __attribute__((__visibility__("hidden"))) diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 8bb1db4e..3ca90359 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -860,11 +860,38 @@ struct cpuinfo_x86_isa { bool phe; bool pmm; bool lwp; + bool erms; + bool smap; + bool serialize; }; extern struct cpuinfo_x86_isa cpuinfo_isa; #endif +static inline bool cpuinfo_has_x86_erms(void) { + #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.erms; + #else + return false; + #endif +} + +static inline bool cpuinfo_has_x86_smap(void) { + #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.smap; + #else + return false; + #endif +} + +static inline bool cpuinfo_has_x86_serialize(void) { + #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.serialize; + #else + return false; + #endif +} + static inline bool cpuinfo_has_x86_rdtsc(void) { #if CPUINFO_ARCH_X86_64 return true; diff --git a/src/x86/init.c b/src/x86/init.c index c87c27a1..eb96e2fc 100644 --- a/src/x86/init.c +++ b/src/x86/init.c @@ -7,11 +7,41 @@ #include #include #include +#include -struct cpuinfo_x86_isa cpuinfo_isa = {0}; +/* + * Structs cpuinfo_x86_isa, cpuinfo_x86_model_info and cpuinfo_x86_processor + * are dumped into cpuid.info file by cpuinfo-svc service on boot. + * Whenever libcpuinfo is initialized by any application, it will attempt to + * read cpuid.info file, if it exists, and the binary dump in the file is + * copied to these structs. If the file doesn't exist, we will fall back to + * original method of calling __cpuid() intrinsics to get the info. + * By this method, we can avoid __cpuid() calls during each init of cpuinfo. + * This will reduce VMX events in virtualized environments thereby + * improving performance. + */ + + +#ifdef __ANDROID__ +struct cpuinfo_x86_cpuid_info x86_cpuid_info = { 0 }; +#endif // __ANDROID__ + +struct cpuinfo_x86_isa cpuinfo_isa = { 0 }; CPUINFO_INTERNAL uint32_t cpuinfo_x86_clflush_size = 0; void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { +#ifdef __ANDROID__ + if (cpuinfo_x86_linux_parse_cpuid_info(&x86_cpuid_info)) { + *processor = x86_cpuid_info.processor; + cpuinfo_isa = x86_cpuid_info.isa; + #ifdef __DEBUG__ + print_cpuid_info_file(); + #endif + return; + } + cpuinfo_log_debug("falling back to __cpuid() method"); +#endif // __ANDROID__ + const struct cpuid_regs leaf0 = cpuid(0); const uint32_t max_base_index = leaf0.eax; const enum cpuinfo_vendor vendor = processor->vendor = @@ -48,6 +78,9 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { cpuinfo_isa = cpuinfo_x86_detect_isa( leaf1, leaf0x80000001, max_base_index, max_extended_index, vendor, uarch); +#ifdef __ANDROID__ + x86_cpuid_info.model = model_info; +#endif // __ANDROID__ } if (max_extended_index >= UINT32_C(0x80000004)) { struct cpuid_regs brand_string[3]; @@ -57,4 +90,8 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { memcpy(processor->brand_string, brand_string, sizeof(processor->brand_string)); cpuinfo_log_debug("raw CPUID brand string: \"%48s\"", processor->brand_string); } +#ifdef __ANDROID__ + x86_cpuid_info.isa = cpuinfo_isa; + x86_cpuid_info.processor = *processor; +#endif // __ANDROID__ } diff --git a/src/x86/isa.c b/src/x86/isa.c index bfd5e776..898a88c9 100644 --- a/src/x86/isa.c +++ b/src/x86/isa.c @@ -814,5 +814,23 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( */ isa.rdpid = !!(structured_feature_info0.ecx & UINT32_C(0x00400000)); + /* + * ERMS instruction: + * - Intel: ebx[bit 9] in structured feature info (ecx = 0). + */ + isa.erms = !!(structured_feature_info0.ebx & UINT32_C(0x00000200)); + + /* + * SMAP instruction: + * - Intel: ebx[bit 20] in structured feature info (ecx = 0). + */ + isa.smap = !!(structured_feature_info0.ebx & UINT32_C(0x00100000)); + + /* + * SERIALIZE instruction: + * - Intel: edx[bit 14] in structured feature info (ecx = 0). + */ + isa.serialize = !!(structured_feature_info0.edx & UINT32_C(0x00004000)); + return isa; } diff --git a/src/x86/linux/api.h b/src/x86/linux/api.h index 26fc5de0..c13b0f4d 100644 --- a/src/x86/linux/api.h +++ b/src/x86/linux/api.h @@ -17,3 +17,20 @@ struct cpuinfo_x86_linux_processor { CPUINFO_INTERNAL bool cpuinfo_x86_linux_parse_proc_cpuinfo( uint32_t max_processors_count, struct cpuinfo_x86_linux_processor processors[restrict static max_processors_count]); + +#ifdef __ANDROID__ +#define CPUID_INFO_FILE "/data/system/cpuid.info" + +struct cpuinfo_x86_cpuid_info { + struct cpuinfo_x86_isa isa; + struct cpuinfo_x86_model_info model; + struct cpuinfo_x86_processor processor; +}; + +CPUINFO_INTERNAL bool cpuinfo_x86_linux_parse_cpuid_info( + struct cpuinfo_x86_cpuid_info* x86_cpuid_info); + +#ifdef __DEBUG__ +CPUINFO_INTERNAL void print_cpuid_info_file(void); +#endif //__DEBUG__ +#endif //__ANDROID__ diff --git a/src/x86/linux/cpuinfo.c b/src/x86/linux/cpuinfo.c index 7df72aba..a9850cc3 100644 --- a/src/x86/linux/cpuinfo.c +++ b/src/x86/linux/cpuinfo.c @@ -217,3 +217,126 @@ bool cpuinfo_x86_linux_parse_proc_cpuinfo( return cpuinfo_linux_parse_multiline_file( "/proc/cpuinfo", BUFFER_SIZE, (cpuinfo_line_callback)parse_line, &state); } + +#ifdef __ANDROID__ +bool cpuinfo_x86_linux_parse_cpuid_info( + struct cpuinfo_x86_cpuid_info* x86_cpuid_info) +{ + cpuinfo_log_debug("reading cpuid.info file"); + FILE* fd_info = fopen(CPUID_INFO_FILE, "rb"); + if (!fd_info) { + cpuinfo_log_warning("failed to open file %s: %s", CPUID_INFO_FILE, strerror(errno)); + return false; + } + + int ret = fread(x86_cpuid_info, sizeof(struct cpuinfo_x86_cpuid_info), 1, fd_info); + if (!ret) { + cpuinfo_log_warning("failed to read cpuid info from %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + if (fclose(fd_info)) { + cpuinfo_log_warning("failed to close file %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + return ret ? true : false; +} + +#ifdef __DEBUG__ +void print_cpuid_info_file (void) +{ + cpuinfo_log_debug("----------------------------"); + /* + cpuinfo_log_debug("%-20s: %d", "ace", cpuinfo_has_x86_ace()); + cpuinfo_log_debug("%-20s: %d", "ace2", cpuinfo_has_x86_ace2()); + cpuinfo_log_debug("%-20s: %d", "clflush", cpuinfo_has_x86_clflush()); + cpuinfo_log_debug("%-20s: %d", "clflushopt", cpuinfo_has_x86_clflushopt()); + cpuinfo_log_debug("%-20s: %d", "lwp", cpuinfo_has_x86_lwp()); + cpuinfo_log_debug("%-20s: %d", "msr", cpuinfo_has_x86_msr()); + cpuinfo_log_debug("%-20s: %d", "phe", cpuinfo_has_x86_phe()); + cpuinfo_log_debug("%-20s: %d", "pmm", cpuinfo_has_x86_pmm()); + cpuinfo_log_debug("%-20s: %d", "rng", cpuinfo_has_x86_rng()); + cpuinfo_log_debug("%-20s: %d", "sysenter", cpuinfo_has_x86_sysenter()); + cpuinfo_log_debug("%-20s: %d", "syscall", cpuinfo_has_x86_syscall()); + cpuinfo_log_debug("%-20s: %d", "emmx", cpuinfo_has_x86_emmx()); + cpuinfo_log_debug("%-20s: %d", "fs_gs_base", cpuinfo_has_x86_fs_gs_base()); + cpuinfo_log_debug("%-20s: %d", "fxsave", cpuinfo_has_x86_fxsave()); + */ + cpuinfo_log_debug("%-20s: %d", "erms", cpuinfo_has_x86_erms()); + cpuinfo_log_debug("%-20s: %d", "smap", cpuinfo_has_x86_smap()); + cpuinfo_log_debug("%-20s: %d", "serialize", cpuinfo_has_x86_serialize()); + cpuinfo_log_debug("%-20s: %d", "adx", cpuinfo_has_x86_adx()); + cpuinfo_log_debug("%-20s: %d", "aes", cpuinfo_has_x86_aes()); + cpuinfo_log_debug("%-20s: %d", "avx", cpuinfo_has_x86_avx()); + cpuinfo_log_debug("%-20s: %d", "avx2", cpuinfo_has_x86_avx2()); + cpuinfo_log_debug("%-20s: %d", "avx512bf16", cpuinfo_has_x86_avx512bf16()); + cpuinfo_log_debug("%-20s: %d", "avx512bitalg", cpuinfo_has_x86_avx512bitalg()); + cpuinfo_log_debug("%-20s: %d", "avx512bw", cpuinfo_has_x86_avx512bw()); + cpuinfo_log_debug("%-20s: %d", "avx512cd", cpuinfo_has_x86_avx512cd()); + cpuinfo_log_debug("%-20s: %d", "avx512dq", cpuinfo_has_x86_avx512dq()); + cpuinfo_log_debug("%-20s: %d", "avx512er", cpuinfo_has_x86_avx512er()); + cpuinfo_log_debug("%-20s: %d", "avx512f", cpuinfo_has_x86_avx512f()); + cpuinfo_log_debug("%-20s: %d", "avx512ifma", cpuinfo_has_x86_avx512ifma()); + cpuinfo_log_debug("%-20s: %d", "avx512pf", cpuinfo_has_x86_avx512pf()); + cpuinfo_log_debug("%-20s: %d", "avx512vbmi", cpuinfo_has_x86_avx512vbmi()); + cpuinfo_log_debug("%-20s: %d", "avx512vbmi2", cpuinfo_has_x86_avx512vbmi2()); + cpuinfo_log_debug("%-20s: %d", "avx512vl", cpuinfo_has_x86_avx512vl()); + cpuinfo_log_debug("%-20s: %d", "avx512vnni", cpuinfo_has_x86_avx512vnni()); + cpuinfo_log_debug("%-20s: %d", "avx512vp2intersect", cpuinfo_has_x86_avx512vp2intersect()); + cpuinfo_log_debug("%-20s: %d", "avx512vpopcntdq", cpuinfo_has_x86_avx512vpopcntdq()); + cpuinfo_log_debug("%-20s: %d", "avx512_4fmaps", cpuinfo_has_x86_avx512_4fmaps()); + cpuinfo_log_debug("%-20s: %d", "avx512_4vnniw", cpuinfo_has_x86_avx512_4vnniw()); + cpuinfo_log_debug("%-20s: %d", "bmi", cpuinfo_has_x86_bmi()); + cpuinfo_log_debug("%-20s: %d", "bmi2", cpuinfo_has_x86_bmi2()); + cpuinfo_log_debug("%-20s: %d", "clwb", cpuinfo_has_x86_clwb()); + cpuinfo_log_debug("%-20s: %d", "clzero", cpuinfo_has_x86_clzero()); + cpuinfo_log_debug("%-20s: %d", "cmpxchg16b", cpuinfo_has_x86_cmpxchg16b()); + cpuinfo_log_debug("%-20s: %d", "f16c", cpuinfo_has_x86_f16c()); + cpuinfo_log_debug("%-20s: %d", "fma3", cpuinfo_has_x86_fma3()); + cpuinfo_log_debug("%-20s: %d", "fma4", cpuinfo_has_x86_fma4()); + cpuinfo_log_debug("%-20s: %d", "gfni", cpuinfo_has_x86_gfni()); + cpuinfo_log_debug("%-20s: %d", "hle", cpuinfo_has_x86_hle()); + cpuinfo_log_debug("%-20s: %d", "lzcnt", cpuinfo_has_x86_lzcnt()); + cpuinfo_log_debug("%-20s: %d", "misaligned_sse", cpuinfo_has_x86_misaligned_sse()); + cpuinfo_log_debug("%-20s: %d", "movbe", cpuinfo_has_x86_movbe()); + cpuinfo_log_debug("%-20s: %d", "mpx", cpuinfo_has_x86_mpx()); + cpuinfo_log_debug("%-20s: %d", "mwait", cpuinfo_has_x86_mwait()); + cpuinfo_log_debug("%-20s: %d", "mwaitx", cpuinfo_has_x86_mwaitx()); + cpuinfo_log_debug("%-20s: %d", "pclmulqdq", cpuinfo_has_x86_pclmulqdq()); + cpuinfo_log_debug("%-20s: %d", "popcnt", cpuinfo_has_x86_popcnt()); + cpuinfo_log_debug("%-20s: %d", "prefetch", cpuinfo_has_x86_prefetch()); + cpuinfo_log_debug("%-20s: %d", "prefetchw", cpuinfo_has_x86_prefetchw()); + cpuinfo_log_debug("%-20s: %d", "prefetchwt1", cpuinfo_has_x86_prefetchwt1()); + cpuinfo_log_debug("%-20s: %d", "rdpid", cpuinfo_has_x86_rdpid()); + cpuinfo_log_debug("%-20s: %d", "rdrand", cpuinfo_has_x86_rdrand()); + cpuinfo_log_debug("%-20s: %d", "rdseed", cpuinfo_has_x86_rdseed()); + cpuinfo_log_debug("%-20s: %d", "rdtscp", cpuinfo_has_x86_rdtscp()); + cpuinfo_log_debug("%-20s: %d", "rtm", cpuinfo_has_x86_rtm()); + cpuinfo_log_debug("%-20s: %d", "sha", cpuinfo_has_x86_sha()); + cpuinfo_log_debug("%-20s: %d", "sse3", cpuinfo_has_x86_sse3()); + cpuinfo_log_debug("%-20s: %d", "sse4a", cpuinfo_has_x86_sse4a()); + cpuinfo_log_debug("%-20s: %d", "sse4_1", cpuinfo_has_x86_sse4_1()); + cpuinfo_log_debug("%-20s: %d", "sse4_2", cpuinfo_has_x86_sse4_2()); + cpuinfo_log_debug("%-20s: %d", "ssse3", cpuinfo_has_x86_ssse3()); + cpuinfo_log_debug("%-20s: %d", "tbm", cpuinfo_has_x86_tbm()); + cpuinfo_log_debug("%-20s: %d", "three_d_now", cpuinfo_has_x86_3dnow()); + cpuinfo_log_debug("%-20s: %d", "three_d_now_plus", cpuinfo_has_x86_3dnow_plus()); + cpuinfo_log_debug("%-20s: %d", "vaes", cpuinfo_has_x86_vaes()); + cpuinfo_log_debug("%-20s: %d", "vpclmulqdq", cpuinfo_has_x86_vpclmulqdq()); + cpuinfo_log_debug("%-20s: %d", "xop", cpuinfo_has_x86_xop()); + cpuinfo_log_debug("%-20s: %d", "xsave", cpuinfo_has_x86_xsave()); + cpuinfo_log_debug("%-20s: %d", "xtest", cpuinfo_has_x86_xtest()); + cpuinfo_log_debug("%-20s: %d", "cmov", cpuinfo_has_x86_cmov()); + cpuinfo_log_debug("%-20s: %d", "cmpxchg8b", cpuinfo_has_x86_cmpxchg8b()); + cpuinfo_log_debug("%-20s: %d", "daz", cpuinfo_has_x86_daz()); + cpuinfo_log_debug("%-20s: %d", "fpu", cpuinfo_has_x86_fpu()); + cpuinfo_log_debug("%-20s: %d", "mmx", cpuinfo_has_x86_mmx()); + cpuinfo_log_debug("%-20s: %d", "mmx_plus", cpuinfo_has_x86_mmx_plus()); + cpuinfo_log_debug("%-20s: %d", "rdtsc", cpuinfo_has_x86_rdtsc()); + cpuinfo_log_debug("%-20s: %d", "sse", cpuinfo_has_x86_sse()); + cpuinfo_log_debug("%-20s: %d", "sse2", cpuinfo_has_x86_sse2()); + cpuinfo_log_debug("%-20s: %d", "three_d_now_geode", cpuinfo_has_x86_3dnow_geode()); + cpuinfo_log_debug("%-20s: %d", "lahf_sahf", cpuinfo_has_x86_lahf_sahf()); + cpuinfo_log_debug("----------------------------"); +} +#endif // __DEBUG__ +#endif // __ANDROID__ diff --git a/tools/cpuinfo-svc.c b/tools/cpuinfo-svc.c new file mode 100644 index 00000000..2148363b --- /dev/null +++ b/tools/cpuinfo-svc.c @@ -0,0 +1,94 @@ +/* Copyright (C) 2024 Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + *    this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + *    this list of conditions and the following disclaimer in the documentation + *    and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Description: cpuinfo-service to initialize and dump cpu info collected + * through __cpuid() calls during device boot. + * it will delete cpuid.info file if it exits and create new. + * + * Author: Unnithan, Balakrishnan + */ + + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef __ANDROID__ +extern struct cpuinfo_x86_cpuid_info x86_cpuid_info; + +CPUINFO_INTERNAL bool write_cpuid_info_file (void) { + cpuinfo_log_debug("writing cpuid.info file"); + FILE* fd_info = fopen(CPUID_INFO_FILE, "wb"); + if (!fd_info) { + cpuinfo_log_error("failed to open file %s: %s", CPUID_INFO_FILE, strerror(errno)); + return false; + } + + int ret = fwrite(&x86_cpuid_info, sizeof(struct cpuinfo_x86_cpuid_info), 1, fd_info); + if (!ret) { + cpuinfo_log_error("failed to write cpuid info in %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + if (fclose(fd_info)) { + cpuinfo_log_error("failed to close file %s: %s", CPUID_INFO_FILE, strerror(errno)); + return false; + } + + return ret ? true : false; +} +#endif // __ANDROID__ + +int main (void) { + cpuinfo_log_info("start service"); +#ifdef __ANDROID__ + if (remove(CPUID_INFO_FILE)) { + cpuinfo_log_warning("failed to delete file %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + if (!cpuinfo_initialize()) { + cpuinfo_log_error("failed to init cpuinfo lib. exit"); + return 1; + } + + if (!write_cpuid_info_file()) { + cpuinfo_log_error("failed to save cpuid info. exit"); + return 1; + } +#endif // __ANDROID__ + cpuinfo_log_info("exit service"); + return 0; +} \ No newline at end of file