arch/mips/dec/kn01-berr.c
Source file repositories/reference/linux-study-clean/arch/mips/dec/kn01-berr.c
File Facts
- System
- Linux kernel
- Corpus path
arch/mips/dec/kn01-berr.c- Extension
.c- Size
- 4999 bytes
- Lines
- 197
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/init.hlinux/interrupt.hlinux/kernel.hlinux/spinlock.hlinux/types.hasm/inst.hasm/irq_regs.hasm/mipsregs.hasm/page.hasm/ptrace.hasm/traps.hlinux/uaccess.hasm/dec/kn01.h
Detected Declarations
function dec_kn01_be_ackfunction dec_kn01_be_backendfunction dec_kn01_be_handlerfunction dec_kn01_be_interruptfunction dec_kn01_be_init
Annotated Snippet
if (data) {
/* This never faults. */
__get_user(insn.word, pc);
vaddr = regs->regs[insn.i_format.rs] +
insn.i_format.simmediate;
} else
vaddr = (long)pc;
if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
address = CPHYSADDR(vaddr);
else {
/* Peek at what physical address the CPU used. */
asid = read_c0_entryhi();
entryhi = asid & (PAGE_SIZE - 1);
entryhi |= vaddr & ~(PAGE_SIZE - 1);
write_c0_entryhi(entryhi);
BARRIER;
tlb_probe();
/* No need to check for presence. */
tlb_read();
entrylo = read_c0_entrylo0();
write_c0_entryhi(asid);
offset = vaddr & (PAGE_SIZE - 1);
address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
}
}
/* Treat low 256MB as memory, high -- as I/O. */
if (address < 0x10000000) {
cycle = mreadstr;
event = paritystr;
} else {
cycle = invoker ? writestr : readstr;
event = timestr;
}
if (is_fixup)
action = MIPS_BE_FIXUP;
if (action != MIPS_BE_FIXUP)
pr_alert_ratelimited("Bus error %s: %s %s %s at %#010lx\n",
kind, agent, cycle, event, address);
return action;
}
int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
{
return dec_kn01_be_backend(regs, is_fixup, 0);
}
irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id)
{
volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
struct pt_regs *regs = get_irq_regs();
int action;
if (!(*csr & KN01_CSR_MEMERR))
return IRQ_NONE; /* Must have been video. */
action = dec_kn01_be_backend(regs, 0, 1);
if (action == MIPS_BE_DISCARD)
return IRQ_HANDLED;
/*
* FIXME: Find the affected processes and kill them, otherwise
* we must die.
*
* The interrupt is asynchronously delivered thus EPC and RA
* may be irrelevant, but are printed for a reference.
*/
printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
regs->cp0_epc, regs->regs[31]);
die("Unrecoverable bus error", regs);
}
void __init dec_kn01_be_init(void)
{
volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
unsigned long flags;
raw_spin_lock_irqsave(&kn01_lock, flags);
/* Preset write-only bits of the Control Register cache. */
cached_kn01_csr = *csr;
cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
cached_kn01_csr |= KN01_CSR_LEDS;
/* Enable parity error detection. */
Annotation
- Immediate include surface: `linux/init.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/spinlock.h`, `linux/types.h`, `asm/inst.h`, `asm/irq_regs.h`, `asm/mipsregs.h`.
- Detected declarations: `function dec_kn01_be_ack`, `function dec_kn01_be_backend`, `function dec_kn01_be_handler`, `function dec_kn01_be_interrupt`, `function dec_kn01_be_init`.
- Atlas domain: Architecture Layer / arch/mips.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.