[Skiboot] [PATCH v3 1/4] external: Add a getsram command

Cédric Le Goater clg at fr.ibm.com
Wed Mar 9 23:30:33 AEDT 2016


The getsram command reads the OCC SRAM. This is useful for debug.

The code is totally inspired from the meltbox tool.

Signed-off-by: Cédric Le Goater <clg at fr.ibm.com>
---

 Changes since v2:

 - added copyright header

 external/xscom-utils/Makefile  |   7 ++-
 external/xscom-utils/getsram.c | 113 +++++++++++++++++++++++++++++++++++++++
 external/xscom-utils/sram.c    | 116 +++++++++++++++++++++++++++++++++++++++++
 external/xscom-utils/sram.h    |  27 ++++++++++
 4 files changed, 261 insertions(+), 2 deletions(-)
 create mode 100644 external/xscom-utils/getsram.c
 create mode 100644 external/xscom-utils/sram.c
 create mode 100644 external/xscom-utils/sram.h

diff --git a/external/xscom-utils/Makefile b/external/xscom-utils/Makefile
index ff9474a4fb96..b5d0d1cd9003 100644
--- a/external/xscom-utils/Makefile
+++ b/external/xscom-utils/Makefile
@@ -1,4 +1,4 @@
-all: getscom putscom
+all: getscom putscom getsram
 
 VERSION=0.1
 CFLAGS=-O2 -g -Wall -m64 -DVERSION=$(VERSION)
@@ -6,12 +6,15 @@ CFLAGS=-O2 -g -Wall -m64 -DVERSION=$(VERSION)
 getscom: getscom.c xscom.c
 	$(CC) $(CFLAGS) -o $@ $^
 
+getsram: getsram.c xscom.c sram.c
+	$(CC) $(CFLAGS) -o $@ $^
+
 putscom: putscom.c xscom.c
 	$(CC) $(CFLAGS) -o $@ $^
 
 .PHONY: clean
 clean:
-	rm -rf getscom putscom
+	rm -rf getscom putscom getsram
 
 .PHONY: distclean
 distclean: clean
