=== modified file 'lava_dispatcher/actions/boot_control.py'
--- lava_dispatcher/actions/boot_control.py	2012-07-27 16:49:32 +0000
+++ lava_dispatcher/actions/boot_control.py	2012-11-14 16:31:18 +0000
@@ -42,7 +42,7 @@
 
     def run(self, options=[]):
         client = self.client
-        client.boot_options = options
+        client.target_device.boot_options = options
         try:
             client.boot_linaro_android_image()
         except Exception as e:
@@ -57,7 +57,7 @@
 
     def run(self, options=[]):
         client = self.client
-        client.boot_options = options
+        client.target_device.boot_options = options
         status = 'pass'
         try:
             client.boot_linaro_image()

=== modified file 'lava_dispatcher/config.py'
--- lava_dispatcher/config.py	2012-10-23 08:54:22 +0000
+++ lava_dispatcher/config.py	2012-11-14 16:34:06 +0000
@@ -32,6 +32,7 @@
     boot_cmds = schema.StringOption(fatal=True) # Can do better here
     boot_cmds_android = schema.StringOption(fatal=True) # And here
     boot_cmds_oe = schema.StringOption(fatal=True) # And here?
+    boot_options = schema.ListOption()
     boot_linaro_timeout = schema.IntOption(default=300)
     boot_part = schema.IntOption(fatal=True)
     boot_part_android_org = schema.IntOption()

=== modified file 'lava_dispatcher/default-config/lava-dispatcher/device-types/fastmodel.conf'
--- lava_dispatcher/default-config/lava-dispatcher/device-types/fastmodel.conf	2012-10-17 16:51:09 +0000
+++ lava_dispatcher/default-config/lava-dispatcher/device-types/fastmodel.conf	2012-11-14 16:34:06 +0000
@@ -19,3 +19,28 @@
 
 # we do usermode networking over the loopback
 default_network_interface = lo
+
+boot_options =
+	motherboard.smsc_91c111.enabled
+	motherboard.hostbridge.userNetworking
+	coretile.cache_state_modelled
+	coretile.cluster0.cpu0.semihosting-enable
+	coretile.cluster0.cpu0.semihosting-cmd_line
+
+[motherboard.smsc_91c111.enabled]
+default = 1
+allowed = 0,1
+
+[motherboard.hostbridge.userNetworking]
+default = 1
+allowed = 0,1
+
+[coretile.cache_state_modelled]
+default = 0
+allowed = 0,1
+
+[coretile.cluster0.cpu0.semihosting-enable]
+default = 1
+allowed = 0,1
+
+[coretile.cluster0.cpu0.semihosting-cmd_line]

=== added file 'lava_dispatcher/device/boot_options.py'
--- lava_dispatcher/device/boot_options.py	1970-01-01 00:00:00 +0000
+++ lava_dispatcher/device/boot_options.py	2012-11-14 19:37:35 +0000
@@ -0,0 +1,81 @@
+# Copyright (C) 2012 Linaro Limited
+#
+# Author: Andy Doan <andy.doan@linaro.org>
+#
+# This file is part of LAVA Dispatcher.
+#
+# LAVA Dispatcher 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.
+#
+# LAVA Dispatcher 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, see <http://www.gnu.org/licenses>.
+
+import logging
+
+
+class BootOption(object):
+    """
+    Parses items from a config ini section into an options object.
+    """
+    def __init__(self, section, items):
+        self.name = section
+        self.value = None
+        self.allowed = None
+        for item in items:
+            if item[0] == 'default':
+                self.value = item[1]
+            elif item[0] == 'allowed':
+                self.allowed = [x.strip() for x in item[1].split(',')]
+            else:
+                logging.warn('section(%s) contains unknown item: %s' %
+                    (section, item))
+
+    def valid(self, option):
+        if self.allowed:
+            return option in self.allowed
+        # if no "allowed" value is set, then we can accept anything
+        return True
+
+
+def as_dict(target):
+    options = {}
+    for opt in target.config.boot_options:
+        if opt in target.config.cp.sections():
+            options[opt] = BootOption(opt, target.config.cp.items(opt))
+        else:
+            logging.warn('no boot option config section for: %s' % opt)
+
+    for opt in target.boot_options:
+        keyval = opt.split('=')
+        if len(keyval) != 2:
+            logging.warn("Invalid boot option format: %s" % opt)
+        elif keyval[0] not in options:
+            logging.warn("Invalid boot option: %s" % keyval[0])
+        elif not options[keyval[0]].valid(keyval[1]):
+            logging.warn("Invalid boot option value: %s" % opt)
+        else:
+            options[keyval[0]].value = keyval[1]
+
+    return options
+
+
+def as_string(target, join_pattern):
+    """
+    pulls the options into a string via the join_pattern. The join pattern
+    can be something like "%s=%s"
+    """
+    options = as_dict(target)
+
+    cmd = ''
+    for option in options.values():
+        if option.value:
+            cmd += join_pattern % (option.name, option.value)
+    return cmd

