[coreboot-gerrit] Patch set updated for coreboot: b89610f util/intelgpio: Handy tool to build gpio.h from dumped values

Edward O'Callaghan (eocallaghan@alterapraxis.com) gerrit at coreboot.org
Tue Aug 26 13:36:28 CEST 2014


Edward O'Callaghan (eocallaghan at alterapraxis.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6762

-gerrit

commit b89610fcfd0c976a96a4e3aa1cd014da1c7cfbf4
Author: Edward O'Callaghan <eocallaghan at alterapraxis.com>
Date:   Tue Aug 26 00:12:03 2014 +1000

    util/intelgpio: Handy tool to build gpio.h from dumped values
    
    This purpose of this tool is to build the 'gpio.h' header from dumped
    values out of the inteltool.
    
    Change-Id: I2812a3546849347567efe71c714fefe39e02e5d7
    Signed-off-by: Edward O'Callaghan <eocallaghan at alterapraxis.com>
---
 .gitignore                  |   1 +
 util/intelgpio/Makefile     |  47 ++++++++
 util/intelgpio/dump_parse.c |  81 ++++++++++++++
 util/intelgpio/intelgpio.c  | 259 ++++++++++++++++++++++++++++++++++++++++++++
 util/intelgpio/intelgpio.h  |  52 +++++++++
 5 files changed, 440 insertions(+)

diff --git a/.gitignore b/.gitignore
index 203ad9a..0a05520 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,7 @@ util/ifdtool/ifdtool
 util/ifdfake/ifdfake
 util/inteltool/.dependencies
 util/inteltool/inteltool
+util/intelgpio/intelgpio
 util/k8resdump/k8resdump
 util/lbtdump/lbtdump
 util/mptable/mptable
