コード例 #1
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int prd_init(struct opal_prd_ctx *ctx)
{
	int rc;

	ctx->page_size = sysconf(_SC_PAGE_SIZE);

	/* set up the device, and do our get_info ioctl */
	ctx->fd = open(opal_prd_devnode, O_RDWR);
	if (ctx->fd < 0) {
		pr_log(LOG_ERR, "FW: Can't open PRD device %s: %m",
				opal_prd_devnode);
		return -1;
	}

	rc = ioctl(ctx->fd, OPAL_PRD_GET_INFO, &ctx->info);
	if (rc) {
		pr_log(LOG_ERR, "FW: Can't query PRD information: %m");
		return -1;
	}

	rc = prd_init_ranges(ctx);
	if (rc) {
		pr_log(LOG_ERR, "FW: can't parse PRD memory information");
		return -1;
	}

	return 0;
}
コード例 #2
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int is_prd_supported(void)
{
	char *path;
	int rc;
	int len;
	char *buf;

	rc = asprintf(&path, "%s/ibm,opal/diagnostics/compatible",
		      devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'compatible' node path: %m");
		return -1;
	}

	rc = open_and_read(path, (void *) &buf, &len);
	if (rc)
		goto out_free;

	if (buf[len - 1] != '\0')
		pr_log(LOG_INFO, "FW: node %s is not nul-terminated", path);

	rc = find_string(buf, len, "ibm,opal-prd") ? 0 : -1;

	free(buf);
out_free:
	free(path);
	return rc;
}
コード例 #3
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int run_attn_loop(struct opal_prd_ctx *ctx)
{
	struct pollfd pollfds[2];
	struct opal_prd_msg msg;
	int rc, fd;

	if (hservice_runtime->enable_attns) {
		pr_debug("HBRT: calling enable_attns");
		rc = call_enable_attns();
		if (rc) {
			pr_log(LOG_ERR, "HBRT: enable_attns() failed, "
					"aborting");
			return -1;
		}
	}

	/* send init message, to unmask interrupts */
	msg.hdr.type = OPAL_PRD_MSG_TYPE_INIT;
	msg.hdr.size = htobe16(sizeof(msg));
	msg.init.version = htobe64(opal_prd_version);
	msg.init.ipoll = htobe64(opal_prd_ipoll);

	pr_debug("FW: writing init message");
	rc = write(ctx->fd, &msg, sizeof(msg));
	if (rc != sizeof(msg)) {
		pr_log(LOG_ERR, "FW: Init message failed: %m. Aborting.");
		return -1;
	}

	pollfds[0].fd = ctx->fd;
	pollfds[0].events = POLLIN | POLLERR;
	pollfds[1].fd = ctx->socket;
	pollfds[1].events = POLLIN | POLLERR;

	for (;;) {
		rc = poll(pollfds, 2, -1);
		if (rc < 0) {
			pr_log(LOG_ERR, "FW: event poll failed: %m");
			exit(EXIT_FAILURE);
		}

		if (!rc)
			continue;

		if (pollfds[0].revents & POLLIN)
			handle_prd_msg(ctx);

		if (pollfds[1].revents & POLLIN) {
			fd = accept(ctx->socket, NULL, NULL);
			if (fd < 0) {
				pr_log(LOG_NOTICE, "CTRL: accept failed: %m");
				continue;
			}
			handle_prd_control(ctx, fd);
			close(fd);
		}
	}

	return 0;
}
コード例 #4
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static void print_ranges(struct opal_prd_ctx *ctx)
{
	int i;

	if (ctx->n_ranges == 0)
		pr_log(LOG_INFO, "FW: No PRD ranges");

	pr_log(LOG_DEBUG, "FW: %d PRD ranges, instances assigned by %s",
			ctx->n_ranges,
			ctx->fw_range_instances ? "firmware" : "userspace");

	for (i = 0; i < ctx->n_ranges; i++) {
		struct prd_range *range = &ctx->ranges[i];
		char instance_str[20];

		if (range->multiple)
			snprintf(instance_str, sizeof(instance_str),
					" [%d]", range->instance);
		else
			instance_str[0] = '\0';

		pr_log(LOG_DEBUG, "FW:  %016lx-%016lx %s%s", range->physaddr,
				range->physaddr + range->size - 1,
				range->name,
				instance_str);
	}
}
コード例 #5
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int map_hbrt_file(struct opal_prd_ctx *ctx, const char *name)
{
	struct stat statbuf;
	int fd, rc;
	void *buf;

	fd = open(name, O_RDONLY);
	if (fd < 0) {
		pr_log(LOG_ERR, "IMAGE: HBRT file open(%s) failed: %m", name);
		return -1;
	}

	rc = fstat(fd, &statbuf);
	if (rc < 0) {
		pr_log(LOG_ERR, "IMAGE: HBRT file fstat(%s) failed: %m", name);
		close(fd);
		return -1;
	}

	buf = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_PRIVATE, fd, 0);
	close(fd);

	if (buf == MAP_FAILED) {
		pr_log(LOG_ERR, "IMAGE: HBRT file mmap(%s, 0x%zx) failed: %m",
				name, statbuf.st_size);
		return -1;
	}

	ctx->code_addr = buf;
	ctx->code_size = statbuf.st_size;
	return -0;
}
コード例 #6
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int handle_msg_attn(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
{
	uint64_t proc, ipoll_mask, ipoll_status;
	int rc;

	proc = be64toh(msg->attn.proc);
	ipoll_status = be64toh(msg->attn.ipoll_status);
	ipoll_mask = be64toh(msg->attn.ipoll_mask);

	if (!hservice_runtime->handle_attns) {
		pr_log_nocall("handle_attns");
		return -1;
	}

	rc = call_handle_attns(proc, ipoll_status, ipoll_mask);
	if (rc) {
		pr_log(LOG_ERR, "HBRT: handle_attns(%lx,%lx,%lx) failed, rc %d",
				proc, ipoll_status, ipoll_mask, rc);
		return -1;
	}

	/* send the response */
	msg->hdr.type = OPAL_PRD_MSG_TYPE_ATTN_ACK;
	msg->hdr.size = htobe16(sizeof(*msg));
	msg->attn_ack.proc = htobe64(proc);
	msg->attn_ack.ipoll_ack = htobe64(ipoll_status);
	rc = write(ctx->fd, msg, sizeof(*msg));

	if (rc != sizeof(*msg)) {
		pr_log(LOG_WARNING, "FW: Failed to send ATTN_ACK message: %m");
		return -1;
	}

	return 0;
}
コード例 #7
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
void hservices_init(struct opal_prd_ctx *ctx, void *code)
{
	uint64_t *s, *d;
	int i, sz;

	pr_debug("IMAGE: code address: %p", code);

	/* We enter at 0x100 into the image. */
	/* Load func desc in BE since we reverse it in thunk */

	hbrt_entry.addr = (void *)htobe64((unsigned long)code + 0x100);
	hbrt_entry.toc = 0; /* No toc for init entry point */

	if (memcmp(code, "HBRTVERS", 8) != 0)
		pr_log(LOG_ERR, "IMAGE: Bad signature for "
				"ibm,hbrt-code-image! exiting");

	pr_debug("IMAGE: calling ibm,hbrt_init()");
	hservice_runtime = call_hbrt_init(&hinterface);
	pr_log(LOG_NOTICE, "IMAGE: hbrt_init complete, version %016lx",
			hservice_runtime->interface_version);

	sz = sizeof(struct runtime_interfaces)/sizeof(uint64_t);
	s = (uint64_t *)hservice_runtime;
	d = (uint64_t *)&hservice_runtime_fixed;
	/* Byte swap the function pointers */
	for (i = 0; i < sz; i++)
		d[i] = be64toh(s[i]);
}
コード例 #8
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int ipmi_recv(int fd, uint8_t *netfn, uint8_t *cmd, long *seq,
		uint8_t *buf, size_t *len)
{
	struct ipmi_recv recv;
	struct ipmi_addr addr;
	int rc;

	recv.addr = (unsigned char *)&addr;
	recv.addr_len = sizeof(addr);
	recv.msg.data = buf;
	recv.msg.data_len = *len;

	rc = ioctl(fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
	if (rc < 0 && errno != EMSGSIZE) {
		pr_log(LOG_WARNING, "IPMI: recv (%zd bytes) failed: %m", *len);
		return -1;
	} else if (rc < 0 && errno == EMSGSIZE) {
		pr_log(LOG_NOTICE, "IPMI: truncated message (netfn %d, cmd %d, "
				"size %zd), continuing anyway",
				recv.msg.netfn, recv.msg.cmd, *len);
	}

	*netfn = recv.msg.netfn;
	*cmd = recv.msg.cmd;
	*seq = recv.msgid;
	*len = recv.msg.data_len;

	return 0;
}
コード例 #9
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static void dump_hbrt_map(struct opal_prd_ctx *ctx)
{
	const char *dump_name = "hbrt.bin";
	int fd, rc;

	if (!ctx->debug)
		return;

	fd = open(dump_name, O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		pr_log(LOG_NOTICE, "IMAGE: couldn't debug image %s for writing",
				dump_name);
		return;
	}

	rc = ftruncate(fd, 0);
	if (rc < 0) {
		pr_log(LOG_NOTICE, "IMAGE: couldn't truncate image %s for writing",
				dump_name);
		return;
	}
	rc = write(fd, ctx->code_addr, ctx->code_size);
	close(fd);

	if (rc != ctx->code_size)
		pr_log(LOG_NOTICE, "IMAGE: write to %s failed: %m", dump_name);
	else
		pr_debug("IMAGE: dumped HBRT binary to %s", dump_name);
}
コード例 #10
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int send_attr_override(struct opal_prd_ctx *ctx, uint32_t argc,
			      char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	struct stat statbuf;
	size_t sz;
	FILE *fd;
	int rc;

	rc = stat(argv[0], &statbuf);
	if (rc) {
		pr_log(LOG_ERR, "CTRL: stat() failed on the file: %m");
		return -1;
	}

	send_msg = malloc(sizeof(*send_msg) + statbuf.st_size);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		return -1;
	}

	send_msg->type = CONTROL_MSG_ATTR_OVERRIDE;
	send_msg->data_len = statbuf.st_size;

	fd = fopen(argv[0], "r");
	if (!fd) {
		pr_log(LOG_NOTICE, "CTRL: can't open %s: %m", argv[0]);
		rc = -1;
		goto out_free;
	}

	sz = fread(send_msg->data, 1, send_msg->data_len, fd);
	fclose(fd);
	if (sz != statbuf.st_size) {
		pr_log(LOG_ERR, "CTRL: short read from the file");
		rc = -1;
		goto out_free;
	}

	rc = send_prd_control(send_msg, &recv_msg);
	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: attribute override returned status %d",
					recv_msg->response);
		free(recv_msg);
	}

