arch/mips/kernel/smp-cps.c
Source file repositories/reference/linux-study-clean/arch/mips/kernel/smp-cps.c
File Facts
- System
- Linux kernel
- Corpus path
arch/mips/kernel/smp-cps.c- Extension
.c- Size
- 25732 bytes
- Lines
- 977
- Domain
- Architecture Layer
- Bucket
- arch/mips
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cpu.hlinux/delay.hlinux/io.hlinux/memblock.hlinux/sched/task_stack.hlinux/sched/hotplug.hlinux/slab.hlinux/smp.hlinux/types.hlinux/irq.hasm/bcache.hasm/mips-cps.hasm/mips_mt.hasm/mipsregs.hasm/pm-cps.hasm/r4kcache.hasm/regdef.hasm/smp.hasm/smp-cps.hasm/time.hasm/uasm.h
Detected Declarations
enum label_idenum cpu_deathfunction power_up_other_clusterfunction core_vpe_countfunction check_64bit_resetfunction allocate_cps_vecsfunction setup_cps_vecsfunction cps_smp_setupfunction calibrate_delay_is_knownfunction cps_prepare_cpusfunction for_each_present_cpufunction init_cluster_l2function boot_corefunction remote_vpe_bootfunction cps_boot_secondaryfunction cps_init_secondaryfunction cps_smp_finishfunction cps_shutdown_this_cpufunction cps_kexec_nonboot_cpufunction cps_cpu_disablefunction play_deadfunction wait_for_sibling_haltfunction cps_cpu_diefunction mips_cps_smp_in_usefunction register_cps_smp_ops
Annotated Snippet
if (timeout) {
mdelay(1);
timeout--;
} else {
pr_warn("Waiting for cluster %u CM to power up... STAT_CONF=0x%x\n",
cluster, stat);
mdelay(1000);
}
}
mips_cm_unlock_other();
}
static unsigned __init core_vpe_count(unsigned int cluster, unsigned core)
{
return min(smp_max_threads, mips_cps_numvps(cluster, core));
}
static void __init *mips_cps_build_core_entry(void *addr)
{
extern void (*nmi_handler)(void);
u32 *p = addr;
u32 val;
struct uasm_label labels[2];
struct uasm_reloc relocs[2];
struct uasm_label *l = labels;
struct uasm_reloc *r = relocs;
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
uasm_i_mfc0(&p, GPR_K0, C0_STATUS);
UASM_i_LA(&p, GPR_T9, ST0_NMI);
uasm_i_and(&p, GPR_K0, GPR_K0, GPR_T9);
uasm_il_bnez(&p, &r, GPR_K0, label_not_nmi);
uasm_i_nop(&p);
UASM_i_LA(&p, GPR_K0, (long)&nmi_handler);
uasm_l_not_nmi(&l, p);
val = CAUSEF_IV;
uasm_i_lui(&p, GPR_K0, val >> 16);
uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
uasm_i_mtc0(&p, GPR_K0, C0_CAUSE);
val = ST0_CU1 | ST0_CU0 | ST0_BEV | ST0_KX_IF_64;
uasm_i_lui(&p, GPR_K0, val >> 16);
uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_ehb(&p);
uasm_i_ori(&p, GPR_A0, 0, read_c0_config() & CONF_CM_CMASK);
UASM_i_LA(&p, GPR_A1, (long)mips_gcr_base);
#if defined(KBUILD_64BIT_SYM32) || defined(CONFIG_32BIT)
UASM_i_LA(&p, GPR_T9, CKSEG1ADDR(__pa_symbol(mips_cps_core_boot)));
#else
UASM_i_LA(&p, GPR_T9, TO_UNCAC(__pa_symbol(mips_cps_core_boot)));
#endif
uasm_i_jr(&p, GPR_T9);
uasm_i_nop(&p);
uasm_resolve_relocs(relocs, labels);
return p;
}
static bool __init check_64bit_reset(void)
{
bool cx_64bit_reset = false;
mips_cm_lock_other(0, 0, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL);
write_gcr_co_reset64_base(CM_GCR_Cx_RESET64_BASE_BEVEXCBASE);
if ((read_gcr_co_reset64_base() & CM_GCR_Cx_RESET64_BASE_BEVEXCBASE) ==
CM_GCR_Cx_RESET64_BASE_BEVEXCBASE)
cx_64bit_reset = true;
mips_cm_unlock_other();
return cx_64bit_reset;
}
static int __init allocate_cps_vecs(void)
{
/* Try to allocate in KSEG1 first */
cps_vec_pa = memblock_phys_alloc_range(BEV_VEC_SIZE, BEV_VEC_ALIGN,
0x0, CSEGX_SIZE - 1);
if (cps_vec_pa)
core_entry_reg = CKSEG1ADDR(cps_vec_pa) &
CM_GCR_Cx_RESET_BASE_BEVEXCBASE;
if (!cps_vec_pa && mips_cm_is64) {
Annotation
- Immediate include surface: `linux/cpu.h`, `linux/delay.h`, `linux/io.h`, `linux/memblock.h`, `linux/sched/task_stack.h`, `linux/sched/hotplug.h`, `linux/slab.h`, `linux/smp.h`.
- Detected declarations: `enum label_id`, `enum cpu_death`, `function power_up_other_cluster`, `function core_vpe_count`, `function check_64bit_reset`, `function allocate_cps_vecs`, `function setup_cps_vecs`, `function cps_smp_setup`, `function calibrate_delay_is_known`, `function cps_prepare_cpus`.
- Atlas domain: Architecture Layer / arch/mips.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.