Skip to contentSkip to conversation

switch support v2

PATCH In review Armin 3 participants 10 messages Dec 16, 2007 – Dec 18, 2007

lore
Share & tools
lore

Armin

author
#0 lore raw

PATCH 1/2 switch support v2

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

vl.c +126 -0
Index: 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;
             }
         }
     }
sysemu.h +20 -0
Index: 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
#1 lore raw

Hi,

Quoted 9 lines · Armin

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]

I find this format utterly ugly. You have sections like INI files, but then refuse to keep to that format.

Besides, I fail to see why this has to be a config file? All other settings are command line switches and/or monitor settings, and there is no good reason why switches and jumpers should not be handled that way.

Ciao,
Dscho

author
#2 lore raw
Quoted 7 lines · Johannes Schindelin

Hi,

Quoted 2 lines · Armin

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.

Quoted 8 lines
Quoted 6 lines

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

I find this format utterly ugly.

I can only make it better then : )

Quoted 3 lines

You have sections like INI files, but then refuse to keep to that format.

Besides, I fail to see why this has to be a config file?

It can be named anything , I suppose "switch"would be better

Quoted 2 lines

All other settings are command line switches and/or monitor settings, and there is no good reason why switches and jumpers should not be handled that way.

Do you mean something like -sw or -jp?

regards,
-Armin

#3 lore raw

Hi,

Quoted 7 lines · Armin
Quoted 3 lines · Johannes Schindelin

All other settings are command line switches and/or monitor settings, and there is no good reason why switches and jumpers should not be handled that way.

Do you mean something like -sw or -jp?

More like "-switch" and "-jumper".

Ciao,
Dscho

#4 lore raw
In reply to Armin

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

qemu -drive if=pflash,unit=0

to use the first bank, and

qemu -drive if=pflash,unit=1

to use the second bank.

Laurent

Quoted 36 lines · Armin
Quoted 9 lines · Johannes Schindelin

Hi,

Quoted 4 lines · Armin

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.

Quoted 8 lines
Quoted 6 lines

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

I find this format utterly ugly.

I can only make it better then : )

Quoted 4 lines

You have sections like INI files, but
then refuse to keep to that format.

Besides, I fail to see why this has to be a config file?

It can be named anything , I suppose "switch"would be better

Quoted 4 lines

All other
settings are command line switches and/or monitor settings, and there is no good reason why switches and jumpers should not be handled that way.

Do you mean something like -sw or -jp?

regards,
-Armin

Signature · 3 lines
----------------- [email protected]  ------------------
  "La perfection est atteinte non quand il ne reste rien à
ajouter mais quand il ne reste rien à enlever." Saint Exupéry
author
#5 lore raw
Quoted 5 lines · Laurent Vivier

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

Quoted 8 lines

qemu -drive if=pflash,unit=0

to use the first bank, and

qemu -drive if=pflash,unit=1

to use the second bank.

Yes, that might work for the flash case but does not address other switches settings. In my case, the Mainstone has two rotary switches that define which frequency to boot up in.

- Armin

Quoted 43 lines

Laurent

Quoted 39 lines · Armin
Quoted 8 lines · Johannes Schindelin

Hi,

Quoted 2 lines · Armin

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.

Quoted 9 lines
Quoted 7 lines

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

I find this format utterly ugly.

I can only make it better then : )

Quoted 4 lines

You have sections like INI files, but then refuse to keep to that format.

Besides, I fail to see why this has to be a config file?

It can be named anything , I suppose "switch"would be better

Quoted 3 lines

All other settings are command line switches and/or monitor settings, and there is no good reason why switches and jumpers should not be handled that way.

Do you mean something like -sw or -jp?

regards,
-Armin

#6 lore raw
Quoted 10 lines · Armin
Quoted 9 lines · Laurent Vivier

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

qemu -drive if=pflash,unit=0

to use the first bank, and

Quoted 7 lines
Quoted 4 lines

qemu -drive if=pflash,unit=1

to use the second bank.

Yes, that might work for the flash case but does not address other switches settings. In my case, the Mainstone has two rotary switches that define which frequency to boot up in.