out_free:
	free(send_msg);
	return rc;
}
コード例 #11
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int send_run_command(struct opal_prd_ctx *ctx, int argc, char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	uint32_t size = 0;
	int rc, i;
	char *s;

	if (!ctx->expert_mode) {
		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
		return -1;
	}

	if (ctx->debug) {
		pr_debug("CTRL: run command arguments:");
		for (i=0; i < argc; i++)
			pr_debug("argv[%d] = %s", i, argv[i]);
	}

	for (i = 0; i < argc; i++)
		size += (strlen(argv[i]) + 1);

	send_msg = malloc(sizeof(*send_msg) + size);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		return -1;
	}

	/* Setup message */
	send_msg->type = CONTROL_MSG_RUN_CMD;
	send_msg->argc = argc;
	send_msg->data_len = size;
	s = (char *)send_msg->data;
	for (i = 0; i < argc; i++) {
		strcpy(s, argv[i]);
		s = s + strlen(argv[i]) + 1;
	}

	rc = send_prd_control(send_msg, &recv_msg);
	free(send_msg);
	if (recv_msg) {
		if (!rc)
			pr_log(LOG_INFO, "Received: %s", recv_msg->data);

		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: run command returned status %d",
					recv_msg->response);
		free(recv_msg);
	}

	return rc;
}
コード例 #12
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static void handle_prd_control_run_cmd(struct control_msg *send_msg,
				       struct control_msg *recv_msg)
{
	char *runcmd_output, *s;
	const char **argv;
	int i, argc;
	size_t size;

