[util / sw] Flash template updates

- All the size parameters are now exposed through flash_ctrl.hjson
- Convert flash_ctrl to take those values instead of defining them
- This allows size_reduce to only change the hjson and nothing else

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_check.py b/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_check.py
index 14df7af..2baf97f 100755
--- a/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_check.py
+++ b/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_check.py
@@ -27,9 +27,9 @@
 def main():
 
     # Check for the following regular expressions in the following source files.
-    files = ["top_pkg.sv", "tl_main_pkg.sv"]
+    files = ["flash_ctrl_reg_pkg.sv", "tl_main_pkg.sv"]
     match = [
-        r"localparam\s+int\s+FLASH_PAGES_PER_BANK\s*=\s*32;",
+        r"parameter\s+int\s+RegPagesPerBank\s*=\s*32;",
         r"localparam\s+logic\s*\[\s*31\s*:\s*0\s*\]\s+ADDR_MASK_EFLASH\s*=\s*32'h\s*0000ffff;"
     ]
 
diff --git a/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_reduce.py b/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_reduce.py
index 42f1be1..c10be40 100755
--- a/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_reduce.py
+++ b/hw/top_earlgrey/util/opentitan_earlgrey_flash_size_reduce.py
@@ -9,6 +9,7 @@
 interface of the flash controller and is thus more or less transparent to software.
 """
 
+import hjson
 import logging as log
 import subprocess
 import sys
@@ -18,51 +19,46 @@
 # Display INFO log messages and up.
 log.basicConfig(level=log.INFO, format="%(levelname)s: %(message)s")
 
+hdr = '''// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+// ------------------- W A R N I N G: A U T O - G E N E R A T E D   C O D E !! -------------------//
+'''
+
+orighdr = hdr + '''
+// This file has been automatically created from top_earlgrey.hjson.
+// This is a reformatted copy of top_earlgrey.hjson
+'''
+
+genhdr = hdr + '''
+// This file has been automatically modified to reduce the size of the flash.
+// To see what has been changed, please compare to top_earlgrey.original.hjson.
+'''
 
 def main():
 
     # Get path to top-level directory
     top_path = os.path.normpath(os.path.join(os.path.dirname(__file__), "../../.."))
+    top_hjson = top_path + "/hw/top_earlgrey/data/top_earlgrey.hjson"
 
-    # Change the following expressions in the following source files.
-    files = [
-        top_path + "/sw/device/lib/flash_ctrl.h",
-        top_path + "/hw/top_earlgrey/rtl/top_pkg.sv",
-        top_path + "/hw/top_earlgrey/data/top_earlgrey.hjson"
-    ]
-    match = [
-        r"(#define\s+FLASH_PAGES_PER_BANK\s+)\d+(\s*)",
-        r"(localparam\s+int\s+FLASH_PAGES_PER_BANK\s*=\s*)\d+(\s*;)",
-        r"({\s*name:\s*\"eflash\"," +
-        r"\s*clock_srcs:\s*{clk_i:\s*\"main\"}," +
-        r"\s*clock_group:\s*\"infra\"," +
-        r"\s*reset_connections:\s*{rst_ni:\s*\"lc\"}," +
-        r"\s*type:\s*\"eflash\"," +
-        r"\s*base_addr:\s*\"0x\w+\"," +
-        r"\s*swaccess:\s*\"ro\"," +
-        r"\s*size:\s*\"0x)\w+"
-    ]
-    replace = [
-        r"\g<1>32\g<2>",  # Change FLASH_PAGES_PER_BANK to 32
-        r"\g<1>32\g<2>",  # Change FLASH_PAGES_PER_BANK to 32
-        r"\g<1>10000"     # Change size to 0x10000
-    ]
+    # Modify hjson to change flash size
+    with open(top_hjson, "r") as hjson_file:
+        cfg = hjson.load(hjson_file,
+                         use_decimal=True)
 
-    # Change source files
-    for idx in range(len(files)):
-        with open(files[idx], 'r+') as file:
-            text = file.read()
-            text, num = re.subn(match[idx], replace[idx], text)
-            if num == 0:
-                print("ERROR: Cannot find regular expression " + match[idx] +
-                      " in " + files[idx] + ". "
-                      "Aborting")
-                sys.exit(1)
-            else:
-                print("Modifying " + files[idx])
-                file.seek(0)
-                file.write(text)
-                file.truncate()
+    # write out original version reformatted
+    with open(top_path + "/hw/top_earlgrey/data/top_earlgrey.original.hjson", "w") as hjson_file:
+         hjson_file.write(orighdr + hjson.dumps(cfg, hjson_file))
+
+    # update value
+    log.info("Updating flash pages_per_bank to 32")
+    for mem in cfg["memory"]:
+        if mem['type'] == 'eflash':
+            mem['pages_per_bank'] = 32
+
+    # write back updated hjson
+    with open(top_hjson, "w") as hjson_file:
+        hjson_file.write(genhdr + hjson.dumps(cfg, hjson_file))
 
     # Regenerate auto-generated files
     print("Regenerating all auto-generated files...")
diff --git a/meson.build b/meson.build
index 66f37b3..f9ac075 100644
--- a/meson.build
+++ b/meson.build
@@ -164,7 +164,7 @@
 # TODO: Considering moving these into hw/ip directories.
 hw_ip_aes_reg_h = gen_hw_hdr.process('hw/ip/aes/data/aes.hjson')
 hw_ip_alert_handler_reg_h = gen_hw_hdr.process('hw/ip/alert_handler/data/alert_handler.hjson')
-hw_ip_flash_ctrl_reg_h = gen_hw_hdr.process('hw/ip/flash_ctrl/data/flash_ctrl.hjson')
+hw_ip_flash_ctrl_reg_h = gen_hw_hdr.process('hw/top_earlgrey/ip/flash_ctrl/data/autogen/flash_ctrl.hjson')
 hw_ip_gpio_reg_h = gen_hw_hdr.process('hw/ip/gpio/data/gpio.hjson')
 hw_ip_hmac_reg_h = gen_hw_hdr.process('hw/ip/hmac/data/hmac.hjson')
 hw_ip_i2c_reg_h = gen_hw_hdr.process('hw/ip/i2c/data/i2c.hjson')
diff --git a/sw/device/lib/flash_ctrl.c b/sw/device/lib/flash_ctrl.c
index cbe623b..e892804 100644
--- a/sw/device/lib/flash_ctrl.c
+++ b/sw/device/lib/flash_ctrl.c
@@ -3,7 +3,6 @@
 // SPDX-License-Identifier: Apache-2.0
 #include "sw/device/lib/flash_ctrl.h"
 
-
 #include "flash_ctrl_regs.h"  // Generated.
 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
 
@@ -52,7 +51,7 @@
   uint32_t *p = (uint32_t *)FLASH_MEM_BASE_ADDR;
   // TODO: Update range to cover entire flash. Limited now to one bank while
   // we debu initialization.
-  for (; p < (uint32_t *)(FLASH_MEM_BASE_ADDR + FLASH_BANK_SZ);) {
+  for (; p < (uint32_t *)(FLASH_MEM_BASE_ADDR + flash_get_bank_size());) {
     mask &= *p++;
     mask &= *p++;
     mask &= *p++;
@@ -74,7 +73,7 @@
   // TODO: Add timeout conditions and add error codes.
   REG32(FLASH_CTRL0_BASE_ADDR + FLASH_CTRL_ADDR_REG_OFFSET) =
       (idx == FLASH_BANK_0) ? FLASH_MEM_BASE_ADDR
-                            : (FLASH_MEM_BASE_ADDR + FLASH_BANK_SZ);
+                            : (FLASH_MEM_BASE_ADDR + flash_get_bank_size());
   REG32(FLASH_CTRL0_BASE_ADDR + FLASH_CTRL_CONTROL_REG_OFFSET) =
       (FLASH_ERASE << FLASH_CTRL_CONTROL_OP_OFFSET |
        FLASH_BANK_ERASE << FLASH_CTRL_CONTROL_ERASE_SEL |
@@ -179,7 +178,7 @@
             << FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_SCRAMBLE_EN_0 |
         0x1 << FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_EN_0;
 
-    bank_sel = region_cfg->base / FLASH_PAGES_PER_BANK;
+    bank_sel = region_cfg->base / flash_get_pages_per_bank();
     if (bank_sel == FLASH_BANK_0) {
       REG32(FLASH_CTRL0_BASE_ADDR +
             FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_REG_OFFSET +
@@ -192,6 +191,18 @@
   }
 }
 
+uint32_t flash_get_banks() { return FLASH_CTRL_PARAM_REGNUMBANKS; }
+
+uint32_t flash_get_pages_per_bank() { return FLASH_CTRL_PARAM_REGPAGESPERBANK; }
+
+uint32_t flash_get_words_per_page() { return FLASH_CTRL_PARAM_WORDSPERPAGE; }
+
+uint32_t flash_get_bank_size() { return FLASH_CTRL_PARAM_BYTESPERBANK; }
+
+uint32_t flash_get_page_size() { return FLASH_CTRL_PARAM_BYTESPERPAGE; }
+
+uint32_t flash_get_word_size() { return FLASH_CTRL_PARAM_BYTESPERWORD; }
+
 void flash_write_scratch_reg(uint32_t value) {
   REG32(FLASH_CTRL0_BASE_ADDR + FLASH_CTRL_SCRATCH_REG_OFFSET) = value;
 }
diff --git a/sw/device/lib/flash_ctrl.h b/sw/device/lib/flash_ctrl.h
index ff5d5cf..eab6bd1 100644
--- a/sw/device/lib/flash_ctrl.h
+++ b/sw/device/lib/flash_ctrl.h
@@ -10,11 +10,6 @@
 
 // Flash memory base defines, _SZ are presented in bytes
 #define FLASH_MEM_BASE_ADDR 0x20000000
-#define FLASH_WORDS_PER_PAGE 128
-#define FLASH_WORD_SZ 8
-#define FLASH_PAGE_SZ (FLASH_WORDS_PER_PAGE * FLASH_WORD_SZ)
-#define FLASH_PAGES_PER_BANK 256
-#define FLASH_BANK_SZ (FLASH_PAGES_PER_BANK * FLASH_PAGE_SZ)
 
 /**
  * Flash bank IDs
@@ -117,6 +112,24 @@
  */
 void flash_cfg_region(const mp_region_t *region_cfg);
 
+/** Get number of flash banks */
+uint32_t flash_get_banks();
+
+/** Get number of pages per bank */
+uint32_t flash_get_pages_per_bank();
+
+/** Get number of words per page */
+uint32_t flash_get_words_per_page();
+
+/** Get size of each bank in bytes */
+uint32_t flash_get_bank_size();
+
+/** Get size of each page in bytes */
+uint32_t flash_get_page_size();
+
+/** Get size of each flash word in bytes */
+uint32_t flash_get_word_size();
+
 /** Write value to flash scratch register */
 void flash_write_scratch_reg(uint32_t value);
 
diff --git a/sw/device/tests/flash_ctrl_test.c b/sw/device/tests/flash_ctrl_test.c
index d8f2285..b4089d9 100644
--- a/sw/device/tests/flash_ctrl_test.c
+++ b/sw/device/tests/flash_ctrl_test.c
@@ -23,6 +23,12 @@
 #define CHECK_EQZ(x) CHECK((x) == 0)
 #define CHECK_NEZ(x) CHECK((x) != 0)
 
+#define FLASH_WORDS_PER_PAGE flash_get_words_per_page()
+#define FLASH_WORD_SZ flash_get_word_size()
+#define FLASH_PAGE_SZ flash_get_page_size()
+#define FLASH_PAGES_PER_BANK flash_get_pages_per_bank()
+#define FLASH_BANK_SZ flash_get_bank_size()
+
 /*
  * Basic test of page erase / program / read functions
  * Tests pages from both the data and info partitions