RSS: Improve DMA ICS

Allow references in commands to prevent mistakes due to manual
calculation. Add configurable base addresses and sizes. Zero DTCM
always. Add OTP program to load SAM. Remove second stage OTP loader.
Allocate space in OTP for integrity checker values and SAM config.
Create dedicated program for reset release and remove duplicate reset
release commands. Add documentation for combining ICSes.

Change-Id: Ib3516b1a468946ffba8f366614d050b58e5ce747
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/docs/platform/arm/rss/readme.rst b/docs/platform/arm/rss/readme.rst
index e50aeb6..65763da 100644
--- a/docs/platform/arm/rss/readme.rst
+++ b/docs/platform/arm/rss/readme.rst
@@ -77,9 +77,17 @@
 Running the code
 ----------------
 
-To run the built images, the flash image must be created by concatenating the
-images that are output from the build. To create the flash image, the following
-``fiptool`` command should be run. ``fiptool`` documentation can be found `here
+To run the built images, first the ROM image must be created from the bl1_1
+binary and the ROM DMA Initial Command Sequence (ICS).::
+
+    srec_cat \
+            bl1_1.bin -Binary     -offset 0x0 \
+            rom_dma_ics.bin -Binary -offset 0x1F000 \
+            -o rom.bin -Binary
+
+Then, the flash image must be created by concatenating the images that are
+output from the build. To create the flash image, the following ``fiptool``
+command should be run. ``fiptool`` documentation can be found `here
 <https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/tools-build.html?highlight=fiptool#building-and-using-the-fip-tool>`_.
 Note that an up-to-date fiptool that supports the RSS UUIDs must be used.::
 
@@ -159,7 +167,7 @@
             fip_gpt.bin -Binary -offset 0x0 \
             -o host_flash.bin -Binary
 
-The BL1_1 ROM binary should be placed in RSS ROM at ``0x11000000`` and the host
+The RSS ROM binary should be placed in RSS ROM at ``0x11000000`` and the host
 flash binary should be placed at the base of the host flash. For the TC
 platform, this is at ``0x80000000``.
 
diff --git a/platform/ext/target/arm/rss/common/CMakeLists.txt b/platform/ext/target/arm/rss/common/CMakeLists.txt
index f47dc75..e5ab539 100644
--- a/platform/ext/target/arm/rss/common/CMakeLists.txt
+++ b/platform/ext/target/arm/rss/common/CMakeLists.txt
@@ -599,16 +599,31 @@
 endif()
 
 ############################## BL1 DMA ###################################