	if (!hservice_runtime->run_command) {
		pr_log_nocall("run_command");
		return;
	}

	argc = recv_msg->argc;
	pr_debug("CTRL: run_command, argc:%d\n", argc);

	argv = malloc(argc * sizeof(*argv));
	if (!argv) {
		pr_log(LOG_ERR, "CTRL: argv buffer malloc failed: %m");
		return;
	}

	s = (char *)recv_msg->data;
	size = 0;
	for (i = 0; i < argc; i++) {
		argv[i] = (char *)htobe64((uint64_t)&s[size]);
		size += (strlen(&s[size]) + 1);
	}

	/* Call HBRT */
	send_msg->response = call_run_command(argc, argv, &runcmd_output);
	runcmd_output = (char *)be64toh((uint64_t)runcmd_output);
	free(argv);

	s = (char *)send_msg->data;
	if (runcmd_output) {
		size = strlen(runcmd_output);
		if (size >= MAX_CONTROL_MSG_BUF) {
			pr_log(LOG_WARNING, "CTRL: output message truncated");
			runcmd_output[MAX_CONTROL_MSG_BUF] = '\0';
			size = MAX_CONTROL_MSG_BUF;
		}

		strcpy(s, runcmd_output);
		send_msg->data_len = size + 1;
		free(runcmd_output);
	} else {
		strcpy(s, "Null");
		send_msg->data_len = strlen("Null") + 1;
	}
}
コード例 #13
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int parse_action(const char *str, enum action *action)
{
	int rc;

	if (!strcmp(str, "occ")) {
		*action = ACTION_OCC_CONTROL;
		rc = 0;
	} else if (!strcmp(str, "daemon")) {
		*action = ACTION_RUN_DAEMON;
		rc = 0;
	} else if (!strcmp(str, "override")) {
		*action = ACTION_ATTR_OVERRIDE;
		rc = 0;
	} else if (!strcmp(str, "htmgt-passthru")) {
		*action = ACTION_HTMGT_PASSTHRU;
		rc = 0;
	} else if (!strcmp(str, "run")) {
		*action = ACTION_RUN_COMMAND;
		return 0;
	} else {
		pr_log(LOG_ERR, "CTRL: unknown argument '%s'", str);
		rc = -1;
	}

	return rc;
}
コード例 #14
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int send_occ_control(struct opal_prd_ctx *ctx, const char *str)
{
	struct control_msg send_msg, *recv_msg = NULL;
	int rc;

	memset(&send_msg, 0, sizeof(send_msg));

	if (!strcmp(str, "enable"))
		send_msg.type = CONTROL_MSG_ENABLE_OCCS;
	else if (!strcmp(str, "disable"))
		send_msg.type = CONTROL_MSG_DISABLE_OCCS;
	else if (!strcmp(str, "reset"))
		send_msg.type = CONTROL_MSG_TEMP_OCC_RESET;
	else if (!strcmp(str, "process-error"))
		send_msg.type = CONTROL_MSG_TEMP_OCC_ERROR;
	else {
		pr_log(LOG_ERR, "CTRL: Invalid OCC action '%s'", str);
		return -1;
	}

	rc = send_prd_control(&send_msg, &recv_msg);
	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: OCC action %s returned status %d", str,
					recv_msg->response);
		free(recv_msg);
	}

	return rc;
}
コード例 #15
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
uint64_t hservice_get_reserved_mem(const char *name, uint32_t instance)
{
	struct prd_range *range;

	pr_debug("IMAGE: hservice_get_reserved_mem: %s, %d", name, instance);

	range = find_range(name, instance);
	if (!range) {
		pr_log(LOG_WARNING, "IMAGE: get_reserved_mem: "
				"no such range %s", name);
		return 0;
	}

	if (!range->buf) {
		uint64_t align_physaddr, offset;

		pr_debug("IMAGE: Mapping 0x%016lx 0x%08lx %s[%d]",
				range->physaddr, range->size,
				range->name, range->instance);

		align_physaddr = range->physaddr & ~(ctx->page_size-1);
		offset = range->physaddr & (ctx->page_size-1);
		range->buf = mmap(NULL, range->size, PROT_WRITE | PROT_READ,
					MAP_SHARED, ctx->fd, align_physaddr);

		if (range->buf == MAP_FAILED)
			pr_log(LOG_ERR,
				"IMAGE: mmap of %s[%d](0x%016lx) failed: %m",
				name, instance, range->physaddr);
		else
			range->buf += offset;
	}

	if (range->buf == MAP_FAILED) {
		pr_log(LOG_WARNING,
				"IMAGE: get_reserved_mem: %s[%d] has no vaddr",
				name, instance);
		return 0;
	}

	pr_debug(
		"IMAGE: hservice_get_reserved_mem: %s[%d](0x%016lx) address %p",
			name, range->instance, range->physaddr,
			range->buf);

	return (uint64_t)range->buf;
}
コード例 #16
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
int hservice_memory_error(uint64_t i_start_addr, uint64_t i_endAddr,
		enum MemoryError_t i_errorType)
{
	const char *sysfsfile, *typestr;
	char buf[ADDR_STRING_SZ];
	int memfd, rc, n;
	uint64_t addr;

