Hello,

Here is a set of patches against the latest cvs and fixed a bad patch also.

I have wanted a scheme to change switch settings at boot time so I change the behavior of the Linux kernel and here is one solution I put together.

This may be one way to simulate switch or jumper settings one may change on a board before booting. It uses a simple text file for input. The file name is pointed to by -config <path to file> on the command line.

example:
config file:
[switches]
7:on
[jumpers]

Note: both [switches] and [jumpers] are required at the moment

to use:
qemu-system-arm -M mainstone -kernel /tftpboot/mainstone -pflash ~/mst_flashl1 -config ~/config.txt

this will enable the processor flash bank on the Mainstone and if I change 7:on to 7:off , I get the main mother board flash.

feedback and comment are always welcome.

-Armin
Index: qemu_dev/vl.c
===================================================================
--- qemu_dev.orig/vl.c
+++ qemu_dev/vl.c
@@ -232,6 +232,8 @@ const char *prom_envs[MAX_PROM_ENVS];
 #endif
 int nb_drives_opt;
 char drives_opt[MAX_DRIVES][1024];
+int configed = 0;
+const char *qemu_config;
 
 static CPUState *cur_cpu;
 static CPUState *next_cpu;
@@ -1557,6 +1559,118 @@ static void quit_timers(void)
     alarm_timer->stop(alarm_timer);
     alarm_timer = NULL;
 }
+/**********************************************************/
+/* config file */
+#define CONFIG_MAXLEN 256
+
+int switch_get_value(SwitchInterfaceType interface, int number)
+{
+    int index;
+
+    struct spdt_switch *sw = config_table[interface].sw;
+
+    for (index = 0; index < config_table[interface].nb_switches; index++){
+        if(sw[index].num == number)
+            return sw[index].value;
+    }
+    return -1;
+}
+
+static ssize_t config_rdline(FILE *fd, char *buf, size_t bufsz)
+{
+    int i, ch;
+    for(i = 0; i < bufsz && (ch=fgetc(fd)) != '\n' ; i++) {
+        if (ch == EOF) {
+            *buf = '\0';
+            return  -1;
+        }
+        if(ch == '[') {
+        return -2;
+        }
+        *buf++ = ch;
+    }
+    *buf = '\0';
+    return i;
+}
+
+static int config_read_switches(FILE *fd, int index)
+{
+    int cnt = 0;
+    int size = 0;
+    char *tmp;
+    int sw_size = sizeof(struct spdt_switch);
+    struct spdt_switch *sw;
+
+    sw = (struct spdt_switch*) malloc(sw_size);
+    if(!sw) {
+        printf("config_read_switches - Malloc error!!");
+        return -ENOMEM;
+    }
+
+    config_table[index].sw = sw;
+    while(size != -1) {
+        char buf[CONFIG_MAXLEN];
+
+        size = config_rdline(fd, buf, CONFIG_MAXLEN);
+        if(size <= 0) {
+            break;
+        }
+
+        tmp = strchr(buf, ':');
+        sw[cnt].value = (strcmp(++tmp,"off")) ? 1 : 0 ;
+        sw[cnt].num = atoi(buf);
+        sw_size += sizeof(struct spdt_switch);
+        sw = (struct spdt_switch *) realloc(config_table[index].sw, sw_size );
+        if(!sw)
+            return -1;
+        cnt++;
+    };
+    return cnt;
+}
+
+static int config_file_read(char const *file)
+{
+    FILE *fd;
+    int index;
+
+    struct  {
+        char *key;
+        SwitchInterfaceType interface;
+    } switch_keywords[]= {
+        {"switches", CFG_SPDT_SWITCH},
+        {"jumpers", CFG_JUMPERS_SWITCH}
+    };
+
+    fd = fopen(file,"r");
+    if(fd < 0) {
+        printf("Open error\n");
+        return -1;
+    }
+
+    for(index = 0; index < (sizeof(switch_keywords)/sizeof(switch_keywords[0]));
+        index++){
+
+        int ret;
+        char buf[CONFIG_MAXLEN];
+        ret = config_rdline(fd, buf, CONFIG_MAXLEN);
+        if(ret == -1) {
+            return -1;
+        }
+        if(ret  == -2) {
+            ret  = config_rdline(fd, buf, CONFIG_MAXLEN);
+            if(ret == -1) {
+                return -1;
+            }
+        }
+        if(strstr(buf, switch_keywords[index].key) != NULL) {
+            int cnt;
+            cnt = config_read_switches(fd,switch_keywords[index].interface);
+            config_table[index].nb_switches = cnt;
+        }
+    }
+    fclose(fd);
+    return 1;
+}
 
 /***********************************************************/
 /* character device */
@@ -7590,6 +7704,7 @@ static void help(int exitcode)
 #endif
            "-clock          force the use of the given methods for timer alarm.\n"
            "                To see what timers are available use -clock help\n"
+           "-config file    config file for kernel startup like switches and jumpers\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -7692,6 +7807,7 @@ enum {
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
     QEMU_OPTION_startdate,
+    QEMU_OPTION_config,
 };
 
 typedef struct QEMUOption {
@@ -7800,6 +7916,7 @@ const QEMUOption qemu_options[] = {
 #endif
     { "clock", HAS_ARG, QEMU_OPTION_clock },
     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
+    { "config", HAS_ARG, QEMU_OPTION_config },
     { NULL },
 };
 
@@ -8631,6 +8748,15 @@ int main(int argc, char **argv)
                     }
                 }
                 break;
+
+            case QEMU_OPTION_config:
+                qemu_config = optarg;
+                configed = config_file_read(qemu_config);
+                if( configed == -1){
+                    fprintf(stderr, "Invalid config file: %s\n",qemu_config);
+                    exit(1);
+                }
+            break;
             }
         }
     }
Index: qemu_dev/sysemu.h
===================================================================
--- qemu_dev.orig/sysemu.h
+++ qemu_dev/sysemu.h
@@ -178,4 +178,24 @@ void do_usb_add(const char *devname);
 void do_usb_del(const char *devname);
 void usb_info(void);
 
+struct spdt_switch{
+    int num;
+    int value;  /* on/off */
+};
+
+typedef enum {
+    CFG_SPDT_SWITCH = 0,
+    CFG_JUMPERS_SWITCH
+} SwitchInterfaceType;
+
+typedef struct SwitchInfo {
+    SwitchInterfaceType interface;
+    struct spdt_switch *sw;
+    int nb_switches;
+} SwitchInfo;
+
+#define MAX_SWITCH_TYPES 2
+SwitchInfo config_table[MAX_SWITCH_TYPES +1];
+
+extern int switch_get_value(SwitchInterfaceType interface, int number);
 #endif

Reply via email to