changeset 500:de574d051887

cp: system config syntax change & parsing code The currently supported statements are: - OPERATOR CONSOLE <rdev> - OPERATOR USERID <userid> - RDEV <rdev> <type> - LOGO <conn> <cons> <filename> <filetype> Additionally, since this patch changes the system config syntax for LOGO statements, fix up the sample config. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Fri, 22 Apr 2011 13:19:26 -0400
parents c49e2a991b17
children f9fe2cddf9e0
files cp/config/system.config cp/include/config.h cp/nucleus/config.c
diffstat 3 files changed, 155 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/cp/config/system.config	Fri Apr 22 13:01:01 2011 -0400
+++ b/cp/config/system.config	Fri Apr 22 13:19:26 2011 -0400
@@ -6,4 +6,4 @@
 RDEV 0009 3215
 
 * DEFINE LOGOS
-LOGO LOCAL HVF LOGO
+LOGO LOCAL 3215 HVF LOGO
--- a/cp/include/config.h	Fri Apr 22 13:01:01 2011 -0400
+++ b/cp/include/config.h	Fri Apr 22 13:19:26 2011 -0400
@@ -8,6 +8,8 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#include <list.h>
+
 /*
  * Base address within a guest's address space; used as the base address for
  * the IPL helper code.
@@ -22,6 +24,16 @@
 #define CONFIG_FILE_NAME		"SYSTEM  "
 #define CONFIG_FILE_TYPE		"CONFIG  "
 
+struct sysconf {
+	u16			oper_con;
+	char			oper_userid[9];
+	struct list_head	rdevs;
+	struct list_head	logos;
+};
+
+/* the actual config */
+extern struct sysconf sysconf;
+
 extern int load_config();
 
 #endif
--- a/cp/nucleus/config.c	Fri Apr 22 13:01:01 2011 -0400
+++ b/cp/nucleus/config.c	Fri Apr 22 13:19:26 2011 -0400
@@ -10,12 +10,141 @@
 #include <edf.h>
 #include <ebcdic.h>
 
-static int parse_config_stmnt(char *stmnt)
+struct sysconf sysconf;
+
+int __get_u16(char *s, u16 *d)
+{
+	u16 ret = 0;
+
+	if (!*s)
+		return -1;
+
+	for(; *s; s++) {
+		if ((*s >= '0') && (*s <= '9'))
+			ret = (ret << 4) | (*s - '0');
+		else if ((*s >= 'A') && (*s <= 'F'))
+			ret = (ret << 4) | (*s - 'A' + 10);
+		else {
+			BUG();
+			return -2;
+		}
+	}
+
+	*d = ret;
+
+	return 0;
+}
+
+static int __parse_operator(char *s)
+{
+	char *t1, *t2;
+
+	if ((t1 = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	if ((t2 = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	if (!strcmp(t1, "CONSOLE")) {
+		return __get_u16(t2, &sysconf.oper_con);
+	} else if (!strcmp(t1, "USERID")) {
+		strncpy(sysconf.oper_userid, t2, 8);
+		sysconf.oper_userid[8] = '\0';
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int __parse_rdev(char *s)
 {
+	u16 devnum, devtype;
+	int ret;
+
+	char *t1, *t2;
+
+	if ((t1 = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	if ((t2 = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	ret = __get_u16(t1, &devnum);
+	if (ret)
+		return ret;
+
+	ret = __get_u16(t2, &devtype);
+	if (ret)
+		return ret;
+
+	/* FIXME: save the <devnum,devtype> pair */
+
+	return 0;
+}
+
+static int __parse_logo(char *s)
+{
+	int ret;
+
+	char *conn, *_devtype, *fn, *ft;
+	u16 devtype;
+
+	if ((conn = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	if ((_devtype = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	ret = __get_u16(_devtype, &devtype);
+	if (ret)
+		return ret;
+
+	if ((fn = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	if ((ft = strsep(&s, " ")) == NULL)
+		return -EINVAL;
+
+	/* FIXME: save the <conn, devtype, fn, ft> pair */
+
+	return 0;
+}
+
+int parse_config_stmnt(char *stmnt)
+{
+	char *s = stmnt;
+	char *tok;
+
 	if (stmnt[0] == '*')
 		return 0; /* comment */
 
-	return 0;
+	if (stmnt[0] == '\0')
+		return 0; /* empty line */
+
+	if ((tok = strsep(&s, " ")) != NULL) {
+		if (!strcmp(tok, "OPERATOR"))
+			return __parse_operator(s);
+		else if (!strcmp(tok, "RDEV"))
+			return __parse_rdev(s);
+		else if (!strcmp(tok, "LOGO"))
+			return __parse_logo(s);
+		else
+			BUG();
+	}
+
+	BUG();
+	return -EINVAL;
+}
+
+static void null_terminate(char *s, int lrecl)
+{
+	int i;
+
+	for(i=lrecl-1; i>=0; i--)
+		if (s[i] != ' ')
+			break;
+
+	s[i+1] = '\0';
 }
 
 int load_config(u32 iplsch)
@@ -23,10 +152,14 @@
 	struct device *dev;
 	struct fs *fs;
 	struct file *file;
-	char buf[CONFIG_LRECL];
+	char buf[CONFIG_LRECL+1];
 	int ret;
 	int i;
 
+	memset(&sysconf, 0, sizeof(struct sysconf));
+	INIT_LIST_HEAD(&sysconf.rdevs);
+	INIT_LIST_HEAD(&sysconf.logos);
+
 	/* find the real device */
 	dev = find_device_by_sch(iplsch);
 	if (IS_ERR(dev))
@@ -50,10 +183,16 @@
 
 		ebcdic2ascii((u8 *) buf, CONFIG_LRECL);
 
+		/* FIXME: uppercase everything */
+
+		null_terminate(buf, CONFIG_LRECL);
+
 		ret = parse_config_stmnt(buf);
 		if (ret)
 			return ret;
 	}
 
+	/* FIXME: load all the logo files */
+
 	return 0;
 }