	switch(i_errorType) {
	case MEMORY_ERROR_CE:
		sysfsfile = mem_offline_soft;
		typestr = "correctable";
		break;
	case MEMORY_ERROR_UE:
		sysfsfile = mem_offline_hard;
		typestr = "uncorrectable";
		break;
	default:
		pr_log(LOG_WARNING, "MEM: Invalid memory error type %d",
				i_errorType);
		return -1;
	}

	pr_log(LOG_ERR, "MEM: Memory error: range %016lx-%016lx, type: %s",
			i_start_addr, i_endAddr, typestr);


	memfd = open(sysfsfile, O_WRONLY);
	if (memfd < 0) {
		pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
				"Unable to open sysfs node %s: %m", sysfsfile);
		return -1;
	}

	for (addr = i_start_addr; addr <= i_endAddr; addr += ctx->page_size) {
		n = snprintf(buf, ADDR_STRING_SZ, "0x%lx", addr);
		rc = write(memfd, buf, n);
		if (rc != n) {
			pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
					"page addr: %016lx type: %d: %m",
				addr, i_errorType);
			return rc;
		}
	}

	return 0;
}
コード例 #17
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int prd_init_ranges(struct opal_prd_ctx *ctx)
{
	struct dirent *dirent;
	char *path;
	DIR *dir;
	int rc;

	rc = asprintf(&path, "%s/reserved-memory", devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'reserved-memory' path "
				"node: %m");
		return -1;
	}

	rc = -1;

	dir = opendir(path);
	if (!dir) {
		pr_log(LOG_ERR, "FW: can't open reserved-memory device-tree "
				"node: %m");
		goto out_free;
	}

	for (;;) {
		dirent = readdir(dir);
		if (!dirent)
			break;

		prd_init_one_range(ctx, path, dirent);
	}

	rc = 0;
	/* sort ranges and assign instance numbers for duplicates (if the
	 * firmware doesn't number instances for us) */
	qsort(ctx->ranges, ctx->n_ranges, sizeof(struct prd_range),
			compare_ranges);

	if (!ctx->fw_range_instances)
		assign_range_instances(ctx);

	print_ranges(ctx);