=== modified file 'lava_dispatcher/device/fastmodel.py'
--- lava_dispatcher/device/fastmodel.py	2012-11-09 20:25:51 +0000
+++ lava_dispatcher/device/fastmodel.py	2012-11-15 22:07:29 +0000
@@ -29,6 +29,8 @@
 import re
 import subprocess
 
+import lava_dispatcher.device.boot_options as boot_options
+
 from lava_dispatcher.device.target import (
     Target
 )
@@ -62,16 +64,6 @@
     FASTMODELS = {'ve': FM_VE, 'foundation': FM_FOUNDATION}
     AXF_IMAGES = {FM_VE: 'img.axf', FM_FOUNDATION: 'img-foundation.axf'}
 
-    BOOT_OPTIONS_VE = {
-        'motherboard.smsc_91c111.enabled': '1',
-        'motherboard.hostbridge.userNetworking': '1',
-        'coretile.cache_state_modelled': '0',
-        'coretile.cluster0.cpu0.semihosting-enable': '1',
-    }
-
-    # a list of allowable values for BOOT_OPTIONS_VE
-    BOOT_VALS = ['0', '1']
-
     def __init__(self, context, config):
         super(FastModelTarget, self).__init__(context, config)
         self._sim_binary = config.simulator_binary
@@ -182,31 +174,16 @@
         os.chown(self._axf, st.st_uid, st.st_gid)
         os.chown(self._sd_image, st.st_uid, st.st_gid)
 
-    def _boot_options_ve(self):
-        options = dict(self.BOOT_OPTIONS_VE)
-        for option in self.boot_options:
-            keyval = option.split('=')
-            if len(keyval) != 2:
-                logging.warn("Invalid boot option format: %s" % option)
-            elif keyval[0] not in self.BOOT_OPTIONS_VE:
-                logging.warn("Invalid boot option: %s" % keyval[0])
-            elif keyval[1] not in self.BOOT_VALS:
-                logging.warn("Invalid boot option value: %s" % option)
-            else:
-                options[keyval[0]] = keyval[1]
-
-        return ' '.join(['-C %s=%s' % (k, v) for k, v in options.iteritems()])
-
     def _get_sim_cmd(self):
+        options = boot_options.as_string(self, join_pattern=' -C %s=%s')
         if self._fastmodel_type == self.FM_VE:
-            options = self._boot_options_ve()
             return ("%s -a coretile.cluster0.*=%s "
                 "-C motherboard.mmc.p_mmc_file=%s "
                 "-C motherboard.hostbridge.userNetPorts='5555=5555' %s") % (
                 self._sim_binary, self._axf, self._sd_image, options)
         elif self._fastmodel_type == self.FM_FOUNDATION:
-            return ("%s --image=%s --block-device=%s --network=nat") % (
-                self._sim_binary, self._axf, self._sd_image)
+            return ("%s --image=%s --block-device=%s --network=nat %s") % (
+                self._sim_binary, self._axf, self._sd_image, options)
 
     def _power_off(self, proc):
         if proc is not None:

=== modified file 'lava_dispatcher/device/master.py'
--- lava_dispatcher/device/master.py	2012-11-15 04:54:00 +0000
+++ lava_dispatcher/device/master.py	2012-11-15 22:07:29 +0000
@@ -29,6 +29,7 @@
 
 import pexpect
 
+import lava_dispatcher.device.boot_options as boot_options
 import lava_dispatcher.tarballcache as tarballcache
 
 from lava_dispatcher.device.target import (
@@ -66,6 +67,7 @@
 
         Target.android_deployment_data['boot_cmds'] = 'boot_cmds_android'
         Target.ubuntu_deployment_data['boot_cmds'] = 'boot_cmds'
+        Target.oe_deployment_data['boot_cmds'] = 'boot_cmds_oe'
 
         # used for tarballcache logic to get proper boot_cmds
         Target.ubuntu_deployment_data['data_type'] = 'ubuntu'
@@ -457,14 +459,9 @@
 
     def _boot_linaro_image(self):
         boot_cmds = self.deployment_data['boot_cmds']
-        for option in self.boot_options:
-            keyval = option.split('=')
-            if len(keyval) != 2:
-                logging.warn("Invalid boot option format: %s" % option)
-            elif keyval[0] != 'boot_cmds':
-                logging.warn("Invalid boot option: %s" % keyval[0])
-            else:
-                boot_cmds = keyval[1].strip()
+        options = boot_options.as_dict(self)
+        if 'boot_cmds' in options:
+            boot_cmds = options['boot_cmds'].value
 
         boot_cmds = getattr(self.config, boot_cmds)
         self._boot(string_to_list(boot_cmds.encode('ascii')))