diff --git a/external/xscom-utils/getsram.c b/external/xscom-utils/getsram.c
new file mode 100644
index 000000000000..6e85fc88a0e0
--- /dev/null
+++ b/external/xscom-utils/getsram.c
@@ -0,0 +1,113 @@
+/* Copyright 2014-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * imitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "xscom.h"
+#include "sram.h"
+
+static void print_usage(void)
+{
+	printf("usage: getsram [-c|--chip chip-id] addr\n");
+	printf("               [--occ-channel|n <chan>]\n");
+	printf("       getsram -v|--version\n");
+}
+
+#define VERSION_STR _str(VERSION)
+#define _str(s) __str(s)
+#define __str(s) #s
+
+int main(int argc, char *argv[])
+{
+	uint64_t val, addr = -1ull;
+	uint32_t def_chip, chip_id = 0xffffffff;
+	bool show_help = false;
+	bool show_version = false;
+	bool no_work = false;
+	int rc;
+	int occ_channel = 0;
+
+	while(1) {
+		static struct option long_opts[] = {
+			{"chip",	required_argument,	NULL,	'c'},
+			{"occ-channel",	required_argument,	NULL,	'n'},
+			{"help",	no_argument,		NULL,	'h'},
+			{"version",	no_argument,		NULL,	'v'},
+		};
+		int c, oidx = 0;
+
+		c = getopt_long(argc, argv, "-c:n:hlv", long_opts, &oidx);
+		if (c == EOF)
+			break;
+		switch(c) {
+		case 1:
+			addr = strtoull(optarg, NULL, 16);
+			break;
+		case 'c':
+			chip_id = strtoul(optarg, NULL, 0);
+			break;
+		case 'n':
+			occ_channel = strtoul(optarg, NULL, 0);
+			if (occ_channel < 0 || occ_channel > 3) {
+				fprintf(stderr, "occ-channel out of range 0 <= c <= 3\n");
+				exit(1);
+			}
+			break;
+		case 'h':
+			show_help = true;
+			break;
+		case 'v':
+			show_version = true;
+			break;
+		default:
+			exit(1);
+		}
+	}
+
+	if (addr == -1ull)
+		no_work = true;
+	if (no_work && !show_version && !show_help) {
+		fprintf(stderr, "Invalid or missing address\n");
+		print_usage();
+		exit(1);
+	}
+	if (show_version)
+		printf("xscom utils version %s\n", VERSION_STR);
+	if (show_help)
+		print_usage();
+	if (no_work)
+		return 0;
+	def_chip = xscom_init();
+	if (def_chip == 0xffffffff) {
+		fprintf(stderr, "No valid XSCOM chip found\n");
+		exit(1);
+	}
+	if (chip_id == 0xffffffff)
+		chip_id = def_chip;
+
+	rc = sram_read(chip_id, occ_channel, addr, &val);
+	if (rc) {
+		fprintf(stderr,"Error %d reading XSCOM\n", rc);
+		exit(1);
+	}
+	printf("OCC%d: %" PRIx64 "\n", occ_channel, val);
+	return 0;
+}
diff --git a/external/xscom-utils/sram.c b/external/xscom-utils/sram.c
new file mode 100644
index 000000000000..74ad9967c969
--- /dev/null
+++ b/external/xscom-utils/sram.c
@@ -0,0 +1,116 @@
+/* Copyright 2014-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * imitations under the License.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <time.h>
+
+#include "xscom.h"
+
+#define DBG(fmt...)	do { if (verbose) printf(fmt); } while(0)
+#define ERR(fmt...)	do { fprintf(stderr, fmt); } while(0)
+
+#define PPC_BIT(bit)		(0x8000000000000000UL >> (bit))
+
+
+#define OCB_PIB_OCBCSR0_0x0006B011	0x0006B011
+#define OCB_PIB_OCBCSR0_ANDx0006B012	0x0006B012
+#define OCB_PIB_OCBCSR0_ORx0006B013	0x0006B013
+#define   OCB_STREAM_MODE			PPC_BIT(4)
+#define   OCB_STREAM_TYPE			PPC_BIT(5)
+#define OCB_PIB_OCBAR0_0x0006B010	0x0006B010
+#define OCB_PIB_OCBDR0_0x0006B015	0x0006B015
+
+int sram_read(uint32_t chip_id, int chan, uint32_t addr, uint64_t *val)
+{
+	uint32_t coff = chan * 0x20;
+	uint64_t sdat;
+	int rc;
+
+	/* Read for debug purposes */
+	rc = xscom_read(chip_id, OCB_PIB_OCBCSR0_0x0006B011 + coff, &sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBCSR0_0x0006B011 read error %d\n", rc);
+		return -1;
+	}
+
+	/* Create an AND mask to clear bit 4 and 5 and poke the AND register */
+	sdat = ~(OCB_STREAM_MODE | OCB_STREAM_TYPE);
+	rc = xscom_write(chip_id, OCB_PIB_OCBCSR0_ANDx0006B012 + coff, sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBCSR0_ANDx0006B012 write error %d\n", rc);
+		return -1;
+	}
+
+	sdat = ((uint64_t)addr) << 32;
+	rc = xscom_write(chip_id, OCB_PIB_OCBAR0_0x0006B010 + coff, sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBAR0_0x0006B010 write error %d\n", rc);
+		return -1;
+	}
+
+	rc = xscom_read(chip_id, OCB_PIB_OCBDR0_0x0006B015 + coff, val);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBAR0_0x0006B010 read error %d\n", rc);
+		return -1;
+	}
+	return 0;
+}
+
+int sram_write(uint32_t chip_id, int chan, uint32_t addr, uint64_t val)
+{
+	uint32_t coff = chan * 0x20;
+	uint64_t sdat;
+	int rc;
+
+#if 0
+	if (dummy) {
+		printf("[dummy] write chip %d OCC sram 0x%08x = %016lx\n",
+		       chip_id, addr, val);
+		return 0;
+	}
+#endif
+
+	/* Read for debug purposes */
+	rc = xscom_read(chip_id, OCB_PIB_OCBCSR0_0x0006B011 + coff, &sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBCSR0_0x0006B011 read error %d\n", rc);
+		return -1;
+	}
+
+	/* Create an AND mask to clear bit 4 and 5 and poke the AND register */
+	sdat = ~(OCB_STREAM_MODE | OCB_STREAM_TYPE);
+	rc = xscom_write(chip_id, OCB_PIB_OCBCSR0_ANDx0006B012 + coff, sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBCSR0_ANDx0006B012 write error %d\n", rc);
+		return -1;
+	}
+
+	sdat = ((uint64_t)addr) << 32;
+	rc = xscom_write(chip_id, OCB_PIB_OCBAR0_0x0006B010 + coff, sdat);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBAR0_0x0006B010 write error %d\n", rc);
+		return -1;
+	}
+
+	rc = xscom_write(chip_id, OCB_PIB_OCBDR0_0x0006B015 + coff, val);
+	if (rc) {
+		ERR("xscom OCB_PIB_OCBAR0_0x0006B010 write error %d\n", rc);
+		return -1;
+	}
+	return 0;
+}
diff --git a/external/xscom-utils/sram.h b/external/xscom-utils/sram.h
new file mode 100644
index 000000000000..1db128ce8fe1
--- /dev/null
+++ b/external/xscom-utils/sram.h
@@ -0,0 +1,27 @@
+/* Copyright 2014-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * imitations under the License.
+ */
+
+#ifndef __SRAM_H
+#define __SRAM_H
+
+#include <stdint.h>
+
+extern int sram_read(uint32_t chip_id, int chan, uint64_t addr, uint64_t *val);
+extern int sram_write(uint32_t chip_id, int chan, uint64_t addr, uint64_t val);
+
+extern void sram_for_each_chip(void (*cb)(uint32_t chip_id));
+
+#endif /* __SRAM_H */
-- 
2.1.4



More information about the Skiboot mailing list