out_free:
	free(path);
	closedir(dir);
	return rc;
}
コード例 #18
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int send_htmgt_passthru(struct opal_prd_ctx *ctx, int argc, char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	int rc, i;

	if (!ctx->expert_mode) {
		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
		return -1;
	}

	send_msg = malloc(sizeof(*send_msg) + argc);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
		return -1;
	}

	send_msg->type = CONTROL_MSG_HTMGT_PASSTHRU;
	send_msg->data_len = argc;

	if (ctx->debug)
		pr_debug("CTRL: HTMGT passthru arguments:");

	for (i = 0; i < argc; i++) {
		if (ctx->debug)
			pr_debug("argv[%d] = %s", i, argv[i]);

		sscanf(argv[i], "%hhx", &send_msg->data[i]);
	}

	rc = send_prd_control(send_msg, &recv_msg);
	free(send_msg);

	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: HTMGT passthru returned status %d",
					recv_msg->response);
		if (recv_msg->response == 0 && recv_msg->data_len)
			hexdump(recv_msg->data, recv_msg->data_len);

		free(recv_msg);
	}

	return rc;
}
コード例 #19
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int handle_prd_msg(struct opal_prd_ctx *ctx)
{
	struct opal_prd_msg msg;
	int size;
	int rc;

	rc = read(ctx->fd, &msg, sizeof(msg));
	if (rc < 0 && errno == EAGAIN)
		return -1;

	if (rc != sizeof(msg)) {
		pr_log(LOG_WARNING, "FW: Error reading events from OPAL: %m");
		return -1;
	}

	size = htobe16(msg.hdr.size);
	if (size < sizeof(msg)) {
		pr_log(LOG_ERR, "FW: Mismatched message size "
				"between opal-prd and firmware "
				"(%d from FW, %zd expected)",
				size, sizeof(msg));
		return -1;
	}

	switch (msg.hdr.type) {
	case OPAL_PRD_MSG_TYPE_ATTN:
		rc = handle_msg_attn(ctx, &msg);
		break;
	case OPAL_PRD_MSG_TYPE_OCC_RESET:
		rc = handle_msg_occ_reset(ctx, &msg);
		break;
	case OPAL_PRD_MSG_TYPE_OCC_ERROR:
		rc = handle_msg_occ_error(ctx, &msg);
		break;
	default:
		pr_log(LOG_WARNING, "Invalid incoming message type 0x%x",
				msg.hdr.type);
		return -1;
	}

	return 0;
}
コード例 #20
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int init_control_socket(struct opal_prd_ctx *ctx)
{
	struct sockaddr_un addr;
	int fd, rc;

	unlink(opal_prd_socket);

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, opal_prd_socket);

	fd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0) {
		pr_log(LOG_WARNING, "CTRL: Can't open control socket %s: %m",
				opal_prd_socket);
		return -1;
	}

	rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	if (rc) {
		pr_log(LOG_WARNING, "CTRL: Can't bind control socket %s: %m",
				opal_prd_socket);
		close(fd);
		return -1;
	}

	rc = listen(fd, 0);
	if (rc) {
		pr_log(LOG_WARNING, "CTRL: Can't listen on "
				"control socket %s: %m", opal_prd_socket);
		close(fd);
		return -1;
	}

	pr_log(LOG_INFO, "CTRL: Listening on control socket %s",
			opal_prd_socket);

	ctx->socket = fd;
	return 0;
}
コード例 #21
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static int send_prd_control(struct control_msg *send_msg,
			    struct control_msg **recv_msg)
{
	struct sockaddr_un addr;
	struct control_msg *msg;
	int sd, rc, size;

