Support configurable RISC-V chip extension (#773)

* Support configurable RISC-V chip extension

Added the FREERTOS_RISCV_EXTENSION option to allow the user
to select which chip extension they want included. Removed the
port for pulpino to instead use the new option.

* Add port GCC_RISC_V_GENERIC and IAR_RISC_V_GENERIC

* Add two rics-v generic ports to support FREERTOS_RISCV_EXTENSION
  config

---------

Co-authored-by: Joe Benczarski <jbenczarski@trijicon.com>
Co-authored-by: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com>
Co-authored-by: Ching-Hsin Lee <chinglee@amazon.com>
Co-authored-by: kar-rahul-aws <118818625+kar-rahul-aws@users.noreply.github.com>
Co-authored-by: Soren Ptak <ptaksoren@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 984e36e..d9ddb7e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,6 +106,7 @@
         " GCC_PPC440_XILINX                - Compiler: GCC           Target: Xilinx PPC440\n"
         " GCC_RISC_V                       - Compiler: GCC           Target: RISC-V\n"
         " GCC_RISC_V_PULPINO_VEGA_RV32M1RM - Compiler: GCC           Target: RISC-V Pulpino Vega RV32M1RM\n"
+        " GCC_RISC_V_GENERIC               - Compiler: GCC           Target: RISC-V with FREERTOS_RISCV_EXTENSION\n"
         " GCC_RL78                         - Compiler: GCC           Target: Renesas RL78\n"
         " GCC_RX100                        - Compiler: GCC           Target: Renesas RX100\n"
         " GCC_RX200                        - Compiler: GCC           Target: Renesas RX200\n"
@@ -156,6 +157,7 @@
         " IAR_MSP430                       - Compiler: IAR           Target: MSP430\n"
         " IAR_MSP430X                      - Compiler: IAR           Target: MSP430X\n"
         " IAR_RISC_V                       - Compiler: IAR           Target: RISC-V\n"
+        " IAR_RISC_V_GENERIC               - Compiler: IAR           Target: RISC-V with FREERTOS_RISCV_EXTENSION\n"
         " IAR_RL78                         - Compiler: IAR           Target: Renesas RL78\n"
         " IAR_RX100                        - Compiler: IAR           Target: Renesas RX100\n"
         " IAR_RX600                        - Compiler: IAR           Target: Renesas RX600\n"
diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt
index 327e923..4d81ef6 100644
--- a/portable/CMakeLists.txt
+++ b/portable/CMakeLists.txt
@@ -1,3 +1,11 @@
+if( FREERTOS_PORT STREQUAL "GCC_RISC_V_GENERIC" )
+    include( GCC/RISC-V/chip_extensions.cmake )
+endif()
+
+if( FREERTOS_PORT STREQUAL "IAR_RISC_V_GENERIC" )
+    include( IAR/RISC-V/chip_extensions.cmake )
+endif()
+
 # FreeRTOS internal cmake file. Do not use it in user top-level project
 
 if (FREERTOS_PORT STREQUAL "A_CUSTOM_PORT")
@@ -292,6 +300,10 @@
         GCC/RISC-V/port.c
         GCC/RISC-V/portASM.S>
 
+    $<$<STREQUAL:${FREERTOS_PORT},GCC_RISC_V_GENERIC>:
+        GCC/RISC-V/port.c
+        GCC/RISC-V/portASM.S>
+
     # Renesas RL78 port for GCC
     $<$<STREQUAL:${FREERTOS_PORT},GCC_RL78>:
         GCC/RL78/port.c
@@ -497,6 +509,10 @@
         IAR/RISC-V/port.c
         IAR/RISC-V/portASM.s>
 
+    $<$<STREQUAL:${FREERTOS_PORT},IAR_RISC_V_GENERIC>:
+        IAR/RISC-V/port.c
+        IAR/RISC-V/portASM.s>
+
     # Renesas RL78 port for IAR EWRL78
     $<$<STREQUAL:${FREERTOS_PORT},IAR_RL78>:
         IAR/RL78/port.c
@@ -845,6 +861,10 @@
         ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V
         ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM>
 
+    $<$<STREQUAL:${FREERTOS_PORT},GCC_RISC_V_GENERIC>:
+        ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V
+        ${CMAKE_CURRENT_LIST_DIR}/GCC/RISC-V/chip_specific_extensions/${FREERTOS_RISCV_EXTENSION}>
+
     # Renesas RL78 port for GCC
     $<$<STREQUAL:${FREERTOS_PORT},GCC_RL78>:${CMAKE_CURRENT_LIST_DIR}/GCC/RL78>
 
@@ -942,6 +962,10 @@
         ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V
         ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions>
 
+    $<$<STREQUAL:${FREERTOS_PORT},IAR_RISC_V_GENERIC>:
+        ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V
+        ${CMAKE_CURRENT_LIST_DIR}/IAR/RISC-V/chip_specific_extensions/${FREERTOS_RISCV_EXTENSION}>
+
     # Renesas RL78 port for IAR EWRL78
     $<$<STREQUAL:${FREERTOS_PORT},IAR_RL78>:${CMAKE_CURRENT_LIST_DIR}/IAR/RL78>
 
diff --git a/portable/GCC/RISC-V/chip_extensions.cmake b/portable/GCC/RISC-V/chip_extensions.cmake
new file mode 100644
index 0000000..c0d2c0d
--- /dev/null
+++ b/portable/GCC/RISC-V/chip_extensions.cmake
@@ -0,0 +1,19 @@
+if( FREERTOS_PORT STREQUAL "GCC_RISC_V_GENERIC" )
+    set( VALID_CHIP_EXTENSIONS
+            "Pulpino_Vega_RV32M1RM"
+            "RISCV_MTIME_CLINT_no_extensions"
+            "RISCV_no_extensions"
+            "RV32I_CLINT_no_extensions" )
+
+    if( ( NOT FREERTOS_RISCV_EXTENSION ) OR ( NOT ( ${FREERTOS_RISCV_EXTENSION} IN_LIST VALID_CHIP_EXTENSIONS ) ) )
+        message(FATAL_ERROR
+                "FREERTOS_RISCV_EXTENSION \"${FREERTOS_RISCV_EXTENSION}\" is not set or unsupported.\n"
+                "Please specify it from top-level CMake file (example):\n"
+                "   set(FREERTOS_RISCV_EXTENSION RISCV_MTIME_CLINT_no_extensions CACHE STRING \"\")\n"
+                " or from CMake command line option:\n"
+                "   -DFREERTOS_RISCV_EXTENSION=RISCV_MTIME_CLINT_no_extensions\n"
+                "\n"
+                " Available extension options:\n"
+                "   ${VALID_CHIP_EXTENSIONS} \n")
+    endif()
+endif()
diff --git a/portable/IAR/RISC-V/chip_extensions.cmake b/portable/IAR/RISC-V/chip_extensions.cmake
new file mode 100644
index 0000000..110ec4a
--- /dev/null
+++ b/portable/IAR/RISC-V/chip_extensions.cmake
@@ -0,0 +1,16 @@
+if( FREERTOS_PORT STREQUAL "IAR_RISC_V_GENERIC" )
+    set( VALID_CHIP_EXTENSIONS
+            "RV32I_CLINT_no_extensions" )
+
+    if( ( NOT FREERTOS_RISCV_EXTENSION ) OR ( NOT ( ${FREERTOS_RISCV_EXTENSION} IN_LIST VALID_CHIP_EXTENSIONS ) ) )
+        message(FATAL_ERROR
+                "FREERTOS_RISCV_EXTENSION \"${FREERTOS_RISCV_EXTENSION}\" is not set or unsupported.\n"
+                "Please specify it from top-level CMake file (example):\n"
+                "   set(FREERTOS_RISCV_EXTENSION RISCV_MTIME_CLINT_no_extensions CACHE STRING \"\")\n"
+                " or from CMake command line option:\n"
+                "   -DFREERTOS_RISCV_EXTENSION=RISCV_MTIME_CLINT_no_extensions\n"
+                "\n"
+                " Available extension options:\n"
+                "   ${VALID_CHIP_EXTENSIONS} \n")
+    endif()
+endif()