Add the RW-only firmware programmer for servo v2

Created a new main programmer class which provides programmer for only
updating the RW portion of BIOS with servo V2.

It does nothing on EC, as EC software sync on the next boot will
automatically overwrite the EC RW portion, using the EC RW image
inside the BIOS RW image.

BUG=chromium:645311
TEST=TBD

Change-Id: Ife660ecb76732aef13a9d27ed911ee9e6e4d2c95
Reviewed-on: https://chromium-review.googlesource.com/383772
Commit-Ready: Wai-Hong Tam <waihong@google.com>
Tested-by: Wai-Hong Tam <waihong@google.com>
Reviewed-by: danny chan <dchan@chromium.org>
(cherry picked from commit c36c4d230bdaf2b23740e5db90acd583a86555bf)
Reviewed-on: https://chromium-review.googlesource.com/390013
Reviewed-by: Michael Tang <ntang@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Mohan Konduri <krk@chromium.org>
Tested-by: Mohan Konduri <krk@chromium.org>
diff --git a/server/cros/servo/firmware_programmer.py b/server/cros/servo/firmware_programmer.py
index aada28b..95e1d0d 100644
--- a/server/cros/servo/firmware_programmer.py
+++ b/server/cros/servo/firmware_programmer.py
@@ -298,6 +298,16 @@
         return result
 
 
+    def _get_flashrom_programmer(self, servo):
+        """Gets a proper flashrom programmer.
+
+        @param servo: A servo object.
+
+        @return A programmer for flashrom.
+        """
+        return FlashromProgrammer(servo)
+
+
     def _factory_bios(self, servo):
         """Instantiates and returns (bios, ec) programmers for the board.
 
@@ -309,16 +319,9 @@
         _bios_prog = None
         _board = servo.get_board()
 
-        servo_prog_state = [
-            'spi2_buf_en:on',
-            'spi2_buf_on_flex_en:on',
-            'spi_hold:off',
-            'cold_reset:on',
-            ]
-
         logging.debug('Setting up BIOS programmer for board: %s', _board)
         if _board in self._valid_boards:
-            _bios_prog = FlashromProgrammer(servo)
+            _bios_prog = self._get_flashrom_programmer(servo)
         else:
             logging.warning('No BIOS programmer found for board: %s', _board)
 
@@ -365,6 +368,36 @@
         self._ec_programmer.program()
 
 
+class ProgrammerV2RwOnly(ProgrammerV2):
+    """Main programmer class which provides programmer for only updating the RW
+    portion of BIOS with servo V2.
+
+    It does nothing on EC, as EC software sync on the next boot will
+    automatically overwrite the EC RW portion, using the EC RW image inside
+    the BIOS RW image.
+
+    """
+
+    def _get_flashrom_programmer(self, servo):
+        """Gets a proper flashrom programmer.
+
+        @param servo: A servo object.
+
+        @return A programmer for flashrom.
+        """
+        return FlashromProgrammer(servo, keep_ro=True)
+
+
+    def program_ec(self, image):
+        """Programs the DUT with provide ec image.
+
+        @param image: (required) location of ec image file.
+
+        """
+        # Do nothing. EC software sync will update the EC RW.
+        pass
+
+
 class ProgrammerV3(object):
     """Main programmer class which provides programmer for BIOS and EC with
     servo V3.
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index e3a0acd..4f10fe1 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -697,6 +697,7 @@
         servo_version = self.get_servo_version()
         if servo_version.startswith('servo_v2'):
             self._programmer = firmware_programmer.ProgrammerV2(self)
+            self._programmer_rw = firmware_programmer.ProgrammerV2RwOnly(self)
         elif servo_version.startswith('servo_v3'):
             self._programmer = firmware_programmer.ProgrammerV3(self)
             self._programmer_rw = firmware_programmer.ProgrammerV3RwOnly(self)