	sd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (!sd) {
		pr_log(LOG_ERR, "CTRL: Failed to create control socket: %m");
		return -1;
	}

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, opal_prd_socket);

	rc = connect(sd, (struct sockaddr *)&addr, sizeof(addr));
	if (rc) {
		pr_log(LOG_ERR, "CTRL: Failed to connect to prd daemon: %m");
		goto out_close;
	}

	size = sizeof(*send_msg) + send_msg->data_len;
	rc = send(sd, send_msg, size, 0);
	if (rc != size) {
		pr_log(LOG_ERR, "CTRL: Failed to send control message: %m");
		rc = -1;
		goto out_close;
	}

	size = sizeof(*msg) + MAX_CONTROL_MSG_BUF;
	msg = malloc(size);
	if (!msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		rc = -1;
		goto out_close;
	}

	*recv_msg = msg;

	/* wait for our reply */
	rc = recv(sd, msg, size, 0);
	if (rc < 0) {
		pr_log(LOG_ERR, "CTRL: Failed to receive control message: %m");
		goto out_close;

	} else if (rc != (sizeof(*msg) + msg->data_len)) {
		pr_log(LOG_WARNING, "CTRL: Short read from control socket");
		rc = -1;
		goto out_close;
	}

	rc = msg->response;

out_close:
	close(sd);
	return rc;
}
コード例 #22
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int map_hbrt_physmem(struct opal_prd_ctx *ctx, const char *name)
{
	struct prd_range *range;
	void *buf;

	range = find_range(name, 0);
	if (!range) {
		pr_log(LOG_ERR, "IMAGE: can't find code region %s", name);
		return -1;
	}

	buf = mmap(NULL, range->size, PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_PRIVATE, ctx->fd, range->physaddr);
	if (buf == MAP_FAILED) {
		pr_log(LOG_ERR, "IMAGE: mmap(range:%s, "
				"phys:0x%016lx, size:0x%016lx) failed: %m",
				name, range->physaddr, range->size);
		return -1;
	}

	ctx->code_addr = buf;
	ctx->code_size = range->size;
	return 0;
}
コード例 #23
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int parse_action(const char *str, enum action *action)
{
	if (!strcmp(str, "occ")) {
		*action = ACTION_OCC_CONTROL;
		return 0;
	}

	if (!strcmp(str, "daemon")) {
		*action = ACTION_RUN_DAEMON;
		return 0;
	}

	pr_log(LOG_ERR, "CTRL: unknown argument '%s'", str);
	return -1;
}
コード例 #24
0
ファイル: opal-prd.c プロジェクト: 1312mukesh/skiboot
static void handle_prd_control_htmgt_passthru(struct control_msg *send_msg,
					      struct control_msg *recv_msg)
{
	uint16_t rsp_len;

