arch/powerpc/kernel/kgdb.c

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/kgdb.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/kgdb.c
Extension
.c
Size
14836 bytes
Lines
496
Domain
Architecture Layer
Bucket
arch/powerpc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (remcom_in_buffer[0] == 's') {
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
			mtspr(SPRN_DBCR0,
			      mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
			regs_set_return_msr(linux_regs, linux_regs->msr | MSR_DE);
#else
			regs_set_return_msr(linux_regs, linux_regs->msr | MSR_SE);
#endif
			atomic_set(&kgdb_cpu_doing_single_step,
				   raw_smp_processor_id());
		}
		return 0;
	}

	return -1;
}

int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
	u32 instr, *addr = (u32 *)bpt->bpt_addr;
	int err;

	err = get_kernel_nofault(instr, addr);
	if (err)
		return err;

	err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
	if (err)
		return -EFAULT;

	*(u32 *)bpt->saved_instr = instr;

	return 0;
}

int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{
	int err;
	unsigned int instr = *(unsigned int *)bpt->saved_instr;
	u32 *addr = (u32 *)bpt->bpt_addr;

	err = patch_instruction(addr, ppc_inst(instr));
	if (err)
		return -EFAULT;

	return 0;
}

/*
 * Global data
 */
const struct kgdb_arch arch_kgdb_ops;

static int kgdb_not_implemented(struct pt_regs *regs)
{
	return 0;
}

static void *old__debugger_ipi;
static void *old__debugger;
static void *old__debugger_bpt;
static void *old__debugger_sstep;
static void *old__debugger_iabr_match;
static void *old__debugger_break_match;
static void *old__debugger_fault_handler;

int kgdb_arch_init(void)
{
	old__debugger_ipi = __debugger_ipi;
	old__debugger = __debugger;
	old__debugger_bpt = __debugger_bpt;
	old__debugger_sstep = __debugger_sstep;
	old__debugger_iabr_match = __debugger_iabr_match;
	old__debugger_break_match = __debugger_break_match;
	old__debugger_fault_handler = __debugger_fault_handler;

	__debugger_ipi = kgdb_debugger_ipi;
	__debugger = kgdb_debugger;
	__debugger_bpt = kgdb_handle_breakpoint;
	__debugger_sstep = kgdb_singlestep;
	__debugger_iabr_match = kgdb_iabr_match;
	__debugger_break_match = kgdb_break_match;
	__debugger_fault_handler = kgdb_not_implemented;

	return 0;
}

void kgdb_arch_exit(void)
{
	__debugger_ipi = old__debugger_ipi;

Annotation

Implementation Notes