int os_perf_cpuarr_refresh(perf_cpu_t *cpu_arr, int cpu_num, int *cpuid_arr, int id_num, boolean_t init) { int i, j, k; perf_cpu_t *cpu; for (i = 0; i < cpu_num; i++) { cpu_arr[i].hit = B_FALSE; } for (i = 0; i < id_num; i++) { if ((cpu = cpu_find(cpu_arr, cpu_num, cpuid_arr[i])) == NULL) { /* * New CPU found. */ if ((j = free_idx_get(cpu_arr, cpu_num, i)) == -1) { return (-1); } cpu_arr[j].cpuid = cpuid_arr[i]; cpu_arr[j].map_base = MAP_FAILED; for (k = 0; k < COUNT_NUM; k++) { cpu_arr[j].fds[k] = INVALID_FD; } cpu_arr[j].hit = B_TRUE; cpu_arr[j].hotadd = !init; if (cpu_arr[j].hotadd) { debug_print(NULL, 2, "cpu%d is hot-added.\n", cpu_arr[i].cpuid); } } else { cpu->hit = B_TRUE; } } for (i = 0; i < cpu_num; i++) { if ((!cpu_arr[i].hit) && (cpu_arr[i].cpuid != INVALID_CPUID)) { /* * This CPU is invalid now. */ cpu_arr[i].hotremove = B_TRUE; debug_print(NULL, 2, "cpu%d is hot-removed.\n", cpu_arr[i].cpuid); } } return (0); }
/* * Find CPU by pcpu pointer. */ static struct cpu_info * cpu_get_info(struct pcpu *pc) { struct cpu_info *cpup; int id; #ifdef __aarch64__ id = pc->pc_acpi_id; #else id = pc->pc_apic_id; #endif cpup = cpu_find(id); if (cpup == NULL) panic("SRAT: CPU with ID %u is not known", id); return (cpup); }
/*********************************************************************** * StackWalk64 (DBGHELP.@) */ BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 frame, PVOID ctx, PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr) { struct cpu_stack_walk csw; struct cpu* cpu; TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n", MachineType, hProcess, hThread, frame, ctx, f_read_mem, FunctionTableAccessRoutine, GetModuleBaseRoutine, f_xlat_adr); if (!(cpu = cpu_find(MachineType))) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } csw.hProcess = hProcess; csw.hThread = hThread; csw.is32 = FALSE; /* sigh... MS isn't even consistent in the func prototypes */ csw.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64; csw.u.s64.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear; csw.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64; csw.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64; if (!cpu->stack_walk(&csw, frame, ctx)) return FALSE; /* we don't handle KdHelp */ frame->KdHelp.Thread = 0xC000FADE; frame->KdHelp.ThCallbackStack = 0x10; frame->KdHelp.ThCallbackBStore = 0; frame->KdHelp.NextCallback = 0; frame->KdHelp.FramePointer = 0; frame->KdHelp.KiCallUserMode = 0xD000DAFE; frame->KdHelp.KeUserCallbackDispatcher = 0xE000F000; frame->KdHelp.SystemRangeStart = 0xC0000000; frame->KdHelp.Reserved[0] /* KiUserExceptionDispatcher */ = 0xE0005000; return TRUE; }
static void srat_parse_entry(ACPI_SUBTABLE_HEADER *entry, void *arg) { ACPI_SRAT_CPU_AFFINITY *cpu; ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic; ACPI_SRAT_MEM_AFFINITY *mem; ACPI_SRAT_GICC_AFFINITY *gicc; static struct cpu_info *cpup; int domain, i, slot; switch (entry->Type) { case ACPI_SRAT_TYPE_CPU_AFFINITY: cpu = (ACPI_SRAT_CPU_AFFINITY *)entry; domain = cpu->ProximityDomainLo | cpu->ProximityDomainHi[0] << 8 | cpu->ProximityDomainHi[1] << 16 | cpu->ProximityDomainHi[2] << 24; if (bootverbose) printf("SRAT: Found CPU APIC ID %u domain %d: %s\n", cpu->ApicId, domain, (cpu->Flags & ACPI_SRAT_CPU_ENABLED) ? "enabled" : "disabled"); if (!(cpu->Flags & ACPI_SRAT_CPU_ENABLED)) break; cpup = cpu_find(cpu->ApicId); if (cpup != NULL) { printf("SRAT: Duplicate local APIC ID %u\n", cpu->ApicId); *(int *)arg = ENXIO; break; } cpup = cpu_add(cpu->ApicId, domain); if (cpup == NULL) printf("SRAT: Ignoring local APIC ID %u (too high)\n", cpu->ApicId); break; case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY: x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)entry; if (bootverbose) printf("SRAT: Found CPU APIC ID %u domain %d: %s\n", x2apic->ApicId, x2apic->ProximityDomain, (x2apic->Flags & ACPI_SRAT_CPU_ENABLED) ? "enabled" : "disabled"); if (!(x2apic->Flags & ACPI_SRAT_CPU_ENABLED)) break; KASSERT(cpu_find(x2apic->ApicId) == NULL, ("Duplicate local APIC ID %u", x2apic->ApicId)); cpup = cpu_add(x2apic->ApicId, x2apic->ProximityDomain); if (cpup == NULL) printf("SRAT: Ignoring local APIC ID %u (too high)\n", x2apic->ApicId); break; case ACPI_SRAT_TYPE_GICC_AFFINITY: gicc = (ACPI_SRAT_GICC_AFFINITY *)entry; if (bootverbose) printf("SRAT: Found CPU UID %u domain %d: %s\n", gicc->AcpiProcessorUid, gicc->ProximityDomain, (gicc->Flags & ACPI_SRAT_GICC_ENABLED) ? "enabled" : "disabled"); if (!(gicc->Flags & ACPI_SRAT_GICC_ENABLED)) break; KASSERT(cpu_find(gicc->AcpiProcessorUid) == NULL, ("Duplicate CPU UID %u", gicc->AcpiProcessorUid)); cpup = cpu_add(gicc->AcpiProcessorUid, gicc->ProximityDomain); if (cpup == NULL) printf("SRAT: Ignoring CPU UID %u (too high)\n", gicc->AcpiProcessorUid); break; case ACPI_SRAT_TYPE_MEMORY_AFFINITY: mem = (ACPI_SRAT_MEM_AFFINITY *)entry; if (bootverbose) printf( "SRAT: Found memory domain %d addr 0x%jx len 0x%jx: %s\n", mem->ProximityDomain, (uintmax_t)mem->BaseAddress, (uintmax_t)mem->Length, (mem->Flags & ACPI_SRAT_MEM_ENABLED) ? "enabled" : "disabled"); if (!(mem->Flags & ACPI_SRAT_MEM_ENABLED)) break; if (mem->BaseAddress >= maxphyaddr || !overlaps_phys_avail(mem->BaseAddress, mem->BaseAddress + mem->Length)) { printf("SRAT: Ignoring memory at addr 0x%jx\n", (uintmax_t)mem->BaseAddress); break; } if (num_mem == VM_PHYSSEG_MAX) { printf("SRAT: Too many memory regions\n"); *(int *)arg = ENXIO; break; } slot = num_mem; for (i = 0; i < num_mem; i++) { if (mem_info[i].end <= mem->BaseAddress) continue; if (mem_info[i].start < (mem->BaseAddress + mem->Length)) { printf("SRAT: Overlapping memory entries\n"); *(int *)arg = ENXIO; return; } slot = i; } for (i = num_mem; i > slot; i--) mem_info[i] = mem_info[i - 1]; mem_info[slot].start = mem->BaseAddress; mem_info[slot].end = mem->BaseAddress + mem->Length; mem_info[slot].domain = mem->ProximityDomain; num_mem++; break; } }
/*********************************************************************** * StackWalk (DBGHELP.@) */ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME frame32, PVOID ctx, PREAD_PROCESS_MEMORY_ROUTINE f_read_mem, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr) { struct cpu_stack_walk csw; STACKFRAME64 frame64; BOOL ret; struct cpu* cpu; TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n", MachineType, hProcess, hThread, frame32, ctx, f_read_mem, FunctionTableAccessRoutine, GetModuleBaseRoutine, f_xlat_adr); if (!(cpu = cpu_find(MachineType))) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } addr_32to64(&frame32->AddrPC, &frame64.AddrPC); addr_32to64(&frame32->AddrReturn, &frame64.AddrReturn); addr_32to64(&frame32->AddrFrame, &frame64.AddrFrame); addr_32to64(&frame32->AddrStack, &frame64.AddrStack); addr_32to64(&frame32->AddrBStore, &frame64.AddrBStore); frame64.FuncTableEntry = frame32->FuncTableEntry; /* FIXME */ frame64.Far = frame32->Far; frame64.Virtual = frame32->Virtual; frame64.Reserved[0] = frame32->Reserved[0]; frame64.Reserved[1] = frame32->Reserved[1]; frame64.Reserved[2] = frame32->Reserved[2]; /* we don't handle KdHelp */ csw.hProcess = hProcess; csw.hThread = hThread; csw.is32 = TRUE; /* sigh... MS isn't even consistent in the func prototypes */ csw.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem; csw.u.s32.f_xlat_adr = f_xlat_adr; csw.u.s32.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess; csw.u.s32.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase; if ((ret = cpu->stack_walk(&csw, &frame64, ctx))) { addr_64to32(&frame64.AddrPC, &frame32->AddrPC); addr_64to32(&frame64.AddrReturn, &frame32->AddrReturn); addr_64to32(&frame64.AddrFrame, &frame32->AddrFrame); addr_64to32(&frame64.AddrStack, &frame32->AddrStack); addr_64to32(&frame64.AddrBStore, &frame32->AddrBStore); frame32->FuncTableEntry = frame64.FuncTableEntry; /* FIXME */ frame32->Params[0] = frame64.Params[0]; frame32->Params[1] = frame64.Params[1]; frame32->Params[2] = frame64.Params[2]; frame32->Params[3] = frame64.Params[3]; frame32->Far = frame64.Far; frame32->Virtual = frame64.Virtual; frame32->Reserved[0] = frame64.Reserved[0]; frame32->Reserved[1] = frame64.Reserved[1]; frame32->Reserved[2] = frame64.Reserved[2]; } return ret; }