arch/sparc/kernel/leon_kernel.c
Source file repositories/reference/linux-study-clean/arch/sparc/kernel/leon_kernel.c
File Facts
- System
- Linux kernel
- Corpus path
arch/sparc/kernel/leon_kernel.c- Extension
.c- Size
- 13937 bytes
- Lines
- 509
- Domain
- Architecture Layer
- Bucket
- arch/sparc
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/errno.hlinux/mutex.hlinux/of.hlinux/interrupt.hlinux/clocksource.hlinux/clockchips.hasm/oplib.hasm/timer.hasm/prom.hasm/leon.hasm/leon_amba.hasm/traps.hasm/cacheflush.hasm/smp.hasm/setup.hkernel.hprom.hirq.h
Detected Declarations
function beenfunction leon_handle_ext_irqfunction leon_eirq_setupfunction leon_get_irqmaskfunction irq_choose_cpufunction leon_set_affinityfunction leon_unmask_irqfunction leon_mask_irqfunction leon_startup_irqfunction leon_shutdown_irqfunction leon_eoi_irqfunction Edgefunction _leon_build_device_irqfunction leon_update_virq_handlingfunction leon_cycles_offsetfunction leon_percpu_timer_ce_interruptfunction leon_init_timersfunction leon_clear_clock_irqfunction leon_load_profile_irqfunction leon_init_IRQ
Annotated Snippet
if (ampopts == 0) {
/* Skip this instance, resource already
* allocated by other OS */
nnp = np;
goto retry;
}
}
/* Select Timer-Instance on Timer Core. Default is zero */
leon3_gptimer_idx = ampopts & 0x7;
pp = of_find_property(np, "reg", &len);
if (pp)
leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)
pp->value;
pp = of_find_property(np, "interrupts", &len);
if (pp)
leon3_gptimer_irq = *(unsigned int *)pp->value;
if (!(leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq))
goto bad;
ctrl = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl);
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
ctrl | LEON3_GPTIMER_CTRL_PENDING);
ctrl = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl);
if ((ctrl & LEON3_GPTIMER_CTRL_PENDING) != 0)
leon3_gptimer_ackmask = ~LEON3_GPTIMER_CTRL_PENDING;
else
leon3_gptimer_ackmask = ~0;
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
(((1000000 / HZ) - 1)));
LEON3_BYPASS_STORE_PA(
&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
/*
* The IRQ controller may (if implemented) consist of multiple
* IRQ controllers, each mapped on a 4Kb boundary.
* Each CPU may be routed to different IRQCTRLs, however
* we assume that all CPUs (in SMP system) is routed to the
* same IRQ Controller, and for non-SMP only one IRQCTRL is
* accessed anyway.
* In AMP systems, Linux must run on CPU0 for the time being.
*/
icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[boot_cpu_id/8]);
icsel = (icsel >> ((7 - (boot_cpu_id&0x7)) * 4)) & 0xf;
leon3_irqctrl_regs += icsel;
/* Mask all IRQs on boot-cpu IRQ controller */
LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[boot_cpu_id], 0);
/* Probe extended IRQ controller */
eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus)
>> 16) & 0xf;
if (eirq != 0)
leon_eirq_setup(eirq);
#ifdef CONFIG_SMP
{
unsigned long flags;
/*
* In SMP, sun4m adds a IPI handler to IRQ trap handler that
* LEON never must take, sun4d and LEON overwrites the branch
* with a NOP.
*/
local_irq_save(flags);
patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
local_ops->cache_all();
local_irq_restore(flags);
}
#endif
config = LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config);
if (config & (1 << LEON3_GPTIMER_SEPIRQ))
leon3_gptimer_irq += leon3_gptimer_idx;
else if ((config & LEON3_GPTIMER_TIMERS) > 1)
pr_warn("GPTIMER uses shared irqs, using other timers of the same core will fail.\n");
#ifdef CONFIG_SMP
/* Install per-cpu IRQ handler for broadcasted ticker */
irq = leon_build_device_irq(leon3_gptimer_irq, handle_percpu_irq,
"per-cpu", 0);
err = request_irq(irq, leon_percpu_timer_ce_interrupt,
IRQF_PERCPU | IRQF_TIMER, "timer", NULL);
#else
irq = _leon_build_device_irq(NULL, leon3_gptimer_irq);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/errno.h`, `linux/mutex.h`, `linux/of.h`, `linux/interrupt.h`, `linux/clocksource.h`, `linux/clockchips.h`, `asm/oplib.h`.
- Detected declarations: `function been`, `function leon_handle_ext_irq`, `function leon_eirq_setup`, `function leon_get_irqmask`, `function irq_choose_cpu`, `function leon_set_affinity`, `function leon_unmask_irq`, `function leon_mask_irq`, `function leon_startup_irq`, `function leon_shutdown_irq`.
- Atlas domain: Architecture Layer / arch/sparc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.