	if (!hservice_runtime->mfg_htmgt_pass_thru) {
		pr_log_nocall("mfg_htmgt_pass_thru");
		return;
	}

	pr_debug("CTRL: calling mfg_htmgt_pass_thru");
	send_msg->response = call_mfg_htmgt_pass_thru(recv_msg->data_len,
						      recv_msg->data, &rsp_len,
						      send_msg->data);
	send_msg->data_len = be16toh(rsp_len);
	if (send_msg->data_len > MAX_CONTROL_MSG_BUF) {
		pr_log(LOG_ERR, "CTRL: response buffer overrun, data len: %d",
				send_msg->data_len);
		send_msg->data_len = MAX_CONTROL_MSG_BUF;
	}
}
コード例 #25
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
int hservice_scom_write(uint64_t chip_id, uint64_t addr,
                               const void *buf)
{
	int rc;
	struct opal_prd_scom scom;

	scom.chip = chip_id;
	scom.addr = addr;
	scom.data = be64toh(*(uint64_t *)buf);

	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_WRITE, &scom);
	if (rc) {
		pr_log(LOG_ERR, "SCOM: ioctl write(chip 0x%lx, addr 0x%lx) "
				"failed: %m", chip_id, addr);
		return 0;
	}

	pr_debug("SCOM: write: chip 0x%lx, addr 0x%lx, val 0x%lx",
			chip_id, addr, scom.data);

	return 0;
}
コード例 #26
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
int hservice_scom_read(uint64_t chip_id, uint64_t addr, void *buf)
{
	int rc;
	struct opal_prd_scom scom;

	scom.chip = chip_id;
	scom.addr = addr;

	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_READ, &scom);
	if (rc) {
		pr_log(LOG_ERR, "SCOM: ioctl read(chip 0x%lx, addr 0x%lx) "
				"failed: %m", chip_id, addr);
		return 0;
	}

	pr_debug("SCOM: read: chip 0x%lx, addr 0x%lx, val 0x%lx",
			chip_id, addr, scom.data);

	*(uint64_t *)buf = htobe64(scom.data);

	return 0;
}
コード例 #27
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
void hservice_assert(void)
{
	pr_log(LOG_ERR, "HBRT: Failed assertion! exiting.");
	exit(EXIT_FAILURE);
}
コード例 #28
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
int hservice_ipmi_msg(uint8_t netfn, uint8_t cmd,
		void *tx_buf, size_t tx_size,
		void *rx_buf, size_t *rx_size)
{
	struct timeval start, now, delta;
	struct pollfd pollfds[1];
	static long seq;
	size_t size;
	int rc, fd;

	size = be64toh(*rx_size);

	fd = open(ipmi_devnode, O_RDWR);
	if (fd < 0) {
		pr_log(LOG_WARNING, "IPMI: Failed to open IPMI device %s: %m",
				ipmi_devnode);
		return -1;
	}

	seq++;
	pr_debug("IPMI: sending %zd bytes (netfn 0x%02x, cmd 0x%02x)",
			tx_size, netfn, cmd);

	rc = ipmi_send(fd, netfn, cmd, seq, tx_buf, tx_size);
	if (rc) {
		pr_log(LOG_WARNING, "IPMI: send failed");
		goto out;
	}

	gettimeofday(&start, NULL);

	pollfds[0].fd = fd;
	pollfds[0].events = POLLIN;

	for (;;) {
		long rx_seq;
		int timeout;

		gettimeofday(&now, NULL);
		timersub(&now, &start, &delta);
		timeout = ipmi_timeout_ms - ((delta.tv_sec * 1000) +
				(delta.tv_usec / 1000));
		if (timeout < 0)
			timeout = 0;

		rc = poll(pollfds, 1, timeout);
		if (rc < 0) {
			pr_log(LOG_ERR, "IPMI: poll(%s) failed: %m",
					ipmi_devnode);
			break;
		}

		if (rc == 0) {
			pr_log(LOG_WARNING, "IPMI: response timeout (>%dms)",
					ipmi_timeout_ms);
			rc = -1;
			break;
		}

		rc = ipmi_recv(fd, &netfn, &cmd, &rx_seq, rx_buf, &size);
		if (rc)
			break;

		if (seq != rx_seq) {
			pr_log(LOG_NOTICE, "IPMI: out-of-sequence reply: %ld, "
					"expected %ld. Dropping message.",
					rx_seq, seq);
			continue;
		}

		pr_debug("IPMI: received %zd bytes", tx_size);
		*rx_size = be64toh(size);
		rc = 0;
		break;
	}

out:
	close(fd);
	return rc;
}
コード例 #29
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
void hservice_puts(const char *str)
{
	pr_log(LOG_INFO, "HBRT: %s", str);
}
コード例 #30
0
ファイル: opal-prd.c プロジェクト: vaibhav92/skiboot
static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,
		struct dirent *dirent)
{
	char *label_path, *reg_path, *instance_path;
	struct prd_range *range;
	int label_len, len, rc;
	__be64 *reg;
	char *label;
	void *buf;

