/* find descriptor with type == 0 */ for (;;) { if (tablelen < 3) return;
len = 2 + ftrs[0]; if (tablelen < len) return; /* descriptor 0 not found */ if (ftrs[1] == 0) break;
tablelen -= len;
ftrs += len;
}
/* loop over bits we know about */ for (i = 0; i < ft_size; ++i, ++fp) { if (fp->pabyte >= ftrs[0]) continue;
bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; if (bit && !fp->clear) {
cur_cpu_spec->cpu_features |= fp->cpu_features;
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
cur_cpu_spec->cpu_user_features2 |= fp->cpu_user_ftrs2;
cur_cpu_spec->mmu_features |= fp->mmu_features;
} elseif (bit == fp->clear) {
cur_cpu_spec->cpu_features &= ~fp->cpu_features;
cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
cur_cpu_spec->cpu_user_features2 &= ~fp->cpu_user_ftrs2;
cur_cpu_spec->mmu_features &= ~fp->mmu_features;
}
}
}
for (i = 0; i < (int)ARRAY_SIZE(feature_properties); ++i, ++fp) {
prop = of_get_flat_dt_prop(node, fp->name, NULL); if (prop && be32_to_cpup(prop) >= fp->min_value) {
cur_cpu_spec->cpu_features |= fp->cpu_feature;
cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr;
}
}
}
staticint __init early_init_dt_scan_cpus(unsignedlong node, constchar *uname, int depth, void *data)
{ constchar *type = of_get_flat_dt_prop(node, "device_type", NULL); const __be32 *cpu_version = NULL; const __be32 *prop; const __be32 *intserv; int i, nthreads; int len; int found = -1; int found_thread = 0;
/* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return0;
if (IS_ENABLED(CONFIG_PPC64))
boot_cpu_node_count++;
/* Get physical cpuid */
intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len); if (!intserv)
intserv = of_get_flat_dt_prop(node, "reg", &len);
nthreads = len / sizeof(int);
/* *Nowseeifanyofthesethreadsmatchourbootcpu. *NOTE:Thismustmatchtheparsingdoneinsmp_setup_cpu_maps.
*/ for (i = 0; i < nthreads; i++) { if (be32_to_cpu(intserv[i]) ==
fdt_boot_cpuid_phys(initial_boot_params)) {
found = boot_cpu_count;
found_thread = i;
} #ifdef CONFIG_SMP /* logical cpu id is always 0 on UP kernels */
boot_cpu_count++; #endif
}
/* Not the boot CPU */ if (found < 0) return0;
boot_cpuid = found;
if (IS_ENABLED(CONFIG_PPC64))
boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
if (nr_cpu_ids % nthreads != 0) {
set_nr_cpu_ids(ALIGN(nr_cpu_ids, nthreads));
pr_warn("nr_cpu_ids was not a multiple of threads_per_core, adjusted to %d\n",
nr_cpu_ids);
}
if (boot_cpuid >= nr_cpu_ids) { // Remember boot core for smp_setup_cpu_maps()
boot_core_hwid = be32_to_cpu(intserv[0]);
pr_warn("Boot CPU %d (core hwid %d) >= nr_cpu_ids, adjusted boot CPU to %d\n",
boot_cpuid, boot_core_hwid, found_thread);
// Adjust boot CPU to appear on logical core 0
boot_cpuid = found_thread;
}
// We can now add the CPU name & PVR to the hardware description
seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR)); if (cpu_version)
seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(cpu_version));
staticint __init early_init_dt_scan_chosen_ppc(unsignedlong node, constchar *uname, int depth, void *data)
{ constunsignedlong *lprop; /* All these set by kernel, so no need to convert endian */
/* Use common scan routine to determine if this is the chosen node */ if (early_init_dt_scan_chosen(data) < 0) return0;
#ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
iommu_is_off = 1; if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
iommu_force_on = 1; #endif
/* mem=x on the command line is the preferred mechanism */
lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL); if (lprop)
memory_limit = *lprop;
/* Each reserved range is an (address,size) pair, 2 cells each,
* totalling 4 cells per range. */ for (i = 0; i < len / (sizeof(*prop) * 4); i++) {
u64 base, size;
base = of_read_number(prop + (i * 4) + 0, 2);
size = of_read_number(prop + (i * 4) + 2, 2);
/* Too early to BUG_ON(), do it by hand */ if (!early_init_dt_verify(params, __pa(params)))
panic("BUG: Failed verifying flat device tree, bad version?");
of_scan_flat_dt(early_init_dt_scan_model, NULL);
#ifdef CONFIG_PPC_RTAS /* Some machines might need RTAS info for debugging, grab it now. */
of_scan_flat_dt(early_init_dt_scan_rtas, NULL); #endif
#ifdef CONFIG_PPC_POWERNV /* Some machines might need OPAL info for debugging, grab it now. */
of_scan_flat_dt(early_init_dt_scan_opal, NULL);
/* Scan tree for ultravisor feature */
of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL); #endif
#ifdefined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) /* scan tree to see if dump is active during last boot */
of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL); #endif
/* Retrieve various informations from the /chosen node of the *device-tree,includingtheplatformtype,initrdlocationand *size,TCEreserve,andmore...
*/
of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line);
/* make sure we've parsed cmdline for mem= before this */ if (memory_limit)
first_memblock_size = min_t(u64, first_memblock_size, memory_limit);
setup_initial_memory_limit(memstart_addr, first_memblock_size); /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */
memblock_reserve(PHYSICAL_START, __pa(_end) - PHYSICAL_START); #ifdef CONFIG_PPC64 /* If relocatable, reserve at least 32k for interrupt vectors etc. */
int_vector_size = __end_interrupts - _stext;
int_vector_size = max_t(phys_addr_t, SZ_32K, int_vector_size); #else /* If relocatable, reserve first 32k for interrupt vectors etc. */
int_vector_size = SZ_32K; #endif if (PHYSICAL_START > MEMORY_START)
memblock_reserve(MEMORY_START, int_vector_size);
reserve_kdump_trampoline(); #ifdefined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) /* *Ifwefailtoreservememoryforfirmware-assisteddumpthen *fallbacktokexecbasedkdump.
*/ if (fadump_reserve_mem() == 0) #endif
arch_reserve_crashkernel();
early_reserve_mem();
if (memory_limit > memblock_phys_mem_size())
memory_limit = 0;
/* Align down to 16 MB which is large page size with hash page translation */
memory_limit = ALIGN_DOWN(memory_limit ?: memblock_phys_mem_size(), SZ_16M);
memblock_enforce_memory_limit(memory_limit);
#ifdefined(CONFIG_PPC_BOOK3S_64) && defined(CONFIG_PPC_4K_PAGES) if (!early_radix_enabled())
memblock_cap_memory_range(0, 1UL << (H_MAX_PHYSMEM_BITS)); #endif
/* We may need to relocate the flat tree, do it now.
* FIXME .. and the initrd too? */
move_device_tree();
DBG("Scanning CPUs ...\n");
dt_cpu_ftrs_scan();
/* Retrieve CPU related informations from the flat tree *(altivecsupport,bootCPUID,...)
*/
of_scan_flat_dt(early_init_dt_scan_cpus, NULL); if (boot_cpuid < 0) {
printk("Failed to identify boot CPU !\n");
BUG();
}
save_fscr_to_task();
#ifdefined(CONFIG_SMP) && defined(CONFIG_PPC64) /* We'll later wait for secondaries to check in; there are *NCPUS-1non-bootCPUs:-)
*/
spinning_secondaries = boot_cpu_count - 1; #endif
mmu_early_init_devtree();
/* Setup param area for passing additional parameters to fadump capture kernel. */
fadump_setup_param_area();
#ifdef CONFIG_PPC_POWERNV /* Scan and build the list of machine check recoverable ranges */
of_scan_flat_dt(early_init_dt_scan_recoverable_ranges, NULL); #endif
epapr_paravirt_early_init();
/* Now try to figure out if we are running on LPAR and so on */
pseries_probe_fw_features();
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.22Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.