diff --git a/util/intelgpio/Makefile b/util/intelgpio/Makefile
new file mode 100644
index 0000000..b09bca9
--- /dev/null
+++ b/util/intelgpio/Makefile
@@ -0,0 +1,47 @@
+#
+# Makefile for intelgpio utility
+#
+# Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+PROGRAM = intelgpio
+
+CC      ?= clang
+INSTALL ?= /usr/bin/install
+PREFIX  ?= /usr/local
+CFLAGS  ?= -O2 -g -Wall -W
+LDFLAGS +=
+
+OBJS = intelgpio.o dump_parse.o
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(OBJS)
+	$(CC) $(CFLAGS) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
+
+clean:
+	rm -f $(PROGRAM) *.o *~
+
+install: $(PROGRAM)
+	mkdir -p $(DESTDIR)$(PREFIX)/sbin
+	$(INSTALL) $(PROGRAM) $(DESTDIR)$(PREFIX)/sbin
+	mkdir -p $(DESTDIR)$(PREFIX)/share/man/man8
+	$(INSTALL) -p -m644 $(PROGRAM).8 $(DESTDIR)$(PREFIX)/share/man/man8
+
+.PHONY: all clean
+
+-include .dependencies
diff --git a/util/intelgpio/dump_parse.c b/util/intelgpio/dump_parse.c
new file mode 100644
index 0000000..ecac9f7
--- /dev/null
+++ b/util/intelgpio/dump_parse.c
@@ -0,0 +1,81 @@
+/*
+ * inteltool - Prepare gpio.h file from register dumps from inteltool.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "intelgpio.h"
+
+/**
+ * Parse a line out of a inteltool dump, NULL is returned when a line could
+ * not be parsed.
+ */
+static struct dump_tuple * parse_line(char * line)
+{
+	struct dump_tuple * row = NULL;
+	uint32_t addr, val;
+
+	/* tokenizes line */
+	if (sscanf(line, "0x%04x:", &addr) != 1)
+		return NULL; // if no address could be read
+	if (sscanf(line, "0x%08x", &val) != 1)
+		return NULL; // if no value could be read
+
+	row = (struct dump_tuple *) malloc(sizeof(struct dump_tuple));
+	row->address = addr;
+	row->registers = val;
+	row->next = NULL;
+
+	return row;
+}
+
+/**
+ * Returns a linked list of each row of the dump where each node is type
+ * struct dump_tuple.
+ */
+struct dump_tuple * process_stdin(FILE *fp)
+{
+	struct dump_tuple * head = NULL, * node = NULL;
+	char * line = NULL;
+	size_t len = 0;
+
+	if (fp == NULL)
+		return NULL;
+
+	while (getline(&line, &len, fp) != -1) {
+		if (head == NULL) {
+			head = parse_line(line);
+			node = head;
+		}
+		else {
+			node->next = parse_line(line);
+			node = node->next;
+		}
+		if (node == NULL) {
+			fprintf(stderr, "dump malformed!\n");
+			exit(1); // FIXME: memory leak here, free-up linked-list !
+		}
+	}
+
+	if (line)
+		free(line);
+
+	return head;
+}
diff --git a/util/intelgpio/intelgpio.c b/util/intelgpio/intelgpio.c
new file mode 100644
index 0000000..53178fa
--- /dev/null
+++ b/util/intelgpio/intelgpio.c
@@ -0,0 +1,259 @@
+/*
+ * inteltool - Prepare gpio.h file from register dumps from inteltool.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define INTELGPIO_VERSION "0.1"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "intelgpio.h"
+
+static const __attribute__((unused)) char *mode[]   = {"MODE_NATIVE", "MODE_GPIO", "mode"};
+static const __attribute__((unused)) char *dir[]    = {"DIR_OUTPUT", "DIR_INPUT", "direction"};
+static const __attribute__((unused)) char *invert[] = {"NO_INVERT", "GPIO_INVERT", "invert"};
+static const __attribute__((unused)) char *level[]  = {"LEVEL_LOW", "LEVEL_HIGH", "level"};
+static const __attribute__((unused)) char *blink[]  = {"NO_BLINK", "BLINK", "blink"};
+static const __attribute__((unused)) char *reset[]  = {"RESET_PWROK", "RESET_RSMRST", "reset"};
+
+static void print_version(void)
+{
+	printf("intelgpio v%s -- ", INTELGPIO_VERSION);
+	printf("Copyright (C) 2014 Edward O'Callaghan\n\n");
+	printf(
+    "This program is free software: you can redistribute it and/or modify\n"
+    "it under the terms of the GNU General Public License as published by\n"
+    "the Free Software Foundation, version 2 of the License.\n\n"
+    "This program is distributed in the hope that it will be useful,\n"
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+    "GNU General Public License for more details.\n\n"
+    "You should have received a copy of the GNU General Public License\n"
+    "along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n");
+}
+
+static void print_usage(const char *name)
+{
+	printf("usage: %s [-vh?sdmlia]\n", name);
+	printf("\n"
+		"   -v | --version:                   print the version\n"
+		"   -h | --help:                      print this help\n\n"
+		"   -b | --boardname=                 name of mainboard\n"
+		"   -s | --set=                       GPIO register set\n"
+		"   -d | --direction=                 direction val\n"
+		"   -m | --mode=                      mode val\n"
+		"   -l | --level=                     level val\n"
+		"   -i | --invert=                    invert val\n"
+		"   -a | --all:                       all register sets 1,2,3\n"
+		"\n");
+	exit(1);
+}
+
+static void build_structs(const char *boardname)
+{
+	unsigned int set;
+
+	for (set = 1; set < 4; set++) {
+		printf("const struct pch_gpio_map %s_gpio_map = {\n", boardname);
+		printf("\t.set%i = {\n", set);
+		printf("\t\t.mode\t\t= &pch_gpio_set%i_mode,\n", set);
+		printf("\t\t.direction\t= &pch_gpio_set%i_direction,\n", set);
+		printf("\t\t.level\t\t= &pch_gpio_set%i_level,\n", set);
+		if (set == 1)
+			printf("\t\t.invert\t\t= &pch_gpio_set%i_invert,\n", set);
+		printf("\t},\n");
+		printf("};\n\n");
+	}
+}
+
+static void print_gpio_config(const char *type[], uint8_t set, uint32_t gpioval) {
+	unsigned int i;
+	uint8_t pin;
+//	char pin_flag;
+
+	printf("const struct pch_gpio_set%i pch_gpio_set%i_%s = {\n", set, set, type[2]);
+	for (i = 0; i < 32; i++) {
+		pin = ((set - 1) * 32 + i);
+//		pin_flag = (pin < 10 ? ' ': '\0');
+//		printf("\t.gpio%i%c = GPIO_%s,\n", pin, pin_flag
+		printf("\t.gpio%i = GPIO_%s,\n", pin
+										, type[(gpioval >> i) & 1]);
+	}
+	printf("};\n\n");
+}
+
+// TODO write to file.. or keep as stdout???
+static void write_gpio_header(uint8_t set, uint32_t mv, uint32_t dv, uint32_t lv, uint32_t iv)
+{
+	// TODO: check bounds on mode, dir, level & invert for sane values??
+	print_gpio_config(mode, set, mv);
+	print_gpio_config(dir, set, dv);
+	print_gpio_config(level, set, lv);
+	if (set == 1)
+		print_gpio_config(invert, set, iv);
+}
+
+static void build_header(struct dump_tuple * head, char * board_name)
+{
+	struct dump_tuple * node = head, * prev = NULL;
+	uint32_t direction1 = 0, mode1 = 0, level1 = 0, invert = 0;
+	uint32_t direction2 = 0, mode2 = 0, level2 = 0;
+	uint32_t direction3 = 0, mode3 = 0, level3 = 0;
+	uint32_t blink = 0;
+
+	if (board_name != NULL) {
+		printf("#ifndef %s_GPIO_H\n", board_name);
+		printf("#define %s_GPIO_H\n\n", board_name);
+	} else {
+		printf("#ifndef GENERIC_GPIO_H\n");
+		printf("#define GENERIC_GPIO_H\n\n");
+	}
+
+// FIXME: convert switch to const array map for lookups.
+	while (node != NULL) {
+		switch(node->address) {
+		case GPIO_USE_SEL:
+			mode1 = node->registers;
+			break;
+		case GP_IO_SEL:
+			direction1 = node->registers;
+			break;
+		case GP_LVL:
+			level1 = node->registers;
+			break;
+		case GPO_BLINK:
+			blink = node->registers; // TODO..
+			break;
+		case GPI_INV:
+			invert = node->registers;
+			break;
+		case GPIO_USE_SEL2:
+			mode2 = node->registers;
+			break;
+		case GP_IO_SEL2:
+			direction2 = node->registers;
+			break;
+		case GP_LVL2:
+			level2 = node->registers;
+			break;
+		case GPIO_USE_SEL3:
+			mode3 = node->registers;
+			break;
+		case GP_IO_SEL3:
+			direction3 = node->registers;
+			break;
+		case GP_LVL3:
+			level3 = node->registers;
+			break;
+		default:
+			fprintf(stderr, "Unknown GPIO address of 0x%04x\n", node->address);
+			break;
+		}
+		prev = node;
+		node = node->next;
+		free(prev);
+	}
+
+	write_gpio_header(1, mode1, direction1, level1, invert);
+	write_gpio_header(2, mode2, direction2, level2, 0);
+	write_gpio_header(3, mode3, direction3, level3, 0);
+
+	if (board_name != NULL) {
+		build_structs(board_name);
+	} else {
+		build_structs("generic");
+	}
+	printf("#endif\n");
+}
+
+int main(int argc, char *argv[])
+{
+	int opt, option_index = 0;
+	uint8_t dump_set = 0, dump_all_sets = 0;
+	uint32_t direction = 0, mode = 0, level = 0, invert = 0;
+	char * mainboard_name = NULL;
+	struct dump_tuple * head = NULL;
+
+	static struct option long_options[] = {
+		{"version",   no_argument,       0, 'v'},
+		{"help",      no_argument,       0, 'h'},
+		{"set",       required_argument, 0, 's'},
+		{"boardname", optional_argument, 0, 'b'},
+		{"direction", required_argument, 0, 'd'},
+		{"mode",      required_argument, 0, 'm'},
+		{"level",     required_argument, 0, 'l'},
+		{"invert",    required_argument, 0, 'i'},
+		{"all",       0,                 0, 'a'},
+		{0, 0, 0, 0}
+	};
+
+	while ((opt = getopt_long(argc, argv, "vh?b:s:d:m:l:i:a",
+				long_options, &option_index)) != EOF) {
+		switch (opt) {
+		case 'v':
+			print_version();
+			exit(0);
+			break;
+		case 'b':
+			mainboard_name = optarg;
+			break;
+		case 's':
+			dump_set = atoi(optarg);
+			break;
+		case 'd':
+			direction = strtol(optarg, NULL, 16);
+			break;
+		case 'm':
+			mode = strtol(optarg, NULL, 16);
+			break;
+		case 'l':
+			level = strtol(optarg, NULL, 16);
+			break;
+		case 'i':
+			invert = strtol(optarg, NULL, 16);
+			break;
+		case 'a':
+			dump_all_sets = 1;
+			break;
+		case 'h':
+		case '?':
+		default:
+			print_usage(argv[0]);
+			exit(0);
+			break;
+		}
+	}
+
+	if (dump_all_sets) {
+		head = process_stdin(stdin);
+		build_header(head, mainboard_name);
+	}
+
+
+// FIXME: check if mode, direction, level and invert were /all/ set..
+	if ((dump_set >= 1) && (dump_set <= 3)) {
+		write_gpio_header(dump_set, mode, direction, level, invert);
+	} else if (!dump_all_sets) {
+		print_usage(argv[0]);
+		exit(0);
+	}
+
+	return 0;
+}
diff --git a/util/intelgpio/intelgpio.h b/util/intelgpio/intelgpio.h
new file mode 100644
index 0000000..a7544b3
--- /dev/null
+++ b/util/intelgpio/intelgpio.h
@@ -0,0 +1,52 @@
+/*
+ * inteltool - Prepare gpio.h file from register dumps from inteltool.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _INTELGPIO_H
+#define _INTELGPIO_H
+
+#include <stdint.h>
+
+/* ICH7 GPIOBASE */
+#define GPIO_USE_SEL	0x00
+#define GP_IO_SEL	0x04
+#define GP_LVL		0x0c
+#define GPO_BLINK	0x18
+#define GPI_INV		0x2c
+#define GPIO_USE_SEL2	0x30
+#define GP_IO_SEL2	0x34
+#define GP_LVL2		0x38
+#define GPIO_USE_SEL3	0x40
+#define GP_IO_SEL3	0x44
+#define GP_LVL3		0x48
+#define GP_RST_SEL1	0x60
+#define GP_RST_SEL2	0x64
+#define GP_RST_SEL3	0x68
+
+
+struct dump_tuple;
+
+struct dump_tuple {
+	uint32_t address;
+	uint32_t registers;
+	struct dump_tuple * next;
+};
+
+struct dump_tuple * process_stdin(FILE *fp);
+
+#endif /* _INTELGPIO_H */



More information about the coreboot-gerrit mailing list