	rc = asprintf(&label_path, "%s/%s/ibm,prd-label", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-label' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&instance_path, "%s/%s/ibm,prd-instance",
			path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-instance' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&reg_path, "%s/%s/reg", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'reg' path "
				" node: %m");
		return -1;
	}

	reg = NULL;
	label = NULL;
	rc = -1;

	rc = open_and_read(label_path, &buf, &label_len);
	if (rc)
		goto out_free;

	label = buf;

	if (label[label_len-1] != '\0')
		pr_log(LOG_INFO, "FW: node %s has invalid ibm,prd-label - "
				"not nul-terminated",
				dirent->d_name);

	rc = open_and_read(reg_path, &buf, &len);
	if (rc)
		goto out_free;

	reg = buf;

	if (len != 2 * sizeof(*reg)) {
		pr_log(LOG_ERR, "FW: node %s has invalid 'reg' size: %d",
				dirent->d_name, len);
		goto out_free;
	}


	ctx->ranges = realloc(ctx->ranges, ++ctx->n_ranges * sizeof(*range));
	range = &ctx->ranges[ctx->n_ranges - 1];
	range->name = strndup(label, label_len);
	range->physaddr = be64toh(reg[0]);
	range->size = be64toh(reg[1]);
	range->buf = NULL;
	range->multiple = false;
	range->instance = 0;

	/* optional instance */
	rc = open_and_read(instance_path, &buf, &len);
	if (!rc && len == sizeof(uint32_t)) {
		range->multiple = true;
		range->instance = be32toh(*(uint32_t *)buf);
		ctx->fw_range_instances = true;
	}
	rc = 0;

out_free:
	free(reg);
	free(label);
	free(instance_path);
	free(reg_path);
	free(label_path);
	return rc;
}