arch/mips/fw/cfe/cfe_api.c

Source file repositories/reference/linux-study-clean/arch/mips/fw/cfe/cfe_api.c

File Facts

System
Linux kernel
Corpus path
arch/mips/fw/cfe/cfe_api.c
Extension
.c
Size
11668 bytes
Lines
481
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.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
 */

/*
 *
 * Broadcom Common Firmware Environment (CFE)
 *
 * This module contains device function stubs (small routines to
 * call the standard "iocb" interface entry point to CFE).
 * There should be one routine here per iocb function call.
 *
 * Authors:  Mitch Lichtenberg, Chris Demetriou
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/printk.h>
#include <asm/mipsregs.h>
#include <asm/fw/cfe/cfe_api.h>
#include "cfe_api_int.h"

unsigned long __initdata cfe_seal;

/* Cast from a native pointer to a cfe_xptr_t and back.	 */
#define XPTR_FROM_NATIVE(n)	((cfe_xptr_t) (intptr_t) (n))
#define NATIVE_FROM_XPTR(x)	((void *) (intptr_t) (x))

int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);

/*
 * Declare the dispatch function with args of "intptr_t".
 * This makes sure whatever model we're compiling in
 * puts the pointers in a single register.  For example,
 * combining -mlong64 and -mips1 or -mips2 would lead to
 * trouble, since the handle and IOCB pointer will be
 * passed in two registers each, and CFE expects one.
 */

static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
static u64 cfe_handle;

int cfe_init(u64 handle, u64 ept)
{
	cfe_dispfunc = NATIVE_FROM_XPTR(ept);
	cfe_handle = handle;
	return 0;
}

int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
{
	if (!cfe_dispfunc)
		return -1;
	return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
}

int cfe_close(int handle)
{
	struct cfe_xiocb xiocb;

	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
	xiocb.xiocb_status = 0;
	xiocb.xiocb_handle = handle;
	xiocb.xiocb_flags = 0;
	xiocb.xiocb_psize = 0;

	cfe_iocb_dispatch(&xiocb);

	return xiocb.xiocb_status;

}

int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
{
	struct cfe_xiocb xiocb;

	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
	xiocb.xiocb_status = 0;
	xiocb.xiocb_handle = 0;
	xiocb.xiocb_flags = 0;
	xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
	xiocb.plist.xiocb_cpuctl.gp_val = gp;
	xiocb.plist.xiocb_cpuctl.sp_val = sp;
	xiocb.plist.xiocb_cpuctl.a1_val = a1;
	xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;

	cfe_iocb_dispatch(&xiocb);

Annotation

Implementation Notes