But I don't think qemu able to emulate frequency ? So it should be useless.

Regards,
Laurent

Signature · 3 lines
----------------- [email protected]  ------------------
  "La perfection est atteinte non quand il ne reste rien à
ajouter mais quand il ne reste rien à enlever." Saint Exupéry
author
#7 lore raw
Quoted 15 lines · Laurent Vivier
Quoted 13 lines · Armin
Quoted 11 lines · Laurent Vivier

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

qemu -drive if=pflash,unit=0

to use the first bank, and

qemu -drive if=pflash,unit=1

Quoted 9 lines
Quoted 5 lines
Quoted 3 lines

to use the second bank.

Yes, that might work for the flash case but does not address other switches settings. In my case, the Mainstone has two rotary switches that define which frequency to boot up in.

But I don't think qemu able to emulate frequency ? So it should be useless.

I am sure that is true and my example might be very week in the above case.
I think if a board we are trying to emulate has boot time configurations governed by jumpers or switches for enabling or disabling certain hardware devices , then having a runtime solution seems more appropriate. It seems silly to have to rebuild to qemu if one wants to switch device A to be uart #2 from an IrdA device when using "-switches 1=on" could do the same.

regards,
Armin

#8 lore raw
Quoted 27 lines · Armin
Quoted 18 lines · Laurent Vivier
Quoted 16 lines · Armin
Quoted 14 lines · Laurent Vivier

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

qemu -drive if=pflash,unit=0

to use the first bank, and

qemu -drive if=pflash,unit=1

to use the second bank.

Quoted 8 lines
Quoted 4 lines

Yes, that might work for the flash case but does not address other switches settings. In my case, the Mainstone has two rotary switches that define which frequency to boot up in.

But I don't think qemu able to emulate frequency ? So it should be useless.

Quoted 7 lines

I am sure that is true and my example might be very week in the above case. I think if a board we are trying to emulate has boot time configurations governed by jumpers or switches for enabling or disabling certain hardware devices , then having a runtime solution seems more appropriate. It seems silly to have to rebuild to qemu if one wants to switch device A to be uart #2 from an IrdA device when using "-switches 1=on" could do the same.

Well, my opinion is not really important here, but I think "-switches 1=on" is too low level... using the "meaning" could be more user-friendly, something like "-deviceA uart2".

Regards,
Laurent

Signature · 3 lines
----------------- [email protected]  ------------------
  "La perfection est atteinte non quand il ne reste rien à
ajouter mais quand il ne reste rien à enlever." Saint Exupéry
author
#9 lore raw
Quoted 32 lines · Laurent Vivier
Quoted 30 lines · Armin
Quoted 28 lines · Laurent Vivier
Quoted 12 lines · Armin
Quoted 9 lines · Laurent Vivier

Hi,

if you just want to configure which bank to use with pflash, perhaps you can do something like:

qemu -drive if=pflash,unit=0

to use the first bank, and

Quoted 9 lines
Quoted 6 lines

qemu -drive if=pflash,unit=1

to use the second bank.

Yes, that might work for the flash case but does not address other switches settings. In my case, the Mainstone has two rotary switches that define which frequency to boot up in.

But I don't think qemu able to emulate frequency ? So it should be useless.

Quoted 8 lines
Quoted 3 lines

I am sure that is true and my example might be very week in the above case.
I think if a board we are trying to emulate has boot time configurations governed by jumpers or switches for enabling or disabling certain hardware devices , then having a runtime solution seems more appropriate. It seems silly to have to rebuild to qemu if one wants to switch device A to be uart #2 from an IrdA device when using "-switches 1=on" could do the same.

Well, my opinion is not really important here, but I think "-switches 1=on" is too low level... using the "meaning" could be more user-friendly, something like "-deviceA uart2".

Sure your opinion matters, I can get an idea stuck in my little brain and not see the trees in the forest. "-device", that got me thinking... Lets say I have a mips port that has one PCI slot on it. I could get a listing of PCI cards supported by this port and select one for use by that PCI slot. This could be extended for local bus (i.e switches & jumpers) , PCMCIA and SD slots.

Regards,
Armin