tools/testing/selftests/powerpc/syscalls/rtas_filter.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/syscalls/rtas_filter.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/syscalls/rtas_filter.c
Extension
.c
Size
5557 bytes
Lines
225
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: syscall or user/kernel boundary
Status
core implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rtas_args {
	__be32 token;
	__be32 nargs;
	__be32 nret;
	__be32 args[16];
	__be32 *rets;	  /* Pointer to return values in args[]. */
};

struct region {
	uint64_t addr;
	uint32_t size;
	struct region *next;
};

static int get_property(const char *prop_path, const char *prop_name,
			char **prop_val, size_t *prop_len)
{
	char path[PATH_MAX];

	int len = snprintf(path, sizeof(path), "%s/%s", prop_path, prop_name);
	if (len < 0 || len >= sizeof(path))
		return -ENOMEM;

	return read_file_alloc(path, prop_val, prop_len);
}

int rtas_token(const char *call_name)
{
	char *prop_buf = NULL;
	size_t len;
	int rc;

	rc = get_property(ofdt_rtas_path, call_name, &prop_buf, &len);
	if (rc < 0) {
		rc = RTAS_UNKNOWN_OP;
		goto err;
	}

	rc = be32_to_cpu(*(int *)prop_buf);

err:
	free(prop_buf);
	return rc;
}

static int read_kregion_bounds(struct region *kregion)
{
	char *buf;
	int err;

	err = read_file_alloc("/proc/ppc64/rtas/rmo_buffer", &buf, NULL);
	if (err) {
		perror("Could not open rmo_buffer file");
		return RTAS_IO_ASSERT;
	}

	sscanf(buf, "%" SCNx64 " %x", &kregion->addr, &kregion->size);
	free(buf);

	if (!(kregion->size && kregion->addr) ||
	    (kregion->size > (PAGE_SIZE * MAX_PAGES))) {
		printf("Unexpected kregion bounds\n");
		return RTAS_IO_ASSERT;
	}

	return 0;
}

static int rtas_call(const char *name, int nargs,
		     int nrets, ...)
{
	struct rtas_args args;
	__be32 *rets[16];
	int i, rc, token;
	va_list ap;

	va_start(ap, nrets);

	token = rtas_token(name);
	if (token == RTAS_UNKNOWN_OP) {
		// We don't care if the call doesn't exist
		printf("call '%s' not available, skipping...", name);
		rc = RTAS_UNKNOWN_OP;
		goto err;
	}

	args.token = cpu_to_be32(token);
	args.nargs = cpu_to_be32(nargs);
	args.nret = cpu_to_be32(nrets);

Annotation

Implementation Notes