arch/sh/kernel/cpu/sh4a/ubc.c

Source file repositories/reference/linux-study-clean/arch/sh/kernel/cpu/sh4a/ubc.c

File Facts

System
Linux kernel
Corpus path
arch/sh/kernel/cpu/sh4a/ubc.c
Extension
.c
Size
2858 bytes
Lines
131
Domain
Architecture Layer
Bucket
arch/sh
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

// SPDX-License-Identifier: GPL-2.0
/*
 * arch/sh/kernel/cpu/sh4a/ubc.c
 *
 * On-chip UBC support for SH-4A CPUs.
 *
 * Copyright (C) 2009 - 2010  Paul Mundt
 */
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <asm/hw_breakpoint.h>

#define UBC_CBR(idx)	(0xff200000 + (0x20 * idx))
#define UBC_CRR(idx)	(0xff200004 + (0x20 * idx))
#define UBC_CAR(idx)	(0xff200008 + (0x20 * idx))
#define UBC_CAMR(idx)	(0xff20000c + (0x20 * idx))

#define UBC_CCMFR	0xff200600
#define UBC_CBCR	0xff200620

/* CRR */
#define UBC_CRR_PCB	(1 << 1)
#define UBC_CRR_BIE	(1 << 0)

/* CBR */
#define UBC_CBR_CE	(1 << 0)

static struct sh_ubc sh4a_ubc;

static void sh4a_ubc_enable(struct arch_hw_breakpoint *info, int idx)
{
	__raw_writel(UBC_CBR_CE | info->len | info->type, UBC_CBR(idx));
	__raw_writel(info->address, UBC_CAR(idx));
}

static void sh4a_ubc_disable(struct arch_hw_breakpoint *info, int idx)
{
	__raw_writel(0, UBC_CBR(idx));
	__raw_writel(0, UBC_CAR(idx));
}

static void sh4a_ubc_enable_all(unsigned long mask)
{
	int i;

	for (i = 0; i < sh4a_ubc.num_events; i++)
		if (mask & (1 << i))
			__raw_writel(__raw_readl(UBC_CBR(i)) | UBC_CBR_CE,
				     UBC_CBR(i));
}

static void sh4a_ubc_disable_all(void)
{
	int i;

	for (i = 0; i < sh4a_ubc.num_events; i++)
		__raw_writel(__raw_readl(UBC_CBR(i)) & ~UBC_CBR_CE,
			     UBC_CBR(i));
}

static unsigned long sh4a_ubc_active_mask(void)
{
	unsigned long active = 0;
	int i;

	for (i = 0; i < sh4a_ubc.num_events; i++)
		if (__raw_readl(UBC_CBR(i)) & UBC_CBR_CE)
			active |= (1 << i);

	return active;
}

static unsigned long sh4a_ubc_triggered_mask(void)
{
	return __raw_readl(UBC_CCMFR);
}

static void sh4a_ubc_clear_triggered_mask(unsigned long mask)
{
	__raw_writel(__raw_readl(UBC_CCMFR) & ~mask, UBC_CCMFR);
}

static struct sh_ubc sh4a_ubc = {
	.name			= "SH-4A",
	.num_events		= 2,
	.trap_nr		= 0x1e0,
	.enable			= sh4a_ubc_enable,
	.disable		= sh4a_ubc_disable,

Annotation

Implementation Notes