-add_custom_target(bl1_1_dma_bin
+set(bin_dir ${CMAKE_BINARY_DIR}/bin)
+
+add_custom_target(dma_icses
     ALL
-    SOURCES bl1_1_dma.bin ${bin_dir}/bl1_1_dma.bin
+    SOURCES rom_dma_ics.bin ${bin_dir}/rom_dma_ics.bin
+            rom_dma_ics.hex ${bin_dir}/rom_dma_ics.hex
+            otp_dma_ics.bin ${bin_dir}/otp_dma_ics.bin
+            otp_dma_ics.hex ${bin_dir}/otp_dma_ics.hex
 )
 
-add_custom_command(OUTPUT bl1_1_dma.bin
-    OUTPUT ${bin_dir}/bl1_1_dma.bin
+add_custom_command(
+    OUTPUT rom_dma_ics.bin
+    OUTPUT otp_dma_ics.bin
+    OUTPUT rom_dma_ics.hex
+    OUTPUT otp_dma_ics.hex
+    OUTPUT ${bin_dir}/rom_dma_ics.bin
+    OUTPUT ${bin_dir}/otp_dma_ics.bin
+    OUTPUT ${bin_dir}/rom_dma_ics.hex
+    OUTPUT ${bin_dir}/otp_dma_ics.hex
     DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bl1/scripts/create_bl1_1_dma_bin.py
     COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/bl1/scripts/create_bl1_1_dma_bin.py
                     --input_file ${CMAKE_CURRENT_SOURCE_DIR}/bl1/scripts/dma_config.yaml
-                    --output_file bl1_1_dma.bin
-    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bl1_1_dma.bin $<TARGET_FILE_DIR:bl1_1>
+                    --output_dir ${CMAKE_CURRENT_BINARY_DIR}
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/rom_dma_ics.bin $<TARGET_FILE_DIR:bl1_1>
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/otp_dma_ics.bin $<TARGET_FILE_DIR:bl1_1>
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/rom_dma_ics.hex $<TARGET_FILE_DIR:bl1_1>
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/otp_dma_ics.hex $<TARGET_FILE_DIR:bl1_1>
 )
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/create_bl1_1_dma_bin.py b/platform/ext/target/arm/rss/common/bl1/scripts/create_bl1_1_dma_bin.py
index cc8d581..c9a2747 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/create_bl1_1_dma_bin.py
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/create_bl1_1_dma_bin.py
@@ -12,11 +12,11 @@
 from yaml.loader import SafeLoader
 
 # logging setup
-logging.basicConfig(level=logging.ERROR, format='%(name)s - %(levelname)s - %(message)s')
+logging.basicConfig(level=logging.WARNING, format='%(name)s - %(levelname)s - %(message)s')
 
 parser = argparse.ArgumentParser()
 parser.add_argument("--input_file", help="DMA programs high level yaml file", required=True)
-parser.add_argument("--output_file", help="Output bin file", required=True)
+parser.add_argument("--output_dir", help="Output directory", required=True)
 args = parser.parse_args()
 
 class Loader(yaml.SafeLoader):
@@ -26,9 +26,13 @@
 
     # load nested yaml files (if any)
     def include(self, node):
-        filename = os.path.join(self._root, self.construct_scalar(node))
-        with open(filename, 'r') as f:
-            return yaml.load(f, Loader)
+        filepath = os.path.join(self._root, self.construct_scalar(node))
+        command_name = os.path.basename(self.construct_scalar(node)).replace('.yaml', '')
+
+        with open(filepath, 'r') as f:
+            child_node = yaml.load(f, Loader)
+            child_node['command_name'] = command_name
+            return child_node
 
 Loader.add_constructor('!include', Loader.include)
 
@@ -41,39 +45,151 @@
             final_val = final_val + (val << i)
     return final_val
 
-def pad_hex(s):
-    return '0x' + s[2:].zfill(8)
+
+def resolve_store_reference(command, key, reference_string):
+    return command_storage_locations[reference_string]
+
+def resolve_exec_reference(command, key, reference_string):
+    command_location = command_execution_locations[reference_string]
+    # Need to set bit 0 if the link should be executed
+    if key != 'SRCADDR' and key != 'DESADDR':
+        try:
+            if command['execute_link']:
+                command_location += 1
+        except KeyError:
+            # Default to performing the link
+            command_location += 1
+    return command_location
+
+def resolve_size_reference(command, key, reference_string):
+    # Convert size to words
+    size = sizes[reference_string] // 4
+    if key == 'XSIZE':
+        size &= 0xFFFF
+        size |= size << 16
+    return size
+
+def resolve_base_address_reference(command, key, reference_string):
+    return location_base_addresses[reference_string]
+
+def resolve_program_reference(command, key, reference_string):
+    if "+" in reference_string:
+        split = reference_string.split(" + ")
+        reference_string = split[0].lstrip()
+        add_value = int(split[1], 0)
+    else:
+        add_value = 0
+
+    if "-" in reference_string:
+        split = reference_string.split(" - ")
+        reference_string = split[0].lstrip()
+        sub_value = int(split[1], 0)
+    else:
+        sub_value = 0
+
+    if "_store_addr" in reference_string:
+        value = resolve_store_reference(command, key, reference_string.replace("_store_addr", ""))
+    elif "_exec_addr" in reference_string:
+        value = resolve_exec_reference(command, key, reference_string.replace("_exec_addr", ""))
+    elif "_size" in reference_string:
+        value = resolve_size_reference(command, key, reference_string.replace("_size", ""))
+    elif "_base_address" in reference_string:
+        value = resolve_base_address_reference(command, key, reference_string.replace("_base_address", ""))
+    else:
+        raise ValueError("Invalid program reference {}".format(reference_string))
+    value = value + add_value - sub_value
+    logging.debug('resolving reference {} as {}'.format(reference_string, hex(value)))
+    return value
 
 # load top level input config file
 with open(args.input_file, 'r') as f:
    data = yaml.load(f, Loader)
 
 program_count = len(data["program"])
-logging.info('Number of DMA programs : %d ', program_count)
-hex_codes=[]
 
-for prog_idx in range(program_count):
-    command_count = len(data["program"][prog_idx]["commands"])
-    logging.info("Program " +str(prog_idx) + " has " +str(command_count) + " comamnds")
-    for cmd_idx in range(command_count):
-        command = data["program"][prog_idx]["commands"][cmd_idx]
+location_base_addresses={}
+location_next_addresses={}
+location_word_arrays={}
+output_locations={}
+
+command_storage_locations = {}
+command_execution_locations = {}
+sizes = {}
+
+reserved_keys=['command_name', 'execute_link']
+
+# Setup locations
+for location in data['locations']:
+    location_word_arrays[location] = []
+    location_base_addresses[location] = data['locations'][location]['base_address']
+    try:
+        reserved_size = data['locations'][location]['reserved']
+    except KeyError:
+        reserved_size = 0
+    location_next_addresses[location] = data['locations'][location]['base_address'] + reserved_size
+    try:
+        sizes[location] = data['locations'][location]['size']
+        size = sizes[location]
+    except KeyError:
+        size = 'unknown'
+        pass
+    logging.info('Location {} at {}, size {}, first usable address {}'.format(
+        location,
+        hex(location_base_addresses[location]),
+        size,
+        hex(location_next_addresses[location])))
+
+for program in data['program']:
+    commands = program['commands']
+    sizes[program['name']] = 0
+    for command in commands:
+        command_size = sum([1 for key in command if key not in reserved_keys]) * 4
+        sizes[command['command_name']] = command_size
+        sizes[program['name']] += command_size
+        command_storage_locations[command['command_name']] = location_next_addresses[program['storage_location']]
+        command_execution_locations[command['command_name']] = location_next_addresses[program['execution_location']]
+        location_next_addresses[program['storage_location']] += command_size
+        # don't increment twice if the storage location is the same as the
+        # execution location
+        if location_next_addresses[program['storage_location']] != location_next_addresses[program['execution_location']]:
+            location_next_addresses[program['execution_location']] += command_size
+        output_locations[program['storage_location']] = True
+    logging.info('Program {} stored at {}, executed from {}, size {}'.format(
+        program['name'],
+        hex(location_next_addresses[program['storage_location']] - sizes[program['name']]),
+        hex(location_next_addresses[program['execution_location']] - sizes[program['name']]),
+        sizes[program['name']],
+        ))
+
+for program in data['program']:
+    commands = program['commands']
+    for command in commands:
+        command["Header"] = calculate_header_word(command["Header"])
+        command_array = []
         for key in command:
-            if key == "Header":
-                header = data["program"][prog_idx]["commands"][cmd_idx]["Header"]
-                header_word = calculate_header_word(header)
-                hex_codes.append(str(hex(header_word)))
-                logging.debug("Calculated header word is %s",str(hex(header_word)))
-            else:
-                hex_codes.append(str(pad_hex(hex(command[key]))))
-                logging.debug(str(key) +': '+ str(pad_hex(hex(command[key]))))
+            if key in reserved_keys:
+                continue
+            try:
+                command_array.append(int(command[key]))
+            except ValueError:
+                command_array.append(int(resolve_program_reference(command, key, command[key])))
+        location_word_arrays[program['storage_location']] += command_array
 
-out_file = open(args.output_file, mode="wb")
-
-for item in hex_codes:
-    data = bytes.fromhex(item.replace('0x','').rstrip())
-    # by default; binary file is little in big endian format; update to little endian for arm */
-    swap_data = bytearray(data)
-    swap_data.reverse()
-    out_file.write(swap_data)
-
-out_file.close()
\ No newline at end of file
+for location in output_locations:
+    try:
+        reserved_size = data['locations'][location]['reserved']
+    except KeyError:
+        reserved_size = 0
+    if len(location_word_arrays[location]) * 4 + reserved_size > sizes[location]:
+        raise Exception
+    with open(os.path.join(args.output_dir, location + "_dma_ics.bin"), mode="wb") as bin_file:
+        with open(os.path.join(args.output_dir, location + "_dma_ics.hex"), mode="wt") as hex_file:
+            logging.info('Writing output binary for location {} to file {} of size {}'.format(
+                location, os.path.join(args.output_dir, location + "_dma_ics.bin"),
+                len(location_word_arrays[location]) * 4))
+            logging.info('Writing output hex for location {} to file {} of size {}'.format(
+                location, os.path.join(args.output_dir, location + "_dma_ics.hex"),
+                len(location_word_arrays[location]) * 4))
+            for word in location_word_arrays[location]:
+                bin_file.write(word.to_bytes(4, byteorder='little'))
+                hex_file.write(word.to_bytes(4, byteorder='big').hex() + '\n')
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/dma_config.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/dma_config.yaml
index 82cef96..30142bb 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/dma_config.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/dma_config.yaml
@@ -4,45 +4,99 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+locations:
+    rom:
+        base_address: 0x1101F000
+        size: 0x1000
+    vm0:
+        base_address: 0x31000000
+        size: 0x10000
+        reserved: 0x4
+    otp:
+        # This has to be manually calculated, and must be updated if the OTP
+        # layout changes
+        base_address: 0x500A4C00
+        size: 0x400
+        reserved: 0x4
+    integrity_checker:
+        base_address: 0x5015C000
+    otp_sam_config:
+        # This has to be manually calculated, and must be updated if the OTP
+        # layout changes
+        base_address: 0x500A1114
+    sam:
+        base_address: 0x5009F000
+    dma350:
+        base_address: 0x50002000
+    dtcm:
+        base_address: 0x34000000
+    lcm:
+        base_address: 0x500A0000
+    rss_system_control_registers:
+        base_address: 0x58021000
+
 program:
-  - location: "rom"                                 # Program 0
+  - storage_location: "rom"
+    execution_location: "rom"
     channel: 0
-    description: "Init flow - Setup DMA Channel 1"
+    name: "program0"
+    description: "Set up DMA Channel 1"
     commands:
       - !include include/program0_cmd0.yaml         # Program 0 - Command 0
       - !include include/program0_cmd1.yaml         # Program 0 - Command 1
+      - !include include/program0_cmd2.yaml         # Program 0 - Command 2
 
-  - location: "rom"                                 # Program 1
+  - storage_location: "rom"
+    execution_location: "rom"
     channel: 1
-    description: "Test Mode"
+    name: "program1"
+    description: "Run only in Virgin TCI mode"
     commands:
       - !include include/program1_cmd0.yaml         # Program 1 - Command 0
-      - !include include/program1_cmd1.yaml         # Program 1 - Command 1
-      - !include include/program1_cmd2.yaml         # Program 1 - Command 2
 
-  - location: "rom"                                 # Program 2
+  - storage_location: "rom"
+    execution_location: "rom"
     channel: 0
+    name: "program2"
     description: "P3 P4 Init"
     commands:
       - !include include/program2_cmd0.yaml         # Program 2 - Command 0
       - !include include/program2_cmd1.yaml         # Program 2 - Command 1
       - !include include/program2_cmd2.yaml         # Program 2 - Command 2
 
-  - location: "rom"                                 # Program 3
+  - storage_location: "rom"
+    execution_location: "rom"
     channel: 1
-    description: "Mission-Provisioning Mode"
+    name: "program3"
+    description: "Run only in CM and DM modes"
     commands:
       - !include include/program3_cmd0.yaml         # Program 3 - Command 0
-      - !include include/program3_cmd1.yaml         # Program 3 - Command 1
-      - !include include/program3_cmd2.yaml         # Program 3 - Command 2
-      - !include include/program3_cmd3.yaml         # Program 3 - Command 3
 
-  - location: "rom"                                 # Program 4
+  - storage_location: "rom"
+    execution_location: "rom"
     channel: 0
-    description: "1st stage OTP loader"
+    name: "program4"
+    description: "OTP ICS loader"
     commands:
       - !include include/program4_cmd0.yaml         # Program 4 - Command 0
       - !include include/program4_cmd1.yaml         # Program 4 - Command 1
       - !include include/program4_cmd2.yaml         # Program 4 - Command 2
       - !include include/program4_cmd3.yaml         # Program 4 - Command 3
       - !include include/program4_cmd4.yaml         # Program 4 - Command 4
+
+  - storage_location: "otp"
+    execution_location: "vm0"
+    channel: 0
+    name: "program5"
+    description: "Copy SAM configuration"
+    commands:
+      - !include include/program5_cmd0.yaml         # Program 5 - Command 0
+      - !include include/program5_cmd1.yaml         # Program 5 - Command 1
+
+  - storage_location: "rom"
+    execution_location: "rom"
+    name: "program6"
+    description: "Release DCU lock and CPUWAIT"
+    commands:
+      - !include include/program6_cmd0.yaml         # Program 6 - Command 0
+      - !include include/program6_cmd1.yaml         # Program 6 - Command 1
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd0.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd0.yaml
index 0bac824..727e48c 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd0.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd0.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command sets the address of program1_cmd0 into the DMA350 Channel1
+# LINKADDR register.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,10 +42,10 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000602
-DESADDR: 0x50003178
+DESADDR: 'dma350_base_address + 0x1178'
 XSIZE: 0x00010000
 DESTRANSCFG: 0x00000000
-FILLVAL: 0x11007041
+FILLVAL: "program1_cmd0_exec_addr"
 GPOEN0: 0x0000001F
 GPOVAL0: 0x00000000
-LINKADDR: 0x11007025
\ No newline at end of file
+LINKADDR: "program0_cmd1_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd1.yaml
index 2b6c6cc..a7bd8fa 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd1.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command writes 0x1 into the DMA350 Channel1 CH_CMD register, this causes
+# it to start running.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,8 +42,8 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000602
-DESADDR: 0x50003100
+DESADDR: 'dma350_base_address + 0x1100'
 XSIZE: 0x00010000
 FILLVAL: 0x00000001
 GPOVAL0: 0x00000001
-LINKADDR: 0x110070C1
\ No newline at end of file
+LINKADDR: "program2_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd2.yaml
similarity index 87%
rename from platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml
rename to platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd2.yaml
index 8344b79..dfecfe2 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program0_cmd2.yaml
@@ -4,6 +4,9 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command zeroes the entire DTCM by writing doublewords.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,9 +41,9 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000603
-DESADDR: 0x34000000
+DESADDR: 'dtcm_base_address'
 XSIZE: 0x10000000
 DESTRANSCFG: 0x000F0044
 FILLVAL: 0x00000000
 GPOVAL0: 0x00000004
-LINKADDR: 0x1100713D
\ No newline at end of file
+LINKADDR: "program2_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd0.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd0.yaml
index ad01f28..84a374d 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd0.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd0.yaml
@@ -4,6 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command in run after trigger 0 is fired. This command stops channel 0
+# from executing by writing Channel0 CH_CMD register. Trigger 0 is fired if the
+# Lifecycle is CM Virgin or RMA
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,11 +43,11 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x12000602
-DESADDR: 0x50003000
+DESADDR: 'dma350_base_address + 0x1000'
 XSIZE: 0x00010000
 DESTRANSCFG: 0x00000000
 FILLVAL: 0x00000008
 SRCTRIGINCFG: 0x00000200
 GPOEN0: 0x0000001F
 GPOVAL0: 0x00000000
-LINKADDR: 0x11007069
\ No newline at end of file
+LINKADDR: "program6_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd0.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd0.yaml
index 62ca3ef..469b0c8 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd0.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd0.yaml
@@ -4,6 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command in run after trigger 1 is fired. This command stops channel 1
+# from executing by writing Channel1 CH_CMD register. Trigger 1 is fired if the
+# Lifecycle is SE, CM PCI/TCI or DM
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,9 +43,9 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x12000602
-DESADDR: 0x50003100
+DESADDR: 'dma350_base_address + 0x1100'
 XSIZE: 0x00010000
 FILLVAL: 0x00000008
 SRCTRIGINCFG: 0x00000201
 GPOVAL0: 0x00000002
-LINKADDR: 0x110070C1
\ No newline at end of file
+LINKADDR: "program2_cmd1_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd1.yaml
index d9cb298..3d0ca9d 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd1.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command sets the address of program3_cmd0 into the DMA350 Channel1
+# LINKADDR register.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,8 +42,8 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000602
-DESADDR: 0x50003178
+DESADDR: 'dma350_base_address + 0x1178'
 XSIZE: 0x00010000
-FILLVAL: 0x110070F9
+FILLVAL: "program3_cmd0_exec_addr"
 GPOVAL0: 0x00000003
-LINKADDR: 0x110070DD
\ No newline at end of file
+LINKADDR: "program2_cmd2_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd2.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd2.yaml
index 7afbdbb..b2ed688 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd2.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program2_cmd2.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command writes 0x1 into the DMA350 Channel1 CH_CMD register, this causes
+# it to start running.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -42,4 +46,4 @@
 XSIZE: 0x00010000
 FILLVAL: 0x00000001
 GPOVAL0: 0x00000003
-LINKADDR: 0x11007179
\ No newline at end of file
+LINKADDR: "program4_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd0.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd0.yaml
index b93501c..068054d 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd0.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd0.yaml
@@ -4,6 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command in run after trigger 2 is fired. This command stops channel 0
+# from executing by writing Channel0 CH_CMD register. Trigger 2 is fired if the
+# Lifecycle is CM TCI/PCI or DM
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,10 +43,10 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x12000602
-DESADDR: 0x50003000
+DESADDR: 'dma350_base_address + 0x1000'
 XSIZE: 0x00010000
 DESTRANSCFG: 0x00000000
 FILLVAL: 0x00000008
 SRCTRIGINCFG: 0x00000202
 GPOVAL0: 0x00000003
-LINKADDR: 0x1100711D
\ No newline at end of file
+LINKADDR: "program6_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd3.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd3.yaml
deleted file mode 100644
index 6dd860b..0000000
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd3.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2023, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-Header:
-  - REGCLEAR: 0
-  - Reserved: 0
-  - INTREN: 0
-  - CTRL: 1
-  - SRCADDR: 0
-  - SRCADDRHI: 0
-  - DESADDR: 1
-  - DESADDRHI: 0
-  - XSIZE: 1
-  - XSIZEHI: 0
-  - SRCTRANSCFG: 0
-  - DESTRANSCFG: 0
-  - XADDRINC: 0
-  - YADDRSTRIDE: 0
-  - FILLVAL: 1
-  - YSIZE: 0
-  - TMPLTCFG: 0
-  - SRCTMPLT: 0
-  - DESTMPLT: 0
-  - SRCTRIGINCFG: 0
-  - DESTRIGINCFG: 0
-  - TRIGOUTCFG: 0
-  - GPOEN0: 0
-  - Reserved: 0
-  - GPOVAL0: 1
-  - Reserved: 0
-  - STREAMINTCFG: 0
-  - Reserved: 0
-  - LINKATTR: 0
-  - AUTOCFG: 0
-  - LINKADDR: 1
-  - LINKADDRHI: 0
-CTRL: 0x10000602
-DESADDR: 0x58021120
-XSIZE: 0x00010000
-FILLVAL: 0x0000000E
-GPOVAL0: 0x00000006
-LINKADDR: 0x00000000
\ No newline at end of file
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd0.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd0.yaml
index 164e237..1c36f37 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd0.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd0.yaml
@@ -4,6 +4,11 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command in run after trigger 1 is fired. This command stops channel 1
+# from executing by writing Channel1 CH_CMD register. Trigger 1 is fired if the
+# Lifecycle is SE, CM PCI/TCI or DM, but at this point we must be in SE.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,9 +43,9 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x12000602
-DESADDR: 0x50003100
+DESADDR: 'dma350_base_address + 0x1100'
 XSIZE: 0x00010000
 FILLVAL: 0x00000008
 SRCTRIGINCFG: 0x00000201
 GPOVAL0: 0x00000004
-LINKADDR: 0x11007199
\ No newline at end of file
+LINKADDR: "program4_cmd1_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd1.yaml
index 7f9eb36..202cff3 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd1.yaml
@@ -4,6 +4,9 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command copies the entire OTP DMA ICS section into VM0.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,10 +41,10 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000202
-SRCADDR: 0x500A4C00
-DESADDR: 0x31000000
-XSIZE: 0x005D005D
+SRCADDR: "otp_base_address"
+DESADDR: "vm0_base_address"
+XSIZE: "otp_size"
 SRCTRANSCFG: 0x00000000
 DESTRIGINCFG: 0x000F0044
 GPOVAL0: 0x00000005
-LINKADDR: 0x110071BD
+LINKADDR: "program4_cmd2_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd2.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd2.yaml
index ac0de72..358dbe1 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd2.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd2.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# Copy 3 words from the end of this command into the ICDA, ICDL, and ICEVA
+# registers of the integrity checker.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,14 +42,14 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000202
-SRCADDR: 0x110071E0
-DESADDR: 0x5015C018
+SRCADDR: 'program4_cmd2_store_addr + 0x28'
+DESADDR: 'integrity_checker_base_address + 0x18'
 XSIZE: 0x00030003
 SRCTRANSCFG: 0x000F0044
 DESTRIGINCFG: 0x00000000
 GPOVAL0: 0x00000006
-LINKADDR: 0x110071F0
-ICDA: 0x31000000
-ICDL: 0x0000005C
-ICEVA: 0x31000170
-ICC: 0x00000081
\ No newline at end of file
+LINKADDR: "program4_cmd3_exec_addr"
+execute_link: false
+ICDA: 'vm0_base_address + 0x4' # The first word in VM0 is the integrity value
+ICDL: 'otp_size - 0x1' # This is measured in words
+ICEVA: 'vm0_base_address'
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd3.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd3.yaml
index fe38664..9f8fd46 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd3.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd3.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# Copy 1 word from the end of this command into the ICC register of the
+# integrity checker. This triggers the checker.
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,10 +42,11 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000202
-SRCADDR: 0x110071EC
-DESADDR: 0x5015C004
+SRCADDR: 'otp_base_address + 0xc'
+DESADDR: 'integrity_checker_base_address + 0x4'
 XSIZE: 0x00010001
 SRCTRANSCFG: 0x000F0044
 DESTRIGINCFG: 0x00000000
 GPOVAL0: 0x00000006
-LINKADDR: 0x11007219
\ No newline at end of file
+LINKADDR: "program4_cmd4_exec_addr"
+ICC: 0x00000081
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd4.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd4.yaml
index 627d64c..56df7d2 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd4.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program4_cmd4.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# Wait for trigger 5 (the integrity checker success trigger) and if it succeeds,
+# then run the first command in the recently-loaded OTP ICS (program 5)
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -40,4 +44,4 @@
 CTRL: 0x12000000
 SRCTRIGINCFG: 0x00000205
 GPOVAL0: 0x00000007
-LINKADDR: 0x31000001
\ No newline at end of file
+LINKADDR: 'program5_cmd0_exec_addr'
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd0.yaml
similarity index 67%
copy from platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml
copy to platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd0.yaml
index 8344b79..eadfb92 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd0.yaml
@@ -4,22 +4,26 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command loads the SAM configuration from OTP into the SAM registers
+# (FIXME which ones?)
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
   - INTREN: 0
   - CTRL: 1
-  - SRCADDR: 0
+  - SRCADDR: 1
   - SRCADDRHI: 0
   - DESADDR: 1
   - DESADDRHI: 0
   - XSIZE: 1
   - XSIZEHI: 0
-  - SRCTRANSCFG: 0
+  - SRCTRANSCFG: 1
   - DESTRANSCFG: 1
   - XADDRINC: 0
   - YADDRSTRIDE: 0
-  - FILLVAL: 1
+  - FILLVAL: 0
   - YSIZE: 0
   - TMPLTCFG: 0
   - SRCTMPLT: 0
@@ -37,10 +41,11 @@
   - AUTOCFG: 0
   - LINKADDR: 1
   - LINKADDRHI: 0
-CTRL: 0x10000603
-DESADDR: 0x34000000
-XSIZE: 0x10000000
-DESTRANSCFG: 0x000F0044
-FILLVAL: 0x00000000
-GPOVAL0: 0x00000004
-LINKADDR: 0x1100713D
\ No newline at end of file
+CTRL: 0x10000202
+SRCADDR: "otp_sam_config_base_address"
+DESADDR: "sam_base_address + 0x14"
+XSIZE: 0x00180018
+SRCTRANSCFG: 0x00000000
+DSTTRANSCFG: 0x00000000
+GPOVAL0: 0x0000000B
+LINKADDR: "program5_cmd1_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd1.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd1.yaml
similarity index 71%
rename from platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd1.yaml
rename to platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd1.yaml
index 2e13af0..8bd400a 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd1.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program5_cmd1.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command waits for trigger 4, then disables the DCU force disable
+# overrides by writing 0x00AAAAAA to the LCM_DCU_FORCE_DISABLE_REGISTER
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -24,7 +28,7 @@
   - TMPLTCFG: 0
   - SRCTMPLT: 0
   - DESTMPLT: 0
-  - SRCTRIGINCFG: 0
+  - SRCTRIGINCFG: 1
   - DESTRIGINCFG: 0
   - TRIGOUTCFG: 0
   - GPOEN0: 0
@@ -37,9 +41,10 @@
   - AUTOCFG: 0
   - LINKADDR: 1
   - LINKADDRHI: 0
-CTRL: 0x10000602
-DESADDR: 0x5802125C
+CTRL: 0x12000602
+DESADDR: 'rss_system_control_registers_base_address + 0x25C'
 XSIZE: 0x00010000
 FILLVAL: 0x00AAAAAA
-GPOVAL0: 0x00000001
-LINKADDR: 0x11007085
\ No newline at end of file
+SRCTRIGINCFG: 0x00000204
+GPOVAL0: 0x0000000C
+LINKADDR: "program6_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd2.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd0.yaml
similarity index 80%
rename from platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd2.yaml
rename to platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd0.yaml
index 58b6162..5d63a0c 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program3_cmd2.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd0.yaml
@@ -4,6 +4,10 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
+
+# This command disables the DCU force disable overrides by writing 0x00AAAAAA to
+# the LCM_DCU_FORCE_DISABLE_REGISTER
+
 Header:
   - REGCLEAR: 0
   - Reserved: 0
@@ -38,9 +42,9 @@
   - LINKADDR: 1
   - LINKADDRHI: 0
 CTRL: 0x10000602
-DESADDR: 0x5802125C
+DESADDR: 'rss_system_control_registers_base_address + 0x25C'
 XSIZE: 0x00010000
 DESTRANSCFG: 0x00000000
 FILLVAL: 0x00AAAAAA
 GPOVAL0: 0x00000005
-LINKADDR: 0x1100715D
\ No newline at end of file
+LINKADDR: "program6_cmd0_exec_addr"
diff --git a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd2.yaml b/platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd1.yaml
similarity index 97%
rename from platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd2.yaml
rename to platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd1.yaml
index 2f41f9b..f985e84 100644
--- a/platform/ext/target/arm/rss/common/bl1/scripts/include/program1_cmd2.yaml
+++ b/platform/ext/target/arm/rss/common/bl1/scripts/include/program6_cmd1.yaml
@@ -42,4 +42,5 @@
 XSIZE: 0x00010000
 FILLVAL: 0x0000000E
 GPOVAL0: 0x00000002
-LINKADDR: 0x00000000
\ No newline at end of file
+LINKADDR: 0x00000000
+execute_link: false
diff --git a/platform/ext/target/arm/rss/common/otp_lcm.c b/platform/ext/target/arm/rss/common/otp_lcm.c
index 4ecd81b..0ea2ac9 100644
--- a/platform/ext/target/arm/rss/common/otp_lcm.c
+++ b/platform/ext/target/arm/rss/common/otp_lcm.c
@@ -41,6 +41,7 @@
             /* Things after this point are not touched by BL1_1, and hence are
              * modifiable by new provisioning code.
              */
+                uint32_t sam_configuration[OTP_SAM_CONFIGURATION_SIZE/ sizeof(uint32_t)];
                 uint32_t cca_system_properties;
                 uint32_t rss_id;
             } cm_locked;
@@ -77,8 +78,8 @@
                 uint32_t reprovisioning_bits;
             } unlocked_area;
         };
