arch/powerpc/boot/oflib.c

Source file repositories/reference/linux-study-clean/arch/powerpc/boot/oflib.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/boot/oflib.c
Extension
.c
Size
5210 bytes
Lines
220
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

struct prom_args {
	__be32 service;	/* Address of service name string. */
	__be32 nargs;	/* Number of input arguments. */
	__be32 nret;	/* Number of output arguments. */
	__be32 args[10];	/* Input/output arguments. */
};

#ifdef __powerpc64__
extern int prom(void *);
#else
static int (*prom) (void *);
#endif

void of_init(void *promptr)
{
#ifndef __powerpc64__
	prom = (int (*)(void *))promptr;
#endif
}

#define ADDR(x)		(u32)(unsigned long)(x)

int of_call_prom(const char *service, int nargs, int nret, ...)
{
	int i;
	struct prom_args args;
	va_list list;

	args.service = cpu_to_be32(ADDR(service));
	args.nargs = cpu_to_be32(nargs);
	args.nret = cpu_to_be32(nret);

	va_start(list, nret);
	for (i = 0; i < nargs; i++)
		args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
	va_end(list);

	for (i = 0; i < nret; i++)
		args.args[nargs+i] = 0;

	if (prom(&args) < 0)
		return PROM_ERROR;

	return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
}

static int of_call_prom_ret(const char *service, int nargs, int nret,
			    prom_arg_t *rets, ...)
{
	int i;
	struct prom_args args;
	va_list list;

	args.service = cpu_to_be32(ADDR(service));
	args.nargs = cpu_to_be32(nargs);
	args.nret = cpu_to_be32(nret);

	va_start(list, rets);
	for (i = 0; i < nargs; i++)
		args.args[i] = cpu_to_be32(va_arg(list, prom_arg_t));
	va_end(list);

	for (i = 0; i < nret; i++)
		args.args[nargs+i] = 0;

	if (prom(&args) < 0)
		return PROM_ERROR;

	if (rets != NULL)
		for (i = 1; i < nret; ++i)
			rets[i-1] = be32_to_cpu(args.args[nargs+i]);

	return (nret > 0) ? be32_to_cpu(args.args[nargs]) : 0;
}

/* returns true if s2 is a prefix of s1 */
static int string_match(const char *s1, const char *s2)
{
	for (; *s2; ++s2)
		if (*s1++ != *s2)
			return 0;
	return 1;
}

/*
 * Older OF's require that when claiming a specific range of addresses,
 * we claim the physical space in the /memory node and the virtual
 * space in the chosen mmu node, and then do a map operation to
 * map virtual to physical.
 */

Annotation

Implementation Notes