/* * If the L2-only sync region is already enabled then leave it at it's * current location.
*/
base_reg = read_gcr_l2_only_sync_base(); if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN) return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE;
/* Default to following the CM */ return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
}
/* L2-only sync was introduced with CM major revision 6 */
major_rev = FIELD_GET(CM_GCR_REV_MAJOR, read_gcr_rev()); if (major_rev < 6) return;
/* Find a location for the L2 sync region */
addr = mips_cm_l2sync_phys_base();
BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr); if (!addr) return;
/* Set the region base address & enable it */
write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN);
/* Map the region */
mips_cm_l2sync_base = ioremap(addr, MIPS_CM_L2SYNC_SIZE);
}
cm_node = of_find_compatible_node(of_root, NULL, "mobileye,eyeq6-cm"); if (!cm_node) return;
pr_info("HCI (Hardware Cache Init for the L2 cache) in GCR_L2_RAM_CONFIG from the CM3 is broken");
mips_cm_is_l2_hci_broken = true;
/* Disable MMID only if it was configured */ if (cpu_has_mmid)
cpu_disable_mmid();
of_node_put(cm_node);
}
int mips_cm_probe(void)
{
phys_addr_t addr;
u32 base_reg; unsigned cpu;
/* * No need to probe again if we have already been * here before.
*/ if (mips_gcr_base) return 0;
mips_gcr_base = ioremap(addr, MIPS_CM_GCR_SIZE); if (!mips_gcr_base) return -ENXIO;
/* sanity check that we're looking at a CM */
base_reg = read_gcr_base(); if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) {
pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n",
(unsignedlong)addr);
iounmap(mips_gcr_base);
mips_gcr_base = NULL; return -ENODEV;
}
/* set default target to memory */
change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM);
/* disable CM regions */
write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR);
write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
/* probe for an L2-only sync region */
mips_cm_probe_l2sync();
/* determine register width for this CM */
mips_cm_is64 = IS_ENABLED(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);
if (cm_rev >= CM_REV_CM3) {
val = FIELD_PREP(CM3_GCR_Cx_OTHER_CORE, core) |
FIELD_PREP(CM3_GCR_Cx_OTHER_VP, vp);
if (cm_rev >= CM_REV_CM3_5) { if (cluster != cpu_cluster(¤t_cpu_data))
val |= CM_GCR_Cx_OTHER_CLUSTER_EN;
val |= CM_GCR_Cx_OTHER_GIC_EN;
val |= FIELD_PREP(CM_GCR_Cx_OTHER_CLUSTER, cluster);
val |= FIELD_PREP(CM_GCR_Cx_OTHER_BLOCK, block);
} else {
WARN_ON(cluster != 0);
WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
}
/* * We need to disable interrupts in SMP systems in order to * ensure that we don't interrupt the caller with code which * may modify the redirect register. We do so here in a * slightly obscure way by using a spin lock, since this has * the neat property of also catching any nested uses of * mips_cm_lock_other() leading to a deadlock or a nice warning * with lockdep enabled.
*/
spin_lock_irqsave(this_cpu_ptr(&cm_core_lock),
*this_cpu_ptr(&cm_core_lock_flags));
} else {
WARN_ON(cluster != 0);
WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL);
/* * We only have a GCR_CL_OTHER per core in systems with * CM 2.5 & older, so have to ensure other VP(E)s don't * race with us.
*/
curr_core = cpu_core(¤t_cpu_data);
spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core),
per_cpu(cm_core_lock_flags, curr_core));
val = FIELD_PREP(CM_GCR_Cx_OTHER_CORENUM, core);
}
write_gcr_cl_other(val);
/* * Ensure the core-other region reflects the appropriate core & * VP before any accesses to it occur.
*/
mb();
}
/* * mips_cps_cluster_bootcfg is allocated in cps_prepare_cpus. If it is * not yet done, then we are so early that only one CPU is running, so * it is the first online CPU in the cluster.
*/ if (IS_ENABLED(CONFIG_MIPS_CPS) && mips_cps_cluster_bootcfg)
local_cl_mask = &mips_cps_cluster_bootcfg[local_cl].cpumask; else returntrue;
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.