-        uint8_t _pad[OTP_TOTAL_SIZE - OTP_DMA_ICS_SIZE - BL1_2_CODE_SIZE -
-                     sizeof(struct lcm_otp_layout_t)];
+        uint8_t _pad0[OTP_TOTAL_SIZE - OTP_DMA_ICS_SIZE - BL1_2_CODE_SIZE -
+                      sizeof(struct lcm_otp_layout_t)];
     };
 
     /* These two are aligned to the end of the OTP. The size of the DMA ICS is
@@ -90,7 +91,13 @@
      * hash using the CC DMA.
      */
     uint32_t bl1_2_image[BL1_2_CODE_SIZE / sizeof(uint32_t)];
-    uint32_t dma_initial_command_sequence[OTP_DMA_ICS_SIZE / sizeof(uint32_t)];
+    __PACKED_UNION {
+        __PACKED_STRUCT {
+            uint32_t integrity_checker_values[4];
+            uint32_t dma_commands[];
+        } dma_initial_command_sequence;
+        uint8_t _pad1[OTP_DMA_ICS_SIZE];
+    };
 };
 
 static const uint16_t otp_offsets[PLAT_OTP_ID_MAX] = {
diff --git a/platform/ext/target/arm/rss/common/partition/region_defs.h b/platform/ext/target/arm/rss/common/partition/region_defs.h
index e4b6347..45c4503 100644
--- a/platform/ext/target/arm/rss/common/partition/region_defs.h
+++ b/platform/ext/target/arm/rss/common/partition/region_defs.h
@@ -193,7 +193,7 @@
 
 /* BL1_2 is in the ITCM */
 #define BL1_2_CODE_START  (ITCM_BASE_S)
-#define BL1_2_CODE_SIZE   (0x3000) /* 12 KiB */
+#define BL1_2_CODE_SIZE   (0x2000) /* 8 KiB */
 #define BL1_2_CODE_LIMIT  (BL1_2_CODE_START + BL1_2_CODE_SIZE - 1)
 
 /* BL2 is aligned to the start of the combined secure/non-secure data region */
diff --git a/platform/ext/target/arm/rss/kronos/rss_memory_sizes.h b/platform/ext/target/arm/rss/kronos/rss_memory_sizes.h
index 6ed4e3e..285f8df 100644
--- a/platform/ext/target/arm/rss/kronos/rss_memory_sizes.h
+++ b/platform/ext/target/arm/rss/kronos/rss_memory_sizes.h
@@ -35,4 +35,7 @@
 /* How much space in ROM is used for the DMA Initial Command Sequence */
 #define ROM_DMA_ICS_SIZE   (0x1000)
 
+/* How much space in OTP can be used for the SAM configuration */
+#define OTP_SAM_CONFIGURATION_SIZE 0x18
+
 #endif /* __RSS_MEMORY_SIZES_H__ */
diff --git a/platform/ext/target/arm/rss/tc/rss_memory_sizes.h b/platform/ext/target/arm/rss/tc/rss_memory_sizes.h
index 6ed4e3e..285f8df 100644
--- a/platform/ext/target/arm/rss/tc/rss_memory_sizes.h
+++ b/platform/ext/target/arm/rss/tc/rss_memory_sizes.h
@@ -35,4 +35,7 @@
 /* How much space in ROM is used for the DMA Initial Command Sequence */
 #define ROM_DMA_ICS_SIZE   (0x1000)
 
+/* How much space in OTP can be used for the SAM configuration */
+#define OTP_SAM_CONFIGURATION_SIZE 0x18
+
 #endif /* __RSS_MEMORY_SIZES_H__ */