diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject
index 648ec1c9f..baa18f1aa 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject
@@ -1,176 +1,93 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project
index f22f74077..f5bd48af5 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project
@@ -1,303 +1,303 @@
-
-
- RTOSDemo
-
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.genmakebuilder
- clean,full,incremental,
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
- full,incremental,
-
-
-
-
-
- org.eclipse.cdt.core.cnature
- org.eclipse.cdt.managedbuilder.core.managedBuildNature
- org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
-
-
-
- FreeRTOS_Source
- 2
- FREERTOS_ROOT/FreeRTOS/Source
-
-
- full_demo/Common_Demo_Tasks
- 2
- FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal
-
-
- full_demo/Common_Demo_Tasks/include
- 2
- FREERTOS_ROOT/FreeRTOS/Demo/Common/include
-
-
-
-
- 1570727806810
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-event_groups.c
-
-
-
- 1570727806825
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-list.c
-
-
-
- 1570727806841
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-queue.c
-
-
-
- 1570727806841
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-stream_buffer.c
-
-
-
- 1570727806841
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-timers.c
-
-
-
- 1570727806856
- FreeRTOS_Source
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-tasks.c
-
-
-
- 1570727892841
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-event_groups.h
-
-
-
- 1570727892856
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-FreeRTOS.h
-
-
-
- 1570727892856
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-message_buffer.h
-
-
-
- 1570727892856
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-queue.h
-
-
-
- 1570727892872
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-semphr.h
-
-
-
- 1570727892872
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-stream_buffer.h
-
-
-
- 1570727892888
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-task.h
-
-
-
- 1570727892888
- FreeRTOS_Source/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-timers.h
-
-
-
- 1570727962643
- FreeRTOS_Source/portable
- 9
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-MemMang
-
-
-
- 1570727962643
- FreeRTOS_Source/portable
- 9
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-GCC
-
-
-
- 1571005814144
- full_demo/Common_Demo_Tasks
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-TimerDemo.c
-
-
-
- 1571005814150
- full_demo/Common_Demo_Tasks
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-blocktim.c
-
-
-
- 1571005814159
- full_demo/Common_Demo_Tasks
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-dynamic.c
-
-
-
- 1571005814167
- full_demo/Common_Demo_Tasks
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-TaskNotify.c
-
-
-
- 1570727992991
- FreeRTOS_Source/portable/GCC
- 9
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-RISC-V
-
-
-
- 1570727979500
- FreeRTOS_Source/portable/MemMang
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-heap_4.c
-
-
-
- 1571005832815
- full_demo/Common_Demo_Tasks/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-TimerDemo.h
-
-
-
- 1571005832820
- full_demo/Common_Demo_Tasks/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-blocktim.h
-
-
-
- 1571005832824
- full_demo/Common_Demo_Tasks/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-dynamic.h
-
-
-
- 1571005832829
- full_demo/Common_Demo_Tasks/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-MessageBufferDemo.h
-
-
-
- 1571005832835
- full_demo/Common_Demo_Tasks/include
- 5
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-TaskNotify.h
-
-
-
- 1570728021983
- FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions
- 9
-
- org.eclipse.ui.ide.multiFilter
- 1.0-name-matches-false-false-RV32I_CLINT_no_extensions
-
-
-
-
-
- FREERTOS_ROOT
- $%7BPARENT-3-PROJECT_LOC%7D
-
-
-
+
+
+ RTOSDemo
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
+
+ FreeRTOS_Source
+ 2
+ FREERTOS_ROOT/FreeRTOS/Source
+
+
+ full_demo/Common_Demo_Tasks
+ 2
+ FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal
+
+
+ full_demo/Common_Demo_Tasks/include
+ 2
+ FREERTOS_ROOT/FreeRTOS/Demo/Common/include
+
+
+
+
+ 1570727806810
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-event_groups.c
+
+
+
+ 1570727806825
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-list.c
+
+
+
+ 1570727806841
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-queue.c
+
+
+
+ 1570727806841
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-stream_buffer.c
+
+
+
+ 1570727806841
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-timers.c
+
+
+
+ 1570727806856
+ FreeRTOS_Source
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-tasks.c
+
+
+
+ 1570727892841
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-event_groups.h
+
+
+
+ 1570727892856
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-FreeRTOS.h
+
+
+
+ 1570727892856
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-message_buffer.h
+
+
+
+ 1570727892856
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-queue.h
+
+
+
+ 1570727892872
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-semphr.h
+
+
+
+ 1570727892872
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-stream_buffer.h
+
+
+
+ 1570727892888
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-task.h
+
+
+
+ 1570727892888
+ FreeRTOS_Source/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-timers.h
+
+
+
+ 1570727962643
+ FreeRTOS_Source/portable
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-MemMang
+
+
+
+ 1570727962643
+ FreeRTOS_Source/portable
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-GCC
+
+
+
+ 1571005814144
+ full_demo/Common_Demo_Tasks
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-TimerDemo.c
+
+
+
+ 1571005814150
+ full_demo/Common_Demo_Tasks
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-blocktim.c
+
+
+
+ 1571005814159
+ full_demo/Common_Demo_Tasks
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-dynamic.c
+
+
+
+ 1571005814167
+ full_demo/Common_Demo_Tasks
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-TaskNotify.c
+
+
+
+ 1570727992991
+ FreeRTOS_Source/portable/GCC
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-RISC-V
+
+
+
+ 1570727979500
+ FreeRTOS_Source/portable/MemMang
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-heap_4.c
+
+
+
+ 1571005832815
+ full_demo/Common_Demo_Tasks/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-TimerDemo.h
+
+
+
+ 1571005832820
+ full_demo/Common_Demo_Tasks/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-blocktim.h
+
+
+
+ 1571005832824
+ full_demo/Common_Demo_Tasks/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-dynamic.h
+
+
+
+ 1571005832829
+ full_demo/Common_Demo_Tasks/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-MessageBufferDemo.h
+
+
+
+ 1571005832835
+ full_demo/Common_Demo_Tasks/include
+ 5
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-TaskNotify.h
+
+
+
+ 1570728021983
+ FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions
+ 9
+
+ org.eclipse.ui.ide.multiFilter
+ 1.0-name-matches-false-false-RV32I_CLINT_no_extensions
+
+
+
+
+
+ FREERTOS_ROOT
+ $%7BPARENT-3-PROJECT_LOC%7D
+
+
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml
index 49f601efa..b1990cea1 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml
@@ -1,26 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h
index 6f5106c9a..9ea57c84f 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h
@@ -1,102 +1,105 @@
-/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- *
- * See http://www.freertos.org/a00110.html.
- *----------------------------------------------------------*/
-#define CLINT_CTRL_ADDR ( 0x02000000UL )
-#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL )
-#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL )
-#define configUSE_PREEMPTION 1
-#define configUSE_IDLE_HOOK 0
-#define configUSE_TICK_HOOK 1
-#define configCPU_CLOCK_HZ ( 32768 )
-#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
-#define configMAX_PRIORITIES ( 7 )
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
-#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 )
-#define configMAX_TASK_NAME_LEN ( 16 )
-#define configUSE_TRACE_FACILITY 0
-#define configUSE_16_BIT_TICKS 0
-#define configIDLE_SHOULD_YIELD 0
-#define configUSE_MUTEXES 1
-#define configQUEUE_REGISTRY_SIZE 8
-#define configCHECK_FOR_STACK_OVERFLOW 2
-#define configUSE_RECURSIVE_MUTEXES 1
-#define configUSE_MALLOC_FAILED_HOOK 1
-#define configUSE_APPLICATION_TASK_TAG 0
-#define configUSE_COUNTING_SEMAPHORES 1
-#define configGENERATE_RUN_TIME_STATS 0
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
-
-/* Software timer definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define configTIMER_QUEUE_LENGTH 8
-#define configTIMER_TASK_STACK_DEPTH ( 160 )
-
-/* Task priorities. Allow these to be overridden. */
-#ifndef uartPRIMARY_PRIORITY
- #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
-#endif
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 1
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xTimerPendFunctionCall 1
-#define INCLUDE_xTaskAbortDelay 1
-#define INCLUDE_xTaskGetHandle 1
-#define INCLUDE_xSemaphoreGetMutexHolder 1
-
-/* Normal assert() semantics without relying on the provision of an assert.h
-header file. */
-void vAssertCalled( void );
-#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
-
-#endif /* FREERTOS_CONFIG_H */
+/*
+ * FreeRTOS V202104.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+#define CLINT_CTRL_ADDR ( 0x02000000UL )
+#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL )
+#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL )
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 1
+#define configCPU_CLOCK_HZ ( 32768 )
+#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
+#define configMAX_PRIORITIES ( 7 )
+#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
+#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 )
+#define configMAX_TASK_NAME_LEN ( 16 )
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 0
+#define configUSE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 8
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MALLOC_FAILED_HOOK 1
+#define configUSE_APPLICATION_TASK_TAG 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
+
+/* Software timer definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
+#define configTIMER_QUEUE_LENGTH 8
+#define configTIMER_TASK_STACK_DEPTH ( 160 )
+
+/* Task priorities. Allow these to be overridden. */
+#ifndef uartPRIMARY_PRIORITY
+ #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
+#endif
+
+/* Set the following definitions to 1 to include the API function, or zero
+to exclude the API function. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskCleanUpResources 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_eTaskGetState 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 1
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xSemaphoreGetMutexHolder 1
+
+/* Normal assert() semantics without relying on the provision of an assert.h
+header file. */
+void vAssertCalled( void );
+#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
+
+/* Map to the platform write function. */
+#define configPRINT_STRING( pcString ) write( STDOUT_FILENO, pcString, strlen( pcString ) )
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url
index 809b91304..34f8fc0bc 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url
@@ -1,5 +1,5 @@
-[InternetShortcut]
-URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html
-IDList=
-[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,2
+[InternetShortcut]
+URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html
+IDList=
+[{000214A0-0000-0000-C000-000000000046}]
+Prop3=19,2
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c
index de0a85bf3..e4e572e1f 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c
@@ -1,197 +1,197 @@
-/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/******************************************************************************
- * NOTE 1: This project provides two demo applications. A simple blinky
- * style project, and a more comprehensive test and demo application. The
- * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
- * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
- * in main.c. This file implements the simply blinky style version.
- *
- * NOTE 2: This file only contains the source code that is specific to the
- * blinky demo. Generic functions, such FreeRTOS hook functions, and functions
- * required to configure the hardware are defined in main.c.
- ******************************************************************************
- *
- * main_blinky() creates one queue, and two tasks. It then starts the
- * scheduler.
- *
- * The Queue Send Task:
- * The queue send task is implemented by the prvQueueSendTask() function in
- * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
- * block for 1000 milliseconds, before sending the value 100 to the queue that
- * was created within main_blinky(). Once the value is sent, the task loops
- * back around to block for another 1000 milliseconds...and so on.
- *
- * The Queue Receive Task:
- * The queue receive task is implemented by the prvQueueReceiveTask() function
- * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
- * blocks on attempts to read data from the queue that was created within
- * main_blinky(). When data is received, the task checks the value of the
- * data, and if the value equals the expected 100, toggles an LED. The 'block
- * time' parameter passed to the queue receive function specifies that the task
- * should be held in the Blocked state indefinitely to wait for data to be
- * available on the queue. The queue receive task will only leave the Blocked
- * state when the queue send task writes to the queue. As the queue send task
- * writes to the queue every 1000 milliseconds, the queue receive task leaves
- * the Blocked state every 1000 milliseconds, and therefore toggles the LED
- * every 200 milliseconds.
- */
-
-/* Standard includes. */
-#include
-#include
-#include
-
-/* Kernel includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/* Priorities used by the tasks. */
-#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
-#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-
-/* The rate at which data is sent to the queue. The 200ms value is converted
-to ticks using the pdMS_TO_TICKS() macro. */
-#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
-
-/* The maximum number items the queue can hold. The priority of the receiving
-task is above the priority of the sending task, so the receiving task will
-preempt the sending task and remove the queue items each time the sending task
-writes to the queue. Therefore the queue will never have more than one item in
-it at any time, and even with a queue length of 1, the sending task will never
-find the queue full. */
-#define mainQUEUE_LENGTH ( 1 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in
- * main.c.
- */
-void main_blinky( void );
-
-/*
- * The tasks as described in the comments at the top of this file.
- */
-static void prvQueueReceiveTask( void *pvParameters );
-static void prvQueueSendTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used by both tasks. */
-static QueueHandle_t xQueue = NULL;
-
-/*-----------------------------------------------------------*/
-
-void main_blinky( void )
-{
- /* Create the queue. */
- xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
-
- if( xQueue != NULL )
- {
- /* Start the two tasks as described in the comments at the top of this
- file. */
- xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
- "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
- configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
- NULL, /* The parameter passed to the task - not used in this case. */
- mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
- NULL ); /* The task handle is not required, so NULL is passed. */
-
- xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
-
- /* Start the tasks and timer running. */
- vTaskStartScheduler();
- }
-
- /* If all is well, the scheduler will now be running, and the following
- line will never be reached. If the following line does execute, then
- there was insufficient FreeRTOS heap memory available for the Idle and/or
- timer tasks to be created. See the memory management section on the
- FreeRTOS web site for more details on the FreeRTOS heap
- http://www.freertos.org/a00111.html. */
- for( ;; );
-}
-/*-----------------------------------------------------------*/
-
-static void prvQueueSendTask( void *pvParameters )
-{
-TickType_t xNextWakeTime;
-const unsigned long ulValueToSend = 100UL;
-BaseType_t xReturned;
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- /* Initialise xNextWakeTime - this only needs to be done once. */
- xNextWakeTime = xTaskGetTickCount();
-
- for( ;; )
- {
- /* Place this task in the blocked state until it is time to run again. */
- vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
-
- /* Send to the queue - causing the queue receive task to unblock and
- toggle the LED. 0 is used as the block time so the sending operation
- will not block - it shouldn't need to block as the queue should always
- be empty at this point in the code. */
- xReturned = xQueueSend( xQueue, &ulValueToSend, 0U );
- configASSERT( xReturned == pdPASS );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvQueueReceiveTask( void *pvParameters )
-{
-unsigned long ulReceivedValue;
-const unsigned long ulExpectedValue = 100UL;
-extern void vToggleLED( void );
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Wait until something arrives in the queue - this task will block
- indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
- FreeRTOSConfig.h. */
- xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
-
- /* To get here something must have been received from the queue, but
- is it the expected value? If it is, toggle the LED. */
- if( ulReceivedValue == ulExpectedValue )
- {
- vToggleLED();
- ulReceivedValue = 0U;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
+/*
+ * FreeRTOS V202104.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+/******************************************************************************
+ * NOTE 1: This project provides two demo applications. A simple blinky
+ * style project, and a more comprehensive test and demo application. The
+ * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
+ * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
+ * in main.c. This file implements the simply blinky style version.
+ *
+ * NOTE 2: This file only contains the source code that is specific to the
+ * blinky demo. Generic functions, such FreeRTOS hook functions, and functions
+ * required to configure the hardware are defined in main.c.
+ ******************************************************************************
+ *
+ * main_blinky() creates one queue, and two tasks. It then starts the
+ * scheduler.
+ *
+ * The Queue Send Task:
+ * The queue send task is implemented by the prvQueueSendTask() function in
+ * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
+ * block for 1000 milliseconds, before sending the value 100 to the queue that
+ * was created within main_blinky(). Once the value is sent, the task loops
+ * back around to block for another 1000 milliseconds...and so on.
+ *
+ * The Queue Receive Task:
+ * The queue receive task is implemented by the prvQueueReceiveTask() function
+ * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
+ * blocks on attempts to read data from the queue that was created within
+ * main_blinky(). When data is received, the task checks the value of the
+ * data, and if the value equals the expected 100, toggles an LED. The 'block
+ * time' parameter passed to the queue receive function specifies that the task
+ * should be held in the Blocked state indefinitely to wait for data to be
+ * available on the queue. The queue receive task will only leave the Blocked
+ * state when the queue send task writes to the queue. As the queue send task
+ * writes to the queue every 1000 milliseconds, the queue receive task leaves
+ * the Blocked state every 1000 milliseconds, and therefore toggles the LED
+ * every 200 milliseconds.
+ */
+
+/* Standard includes. */
+#include
+#include
+#include
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+/* Priorities used by the tasks. */
+#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
+#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
+
+/* The rate at which data is sent to the queue. The 200ms value is converted
+to ticks using the pdMS_TO_TICKS() macro. */
+#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
+
+/* The maximum number items the queue can hold. The priority of the receiving
+task is above the priority of the sending task, so the receiving task will
+preempt the sending task and remove the queue items each time the sending task
+writes to the queue. Therefore the queue will never have more than one item in
+it at any time, and even with a queue length of 1, the sending task will never
+find the queue full. */
+#define mainQUEUE_LENGTH ( 1 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in
+ * main.c.
+ */
+void main_blinky( void );
+
+/*
+ * The tasks as described in the comments at the top of this file.
+ */
+static void prvQueueReceiveTask( void *pvParameters );
+static void prvQueueSendTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used by both tasks. */
+static QueueHandle_t xQueue = NULL;
+
+/*-----------------------------------------------------------*/
+
+void main_blinky( void )
+{
+ /* Create the queue. */
+ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
+
+ if( xQueue != NULL )
+ {
+ /* Start the two tasks as described in the comments at the top of this
+ file. */
+ xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
+ "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
+ configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
+ NULL, /* The parameter passed to the task - not used in this case. */
+ mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
+ NULL ); /* The task handle is not required, so NULL is passed. */
+
+ xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
+
+ /* Start the tasks and timer running. */
+ vTaskStartScheduler();
+ }
+
+ /* If all is well, the scheduler will now be running, and the following
+ line will never be reached. If the following line does execute, then
+ there was insufficient FreeRTOS heap memory available for the Idle and/or
+ timer tasks to be created. See the memory management section on the
+ FreeRTOS web site for more details on the FreeRTOS heap
+ http://www.freertos.org/a00111.html. */
+ for( ;; );
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueSendTask( void *pvParameters )
+{
+TickType_t xNextWakeTime;
+const unsigned long ulValueToSend = 100UL;
+BaseType_t xReturned;
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ /* Initialise xNextWakeTime - this only needs to be done once. */
+ xNextWakeTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ /* Place this task in the blocked state until it is time to run again. */
+ vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
+
+ /* Send to the queue - causing the queue receive task to unblock and
+ toggle the LED. 0 is used as the block time so the sending operation
+ will not block - it shouldn't need to block as the queue should always
+ be empty at this point in the code. */
+ xReturned = xQueueSend( xQueue, &ulValueToSend, 0U );
+ configASSERT( xReturned == pdPASS );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvQueueReceiveTask( void *pvParameters )
+{
+unsigned long ulReceivedValue;
+const unsigned long ulExpectedValue = 100UL;
+extern void vToggleLED( void );
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ for( ;; )
+ {
+ /* Wait until something arrives in the queue - this task will block
+ indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
+ FreeRTOSConfig.h. */
+ xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
+
+ /* To get here something must have been received from the queue, but
+ is it the expected value? If it is, toggle the LED. */
+ if( ulReceivedValue == ulExpectedValue )
+ {
+ vToggleLED();
+ ulReceivedValue = 0U;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md
new file mode 100644
index 000000000..f5abca5bf
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md
@@ -0,0 +1,13 @@
+HiFive1 Rev B is a low-cost, Arduino-compatible development board featuring the Freedom E310. It’s the best way to start prototyping and developing your RISC‑V applications.
+
+This target is ideal for getting familiar with the RISC-V ISA instruction set and the freedom-metal libraries. It supports:
+
+- 1 hart with RV32IMAC core
+- 4 hardware breakpoints
+- Physical Memory Protection with 8 regions
+- 16 local interrupts signal that can be connected to off core complex devices
+- Up to 127 PLIC interrupt signals that can be connected to off core complex devices, with 7 priority levels
+- GPIO memory with 16 interrupt lines
+- SPI memory with 1 interrupt line
+- Serial port with 1 interrupt line
+- 1 RGB LEDS
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts
new file mode 100644
index 000000000..f68e58441
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts
@@ -0,0 +1,262 @@
+/dts-v1/;
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "sifive,hifive1-revb";
+ model = "sifive,hifive1-revb";
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "sifive,fe310-g000";
+ L6: cpu@0 {
+ clocks = <&hfclk>;
+ compatible = "sifive,rocket0", "riscv";
+ device_type = "cpu";
+ i-cache-block-size = <64>;
+ i-cache-sets = <128>;
+ i-cache-size = <16384>;
+ next-level-cache = <&spi0>;
+ reg = <0>;
+ riscv,isa = "rv32imac";
+ riscv,pmpregions = <8>;
+ sifive,itim = <&itim>;
+ sifive,dtim = <&dtim>;
+ status = "okay";
+ timebase-frequency = <16000000>;
+ hardware-exec-breakpoint-count = <4>;
+ hlic: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ };
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ compatible = "sifive,hifive1";
+ ranges;
+ hfxoscin: clock@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <16000000>;
+ };
+ hfxoscout: clock@1 {
+ compatible = "sifive,fe310-g000,hfxosc";
+ clocks = <&hfxoscin>;
+ reg = <&prci 0x4>;
+ reg-names = "config";
+ };
+ hfroscin: clock@2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <72000000>;
+ };
+ hfroscout: clock@3 {
+ compatible = "sifive,fe310-g000,hfrosc";
+ clocks = <&hfroscin>;
+ reg = <&prci 0x0>;
+ reg-names = "config";
+ };
+ hfclk: clock@4 {
+ compatible = "sifive,fe310-g000,pll";
+ clocks = <&hfxoscout &hfroscout>;
+ clock-names = "pllref", "pllsel0";
+ reg = <&prci 0x8 &prci 0xc>;
+ reg-names = "config", "divider";
+ clock-frequency = <16000000>;
+ };
+ lfrosc: clock@5 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+ psdlfaltclk: clock@6 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+ lfclk: clock@7 {
+ compatible = "sifive,fe310-g000,lfrosc";
+ clocks = <&lfrosc &psdlfaltclk>;
+ clock-names = "lfrosc", "psdlfaltclk";
+ reg = <&aon 0x70 &aon 0x7C>;
+ reg-names = "config", "mux";
+ };
+ debug-controller@0 {
+ compatible = "sifive,debug-011", "riscv,debug-011";
+ interrupts-extended = <&hlic 65535>;
+ reg = <0x0 0x1000>;
+ reg-names = "control";
+ };
+ /* Missing: Error device */
+ maskrom@1000 {
+ reg = <0x1000 0x2000>;
+ reg-names = "mem";
+ };
+ otp@20000 {
+ reg = <0x20000 0x2000 0x10010000 0x1000>;
+ reg-names = "mem", "control";
+ };
+ clint: clint@2000000 {
+ compatible = "riscv,clint0";
+ interrupts-extended = <&hlic 3 &hlic 7>;
+ reg = <0x2000000 0x10000>;
+ reg-names = "control";
+ };
+ itim: itim@8000000 {
+ compatible = "sifive,itim0";
+ reg = <0x8000000 0x2000>;
+ reg-names = "mem";
+ };
+ plic: interrupt-controller@c000000 {
+ #interrupt-cells = <1>;
+ compatible = "riscv,plic0";
+ interrupt-controller;
+ interrupts-extended = <&hlic 11>;
+ reg = <0xc000000 0x4000000>;
+ reg-names = "control";
+ riscv,max-priority = <7>;
+ riscv,ndev = <52>;
+ };
+ aon: aon@10000000 {
+ compatible = "sifive,aon0";
+ reg = <0x10000000 0x8000>;
+ reg-names = "mem";
+ interrupt-parent = <&plic>;
+ interrupts = <1 2>;
+ clocks = <&lfclk>;
+ };
+ prci: prci@10008000 {
+ compatible = "sifive,fe310-g000,prci";
+ reg = <0x10008000 0x8000>;
+ reg-names = "mem";
+ };
+ gpio0: gpio@10012000 {
+ compatible = "sifive,gpio0";
+ interrupt-parent = <&plic>;
+ interrupts = <8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
+ 23 24 25 26 27 28 29 30 31 32 33 34 35 36
+ 27 28 29>;
+ reg = <0x10012000 0x1000>;
+ reg-names = "control";
+ };
+ led@0 {
+ compatible = "sifive,gpio-leds";
+ label = "LD0red";
+ gpios = <&gpio0 22>;
+ linux,default-trigger = "none";
+ };
+ led@1 {
+ compatible = "sifive,gpio-leds";
+ label = "LD0green";
+ gpios = <&gpio0 19>;
+ linux,default-trigger = "none";
+ };
+ led@2 {
+ compatible = "sifive,gpio-leds";
+ label = "LD0blue";
+ gpios = <&gpio0 21>;
+ linux,default-trigger = "none";
+ };
+ uart0: serial@10013000 {
+ compatible = "sifive,uart0";
+ interrupt-parent = <&plic>;
+ interrupts = <3>;
+ reg = <0x10013000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0x30000>;
+ };
+ spi0: spi@10014000 {
+ compatible = "sifive,spi0";
+ interrupt-parent = <&plic>;
+ interrupts = <5>;
+ reg = <0x10014000 0x1000 0x20000000 0x7A120>;
+ reg-names = "control", "mem";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0x0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x20000000 0x424000>;
+ };
+ };
+ pwm0: pwm@10015000 {
+ compatible = "sifive,pwm0";
+ sifive,comparator-widthbits = <8>;
+ sifive,ncomparators = <4>;
+ interrupt-parent = <&plic>;
+ interrupts = <40 41 42 43>;
+ reg = <0x10015000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0F 0x0F>;
+ };
+ i2c0: i2c@10016000 {
+ compatible = "sifive,i2c0";
+ interrupt-parent = <&plic>;
+ interrupts = <52>;
+ reg = <0x10016000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0x3000>;
+ };
+ uart1: serial@10023000 {
+ compatible = "sifive,uart0";
+ interrupt-parent = <&plic>;
+ interrupts = <4>;
+ reg = <0x10023000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0x840000>;
+ };
+ spi1: spi@10024000 {
+ compatible = "sifive,spi0";
+ interrupt-parent = <&plic>;
+ interrupts = <6>;
+ reg = <0x10024000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0x0003C>;
+ };
+ pwm1: pwm@10025000 {
+ compatible = "sifive,pwm0";
+ sifive,comparator-widthbits = <16>;
+ sifive,ncomparators = <4>;
+ interrupt-parent = <&plic>;
+ interrupts = <44 45 46 47>;
+ reg = <0x10025000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x780000 0x780000>;
+ };
+ spi2: spi@10034000 {
+ compatible = "sifive,spi0";
+ interrupt-parent = <&plic>;
+ interrupts = <7>;
+ reg = <0x10034000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x0 0xFC000000>;
+ };
+ pwm2: pwm@10035000 {
+ compatible = "sifive,pwm0";
+ sifive,comparator-widthbits = <16>;
+ sifive,ncomparators = <4>;
+ interrupt-parent = <&plic>;
+ interrupts = <48 49 50 51>;
+ reg = <0x10035000 0x1000>;
+ reg-names = "control";
+ clocks = <&hfclk>;
+ pinmux = <&gpio0 0x3C00 0x3C00>;
+ };
+ dtim: dtim@80000000 {
+ compatible = "sifive,dtim0";
+ reg = <0x80000000 0x4000>;
+ reg-names = "mem";
+ };
+ };
+};
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts
index 970d3be72..098c25c4b 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts
@@ -1,209 +1,10 @@
-/dts-v1/;
-
+/include/ "core.dts"
/ {
- #address-cells = <1>;
- #size-cells = <1>;
- compatible = "sifive,hifive1-revb";
- model = "sifive,hifive1-revb";
-
- chosen {
- stdout-path = "/soc/serial@10013000:115200";
- metal,entry = <&spi0 0x10000>;
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "sifive,fe310-g000";
- L6: cpu@0 {
- clocks = <&hfclk>;
- compatible = "sifive,rocket0", "riscv";
- device_type = "cpu";
- i-cache-block-size = <64>;
- i-cache-sets = <128>;
- i-cache-size = <16384>;
- next-level-cache = <&spi0>;
- reg = <0>;
- riscv,isa = "rv32imac";
- riscv,pmpregions = <8>;
- sifive,dtim = <&dtim>;
- status = "okay";
- timebase-frequency = <1000000>;
- hardware-exec-breakpoint-count = <4>;
- hlic: interrupt-controller {
- #interrupt-cells = <1>;
- compatible = "riscv,cpu-intc";
- interrupt-controller;
- };
- };
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- #clock-cells = <1>;
- compatible = "sifive,hifive1";
- ranges;
- hfxoscin: clock@0 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <16000000>;
- };
- hfxoscout: clock@1 {
- compatible = "sifive,fe310-g000,hfxosc";
- clocks = <&hfxoscin>;
- reg = <&prci 0x4>;
- reg-names = "config";
- };
- hfroscin: clock@2 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <72000000>;
- };
- hfroscout: clock@3 {
- compatible = "sifive,fe310-g000,hfrosc";
- clocks = <&hfroscin>;
- reg = <&prci 0x0>;
- reg-names = "config";
- };
- hfclk: clock@4 {
- compatible = "sifive,fe310-g000,pll";
- clocks = <&hfxoscout &hfroscout>;
- clock-names = "pllref", "pllsel0";
- reg = <&prci 0x8 &prci 0xc>;
- reg-names = "config", "divider";
- clock-frequency = <16000000>;
- };
-
- lfroscin: clock@5 {
- #clock-cells = <0>;
- compatible = "fixed-clock";
- clock-frequency = <32000000>;
- };
- lfclk: clock@6 {
- compatible = "sifive,fe310-g000,lfrosc";
- clocks = <&lfroscin>;
- reg = <&aon 0x70>;
- reg-names = "config";
- };
-
- aon: aon@10000000 {
- compatible = "sifive,aon0";
- reg = <0x10000000 0x8000>;
- reg-names = "mem";
- };
-
- prci: prci@10008000 {
- compatible = "sifive,fe310-g000,prci";
- reg = <0x10008000 0x8000>;
- reg-names = "mem";
- };
-
- clint: clint@2000000 {
- compatible = "riscv,clint0";
- interrupts-extended = <&hlic 3 &hlic 7>;
- reg = <0x2000000 0x10000>;
- reg-names = "control";
- };
- local-external-interrupts-0 {
- compatible = "sifive,local-external-interrupts0";
- interrupt-parent = <&hlic>;
- interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
- };
- plic: interrupt-controller@c000000 {
- #interrupt-cells = <1>;
- compatible = "riscv,plic0";
- interrupt-controller;
- interrupts-extended = <&hlic 11>;
- reg = <0xc000000 0x4000000>;
- reg-names = "control";
- riscv,max-priority = <7>;
- riscv,ndev = <26>;
- };
- global-external-interrupts {
- compatile = "sifive,global-external-interrupts0";
- interrupt-parent = <&plic>;
- interrupts = <1 2 3 4>;
- };
-
- debug-controller@0 {
- compatible = "sifive,debug-011", "riscv,debug-011";
- interrupts-extended = <&hlic 65535>;
- reg = <0x0 0x100>;
- reg-names = "control";
- };
-
- maskrom@1000 {
- reg = <0x1000 0x2000>;
- reg-names = "mem";
- };
- otp@20000 {
- reg = <0x20000 0x2000 0x10010000 0x1000>;
- reg-names = "mem", "control";
- };
-
- dtim: dtim@80000000 {
- compatible = "sifive,dtim0";
- reg = <0x80000000 0x4000>;
- reg-names = "mem";
- };
-
- pwm@10015000 {
- compatible = "sifive,pwm0";
- interrupt-parent = <&plic>;
- interrupts = <23 24 25 26>;
- reg = <0x10015000 0x1000>;
- reg-names = "control";
- };
- gpio0: gpio@10012000 {
- compatible = "sifive,gpio0";
- interrupt-parent = <&plic>;
- interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>;
- reg = <0x10012000 0x1000>;
- reg-names = "control";
- };
- uart0: serial@10013000 {
- compatible = "sifive,uart0";
- interrupt-parent = <&plic>;
- interrupts = <5>;
- reg = <0x10013000 0x1000>;
- reg-names = "control";
- clocks = <&hfclk>;
- pinmux = <&gpio0 0x30000 0x30000>;
- };
- spi0: spi@10014000 {
- compatible = "sifive,spi0";
- interrupt-parent = <&plic>;
- interrupts = <6>;
- reg = <0x10014000 0x1000 0x20000000 0x7A120>;
- reg-names = "control", "mem";
- clocks = <&hfclk>;
- pinmux = <&gpio0 0x0003C 0x0003C>;
- };
- i2c0: i2c@10016000 {
- compatible = "sifive,i2c0";
- interrupt-parent = <&plic>;
- interrupts = <52>;
- reg = <0x10016000 0x1000>;
- reg-names = "control";
- };
- led@0red {
- compatible = "sifive,gpio-leds";
- label = "LD0red";
- gpios = <&gpio0 22>;
- linux,default-trigger = "none";
- };
- led@0green {
- compatible = "sifive,gpio-leds";
- label = "LD0green";
- gpios = <&gpio0 19>;
- linux,default-trigger = "none";
- };
- led@0blue {
- compatible = "sifive,gpio-leds";
- label = "LD0blue";
- gpios = <&gpio0 21>;
- linux,default-trigger = "none";
- };
- };
+ chosen {
+ metal,entry = <&spi0 1 65536>;
+ metal,boothart = <&L6>;
+ stdout-path = "/soc/serial@10013000:115200";
+ metal,itim = <&itim 0 0>;
+ metal,ram = <&dtim 0 0>;
+ };
};
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd
new file mode 100644
index 000000000..3ad2768bd
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd
@@ -0,0 +1,3169 @@
+
+
+ sifive_hifive1_revb
+ 0.1
+ From sifive,hifive1-revb,model device generator
+ 8
+ 32
+ 32
+ read-write
+
+
+ riscv_clint0_0
+ From riscv,clint0,control peripheral generator
+ 0x2000000
+
+ 0
+ 0x10000
+ registers
+
+
+
+ msip_0
+ MSIP Register for hart 0
+ 0x0
+
+
+ mtimecmp_0
+ MTIMECMP Register for hart 0
+ 0x4000
+ 64
+
+
+ mtime
+ MTIME Register
+ 0xBFF8
+ 64
+
+
+
+
+ riscv_plic0_0
+ From riscv,plic0,control peripheral generator
+ 0xC000000
+
+ 0
+ 0x4000000
+ registers
+
+
+
+ priority_1
+ PRIORITY Register for interrupt id 1
+ 0x4
+
+
+ priority_2
+ PRIORITY Register for interrupt id 2
+ 0x8
+
+
+ priority_3
+ PRIORITY Register for interrupt id 3
+ 0xC
+
+
+ priority_4
+ PRIORITY Register for interrupt id 4
+ 0x10
+
+
+ priority_5
+ PRIORITY Register for interrupt id 5
+ 0x14
+
+
+ priority_6
+ PRIORITY Register for interrupt id 6
+ 0x18
+
+
+ priority_7
+ PRIORITY Register for interrupt id 7
+ 0x1C
+
+
+ priority_8
+ PRIORITY Register for interrupt id 8
+ 0x20
+
+
+ priority_9
+ PRIORITY Register for interrupt id 9
+ 0x24
+
+
+ priority_10
+ PRIORITY Register for interrupt id 10
+ 0x28
+
+
+ priority_11
+ PRIORITY Register for interrupt id 11
+ 0x2C
+
+
+ priority_12
+ PRIORITY Register for interrupt id 12
+ 0x30
+
+
+ priority_13
+ PRIORITY Register for interrupt id 13
+ 0x34
+
+
+ priority_14
+ PRIORITY Register for interrupt id 14
+ 0x38
+
+
+ priority_15
+ PRIORITY Register for interrupt id 15
+ 0x3C
+
+
+ priority_16
+ PRIORITY Register for interrupt id 16
+ 0x40
+
+
+ priority_17
+ PRIORITY Register for interrupt id 17
+ 0x44
+
+
+ priority_18
+ PRIORITY Register for interrupt id 18
+ 0x48
+
+
+ priority_19
+ PRIORITY Register for interrupt id 19
+ 0x4C
+
+
+ priority_20
+ PRIORITY Register for interrupt id 20
+ 0x50
+
+
+ priority_21
+ PRIORITY Register for interrupt id 21
+ 0x54
+
+
+ priority_22
+ PRIORITY Register for interrupt id 22
+ 0x58
+
+
+ priority_23
+ PRIORITY Register for interrupt id 23
+ 0x5C
+
+
+ priority_24
+ PRIORITY Register for interrupt id 24
+ 0x60
+
+
+ priority_25
+ PRIORITY Register for interrupt id 25
+ 0x64
+
+
+ priority_26
+ PRIORITY Register for interrupt id 26
+ 0x68
+
+
+ priority_27
+ PRIORITY Register for interrupt id 27
+ 0x6C
+
+
+ priority_28
+ PRIORITY Register for interrupt id 28
+ 0x70
+
+
+ priority_29
+ PRIORITY Register for interrupt id 29
+ 0x74
+
+
+ priority_30
+ PRIORITY Register for interrupt id 30
+ 0x78
+
+
+ priority_31
+ PRIORITY Register for interrupt id 31
+ 0x7C
+
+
+ priority_32
+ PRIORITY Register for interrupt id 32
+ 0x80
+
+
+ priority_33
+ PRIORITY Register for interrupt id 33
+ 0x84
+
+
+ priority_34
+ PRIORITY Register for interrupt id 34
+ 0x88
+
+
+ priority_35
+ PRIORITY Register for interrupt id 35
+ 0x8C
+
+
+ priority_36
+ PRIORITY Register for interrupt id 36
+ 0x90
+
+
+ priority_37
+ PRIORITY Register for interrupt id 37
+ 0x94
+
+
+ priority_38
+ PRIORITY Register for interrupt id 38
+ 0x98
+
+
+ priority_39
+ PRIORITY Register for interrupt id 39
+ 0x9C
+
+
+ priority_40
+ PRIORITY Register for interrupt id 40
+ 0xA0
+
+
+ priority_41
+ PRIORITY Register for interrupt id 41
+ 0xA4
+
+
+ priority_42
+ PRIORITY Register for interrupt id 42
+ 0xA8
+
+
+ priority_43
+ PRIORITY Register for interrupt id 43
+ 0xAC
+
+
+ priority_44
+ PRIORITY Register for interrupt id 44
+ 0xB0
+
+
+ priority_45
+ PRIORITY Register for interrupt id 45
+ 0xB4
+
+
+ priority_46
+ PRIORITY Register for interrupt id 46
+ 0xB8
+
+
+ priority_47
+ PRIORITY Register for interrupt id 47
+ 0xBC
+
+
+ priority_48
+ PRIORITY Register for interrupt id 48
+ 0xC0
+
+
+ priority_49
+ PRIORITY Register for interrupt id 49
+ 0xC4
+
+
+ priority_50
+ PRIORITY Register for interrupt id 50
+ 0xC8
+
+
+ priority_51
+ PRIORITY Register for interrupt id 51
+ 0xCC
+
+
+ priority_52
+ PRIORITY Register for interrupt id 52
+ 0xD0
+
+
+ pending_0
+ PENDING Register for interrupt ids 31 to 0
+ 0x1000
+
+
+ pending_1
+ PENDING Register for interrupt ids 52 to 32
+ 0x1004
+
+
+ enable_0_0
+ ENABLE Register for interrupt ids 31 to 0 for hart 0
+ 0x2000
+
+
+ enable_1_0
+ ENABLE Register for interrupt ids 52 to 32 for hart 0
+ 0x2004
+
+
+ threshold_0
+ PRIORITY THRESHOLD Register for hart 0
+ 0x200000
+
+
+ claimplete_0
+ CLAIM and COMPLETE Register for hart 0
+ 0x200004
+
+
+
+
+ sifive_aon0_0
+ From sifive,aon0,mem peripheral generator
+ 0x10000000
+
+ 0
+ 0x8000
+ registers
+
+
+
+ backup_0
+ Backup Register 0
+ 0x80
+
+
+ backup_1
+ Backup Register 1
+ 0x84
+
+
+ backup_2
+ Backup Register 2
+ 0x88
+
+
+ backup_3
+ Backup Register 3
+ 0x8C
+
+
+ backup_4
+ Backup Register 4
+ 0x90
+
+
+ backup_5
+ Backup Register 5
+ 0x94
+
+
+ backup_6
+ Backup Register 6
+ 0x98
+
+
+ backup_7
+ Backup Register 7
+ 0x9C
+
+
+ backup_8
+ Backup Register 8
+ 0xA0
+
+
+ backup_9
+ Backup Register 9
+ 0xA4
+
+
+ backup_10
+ Backup Register 10
+ 0xA8
+
+
+ backup_11
+ Backup Register 11
+ 0xAC
+
+
+ backup_12
+ Backup Register 12
+ 0xB0
+
+
+ backup_13
+ Backup Register 13
+ 0xB4
+
+
+ backup_14
+ Backup Register 14
+ 0xB8
+
+
+ backup_15
+ Backup Register 15
+ 0xBC
+
+
+ wdogcfg
+ wdog Configuration
+ 0x0
+
+
+ wdogscale
+ Counter scale value.
+ [3:0]
+ read-write
+
+
+ wdogrsten
+ Controls whether the comparator output can set the wdogrst bit and hence cause a full reset.
+ [8:8]
+ read-write
+
+
+ wdogzerocmp
+ Reset counter to zero after match.
+ [9:9]
+ read-write
+
+
+ wdogenalways
+ Enable Always - run continuously
+ [12:12]
+ read-write
+
+
+ wdogcoreawake
+ Increment the watchdog counter if the processor is not asleep
+ [13:13]
+ read-write
+
+
+ wdogip0
+ Interrupt 0 Pending
+ [28:28]
+ read-write
+
+
+
+
+ wdogcount
+ Counter Register
+ 0x8
+
+
+ wdogs
+ Scaled value of Counter
+ 0x10
+
+
+ wdogfeed
+ Feed register
+ 0x18
+
+
+ wdogkey
+ Key Register
+ 0x1C
+
+
+ wdogcmp0
+ Comparator 0
+ 0x20
+
+
+ rtccfg
+ rtc Configuration
+ 0x40
+
+
+ rtcscale
+ Counter scale value.
+ [3:0]
+ read-write
+
+
+ rtcenalways
+ Enable Always - run continuously
+ [12:12]
+ read-write
+
+
+ rtcip0
+ Interrupt 0 Pending
+ [28:28]
+ read-write
+
+
+
+
+ rtccountlo
+ Low bits of Counter
+ 0x48
+
+
+ rtccounthi
+ High bits of Counter
+ 0x4C
+
+
+ rtcs
+ Scaled value of Counter
+ 0x50
+
+
+ rtccmp0
+ Comparator 0
+ 0x60
+
+
+ pmuwakeupi0
+ Wakeup program instruction 0
+ 0x100
+
+
+ pmuwakeupi1
+ Wakeup program instruction 1
+ 0x104
+
+
+ pmuwakeupi2
+ Wakeup program instruction 2
+ 0x108
+
+
+ pmuwakeupi3
+ Wakeup program instruction 3
+ 0x10C
+
+
+ pmuwakeupi4
+ Wakeup program instruction 4
+ 0x110
+
+
+ pmuwakeupi5
+ Wakeup program instruction 5
+ 0x114
+
+
+ pmuwakeupi6
+ Wakeup program instruction 6
+ 0x118
+
+
+ pmuwakeupi7
+ Wakeup program instruction 7
+ 0x11C
+
+
+ pmusleepi0
+ Sleep program instruction 0
+ 0x120
+
+
+ pmusleepi1
+ Sleep program instruction 1
+ 0x124
+
+
+ pmusleepi2
+ Sleep program instruction 2
+ 0x128
+
+
+ pmusleepi3
+ Sleep program instruction 3
+ 0x12C
+
+
+ pmusleepi4
+ Sleep program instruction 4
+ 0x130
+
+
+ pmusleepi5
+ Sleep program instruction 5
+ 0x134
+
+
+ pmusleepi6
+ Sleep program instruction 6
+ 0x138
+
+
+ pmusleepi7
+ Sleep program instruction 7
+ 0x13C
+
+
+ pmuie
+ PMU Interrupt Enables
+ 0x140
+
+
+ pmucause
+ PMU Wakeup Cause
+ 0x144
+
+
+ pmusleep
+ Initiate PMU Sleep Sequence
+ 0x148
+
+
+ pmukey
+ PMU Key. Reads as 1 when PMU is unlocked
+ 0x14C
+
+
+ aoncfg
+ AON Block Configuration Information
+ 0x300
+
+
+ has_bandgap
+ Bandgap feature is present
+ [0:0]
+ read-only
+
+
+ has_bod
+ Brownout detector feature is present
+ [1:1]
+ read-only
+
+
+ has_lfrosc
+ Low Frequency Ring Oscillator feature is present
+ [2:2]
+ read-only
+
+
+ has_lfrcosc
+ Low Frequency RC Oscillator feature is present
+ [3:3]
+ read-only
+
+
+ has_lfxosc
+ Low Frequency Crystal Oscillator feature is present
+ [4:4]
+ read-only
+
+
+ has_por
+ Power-On-Reset feature is present
+ [5:5]
+ read-only
+
+
+ has_ldo
+ Low Dropout Regulator feature is present
+ [6:6]
+ read-only
+
+
+
+
+ lfrosccfg
+ Ring Oscillator Configuration and Status
+ 0x70
+
+
+ lfroscdiv
+ Ring Oscillator Divider Register
+ [5:0]
+ read-write
+
+
+ lfrosctrim
+ Ring Oscillator Trim Register
+ [20:16]
+ read-write
+
+
+ lfroscen
+ Ring Oscillator Enable
+ [30:30]
+ read-write
+
+
+ lfroscrdy
+ Ring Oscillator Ready
+ [31:31]
+ read-only
+
+
+
+
+ lfclkmux
+ Low-Frequency Clock Mux Control and Status
+ 0x7C
+
+
+ lfextclk_sel
+ Low Frequency Clock Source Selector
+ [0:0]
+ read-write
+
+
+ internal
+ Use internal LF clock source
+ 0
+
+
+ external
+ Use external LF clock source
+ 1
+
+
+
+
+ lfextclk_mux_status
+ Setting of the aon_lfclksel pin
+ [31:31]
+ read-only
+
+
+ external
+ Use external LF clock source
+ 0
+
+
+ sw
+ Use clock source selected by lfextclk_sel
+ 1
+
+
+
+
+
+
+
+
+ sifive_fe310_g000_prci_0
+ From sifive,fe310-g000,prci,mem peripheral generator
+ 0x10008000
+
+ 0
+ 0x8000
+ registers
+
+
+
+ hfrosccfg
+ Ring Oscillator Configuration and Status
+ 0x0
+
+
+ hfroscdiv
+ Ring Oscillator Divider Register
+ [5:0]
+ read-write
+
+
+ hfrosctrim
+ Ring Oscillator Trim Register
+ [20:16]
+ read-write
+
+
+ hfroscen
+ Ring Oscillator Enable
+ [30:30]
+ read-write
+
+
+ hfroscrdy
+ Ring Oscillator Ready
+ [31:31]
+ read-only
+
+
+
+
+ hfxosccfg
+ Crystal Oscillator Configuration and Status
+ 0x4
+
+
+ hfxoscen
+ Crystal Oscillator Enable
+ [30:30]
+ read-write
+
+
+ hfxoscrdy
+ Crystal Oscillator Ready
+ [31:31]
+ read-only
+
+
+
+
+ pllcfg
+ PLL Configuration and Status
+ 0x8
+
+
+ pllr
+ PLL R Value
+ [2:0]
+ read-write
+
+
+ pllf
+ PLL F Value
+ [9:4]
+ read-write
+
+
+ pllq
+ PLL Q Value
+ [11:10]
+ read-write
+
+
+ pllsel
+ PLL Select
+ [16:16]
+ read-write
+
+
+ pllrefsel
+ PLL Reference Select
+ [17:17]
+ read-write
+
+
+ pllbypass
+ PLL Bypass
+ [18:18]
+ read-write
+
+
+ plllock
+ PLL Lock
+ [31:31]
+ read-only
+
+
+
+
+ plloutdiv
+ PLL Final Divide Configuration
+ 0xC
+
+
+ plloutdiv
+ PLL Final Divider Value
+ [5:0]
+ read-write
+
+
+ plloutdivby1
+ PLL Final Divide By 1
+ [13:8]
+ read-write
+
+
+
+
+ procmoncfg
+ Process Monitor Configuration and Status
+ 0xF0
+
+
+ procmon_div_sel
+ Proccess Monitor Divider
+ [4:0]
+ read-write
+
+
+ procmon_delay_sel
+ Process Monitor Delay Selector
+ [12:8]
+ read-write
+
+
+ procmon_en
+ Process Monitor Enable
+ [16:16]
+ read-write
+
+
+ procomon_sel
+ Process Monitor Select
+ [25:24]
+ read-write
+
+
+
+
+
+
+ sifive_gpio0_0
+ From sifive,gpio0,control peripheral generator
+ 0x10012000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ input_val
+ Pin value
+ 0x0
+
+
+ input_en
+ Pin input enable
+ 0x4
+
+
+ output_en
+ Pin output enable
+ 0x8
+
+
+ output_val
+ Output value
+ 0xC
+
+
+ pue
+ Internal pull-up enable
+ 0x10
+
+
+ ds
+ Pin drive strength
+ 0x14
+
+
+ rise_ie
+ Rise interrupt enable
+ 0x18
+
+
+ rise_ip
+ Rise interrupt pending
+ 0x1C
+
+
+ fall_ie
+ Fall interrupt enable
+ 0x20
+
+
+ fall_ip
+ Fall interrupt pending
+ 0x24
+
+
+ high_ie
+ High interrupt enable
+ 0x28
+
+
+ high_ip
+ High interrupt pending
+ 0x2C
+
+
+ low_ie
+ Low interrupt enable
+ 0x30
+
+
+ low_ip
+ Low interrupt pending
+ 0x34
+
+
+ iof_en
+ I/O function enable
+ 0x38
+
+
+ iof_sel
+ I/O function select
+ 0x3C
+
+
+ out_xor
+ Output XOR (invert)
+ 0x40
+
+
+
+
+ sifive_uart0_0
+ From sifive,uart0,control peripheral generator
+ 0x10013000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ txdata
+ Transmit data register
+ 0x0
+
+
+ data
+ Transmit data
+ [7:0]
+ read-write
+
+
+ full
+ Transmit FIFO full
+ [31:31]
+ read-only
+
+
+
+
+ rxdata
+ Receive data register
+ 0x4
+
+
+ data
+ Received data
+ [7:0]
+ read-only
+
+
+ empty
+ Receive FIFO empty
+ [31:31]
+ read-only
+
+
+
+
+ txctrl
+ Transmit control register
+ 0x8
+
+
+ txen
+ Transmit enable
+ [0:0]
+ read-write
+
+
+ nstop
+ Number of stop bits
+ [1:1]
+ read-write
+
+
+ txcnt
+ Transmit watermark level
+ [18:16]
+ read-write
+
+
+
+
+ rxctrl
+ Receive control register
+ 0xC
+
+
+ rxen
+ Receive enable
+ [0:0]
+ read-write
+
+
+ rxcnt
+ Receive watermark level
+ [18:16]
+ read-write
+
+
+
+
+ ie
+ UART interrupt enable
+ 0x10
+
+
+ txwm
+ Transmit watermark interrupt enable
+ [0:0]
+ read-write
+
+
+ rxwm
+ Receive watermark interrupt enable
+ [1:1]
+ read-write
+
+
+
+
+ ip
+ UART interrupt pending
+ 0x14
+
+
+ txwm
+ Transmit watermark interrupt pending
+ [0:0]
+ read-only
+
+
+ rxwm
+ Receive watermark interrupt pending
+ [1:1]
+ read-only
+
+
+
+
+ div
+ Baud rate divisor
+ 0x18
+
+
+ div
+ Baud rate divisor.
+ [15:0]
+ read-write
+
+
+
+
+
+
+ sifive_spi0_0
+ From sifive,spi0,control peripheral generator
+ 0x10014000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ sckdiv
+ Serial clock divisor
+ 0x0
+
+
+ div
+ Divisor for serial clock.
+ [11:0]
+ read-write
+
+
+
+
+ sckmode
+ Serial clock mode
+ 0x4
+
+
+ pha
+ Serial clock phase
+ [0:0]
+ read-write
+
+
+ pol
+ Serial clock polarity
+ [1:1]
+ read-write
+
+
+
+
+ csid
+ Chip select ID
+ 0x10
+
+
+ csid
+ Chip select ID.
+ [31:0]
+ read-write
+
+
+
+
+ csdef
+ Chip select default
+ 0x14
+
+
+ csdef
+ Chip select default value. Reset to all-1s.
+ [31:0]
+ read-write
+
+
+
+
+ csmode
+ Chip select mode
+ 0x18
+
+
+ mode
+ Chip select mode
+ [1:0]
+ read-write
+
+
+
+
+ delay0
+ Delay control 0
+ 0x28
+
+
+ cssck
+ CS to SCK Delay
+ [7:0]
+ read-write
+
+
+ sckcs
+ SCK to CS Delay
+ [23:16]
+ read-write
+
+
+
+
+ delay1
+ Delay control 1
+ 0x2C
+
+
+ intercs
+ Minimum CS inactive time
+ [7:0]
+ read-write
+
+
+ interxfr
+ Maximum interframe delay
+ [23:16]
+ read-write
+
+
+
+
+ extradel
+ SPI extra sampling delay to increase the SPI frequency
+ 0x38
+
+
+ coarse
+ Coarse grain sample delay (multiples of system clocks)
+ [11:0]
+ read-write
+
+
+ fine
+ Fine grain sample delay (multiples of process-specific buffer delay)
+ [16:12]
+ read-write
+
+
+
+
+ sampledel
+ Number of delay stages from slave to the SPI controller
+ 0x3C
+
+
+ sd
+ Number of delay stages from slave to SPI controller
+ [4:0]
+ read-write
+
+
+
+
+ fmt
+ Frame format
+ 0x40
+
+
+ proto
+ SPI protocol
+ [1:0]
+ read-write
+
+
+ endian
+ SPI endianness
+ [2:2]
+ read-write
+
+
+ dir
+ SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.
+ [3:3]
+ read-write
+
+
+ len
+ Number of bits per frame
+ [19:16]
+ read-write
+
+
+
+
+ txdata
+ Tx FIFO Data
+ 0x48
+
+
+ data
+ Transmit data
+ [7:0]
+ read-write
+
+
+ full
+ FIFO full flag
+ [31:31]
+ read-only
+
+
+
+
+ rxdata
+ Rx FIFO data
+ 0x4C
+
+
+ data
+ Received data
+ [7:0]
+ read-only
+
+
+ empty
+ FIFO empty flag
+ [31:31]
+ read-write
+
+
+
+
+ txmark
+ Tx FIFO watermark
+ 0x50
+
+
+ txmark
+ Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.
+ [2:0]
+ read-write
+
+
+
+
+ rxmark
+ Rx FIFO watermark
+ 0x54
+
+
+ rxmark
+ Receive watermark
+ [2:0]
+ read-write
+
+
+
+
+ fctrl
+ SPI flash interface control
+ 0x60
+
+
+ en
+ SPI Flash Mode Select
+ [0:0]
+ read-write
+
+
+
+
+ ffmt
+ SPI flash instruction format
+ 0x64
+
+
+ cmd_en
+ Enable sending of command
+ [0:0]
+ read-write
+
+
+ addr_len
+ Number of address bytes (0 to 4)
+ [3:1]
+ read-write
+
+
+ pad_cnt
+ Number of dummy cycles
+ [7:4]
+ read-write
+
+
+ cmd_proto
+ Protocol for transmitting command
+ [9:8]
+ read-write
+
+
+ addr_proto
+ Protocol for transmitting address and padding
+ [11:10]
+ read-write
+
+
+ data_proto
+ Protocol for receiving data bytes
+ [13:12]
+ read-write
+
+
+ cmd_code
+ Value of command byte
+ [23:16]
+ read-write
+
+
+ pad_code
+ First 8 bits to transmit during dummy cycles
+ [31:24]
+ read-write
+
+
+
+
+ ie
+ SPI interrupt enable
+ 0x70
+
+
+ txwm
+ Transmit watermark enable
+ [0:0]
+ read-write
+
+
+ rxwm
+ Receive watermark enable
+ [1:1]
+ read-write
+
+
+
+
+ ip
+ SPI interrupt pending
+ 0x74
+
+
+ txwm
+ Transmit watermark pending
+ [0:0]
+ read-only
+
+
+ rxwm
+ Receive watermark pending
+ [1:1]
+ read-only
+
+
+
+
+
+
+ sifive_pwm0_0
+ From sifive,pwm0,control peripheral generator
+ 0x10015000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ pwmcfg
+ PWM configuration register
+ 0x0
+
+
+ pwmscale
+ PWM Counter scale
+ [3:0]
+ read-write
+
+
+ pwmsticky
+ PWM Sticky - disallow clearing pwmcmpXip bits
+ [8:8]
+ read-write
+
+
+ pwmzerocmp
+ PWM Zero - counter resets to zero after match
+ [9:9]
+ read-write
+
+
+ pwmdeglitch
+ PWM Deglitch - latch pwmcmpXip within same cycle
+ [10:10]
+ read-write
+
+
+ pwmenalways
+ PWM enable always - run continuously
+ [12:12]
+ read-write
+
+
+ pwmenoneshot
+ PWM enable one shot - run one cycle
+ [13:13]
+ read-write
+
+
+ pwmcmp0center
+ PWM0 Compare Center
+ [16:16]
+ read-write
+
+
+ pwmcmp1center
+ PWM1 Compare Center
+ [17:17]
+ read-write
+
+
+ pwmcmp2center
+ PWM2 Compare Center
+ [18:18]
+ read-write
+
+
+ pwmcmp3center
+ PWM3 Compare Center
+ [19:19]
+ read-write
+
+
+ pwmcmp0invert
+ PWM0 Invert
+ [20:20]
+ read-write
+
+
+ pwmcmp1invert
+ PWM1 Invert
+ [21:21]
+ read-write
+
+
+ pwmcmp2invert
+ PWM2 Invert
+ [22:22]
+ read-write
+
+
+ pwmcmp3invert
+ PWM3 Invert
+ [23:23]
+ read-write
+
+
+ pwmcmp0gang
+ PWM0/PWM1 Compare Gang
+ [24:24]
+ read-write
+
+
+ pwmcmp1gang
+ PWM1/PWM2 Compare Gang
+ [25:25]
+ read-write
+
+
+ pwmcmp2gang
+ PWM2/PWM3 Compare Gang
+ [26:26]
+ read-write
+
+
+ pwmcmp3gang
+ PWM3/PWM0 Compare Gang
+ [27:27]
+ read-write
+
+
+ pwmcmp0ip
+ PWM0 Interrupt Pending
+ [28:28]
+ read-write
+
+
+ pwmcmp1ip
+ PWM1 Interrupt Pending
+ [29:29]
+ read-write
+
+
+ pwmcmp2ip
+ PWM2 Interrupt Pending
+ [30:30]
+ read-write
+
+
+ pwmcmp3ip
+ PWM3 Interrupt Pending
+ [31:31]
+ read-write
+
+
+
+
+ pwmcount
+ PWM count register
+ 0x8
+
+
+ pwmcount
+ PWM count register.
+ [30:0]
+ read-write
+
+
+
+
+ pwms
+ Scaled PWM count register
+ 0x10
+
+
+ pwms
+ Scaled PWM count register.
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp0
+ PWM 0 compare register
+ 0x20
+
+
+ pwmcmp0
+ PWM 0 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp1
+ PWM 1 compare register
+ 0x24
+
+
+ pwmcmp1
+ PWM 1 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp2
+ PWM 2 compare register
+ 0x28
+
+
+ pwmcmp2
+ PWM 2 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp3
+ PWM 3 compare register
+ 0x2C
+
+
+ pwmcmp3
+ PWM 3 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+
+
+ sifive_i2c0_0
+ From sifive,i2c0,control peripheral generator
+ 0x10016000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ prescale_low
+ Clock Prescale register lo-byte
+ 0x0
+
+
+ prescale_high
+ Clock Prescale register hi-byte
+ 0x4
+
+
+ control
+ Control register
+ 0x8
+
+
+ en
+ I2C core enable bit
+ [6:6]
+ read-write
+
+
+ ien
+ I2C core interrupt enable bit
+ [7:7]
+ read-write
+
+
+
+
+ transmit__receive
+ Transmit and receive data byte register
+ 0xC
+
+
+ command__status
+ Command write and status read register
+ 0x10
+
+
+ wr_iack__rd_if
+ Clear interrupt and Interrupt pending
+ [0:0]
+ read-write
+
+
+ wr_res__rd_tip
+ Reserved and Transfer in progress
+ [1:1]
+ read-write
+
+
+ wr_res__rd_res
+ Reserved and Reserved
+ [2:2]
+ read-write
+
+
+ wr_ack__rd_res
+ Send ACK/NACK and Reserved
+ [3:3]
+ read-write
+
+
+ wr_txd__rd_res
+ Transmit data and Reserved
+ [4:4]
+ read-write
+
+
+ wr_rxd__rd_al
+ Receive data and Arbitration lost
+ [5:5]
+ read-write
+
+
+ wr_sto__rd_busy
+ Generate stop and I2C bus busy
+ [6:6]
+ read-write
+
+
+ wr_sta__rd_rxack
+ Generate start and Got ACK/NACK
+ [7:7]
+ read-write
+
+
+
+
+
+
+ sifive_uart0_1
+ From sifive,uart0,control peripheral generator
+ 0x10023000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ txdata
+ Transmit data register
+ 0x0
+
+
+ data
+ Transmit data
+ [7:0]
+ read-write
+
+
+ full
+ Transmit FIFO full
+ [31:31]
+ read-only
+
+
+
+
+ rxdata
+ Receive data register
+ 0x4
+
+
+ data
+ Received data
+ [7:0]
+ read-only
+
+
+ empty
+ Receive FIFO empty
+ [31:31]
+ read-only
+
+
+
+
+ txctrl
+ Transmit control register
+ 0x8
+
+
+ txen
+ Transmit enable
+ [0:0]
+ read-write
+
+
+ nstop
+ Number of stop bits
+ [1:1]
+ read-write
+
+
+ txcnt
+ Transmit watermark level
+ [18:16]
+ read-write
+
+
+
+
+ rxctrl
+ Receive control register
+ 0xC
+
+
+ rxen
+ Receive enable
+ [0:0]
+ read-write
+
+
+ rxcnt
+ Receive watermark level
+ [18:16]
+ read-write
+
+
+
+
+ ie
+ UART interrupt enable
+ 0x10
+
+
+ txwm
+ Transmit watermark interrupt enable
+ [0:0]
+ read-write
+
+
+ rxwm
+ Receive watermark interrupt enable
+ [1:1]
+ read-write
+
+
+
+
+ ip
+ UART interrupt pending
+ 0x14
+
+
+ txwm
+ Transmit watermark interrupt pending
+ [0:0]
+ read-only
+
+
+ rxwm
+ Receive watermark interrupt pending
+ [1:1]
+ read-only
+
+
+
+
+ div
+ Baud rate divisor
+ 0x18
+
+
+ div
+ Baud rate divisor.
+ [15:0]
+ read-write
+
+
+
+
+
+
+ sifive_spi0_1
+ From sifive,spi0,control peripheral generator
+ 0x10024000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ sckdiv
+ Serial clock divisor
+ 0x0
+
+
+ div
+ Divisor for serial clock.
+ [11:0]
+ read-write
+
+
+
+
+ sckmode
+ Serial clock mode
+ 0x4
+
+
+ pha
+ Serial clock phase
+ [0:0]
+ read-write
+
+
+ pol
+ Serial clock polarity
+ [1:1]
+ read-write
+
+
+
+
+ csid
+ Chip select ID
+ 0x10
+
+
+ csid
+ Chip select ID.
+ [31:0]
+ read-write
+
+
+
+
+ csdef
+ Chip select default
+ 0x14
+
+
+ csdef
+ Chip select default value. Reset to all-1s.
+ [31:0]
+ read-write
+
+
+
+
+ csmode
+ Chip select mode
+ 0x18
+
+
+ mode
+ Chip select mode
+ [1:0]
+ read-write
+
+
+
+
+ delay0
+ Delay control 0
+ 0x28
+
+
+ cssck
+ CS to SCK Delay
+ [7:0]
+ read-write
+
+
+ sckcs
+ SCK to CS Delay
+ [23:16]
+ read-write
+
+
+
+
+ delay1
+ Delay control 1
+ 0x2C
+
+
+ intercs
+ Minimum CS inactive time
+ [7:0]
+ read-write
+
+
+ interxfr
+ Maximum interframe delay
+ [23:16]
+ read-write
+
+
+
+
+ extradel
+ SPI extra sampling delay to increase the SPI frequency
+ 0x38
+
+
+ coarse
+ Coarse grain sample delay (multiples of system clocks)
+ [11:0]
+ read-write
+
+
+ fine
+ Fine grain sample delay (multiples of process-specific buffer delay)
+ [16:12]
+ read-write
+
+
+
+
+ sampledel
+ Number of delay stages from slave to the SPI controller
+ 0x3C
+
+
+ sd
+ Number of delay stages from slave to SPI controller
+ [4:0]
+ read-write
+
+
+
+
+ fmt
+ Frame format
+ 0x40
+
+
+ proto
+ SPI protocol
+ [1:0]
+ read-write
+
+
+ endian
+ SPI endianness
+ [2:2]
+ read-write
+
+
+ dir
+ SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.
+ [3:3]
+ read-write
+
+
+ len
+ Number of bits per frame
+ [19:16]
+ read-write
+
+
+
+
+ txdata
+ Tx FIFO Data
+ 0x48
+
+
+ data
+ Transmit data
+ [7:0]
+ read-write
+
+
+ full
+ FIFO full flag
+ [31:31]
+ read-only
+
+
+
+
+ rxdata
+ Rx FIFO data
+ 0x4C
+
+
+ data
+ Received data
+ [7:0]
+ read-only
+
+
+ empty
+ FIFO empty flag
+ [31:31]
+ read-write
+
+
+
+
+ txmark
+ Tx FIFO watermark
+ 0x50
+
+
+ txmark
+ Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.
+ [2:0]
+ read-write
+
+
+
+
+ rxmark
+ Rx FIFO watermark
+ 0x54
+
+
+ rxmark
+ Receive watermark
+ [2:0]
+ read-write
+
+
+
+
+ fctrl
+ SPI flash interface control
+ 0x60
+
+
+ en
+ SPI Flash Mode Select
+ [0:0]
+ read-write
+
+
+
+
+ ffmt
+ SPI flash instruction format
+ 0x64
+
+
+ cmd_en
+ Enable sending of command
+ [0:0]
+ read-write
+
+
+ addr_len
+ Number of address bytes (0 to 4)
+ [3:1]
+ read-write
+
+
+ pad_cnt
+ Number of dummy cycles
+ [7:4]
+ read-write
+
+
+ cmd_proto
+ Protocol for transmitting command
+ [9:8]
+ read-write
+
+
+ addr_proto
+ Protocol for transmitting address and padding
+ [11:10]
+ read-write
+
+
+ data_proto
+ Protocol for receiving data bytes
+ [13:12]
+ read-write
+
+
+ cmd_code
+ Value of command byte
+ [23:16]
+ read-write
+
+
+ pad_code
+ First 8 bits to transmit during dummy cycles
+ [31:24]
+ read-write
+
+
+
+
+ ie
+ SPI interrupt enable
+ 0x70
+
+
+ txwm
+ Transmit watermark enable
+ [0:0]
+ read-write
+
+
+ rxwm
+ Receive watermark enable
+ [1:1]
+ read-write
+
+
+
+
+ ip
+ SPI interrupt pending
+ 0x74
+
+
+ txwm
+ Transmit watermark pending
+ [0:0]
+ read-only
+
+
+ rxwm
+ Receive watermark pending
+ [1:1]
+ read-only
+
+
+
+
+
+
+ sifive_pwm0_1
+ From sifive,pwm0,control peripheral generator
+ 0x10025000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ pwmcfg
+ PWM configuration register
+ 0x0
+
+
+ pwmscale
+ PWM Counter scale
+ [3:0]
+ read-write
+
+
+ pwmsticky
+ PWM Sticky - disallow clearing pwmcmpXip bits
+ [8:8]
+ read-write
+
+
+ pwmzerocmp
+ PWM Zero - counter resets to zero after match
+ [9:9]
+ read-write
+
+
+ pwmdeglitch
+ PWM Deglitch - latch pwmcmpXip within same cycle
+ [10:10]
+ read-write
+
+
+ pwmenalways
+ PWM enable always - run continuously
+ [12:12]
+ read-write
+
+
+ pwmenoneshot
+ PWM enable one shot - run one cycle
+ [13:13]
+ read-write
+
+
+ pwmcmp0center
+ PWM0 Compare Center
+ [16:16]
+ read-write
+
+
+ pwmcmp1center
+ PWM1 Compare Center
+ [17:17]
+ read-write
+
+
+ pwmcmp2center
+ PWM2 Compare Center
+ [18:18]
+ read-write
+
+
+ pwmcmp3center
+ PWM3 Compare Center
+ [19:19]
+ read-write
+
+
+ pwmcmp0invert
+ PWM0 Invert
+ [20:20]
+ read-write
+
+
+ pwmcmp1invert
+ PWM1 Invert
+ [21:21]
+ read-write
+
+
+ pwmcmp2invert
+ PWM2 Invert
+ [22:22]
+ read-write
+
+
+ pwmcmp3invert
+ PWM3 Invert
+ [23:23]
+ read-write
+
+
+ pwmcmp0gang
+ PWM0/PWM1 Compare Gang
+ [24:24]
+ read-write
+
+
+ pwmcmp1gang
+ PWM1/PWM2 Compare Gang
+ [25:25]
+ read-write
+
+
+ pwmcmp2gang
+ PWM2/PWM3 Compare Gang
+ [26:26]
+ read-write
+
+
+ pwmcmp3gang
+ PWM3/PWM0 Compare Gang
+ [27:27]
+ read-write
+
+
+ pwmcmp0ip
+ PWM0 Interrupt Pending
+ [28:28]
+ read-write
+
+
+ pwmcmp1ip
+ PWM1 Interrupt Pending
+ [29:29]
+ read-write
+
+
+ pwmcmp2ip
+ PWM2 Interrupt Pending
+ [30:30]
+ read-write
+
+
+ pwmcmp3ip
+ PWM3 Interrupt Pending
+ [31:31]
+ read-write
+
+
+
+
+ pwmcount
+ PWM count register
+ 0x8
+
+
+ pwmcount
+ PWM count register.
+ [30:0]
+ read-write
+
+
+
+
+ pwms
+ Scaled PWM count register
+ 0x10
+
+
+ pwms
+ Scaled PWM count register.
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp0
+ PWM 0 compare register
+ 0x20
+
+
+ pwmcmp0
+ PWM 0 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp1
+ PWM 1 compare register
+ 0x24
+
+
+ pwmcmp1
+ PWM 1 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp2
+ PWM 2 compare register
+ 0x28
+
+
+ pwmcmp2
+ PWM 2 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp3
+ PWM 3 compare register
+ 0x2C
+
+
+ pwmcmp3
+ PWM 3 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+
+
+ sifive_spi0_2
+ From sifive,spi0,control peripheral generator
+ 0x10034000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ sckdiv
+ Serial clock divisor
+ 0x0
+
+
+ div
+ Divisor for serial clock.
+ [11:0]
+ read-write
+
+
+
+
+ sckmode
+ Serial clock mode
+ 0x4
+
+
+ pha
+ Serial clock phase
+ [0:0]
+ read-write
+
+
+ pol
+ Serial clock polarity
+ [1:1]
+ read-write
+
+
+
+
+ csid
+ Chip select ID
+ 0x10
+
+
+ csid
+ Chip select ID.
+ [31:0]
+ read-write
+
+
+
+
+ csdef
+ Chip select default
+ 0x14
+
+
+ csdef
+ Chip select default value. Reset to all-1s.
+ [31:0]
+ read-write
+
+
+
+
+ csmode
+ Chip select mode
+ 0x18
+
+
+ mode
+ Chip select mode
+ [1:0]
+ read-write
+
+
+
+
+ delay0
+ Delay control 0
+ 0x28
+
+
+ cssck
+ CS to SCK Delay
+ [7:0]
+ read-write
+
+
+ sckcs
+ SCK to CS Delay
+ [23:16]
+ read-write
+
+
+
+
+ delay1
+ Delay control 1
+ 0x2C
+
+
+ intercs
+ Minimum CS inactive time
+ [7:0]
+ read-write
+
+
+ interxfr
+ Maximum interframe delay
+ [23:16]
+ read-write
+
+
+
+
+ extradel
+ SPI extra sampling delay to increase the SPI frequency
+ 0x38
+
+
+ coarse
+ Coarse grain sample delay (multiples of system clocks)
+ [11:0]
+ read-write
+
+
+ fine
+ Fine grain sample delay (multiples of process-specific buffer delay)
+ [16:12]
+ read-write
+
+
+
+
+ sampledel
+ Number of delay stages from slave to the SPI controller
+ 0x3C
+
+
+ sd
+ Number of delay stages from slave to SPI controller
+ [4:0]
+ read-write
+
+
+
+
+ fmt
+ Frame format
+ 0x40
+
+
+ proto
+ SPI protocol
+ [1:0]
+ read-write
+
+
+ endian
+ SPI endianness
+ [2:2]
+ read-write
+
+
+ dir
+ SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.
+ [3:3]
+ read-write
+
+
+ len
+ Number of bits per frame
+ [19:16]
+ read-write
+
+
+
+
+ txdata
+ Tx FIFO Data
+ 0x48
+
+
+ data
+ Transmit data
+ [7:0]
+ read-write
+
+
+ full
+ FIFO full flag
+ [31:31]
+ read-only
+
+
+
+
+ rxdata
+ Rx FIFO data
+ 0x4C
+
+
+ data
+ Received data
+ [7:0]
+ read-only
+
+
+ empty
+ FIFO empty flag
+ [31:31]
+ read-write
+
+
+
+
+ txmark
+ Tx FIFO watermark
+ 0x50
+
+
+ txmark
+ Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.
+ [2:0]
+ read-write
+
+
+
+
+ rxmark
+ Rx FIFO watermark
+ 0x54
+
+
+ rxmark
+ Receive watermark
+ [2:0]
+ read-write
+
+
+
+
+ fctrl
+ SPI flash interface control
+ 0x60
+
+
+ en
+ SPI Flash Mode Select
+ [0:0]
+ read-write
+
+
+
+
+ ffmt
+ SPI flash instruction format
+ 0x64
+
+
+ cmd_en
+ Enable sending of command
+ [0:0]
+ read-write
+
+
+ addr_len
+ Number of address bytes (0 to 4)
+ [3:1]
+ read-write
+
+
+ pad_cnt
+ Number of dummy cycles
+ [7:4]
+ read-write
+
+
+ cmd_proto
+ Protocol for transmitting command
+ [9:8]
+ read-write
+
+
+ addr_proto
+ Protocol for transmitting address and padding
+ [11:10]
+ read-write
+
+
+ data_proto
+ Protocol for receiving data bytes
+ [13:12]
+ read-write
+
+
+ cmd_code
+ Value of command byte
+ [23:16]
+ read-write
+
+
+ pad_code
+ First 8 bits to transmit during dummy cycles
+ [31:24]
+ read-write
+
+
+
+
+ ie
+ SPI interrupt enable
+ 0x70
+
+
+ txwm
+ Transmit watermark enable
+ [0:0]
+ read-write
+
+
+ rxwm
+ Receive watermark enable
+ [1:1]
+ read-write
+
+
+
+
+ ip
+ SPI interrupt pending
+ 0x74
+
+
+ txwm
+ Transmit watermark pending
+ [0:0]
+ read-only
+
+
+ rxwm
+ Receive watermark pending
+ [1:1]
+ read-only
+
+
+
+
+
+
+ sifive_pwm0_2
+ From sifive,pwm0,control peripheral generator
+ 0x10035000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ pwmcfg
+ PWM configuration register
+ 0x0
+
+
+ pwmscale
+ PWM Counter scale
+ [3:0]
+ read-write
+
+
+ pwmsticky
+ PWM Sticky - disallow clearing pwmcmpXip bits
+ [8:8]
+ read-write
+
+
+ pwmzerocmp
+ PWM Zero - counter resets to zero after match
+ [9:9]
+ read-write
+
+
+ pwmdeglitch
+ PWM Deglitch - latch pwmcmpXip within same cycle
+ [10:10]
+ read-write
+
+
+ pwmenalways
+ PWM enable always - run continuously
+ [12:12]
+ read-write
+
+
+ pwmenoneshot
+ PWM enable one shot - run one cycle
+ [13:13]
+ read-write
+
+
+ pwmcmp0center
+ PWM0 Compare Center
+ [16:16]
+ read-write
+
+
+ pwmcmp1center
+ PWM1 Compare Center
+ [17:17]
+ read-write
+
+
+ pwmcmp2center
+ PWM2 Compare Center
+ [18:18]
+ read-write
+
+
+ pwmcmp3center
+ PWM3 Compare Center
+ [19:19]
+ read-write
+
+
+ pwmcmp0invert
+ PWM0 Invert
+ [20:20]
+ read-write
+
+
+ pwmcmp1invert
+ PWM1 Invert
+ [21:21]
+ read-write
+
+
+ pwmcmp2invert
+ PWM2 Invert
+ [22:22]
+ read-write
+
+
+ pwmcmp3invert
+ PWM3 Invert
+ [23:23]
+ read-write
+
+
+ pwmcmp0gang
+ PWM0/PWM1 Compare Gang
+ [24:24]
+ read-write
+
+
+ pwmcmp1gang
+ PWM1/PWM2 Compare Gang
+ [25:25]
+ read-write
+
+
+ pwmcmp2gang
+ PWM2/PWM3 Compare Gang
+ [26:26]
+ read-write
+
+
+ pwmcmp3gang
+ PWM3/PWM0 Compare Gang
+ [27:27]
+ read-write
+
+
+ pwmcmp0ip
+ PWM0 Interrupt Pending
+ [28:28]
+ read-write
+
+
+ pwmcmp1ip
+ PWM1 Interrupt Pending
+ [29:29]
+ read-write
+
+
+ pwmcmp2ip
+ PWM2 Interrupt Pending
+ [30:30]
+ read-write
+
+
+ pwmcmp3ip
+ PWM3 Interrupt Pending
+ [31:31]
+ read-write
+
+
+
+
+ pwmcount
+ PWM count register
+ 0x8
+
+
+ pwmcount
+ PWM count register.
+ [30:0]
+ read-write
+
+
+
+
+ pwms
+ Scaled PWM count register
+ 0x10
+
+
+ pwms
+ Scaled PWM count register.
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp0
+ PWM 0 compare register
+ 0x20
+
+
+ pwmcmp0
+ PWM 0 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp1
+ PWM 1 compare register
+ 0x24
+
+
+ pwmcmp1
+ PWM 1 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp2
+ PWM 2 compare register
+ 0x28
+
+
+ pwmcmp2
+ PWM 2 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+ pwmcmp3
+ PWM 3 compare register
+ 0x2C
+
+
+ pwmcmp3
+ PWM 3 Compare Value
+ [15:0]
+ read-write
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h
new file mode 100644
index 000000000..32a33abd7
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h
@@ -0,0 +1,259 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__ATOMIC_H
+#define METAL__ATOMIC_H
+
+#include
+
+#include
+
+typedef volatile int32_t metal_atomic_t;
+
+#define METAL_ATOMIC_DECLARE(name) \
+ __attribute((section(".data.atomics"))) metal_atomic_t name
+
+#define _METAL_STORE_AMO_ACCESS_FAULT 7
+
+/* This macro stores the memory address in mtval like a normal store/amo access
+ * fault, triggers a trap, and then if execution returns, returns 0 as an
+ * arbitrary choice */
+#define _METAL_TRAP_AMO_ACCESS(addr) \
+ __asm__("csrw mtval, %[atomic]" ::[atomic] "r"(a)); \
+ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); \
+ return 0;
+
+/*!
+ * @brief Check if the platform supports atomic operations
+ *
+ * @return 1 if atomic operations are supported, 0 if not
+ */
+__inline__ int32_t metal_atomic_available(void) {
+#ifdef __riscv_atomic
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/*!
+ * @brief Atomically increment a metal_atomic_t and return its old value
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to increment
+ * @param increment the amount to increment the value
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_add(metal_atomic_t *a, int32_t increment) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amoadd.w %[old], %[increment], (%[atomic])"
+ : [old] "=r"(old)
+ : [increment] "r"(increment), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically bitwise-AND a metal_atomic_t and return its old value
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to bitwise-AND
+ * @param mask the bitmask to AND
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_and(metal_atomic_t *a, int32_t mask) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amoand.w %[old], %[mask], (%[atomic])"
+ : [old] "=r"(old)
+ : [mask] "r"(mask), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically bitwise-OR a metal_atomic_t and return its old value
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to bitwise-OR
+ * @param mask the bitmask to OR
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_or(metal_atomic_t *a, int32_t mask) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amoor.w %[old], %[mask], (%[atomic])"
+ : [old] "=r"(old)
+ : [mask] "r"(mask), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically swap a metal_atomic_t and return its old value
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to swap
+ * @param new_value the value to store in the metal_atomic_t
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_swap(metal_atomic_t *a, int32_t new_value) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amoswap.w %[old], %[newval], (%[atomic])"
+ : [old] "=r"(old)
+ : [newval] "r"(new_value), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically bitwise-XOR a metal_atomic_t and return its old value
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to bitwise-XOR
+ * @param mask the bitmask to XOR
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_xor(metal_atomic_t *a, int32_t mask) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amoxor.w %[old], %[mask], (%[atomic])"
+ : [old] "=r"(old)
+ : [mask] "r"(mask), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically set the value of a memory location to the greater of
+ * its current value or a value to compare it with.
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to swap
+ * @param compare the value to compare with the value in memory
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_max(metal_atomic_t *a, int32_t compare) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amomax.w %[old], %[compare], (%[atomic])"
+ : [old] "=r"(old)
+ : [compare] "r"(compare), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically set the value of a memory location to the (unsigned)
+ * greater of its current value or a value to compare it with.
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to swap
+ * @param compare the value to compare with the value in memory
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ uint32_t metal_atomic_max_u(metal_atomic_t *a, uint32_t compare) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amomaxu.w %[old], %[compare], (%[atomic])"
+ : [old] "=r"(old)
+ : [compare] "r"(compare), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically set the value of a memory location to the lesser of
+ * its current value or a value to compare it with.
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to swap
+ * @param compare the value to compare with the value in memory
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ int32_t metal_atomic_min(metal_atomic_t *a, int32_t compare) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amomin.w %[old], %[compare], (%[atomic])"
+ : [old] "=r"(old)
+ : [compare] "r"(compare), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+/*!
+ * @brief Atomically set the value of a memory location to the (unsigned) lesser
+ * of its current value or a value to compare it with.
+ *
+ * If atomics are not supported on the platform, this function will trap with
+ * a Store/AMO access fault.
+ *
+ * @param a The pointer to the value to swap
+ * @param compare the value to compare with the value in memory
+ *
+ * @return The previous value of the metal_atomic_t
+ */
+__inline__ uint32_t metal_atomic_min_u(metal_atomic_t *a, uint32_t compare) {
+#ifdef __riscv_atomic
+ int32_t old;
+ __asm__ volatile("amominu.w %[old], %[compare], (%[atomic])"
+ : [old] "=r"(old)
+ : [compare] "r"(compare), [atomic] "r"(a)
+ : "memory");
+ return old;
+#else
+ _METAL_TRAP_AMO_ACCESS(a);
+#endif
+}
+
+#endif /* METAL__ATOMIC_H */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h
index 0c26f435a..bef645967 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h
@@ -15,7 +15,8 @@ struct metal_button;
struct metal_button_vtable {
int (*button_exist)(struct metal_button *button, char *label);
- struct metal_interrupt* (*interrupt_controller)(struct metal_button *button);
+ struct metal_interrupt *(*interrupt_controller)(
+ struct metal_button *button);
int (*get_interrupt_id)(struct metal_button *button);
};
@@ -35,8 +36,7 @@ struct metal_button {
* @param label The DeviceTree label for the button
* @return A handle for the button
*/
-struct metal_button* metal_button_get(char *label);
-
+struct metal_button *metal_button_get(char *label);
/*!
* @brief Get the interrupt controller for a button
@@ -45,8 +45,10 @@ struct metal_button* metal_button_get(char *label);
* @return A pointer to the interrupt controller responsible for handling
* button interrupts.
*/
-inline struct metal_interrupt*
- metal_button_interrupt_controller(struct metal_button *button) { return button->vtable->interrupt_controller(button); }
+__inline__ struct metal_interrupt *
+metal_button_interrupt_controller(struct metal_button *button) {
+ return button->vtable->interrupt_controller(button);
+}
/*!
* @brief Get the interrupt id for a button
@@ -54,6 +56,8 @@ inline struct metal_interrupt*
* @param button The handle for the button
* @return The interrupt id corresponding to a button.
*/
-inline int metal_button_get_interrupt_id(struct metal_button *button) { return button->vtable->get_interrupt_id(button); }
+__inline__ int metal_button_get_interrupt_id(struct metal_button *button) {
+ return button->vtable->get_interrupt_id(button);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h
index a8a60ada6..673a8b13e 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h
@@ -1,4 +1,4 @@
-/* Copyright 2018 SiFive, Inc */
+/* Copyright 2020 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */
#ifndef METAL__CACHE_H
@@ -9,40 +9,58 @@
*
* @brief API for configuring caches
*/
-
-struct metal_cache;
-
-struct __metal_cache_vtable {
- void (*init)(struct metal_cache *cache, int ways);
- int (*get_enabled_ways)(struct metal_cache *cache);
- int (*set_enabled_ways)(struct metal_cache *cache, int ways);
-};
+#include
/*!
* @brief a handle for a cache
+ * Note: To be deprecated in next release.
*/
struct metal_cache {
- const struct __metal_cache_vtable *vtable;
+ uint8_t __no_empty_structs;
};
+/*!
+ * @brief Initialize L2 cache controller.
+ * Enables all available cache ways.
+ * @param None
+ * @return 0 If no error
+ */
+int metal_l2cache_init(void);
+
+/*!
+ * @brief Get the current number of enabled L2 cache ways
+ * @param None
+ * @return The current number of enabled L2 cache ways
+ */
+int metal_l2cache_get_enabled_ways(void);
+
+/*!
+ * @brief Enable the requested number of L2 cache ways
+ * @param ways Number of ways to enable
+ * @return 0 if the ways are successfully enabled
+ */
+int metal_l2cache_set_enabled_ways(int ways);
+
/*!
* @brief Initialize a cache
* @param cache The handle for the cache to initialize
* @param ways The number of ways to enable
*
* Initializes a cache with the requested number of ways enabled.
+ * Note: API to be deprecated in next release.
*/
-inline void metal_cache_init(struct metal_cache *cache, int ways) {
- return cache->vtable->init(cache, ways);
+__inline__ void metal_cache_init(struct metal_cache *cache, int ways) {
+ metal_l2cache_init();
}
/*!
* @brief Get the current number of enabled cache ways
* @param cache The handle for the cache
* @return The current number of enabled cache ways
+ * Note: API to be deprecated in next release.
*/
-inline int metal_cache_get_enabled_ways(struct metal_cache *cache) {
- return cache->vtable->get_enabled_ways(cache);
+__inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) {
+ return metal_l2cache_get_enabled_ways();
}
/*!
@@ -50,9 +68,41 @@ inline int metal_cache_get_enabled_ways(struct metal_cache *cache) {
* @param cache The handle for the cache
* @param ways The number of ways to enabled
* @return 0 if the ways are successfully enabled
+ * Note: API to be deprecated in next release.
*/
-inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) {
- return cache->vtable->set_enabled_ways(cache, ways);
+__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache,
+ int ways) {
+ return metal_l2cache_set_enabled_ways(ways);
}
+/*!
+ * @brief Check if dcache is supported on the core
+ * @param hartid The core to check
+ * @return 1 if dcache is present
+ */
+int metal_dcache_l1_available(int hartid);
+
+/*!
+ * @brief Flush dcache for L1 on the requested core with write back
+ * @param hartid The core to flush
+ * @param address The virtual address of cacheline to invalidate
+ * @return None
+ */
+void metal_dcache_l1_flush(int hartid, uintptr_t address);
+
+/*!
+ * @brief Discard dcache for L1 on the requested core with no write back
+ * @param hartid The core to discard
+ * @param address The virtual address of cacheline to invalidate
+ * @return None
+ */
+void metal_dcache_l1_discard(int hartid, uintptr_t address);
+
+/*!
+ * @brief Check if icache is supported on the core
+ * @param hartid The core to check
+ * @return 1 if icache is present
+ */
+int metal_icache_l1_available(int hartid);
+
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h
index 277841e01..cfe29f6b7 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h
@@ -4,11 +4,12 @@
#ifndef METAL__CLOCK_H
#define METAL__CLOCK_H
-/*!
+/*!
* @file clock.h
* @brief API for manipulating clock sources
*
- * The clock interface allows for controlling the rate of various clocks in the system.
+ * The clock interface allows for controlling the rate of various clocks in the
+ * system.
*/
struct metal_clock;
@@ -22,37 +23,82 @@ struct __metal_clock_vtable {
};
/*!
- * @brief Function signature of clock pre-rate change callbacks
+ * @brief Function signature of clock rate change callbacks
*/
-typedef void (*metal_clock_pre_rate_change_callback)(void *priv);
+typedef void (*metal_clock_rate_change_callback)(void *priv);
+
+struct _metal_clock_callback_t;
+struct _metal_clock_callback_t {
+ /* The callback function */
+ metal_clock_rate_change_callback callback;
+
+ /* Private data for the callback function */
+ void *priv;
+
+ struct _metal_clock_callback_t *_next;
+};
/*!
- * @brief Function signature of clock post-rate change callbacks
+ * @brief Type for the linked list of callbacks for clock rate changes
*/
-typedef void (*metal_clock_post_rate_change_callback)(void *priv);
+typedef struct _metal_clock_callback_t metal_clock_callback;
+
+/*!
+ * @brief Call all callbacks in the linked list, if any are registered
+ */
+__inline__ void
+_metal_clock_call_all_callbacks(const metal_clock_callback *const list) {
+ const metal_clock_callback *current = list;
+ while (current) {
+ current->callback(current->priv);
+ current = current->_next;
+ }
+}
+
+/*!
+ * @brief Append a callback to the linked list and return the head of the list
+ */
+__inline__ metal_clock_callback *
+_metal_clock_append_to_callbacks(metal_clock_callback *list,
+ metal_clock_callback *const cb) {
+ cb->_next = NULL;
+
+ if (!list) {
+ return cb;
+ }
+
+ metal_clock_callback *current = list;
+
+ while ((current->_next) != NULL) {
+ current = current->_next;
+ }
+
+ current->_next = cb;
+
+ return list;
+}
/*!
* @struct metal_clock
* @brief The handle for a clock
*
- * Clocks are defined as a pointer to a `struct metal_clock`, the contents of which
- * are implementation defined. Users of the clock interface must call functions
- * which accept a `struct metal_clock *` as an argument to interract with the clock.
+ * Clocks are defined as a pointer to a `struct metal_clock`, the contents of
+ * which are implementation defined. Users of the clock interface must call
+ * functions which accept a `struct metal_clock *` as an argument to interract
+ * with the clock.
*
- * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has been
- * defined, making it impossible to call any of these functions without invoking
- * implementation-defined behavior.
+ * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has
+ * been defined, making it impossible to call any of these functions without
+ * invoking implementation-defined behavior.
*/
struct metal_clock {
const struct __metal_clock_vtable *vtable;
- /* Pre-rate change callback */
- metal_clock_pre_rate_change_callback _pre_rate_change_callback;
- void *_pre_rate_change_callback_priv;
+ /* Pre-rate change callback linked list */
+ metal_clock_callback *_pre_rate_change_callback;
- /* Post-rate change callback */
- metal_clock_post_rate_change_callback _post_rate_change_callback;
- void *_post_rate_change_callback_priv;
+ /* Post-rate change callback linked list */
+ metal_clock_callback *_post_rate_change_callback;
};
/*!
@@ -61,7 +107,9 @@ struct metal_clock {
* @param clk The handle for the clock
* @return The current rate of the clock in Hz
*/
-inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk->vtable->get_rate_hz(clk); }
+__inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk) {
+ return clk->vtable->get_rate_hz(clk);
+}
/*!
* @brief Set the current rate of a clock
@@ -74,18 +122,15 @@ inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk-
* to the given rate in Hz. Returns the actual value that's been selected, which
* could be anything!
*
- * Prior to and after the rate change of the clock, this will call the registered
- * pre- and post-rate change callbacks.
+ * Prior to and after the rate change of the clock, this will call the
+ * registered pre- and post-rate change callbacks.
*/
-inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz)
-{
- if(clk->_pre_rate_change_callback != NULL)
- clk->_pre_rate_change_callback(clk->_pre_rate_change_callback_priv);
+__inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) {
+ _metal_clock_call_all_callbacks(clk->_pre_rate_change_callback);
long out = clk->vtable->set_rate_hz(clk, hz);
- if (clk->_post_rate_change_callback != NULL)
- clk->_post_rate_change_callback(clk->_post_rate_change_callback_priv);
+ _metal_clock_call_all_callbacks(clk->_post_rate_change_callback);
return out;
}
@@ -95,12 +140,12 @@ inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz)
*
* @param clk The handle for the clock
* @param cb The callback to be registered
- * @param priv Private data for the callback handler
*/
-inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_pre_rate_change_callback cb, void *priv)
-{
- clk->_pre_rate_change_callback = cb;
- clk->_pre_rate_change_callback_priv = priv;
+__inline__ void
+metal_clock_register_pre_rate_change_callback(struct metal_clock *clk,
+ metal_clock_callback *cb) {
+ clk->_pre_rate_change_callback =
+ _metal_clock_append_to_callbacks(clk->_pre_rate_change_callback, cb);
}
/*!
@@ -108,12 +153,12 @@ inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *cl
*
* @param clk The handle for the clock
* @param cb The callback to be registered
- * @param priv Private data for the callback handler
*/
-inline void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_post_rate_change_callback cb, void *priv)
-{
- clk->_post_rate_change_callback = cb;
- clk->_post_rate_change_callback_priv = priv;
+__inline__ void
+metal_clock_register_post_rate_change_callback(struct metal_clock *clk,
+ metal_clock_callback *cb) {
+ clk->_post_rate_change_callback =
+ _metal_clock_append_to_callbacks(clk->_post_rate_change_callback, cb);
}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h
index 62c0ea975..80ca5fee4 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h
@@ -4,18 +4,19 @@
#ifndef METAL__COMPILER_H
#define METAL__COMPILER_H
-#define __METAL_DECLARE_VTABLE(type) \
- extern const struct type type;
+#define __METAL_DECLARE_VTABLE(type) extern const struct type type;
-#define __METAL_DEFINE_VTABLE(type) \
- const struct type type
+#define __METAL_DEFINE_VTABLE(type) const struct type type
-#define __METAL_GET_FIELD(reg, mask) \
+#define __METAL_GET_FIELD(reg, mask) \
(((reg) & (mask)) / ((mask) & ~((mask) << 1)))
/* Set field with mask for a given value */
-#define __METAL_SET_FIELD(reg, mask, val) \
- (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
+#define __METAL_SET_FIELD(reg, mask, val) \
+ (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
+
+#define __METAL_MIN(a, b) ((a) < (b) ? (a) : (b))
+#define __METAL_MAX(a, b) ((a) > (b) ? (a) : (b))
void _metal_trap(int ecode);
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h
index 453bd12de..98d7e6680 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h
@@ -9,33 +9,35 @@
#ifndef METAL__CPU_H
#define METAL__CPU_H
-#include
#include
+#include
struct metal_cpu;
/*!
* @brief Function signature for exception handlers
*/
-typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode);
+typedef void (*metal_exception_handler_t)(struct metal_cpu *cpu, int ecode);
struct metal_cpu_vtable {
- unsigned long long (*timer_get)(struct metal_cpu *cpu);
+ unsigned long long (*mcycle_get)(struct metal_cpu *cpu);
unsigned long long (*timebase_get)(struct metal_cpu *cpu);
unsigned long long (*mtime_get)(struct metal_cpu *cpu);
int (*mtimecmp_set)(struct metal_cpu *cpu, unsigned long long time);
- struct metal_interrupt* (*tmr_controller_interrupt)(struct metal_cpu *cpu);
+ struct metal_interrupt *(*tmr_controller_interrupt)(struct metal_cpu *cpu);
int (*get_tmr_interrupt_id)(struct metal_cpu *cpu);
- struct metal_interrupt* (*sw_controller_interrupt)(struct metal_cpu *cpu);
+ struct metal_interrupt *(*sw_controller_interrupt)(struct metal_cpu *cpu);
int (*get_sw_interrupt_id)(struct metal_cpu *cpu);
int (*set_sw_ipi)(struct metal_cpu *cpu, int hartid);
int (*clear_sw_ipi)(struct metal_cpu *cpu, int hartid);
int (*get_msip)(struct metal_cpu *cpu, int hartid);
- struct metal_interrupt* (*controller_interrupt)(struct metal_cpu *cpu);
- int (*exception_register)(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler);
+ struct metal_interrupt *(*controller_interrupt)(struct metal_cpu *cpu);
+ int (*exception_register)(struct metal_cpu *cpu, int ecode,
+ metal_exception_handler_t handler);
int (*get_ilen)(struct metal_cpu *cpu, uintptr_t epc);
uintptr_t (*get_epc)(struct metal_cpu *cpu);
int (*set_epc)(struct metal_cpu *cpu, uintptr_t epc);
+ struct metal_buserror *(*get_buserror)(struct metal_cpu *cpu);
};
/*! @brief A device handle for a CPU hart
@@ -49,17 +51,17 @@ struct metal_cpu {
* @param hartid The ID of the desired CPU hart
* @return A pointer to the CPU device handle
*/
-struct metal_cpu* metal_cpu_get(int hartid);
+struct metal_cpu *metal_cpu_get(unsigned int hartid);
/*! @brief Get the hartid of the CPU hart executing this function
*
* @return The hartid of the current CPU hart */
-int metal_cpu_get_current_hartid();
+int metal_cpu_get_current_hartid(void);
/*! @brief Get the number of CPU harts
- *
+ *
* @return The number of CPU harts */
-int metal_cpu_get_num_harts();
+int metal_cpu_get_num_harts(void);
/*! @brief Get the CPU cycle count timer value
*
@@ -68,8 +70,9 @@ int metal_cpu_get_num_harts();
* @param cpu The CPU device handle
* @return The value of the CPU cycle count timer
*/
-inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu)
-{ return cpu->vtable->timer_get(cpu); }
+__inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) {
+ return cpu->vtable->mcycle_get(cpu);
+}
/*! @brief Get the timebase of the CPU
*
@@ -78,8 +81,9 @@ inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu)
* @param cpu The CPU device handle
* @return The value of the cycle count timer timebase
*/
-inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu)
-{ return cpu->vtable->timebase_get(cpu); }
+__inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) {
+ return cpu->vtable->timebase_get(cpu);
+}
/*! @brief Get the value of the mtime RTC
*
@@ -90,8 +94,9 @@ inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu)
* @param cpu The CPU device handle
* @return The value of mtime, or 0 if failure
*/
-inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu)
-{ return cpu->vtable->mtime_get(cpu); }
+__inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) {
+ return cpu->vtable->mtime_get(cpu);
+}
/*! @brief Set the value of the RTC mtimecmp RTC
*
@@ -103,20 +108,24 @@ inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu)
* @param time The value to set the compare register to
* @return The value of mtimecmp or -1 if error
*/
-inline int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time)
-{ return cpu->vtable->mtimecmp_set(cpu, time); }
+__inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu,
+ unsigned long long time) {
+ return cpu->vtable->mtimecmp_set(cpu, time);
+}
/*! @brief Get a reference to RTC timer interrupt controller
*
- * Get a reference to the interrupt controller for the real-time clock interrupt.
- * The controller returned by this function must be initialized before any interrupts
- * are registered or enabled with it.
+ * Get a reference to the interrupt controller for the real-time clock
+ * interrupt. The controller returned by this function must be initialized
+ * before any interrupts are registered or enabled with it.
*
* @param cpu The CPU device handle
* @return A pointer to the timer interrupt handle
*/
-inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu)
-{ return cpu->vtable->tmr_controller_interrupt(cpu); }
+__inline__ struct metal_interrupt *
+metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu) {
+ return cpu->vtable->tmr_controller_interrupt(cpu);
+}
/*! @brief Get the RTC timer interrupt id
*
@@ -125,20 +134,23 @@ inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal
* @param cpu The CPU device handle
* @return The timer interrupt ID
*/
-inline int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu)
-{ return cpu->vtable->get_tmr_interrupt_id(cpu); }
+__inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu) {
+ return cpu->vtable->get_tmr_interrupt_id(cpu);
+}
/*! @brief Get a reference to the software interrupt controller
*
* Get a reference to the interrupt controller for the software/inter-process
- * interrupt. The controller returned by this function must be initialized before
- * any interrupts are registered or enabled with it.
+ * interrupt. The controller returned by this function must be initialized
+ * before any interrupts are registered or enabled with it.
*
* @param cpu The CPU device handle
* @return A pointer to the software interrupt handle
*/
-inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu)
-{ return cpu->vtable->sw_controller_interrupt(cpu); }
+__inline__ struct metal_interrupt *
+metal_cpu_software_interrupt_controller(struct metal_cpu *cpu) {
+ return cpu->vtable->sw_controller_interrupt(cpu);
+}
/*! @brief Get the software interrupt id
*
@@ -147,8 +159,9 @@ inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct me
* @param cpu The CPU device handle
* @return the software interrupt ID
*/
-inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu)
-{ return cpu->vtable->get_sw_interrupt_id(cpu); }
+__inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) {
+ return cpu->vtable->get_sw_interrupt_id(cpu);
+}
/*!
* @brief Set the inter-process interrupt for a hart
@@ -161,8 +174,9 @@ inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu)
* @param hartid The CPU hart ID to be interrupted
* @return 0 upon success
*/
-inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid)
-{ return cpu->vtable->set_sw_ipi(cpu, hartid); }
+__inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) {
+ return cpu->vtable->set_sw_ipi(cpu, hartid);
+}
/*!
* @brief Clear the inter-process interrupt for a hart
@@ -175,8 +189,9 @@ inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid)
* @param hartid The CPU hart ID to clear
* @return 0 upon success
*/
-inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid)
-{ return cpu->vtable->clear_sw_ipi(cpu, hartid); }
+__inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) {
+ return cpu->vtable->clear_sw_ipi(cpu, hartid);
+}
/*!
* @brief Get the value of MSIP for the given hart
@@ -190,8 +205,9 @@ inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid)
* @param hartid The CPU hart to read
* @return 0 upon success
*/
-inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid)
-{ return cpu->vtable->get_msip(cpu, hartid); }
+__inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) {
+ return cpu->vtable->get_msip(cpu, hartid);
+}
/*!
* @brief Get the interrupt controller for the CPU
@@ -204,22 +220,26 @@ inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid)
* @param cpu The CPU device handle
* @return The handle for the CPU interrupt controller
*/
-inline struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu)
-{ return cpu->vtable->controller_interrupt(cpu); }
+__inline__ struct metal_interrupt *
+metal_cpu_interrupt_controller(struct metal_cpu *cpu) {
+ return cpu->vtable->controller_interrupt(cpu);
+}
/*!
* @brief Register an exception handler
- *
- * Register an exception handler for the CPU. The CPU interrupt controller must be initialized
- * before this function is called.
+ *
+ * Register an exception handler for the CPU. The CPU interrupt controller must
+ * be initialized before this function is called.
*
* @param cpu The CPU device handle
* @param ecode The exception code to register a handler for
* @param handler Callback function for the exception handler
* @return 0 upon success
*/
-inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler)
-{ return cpu->vtable->exception_register(cpu, ecode, handler); }
+__inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode,
+ metal_exception_handler_t handler) {
+ return cpu->vtable->exception_register(cpu, ecode, handler);
+}
/*!
* @brief Get the length of an instruction in bytes
@@ -237,8 +257,10 @@ inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_
* @param epc The address of the instruction to measure
* @return the length of the instruction in bytes
*/
-inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc)
-{ return cpu->vtable->get_ilen(cpu, epc); }
+__inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu,
+ uintptr_t epc) {
+ return cpu->vtable->get_ilen(cpu, epc);
+}
/*!
* @brief Get the program counter of the current exception.
@@ -249,8 +271,9 @@ inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc
* @param cpu The CPU device handle
* @return The value of the program counter at the time of the exception
*/
-inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu)
-{ return cpu->vtable->get_epc(cpu); }
+__inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) {
+ return cpu->vtable->get_epc(cpu);
+}
/*!
* @brief Set the exception program counter
@@ -265,7 +288,20 @@ inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu)
* @param epc The address to set the exception program counter to
* @return 0 upon success
*/
-inline int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc)
-{ return cpu->vtable->set_epc(cpu, epc); }
+__inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu,
+ uintptr_t epc) {
+ return cpu->vtable->set_epc(cpu, epc);
+}
+
+/*!
+ * @brief Get the handle for the hart's bus error unit
+ *
+ * @param cpu The CPU device handle
+ * @return A pointer to the bus error unit handle
+ */
+__inline__ struct metal_buserror *
+metal_cpu_get_buserror(struct metal_cpu *cpu) {
+ return cpu->vtable->get_buserror(cpu);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h
new file mode 100644
index 000000000..8375d8a44
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h
@@ -0,0 +1,32 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__CSR_H
+#define METAL__CSR_H
+
+#include
+#include
+#include
+
+/*!
+ * @file csr.h
+ * @brief A collection of APIs for get and set CSR registers
+ */
+
+/*!
+ * @brief Read a given CSR register without checking validity of CSR offset
+ * @param crs Register label or hex value offset to read from
+ * @param value Variable name of uintprt_t type to get the value
+ */
+#define METAL_CPU_GET_CSR(reg, value) \
+ __asm__ volatile("csrr %0, " #reg : "=r"(value));
+
+/*!
+ * @brief Write to a given CSR register without checking validity of CSR offset
+ * @param crs Register label or hex value offset to write to
+ * @param value Variable name of uintprt_t type to set the value
+ */
+#define METAL_CPU_SET_CSR(reg, value) \
+ __asm__ volatile("csrw " #reg ", %0" : : "r"(value));
+
+#endif // METAL__CSR_H
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h
index 2647c5981..b25f54144 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h
@@ -6,8 +6,8 @@
struct __metal_driver_fixed_clock;
-#include
#include
+#include
struct __metal_driver_vtable_fixed_clock {
struct __metal_clock_vtable clock;
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h
index 936ce8d77..84e4fd580 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h
@@ -6,8 +6,8 @@
struct __metal_driver_fixed_factor_clock;
-#include
#include
+#include
struct __metal_driver_vtable_fixed_factor_clock {
struct __metal_clock_vtable clock;
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h
index 08d571e1c..ceda473e2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h
@@ -21,4 +21,7 @@ struct __metal_driver_riscv_clint0 {
};
#undef __METAL_MACHINE_MACROS
+int __metal_driver_riscv_clint0_command_request(
+ struct metal_interrupt *controller, int command, void *data);
+
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h
index eb1e5b8ca..f3005f01f 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h
@@ -4,148 +4,154 @@
#ifndef METAL__DRIVERS__RISCV_CPU_H
#define METAL__DRIVERS__RISCV_CPU_H
-#include
-#include
#include
+#include
+#include
-#define METAL_MAX_CORES 8
-#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */
-#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */
-#define METAL_DEFAULT_RTC_FREQ 32768
+#define METAL_MAX_CORES 8
+#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */
+#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */
+#define METAL_DEFAULT_RTC_FREQ 32768
-#define METAL_DISABLE 0
-#define METAL_ENABLE 1
+#define METAL_DISABLE 0
+#define METAL_ENABLE 1
-#define METAL_ISA_A_EXTENSIONS 0x0001
-#define METAL_ISA_C_EXTENSIONS 0x0004
-#define METAL_ISA_D_EXTENSIONS 0x0008
-#define METAL_ISA_E_EXTENSIONS 0x0010
-#define METAL_ISA_F_EXTENSIONS 0x0020
-#define METAL_ISA_G_EXTENSIONS 0x0040
-#define METAL_ISA_I_EXTENSIONS 0x0100
-#define METAL_ISA_M_EXTENSIONS 0x1000
-#define METAL_ISA_N_EXTENSIONS 0x2000
-#define METAL_ISA_Q_EXTENSIONS 0x10000
-#define METAL_ISA_S_EXTENSIONS 0x40000
-#define METAL_ISA_U_EXTENSIONS 0x100000
-#define METAL_ISA_V_EXTENSIONS 0x200000
-#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL
-#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL
+#define METAL_ISA_A_EXTENSIONS 0x0001
+#define METAL_ISA_C_EXTENSIONS 0x0004
+#define METAL_ISA_D_EXTENSIONS 0x0008
+#define METAL_ISA_E_EXTENSIONS 0x0010
+#define METAL_ISA_F_EXTENSIONS 0x0020
+#define METAL_ISA_G_EXTENSIONS 0x0040
+#define METAL_ISA_I_EXTENSIONS 0x0100
+#define METAL_ISA_M_EXTENSIONS 0x1000
+#define METAL_ISA_N_EXTENSIONS 0x2000
+#define METAL_ISA_Q_EXTENSIONS 0x10000
+#define METAL_ISA_S_EXTENSIONS 0x40000
+#define METAL_ISA_U_EXTENSIONS 0x100000
+#define METAL_ISA_V_EXTENSIONS 0x200000
+#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL
+#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL
#define METAL_ISA_XL128_EXTENSIONS 0xC000000000000000UL
-#define METAL_MTVEC_DIRECT 0x00
-#define METAL_MTVEC_VECTORED 0x01
-#define METAL_MTVEC_CLIC 0x02
-#define METAL_MTVEC_CLIC_VECTORED 0x03
-#define METAL_MTVEC_CLIC_RESERVED 0x3C
-#define METAL_MTVEC_MASK 0x3F
+#define METAL_MTVEC_DIRECT 0x00
+#define METAL_MTVEC_VECTORED 0x01
+#define METAL_MTVEC_CLIC 0x02
+#define METAL_MTVEC_CLIC_VECTORED 0x03
+#define METAL_MTVEC_CLIC_RESERVED 0x3C
+#define METAL_MTVEC_MASK 0x3F
#if __riscv_xlen == 32
-#define METAL_MCAUSE_INTR 0x80000000UL
-#define METAL_MCAUSE_CAUSE 0x000003FFUL
+#define METAL_MCAUSE_INTR 0x80000000UL
+#define METAL_MCAUSE_CAUSE 0x000003FFUL
#else
-#define METAL_MCAUSE_INTR 0x8000000000000000UL
-#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL
+#define METAL_MCAUSE_INTR 0x8000000000000000UL
+#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL
#endif
-#define METAL_MCAUSE_MINHV 0x40000000UL
-#define METAL_MCAUSE_MPP 0x30000000UL
-#define METAL_MCAUSE_MPIE 0x08000000UL
-#define METAL_MCAUSE_MPIL 0x00FF0000UL
-#define METAL_MSTATUS_MIE 0x00000008UL
-#define METAL_MSTATUS_MPIE 0x00000080UL
-#define METAL_MSTATUS_MPP 0x00001800UL
-#define METAL_MSTATUS_FS_INIT 0x00002000UL
-#define METAL_MSTATUS_FS_CLEAN 0x00004000UL
-#define METAL_MSTATUS_FS_DIRTY 0x00006000UL
-#define METAL_MSTATUS_MPRV 0x00020000UL
-#define METAL_MSTATUS_MXR 0x00080000UL
-#define METAL_MINTSTATUS_MIL 0xFF000000UL
-#define METAL_MINTSTATUS_SIL 0x0000FF00UL
-#define METAL_MINTSTATUS_UIL 0x000000FFUL
+#define METAL_MCAUSE_MINHV 0x40000000UL
+#define METAL_MCAUSE_MPP 0x30000000UL
+#define METAL_MCAUSE_MPIE 0x08000000UL
+#define METAL_MCAUSE_MPIL 0x00FF0000UL
+#define METAL_MSTATUS_MIE 0x00000008UL
+#define METAL_MSTATUS_MPIE 0x00000080UL
+#define METAL_MSTATUS_MPP 0x00001800UL
+#define METAL_MSTATUS_FS_INIT 0x00002000UL
+#define METAL_MSTATUS_FS_CLEAN 0x00004000UL
+#define METAL_MSTATUS_FS_DIRTY 0x00006000UL
+#define METAL_MSTATUS_MPRV 0x00020000UL
+#define METAL_MSTATUS_MXR 0x00080000UL
+#define METAL_MINTSTATUS_MIL 0xFF000000UL
+#define METAL_MINTSTATUS_SIL 0x0000FF00UL
+#define METAL_MINTSTATUS_UIL 0x000000FFUL
-#define METAL_LOCAL_INTR(X) (16 + X)
-#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR)
-#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0)
-#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1)
-#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3)
-#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7)
-#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11)
+#define METAL_LOCAL_INTR(X) (16 + X)
+#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR)
+#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0)
+#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1)
+#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3)
+#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7)
+#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11)
#define METAL_LOCAL_INTR_EXCEPTION(X) (METAL_MCAUSE_INTR + METAL_LOCAL_INTR(X))
-#define METAL_LOCAL_INTR_RESERVE0 1
-#define METAL_LOCAL_INTR_RESERVE1 2
-#define METAL_LOCAL_INTR_RESERVE2 4
-#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */
-#define METAL_LOCAL_INTR_RESERVE4 16
-#define METAL_LOCAL_INTR_RESERVE5 32
-#define METAL_LOCAL_INTR_RESERVE6 64
-#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */
-#define METAL_LOCAL_INTR_RESERVE8 256
-#define METAL_LOCAL_INTR_RESERVE9 512
-#define METAL_LOCAL_INTR_RESERVE10 1024
-#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */
+#define METAL_LOCAL_INTR_RESERVE0 1
+#define METAL_LOCAL_INTR_RESERVE1 2
+#define METAL_LOCAL_INTR_RESERVE2 4
+#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */
+#define METAL_LOCAL_INTR_RESERVE4 16
+#define METAL_LOCAL_INTR_RESERVE5 32
+#define METAL_LOCAL_INTR_RESERVE6 64
+#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */
+#define METAL_LOCAL_INTR_RESERVE8 256
+#define METAL_LOCAL_INTR_RESERVE9 512
+#define METAL_LOCAL_INTR_RESERVE10 1024
+#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */
/* Bit12 to Bit15 are Reserved */
-#define METAL_LOCAL_INTERRUPT(X) (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */
-#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE
+#define METAL_LOCAL_INTERRUPT(X) \
+ (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */
+#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE
+
+#define METAL_INSN_LENGTH_MASK 3
+#define METAL_INSN_NOT_COMPRESSED 3
typedef enum {
- METAL_MACHINE_PRIVILEGE_MODE,
- METAL_SUPERVISOR_PRIVILEGE_MODE,
- METAL_USER_PRIVILEGE_MODE,
+ METAL_MACHINE_PRIVILEGE_MODE,
+ METAL_SUPERVISOR_PRIVILEGE_MODE,
+ METAL_USER_PRIVILEGE_MODE,
} metal_privilege_mode_e;
typedef enum {
- METAL_INTERRUPT_ID_BASE,
- METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3),
- METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7),
- METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11),
- METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)),
- METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)),
- METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)),
- METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)),
- METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)),
- METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)),
- METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)),
- METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)),
- METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)),
- METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)),
- METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)),
- METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)),
- METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)),
- METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)),
- METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)),
- METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)),
- METAL_INTERRUPT_ID_LCMX,
- METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX,
- METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1),
+ METAL_INTERRUPT_ID_BASE,
+ METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3),
+ METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7),
+ METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11),
+ METAL_INTERRUPT_ID_CSW = (METAL_INTERRUPT_ID_BASE + 12),
+ METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)),
+ METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)),
+ METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)),
+ METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)),
+ METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)),
+ METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)),
+ METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)),
+ METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)),
+ METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)),
+ METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)),
+ METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)),
+ METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)),
+ METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)),
+ METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)),
+ METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)),
+ METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)),
+ METAL_INTERRUPT_ID_LCMX,
+ METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX,
+ METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1),
+ METAL_INTERRUPT_ID_BEU = 128,
} metal_interrupt_id_e;
typedef enum {
- METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */
- METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */
- METAL_II_EXCEPTION_CODE, /* Illegal instruction */
- METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */
- METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */
- METAL_LAF_EXCEPTION_CODE, /* Load access fault */
- METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */
- METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */
- METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */
- METAL_R9_EXCEPTION_CODE, /* Reserved */
- METAL_R10_EXCEPTION_CODE, /* Reserved */
- METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */
- METAL_MAX_EXCEPTION_CODE,
+ METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */
+ METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */
+ METAL_II_EXCEPTION_CODE, /* Illegal instruction */
+ METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */
+ METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */
+ METAL_LAF_EXCEPTION_CODE, /* Load access fault */
+ METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */
+ METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */
+ METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */
+ METAL_R9_EXCEPTION_CODE, /* Reserved */
+ METAL_R10_EXCEPTION_CODE, /* Reserved */
+ METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */
+ METAL_MAX_EXCEPTION_CODE,
} metal_exception_code_e;
typedef enum {
- METAL_TIMER_MTIME_GET = 1,
- METAL_SOFTWARE_IPI_CLEAR,
- METAL_SOFTWARE_IPI_SET,
- METAL_SOFTWARE_MSIP_GET,
- METAL_MAX_INTERRUPT_GET,
- METAL_INDEX_INTERRUPT_GET,
+ METAL_TIMER_MTIME_GET = 1,
+ METAL_SOFTWARE_IPI_CLEAR,
+ METAL_SOFTWARE_IPI_SET,
+ METAL_SOFTWARE_MSIP_GET,
+ METAL_MAX_INTERRUPT_GET,
+ METAL_INDEX_INTERRUPT_GET,
} metal_interrup_cmd_e;
typedef struct __metal_interrupt_data {
long long pad : 64;
- metal_interrupt_handler_t handler;
+ metal_interrupt_handler_t handler;
void *sub_int;
void *exint_data;
} __metal_interrupt_data;
@@ -154,30 +160,15 @@ typedef struct __metal_interrupt_data {
uintptr_t __metal_myhart_id(void);
-struct __metal_driver_interrupt_controller_vtable {
- void (*interrupt_init)(struct metal_interrupt *controller);
- int (*interrupt_register)(struct metal_interrupt *controller,
- int id, metal_interrupt_handler_t isr, void *priv_data);
- int (*interrupt_enable)(struct metal_interrupt *controller, int id);
- int (*interrupt_disable)(struct metal_interrupt *controller, int id);
- int (*command_request)(struct metal_interrupt *intr, int cmd, void *data);
-};
-
struct __metal_driver_vtable_riscv_cpu_intc {
- struct metal_interrupt_vtable controller_vtable;
+ struct metal_interrupt_vtable controller_vtable;
};
-
void __metal_interrupt_global_enable(void);
void __metal_interrupt_global_disable(void);
-void __metal_controller_interrupt_vector(metal_vector_mode mode, void *vec_table);
-inline int __metal_controller_interrupt_is_selective_vectored (void)
-{
- uintptr_t val;
-
- asm volatile ("csrr %0, mtvec" : "=r"(val));
- return ((val & METAL_MTVEC_CLIC_VECTORED) == METAL_MTVEC_CLIC);
-}
+metal_vector_mode __metal_controller_interrupt_vector_mode(void);
+void __metal_controller_interrupt_vector(metal_vector_mode mode,
+ void *vec_table);
__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc)
@@ -186,18 +177,20 @@ struct __metal_driver_riscv_cpu_intc {
int init_done;
uintptr_t metal_mtvec_table[METAL_MAX_MI];
__metal_interrupt_data metal_int_table[METAL_MAX_MI];
+ __metal_interrupt_data metal_int_beu;
metal_exception_handler_t metal_exception_table[METAL_MAX_ME];
};
/* CPU driver*/
struct __metal_driver_vtable_cpu {
- struct metal_cpu_vtable cpu_vtable;
+ struct metal_cpu_vtable cpu_vtable;
};
__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu)
struct __metal_driver_cpu {
struct metal_cpu cpu;
+ unsigned int hpm_count; /* Available HPM counters per CPU */
};
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h
index 159ee6d69..fac76fbc3 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h
@@ -7,10 +7,10 @@
#include
#include
-#define METAL_PLIC_SOURCE_MASK 0x1F
-#define METAL_PLIC_SOURCE_SHIFT 5
-#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2
-#define METAL_PLIC_SOURCE_PENDING_SHIFT 0
+#define METAL_PLIC_SOURCE_MASK 0x1F
+#define METAL_PLIC_SOURCE_SHIFT 5
+#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2
+#define METAL_PLIC_SOURCE_PENDING_SHIFT 0
struct __metal_driver_vtable_riscv_plic0 {
struct metal_interrupt_vtable plic_vtable;
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h
new file mode 100644
index 000000000..20972109b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h
@@ -0,0 +1,184 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_BUSERROR0_H
+#define METAL__DRIVERS__SIFIVE_BUSERROR0_H
+
+/*!
+ * @file sifive_buserror0.h
+ *
+ * @brief API for configuring the SiFive Bus Error Unit
+ */
+
+#include
+#include
+#include
+
+/*!
+ * @brief The set of possible events handled by a SiFive Bus Error Unit
+ */
+typedef enum {
+ /*! @brief No event or error has been detected */
+ METAL_BUSERROR_EVENT_NONE = 0,
+
+ /*! @brief A correctable ECC error has occurred in the I$ or ITIM */
+ METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR = (1 << 2),
+ /*! @brief An uncorrectable ECC error has occurred in the I$ or ITIM */
+ METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR = (1 << 3),
+ /*! @brief A TileLink load or store bus error has occurred */
+ METAL_BUSERROR_EVENT_LOAD_STORE_ERROR = (1 << 5),
+ /*! @brief A correctable ECC error has occurred in the D$ or DTIM */
+ METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR = (1 << 6),
+ /*! @brief An uncorrectable ECC error has occurred in the D$ or DTIM */
+ METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR = (1 << 7),
+
+ /*! @brief Used to set/clear all interrupts or query/clear all accrued
+ events */
+ METAL_BUSERROR_EVENT_ALL =
+ METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR |
+ METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR |
+ METAL_BUSERROR_EVENT_LOAD_STORE_ERROR |
+ METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR |
+ METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR,
+ /*! @brief A synonym of METAL_BUSERROR_EVENT_ALL */
+ METAL_BUSERROR_EVENT_ANY = METAL_BUSERROR_EVENT_ALL,
+
+ /*! @brief A value which is impossible for the bus error unit to report.
+ * Indicates an error has occurred if provided as a return value. */
+ METAL_BUSERROR_EVENT_INVALID = (1 << 8),
+} metal_buserror_event_t;
+
+/*!
+ * @brief The handle for a bus error unit
+ */
+struct metal_buserror {
+ uint8_t __no_empty_structs;
+};
+
+/*!
+ * @brief Enable bus error events
+ *
+ * Enabling bus error events causes them to be registered as accrued and,
+ * if the corresponding interrupt is inabled, trigger interrupts.
+ *
+ * @param beu The bus error unit handle
+ * @param events A mask of error events to enable
+ * @param enabled True if the mask should be enabled, false if they should be
+ * disabled
+ * @return 0 upon success
+ */
+int metal_buserror_set_event_enabled(struct metal_buserror *beu,
+ metal_buserror_event_t events,
+ bool enabled);
+
+/*!
+ * @brief Get enabled bus error events
+ * @param beu The bus error unit handle
+ * @return A mask of all enabled events
+ */
+metal_buserror_event_t
+metal_buserror_get_event_enabled(struct metal_buserror *beu);
+
+/*!
+ * @brief Enable or disable the platform interrupt
+ *
+ * @param beu The bus error unit handle
+ * @param event The error event which would trigger the interrupt
+ * @param enabled True if the interrupt should be enabled
+ * @return 0 upon success
+ */
+int metal_buserror_set_platform_interrupt(struct metal_buserror *beu,
+ metal_buserror_event_t events,
+ bool enabled);
+
+/*!
+ * @brief Enable or disable the hart-local interrupt
+ *
+ * @param beu The bus error unit handle
+ * @param event The error event which would trigger the interrupt
+ * @param enabled True if the interrupt should be enabled
+ * @return 0 upon success
+ */
+int metal_buserror_set_local_interrupt(struct metal_buserror *beu,
+ metal_buserror_event_t events,
+ bool enabled);
+
+/*!
+ * @brief Get the error event which caused the most recent interrupt
+ *
+ * This method should be called from within the interrupt handler for the bus
+ * error unit interrupt
+ *
+ * @param beu The bus error unit handle
+ * @return The event which caused the interrupt
+ */
+metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu);
+
+/*!
+ * @brief Clear the cause register for the bus error unit
+ *
+ * This method should be called from within the interrupt handler for the bus
+ * error unit to un-latch the cause register for the next event
+ *
+ * @param beu The bus error unit handle
+ * @return 0 upon success
+ */
+int metal_buserror_clear_cause(struct metal_buserror *beu);
+
+/*!
+ * @brief Get the physical address of the error event
+ *
+ * This method should be called from within the interrupt handler for the bus
+ * error unit.
+ *
+ * @param beu The bus error unit handle
+ * @return The address of the error event
+ */
+uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu);
+
+/*!
+ * @brief Returns true if the event is set in the accrued register
+ *
+ * @param beu The bus error unit handle
+ * @param event The event to query
+ * @return True if the event is set in the accrued register
+ */
+bool metal_buserror_is_event_accrued(struct metal_buserror *beu,
+ metal_buserror_event_t events);
+
+/*!
+ * @brief Clear the given event from the accrued register
+ *
+ * @param beu The bus error unit handle
+ * @param event The event to clear
+ * @return 0 upon success
+ */
+int metal_buserror_clear_event_accrued(struct metal_buserror *beu,
+ metal_buserror_event_t events);
+
+/*!
+ * @brief get the platform-level interrupt parent of the bus error unit
+ *
+ * @param beu The bus error unit handle
+ * @return A pointer to the interrupt parent
+ */
+struct metal_interrupt *
+metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu);
+
+/*!
+ * @brief Get the platform-level interrupt id for the bus error unit interrupt
+ *
+ * @param beu The bus error unit handle
+ * @return The interrupt id
+ */
+int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu);
+
+/*!
+ * @brief Get the hart-local interrupt id for the bus error unit interrupt
+ *
+ * @param beu The bus error unit handle
+ * @return The interrupt id
+ */
+int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h
new file mode 100644
index 000000000..13a47c0b9
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h
@@ -0,0 +1,140 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H
+#define METAL__DRIVERS__SIFIVE_CCACHE0_H
+
+/*!
+ * @file sifive_ccache0.h
+ *
+ * @brief API for configuring the SiFive L2 cache controller
+ */
+
+#include
+#include
+
+/*! @brief Cache configuration data */
+typedef struct {
+ uint32_t num_bank;
+ uint32_t num_ways;
+ uint32_t num_sets;
+ uint32_t block_size;
+} sifive_ccache0_config;
+
+/*! @brief Set of values for ECC error type */
+typedef enum {
+ SIFIVE_CCACHE0_DATA = 0,
+ SIFIVE_CCACHE0_DIR = 1,
+} sifive_ccache0_ecc_errtype_t;
+
+/*! @brief Initialize cache controller, enables all available
+ * cache-ways.
+ * Note: If LIM is in use, corresponding cache ways are not enabled.
+ * @param None.
+ * @return 0 If no error.*/
+int sifive_ccache0_init(void);
+
+/*! @brief Get cache configuration data.
+ * @param config User specified data buffer.
+ * @return None.*/
+void sifive_ccache0_get_config(sifive_ccache0_config *config);
+
+/*! @brief Get currently active cache ways.
+ * @param None.
+ * @return Number of cache ways enabled.*/
+uint32_t sifive_ccache0_get_enabled_ways(void);
+
+/*! @brief Enable specified cache ways.
+ * @param ways Number of ways to be enabled.
+ * @return 0 If no error.*/
+int sifive_ccache0_set_enabled_ways(uint32_t ways);
+
+/*! @brief Inject ECC error into data or meta-data.
+ * @param bitindex Bit index to be corrupted on next cache operation.
+ * @param type ECC error target location.
+ * @return None.*/
+void sifive_ccache0_inject_ecc_error(uint32_t bitindex,
+ sifive_ccache0_ecc_errtype_t type);
+
+/*! @brief Flush out entire cache block containing given address.
+ * @param flush_addr Address for the cache block to be flushed.
+ * @return None.*/
+void sifive_ccache0_flush(uintptr_t flush_addr);
+
+/*! @brief Get most recently ECC corrected address.
+ * @param type ECC error target location.
+ * @return Last corrected ECC address.*/
+uintptr_t sifive_ccache0_get_ecc_fix_addr(sifive_ccache0_ecc_errtype_t type);
+
+/*! @brief Get number of times ECC errors were corrected.
+ * Clears related ECC interrupt signals.
+ * @param type ECC error target location.
+ * @return Corrected ECC error count.*/
+uint32_t sifive_ccache0_get_ecc_fix_count(sifive_ccache0_ecc_errtype_t type);
+
+/*! @brief Get address location of most recent uncorrected ECC error.
+ * @param type ECC error target location.
+ * @return Last uncorrected ECC address.*/
+uintptr_t sifive_ccache0_get_ecc_fail_addr(sifive_ccache0_ecc_errtype_t type);
+
+/*! @brief Get number of times ECC errors were not corrected.
+ * Clears related ECC interrupt signals.
+ * @param type ECC error target location.
+ * @return Uncorrected ECC error count.*/
+uint32_t sifive_ccache0_get_ecc_fail_count(sifive_ccache0_ecc_errtype_t type);
+
+/*! @brief Get currently active way enable mask value for the given master ID.
+ * @param master_id Cache controller master ID.
+ * @return Way enable mask. */
+uint64_t sifive_ccache0_get_way_mask(uint32_t master_id);
+
+/*! @brief Set way enable mask for the given master ID.
+ * @param master_id Cache controller master ID.
+ * @param waymask Specify ways to be enabled.
+ * @return 0 If no error.*/
+int sifive_ccache0_set_way_mask(uint32_t master_id, uint64_t waymask);
+
+/*! @brief Select cache performance events to be counted.
+ * @param counter Cache performance monitor counter index.
+ * @param mask Event selection mask.
+ * @return None.*/
+void sifive_ccache0_set_pmevent_selector(uint32_t counter, uint64_t mask);
+
+/*! @brief Get currently set events for the given counter index.
+ * @param counter Cache performance monitor counter index.
+ * @return Event selection mask.*/
+uint64_t sifive_ccache0_get_pmevent_selector(uint32_t counter);
+
+/*! @brief Clears specified cache performance counter.
+ * @param counter Cache performance monitor counter index.
+ * @return None.*/
+void sifive_ccache0_clr_pmevent_counter(uint32_t counter);
+
+/*! @brief Reads specified cache performance counter.
+ * @param counter Cache performance monitor counter index.
+ * @return Counter value.*/
+uint64_t sifive_ccache0_get_pmevent_counter(uint32_t counter);
+
+/*! @brief Select cache clients to be excluded from performance monitoring.
+ * @param mask Client disable mask.
+ * @return None.*/
+void sifive_ccache0_set_client_filter(uint64_t mask);
+
+/*! @brief Get currently set cache client disable mask.
+ * @param None.
+ * @return Client disable mask.*/
+uint64_t sifive_ccache0_get_client_filter(void);
+
+/*! @brief Get interrupt IDs for the cache controller.
+ * @param src Interrupt trigger source index.
+ * @return Interrupt id.*/
+int sifive_ccache0_get_interrupt_id(uint32_t src);
+
+/*! @brief Get interrupt controller of the cache.
+ * The interrupt controller must be initialized before any interrupts can be
+ * registered or enabled with it.
+ * @param None.
+ * @return Handle for the interrupt controller.*/
+struct metal_interrupt *sifive_ccache0_interrupt_controller(void);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h
index db9674625..b8ff82271 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h
@@ -7,21 +7,21 @@
#include
#include
-#define METAL_CLIC_MAX_NMBITS 2
-#define METAL_CLIC_MAX_NLBITS 8
-#define METAL_CLIC_MAX_NVBITS 1
+#define METAL_CLIC_MAX_NMBITS 2
+#define METAL_CLIC_MAX_NLBITS 8
+#define METAL_CLIC_MAX_NVBITS 1
-#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00
-#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20
-#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40
-#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60
-#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E
-#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40
+#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60
+#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E
+#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01
-#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */
-#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */
+#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */
+#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */
-#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1)
+#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1)
struct __metal_driver_vtable_sifive_clic0 {
struct metal_interrupt_vtable clic_vtable;
@@ -34,9 +34,15 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0)
struct __metal_driver_sifive_clic0 {
struct metal_interrupt controller;
int init_done;
- metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS];
+ struct {
+ } __attribute__((aligned(64)));
+ metal_interrupt_vector_handler_t
+ metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS];
__metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS];
};
#undef __METAL_MACHINE_MACROS
+int __metal_driver_sifive_clic0_command_request(
+ struct metal_interrupt *controller, int command, void *data);
+
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h
index d311f0cf2..d60d3a3bd 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h
@@ -4,9 +4,9 @@
#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H
#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H
-#include
-#include
#include
+#include
+#include
#include
struct __metal_driver_vtable_sifive_fe310_g000_hfrosc {
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h
new file mode 100644
index 000000000..2650584ad
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h
@@ -0,0 +1,21 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H
+#define METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H
+
+#include
+#include
+#include
+
+struct __metal_driver_vtable_sifive_fe310_g000_lfrosc {
+ struct __metal_clock_vtable clock;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc)
+
+struct __metal_driver_sifive_fe310_g000_lfrosc {
+ struct metal_clock clock;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h
index 87c9ca985..4fca30167 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h
@@ -10,14 +10,16 @@
struct __metal_driver_sifive_fe310_g000_prci;
struct __metal_driver_vtable_sifive_fe310_g000_prci {
- long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset);
- long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset, long value);
+ long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *,
+ long offset);
+ long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *,
+ long offset, long value);
};
__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci)
struct __metal_driver_sifive_fe310_g000_prci {
+ const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable;
};
#endif
-
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h
deleted file mode 100644
index 8c3cf907e..000000000
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright 2018 SiFive, Inc */
-/* SPDX-License-Identifier: Apache-2.0 */
-
-#ifndef METAL__DRIVERS__SIFIVE_FU540_C000_L2_H
-#define METAL__DRIVERS__SIFIVE_FU540_C000_L2_H
-
-struct __metal_driver_sifive_fu540_c000_l2;
-
-#include
-#include
-
-struct __metal_driver_vtable_sifive_fu540_c000_l2 {
- struct __metal_cache_vtable cache;
-};
-
-__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2)
-
-struct __metal_driver_sifive_fu540_c000_l2 {
- struct metal_cache cache;
-};
-
-#endif
-
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h
index a0caeaba8..7227eee02 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h
@@ -4,12 +4,12 @@
#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H
#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H
-#include
#include
#include
+#include
struct __metal_driver_vtable_sifive_button {
- struct metal_button_vtable button_vtable;
+ struct metal_button_vtable button_vtable;
};
__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button)
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h
index a8dacf116..abfca01c2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h
@@ -4,12 +4,12 @@
#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H
#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H
+#include
#include
#include
-#include
struct __metal_driver_vtable_sifive_led {
- struct metal_led_vtable led_vtable;
+ struct metal_led_vtable led_vtable;
};
__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led)
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h
index c9c7839e9..be55a0446 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h
@@ -4,12 +4,12 @@
#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H
#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H
+#include
#include
#include
-#include
struct __metal_driver_vtable_sifive_switch {
- struct metal_switch_vtable switch_vtable;
+ struct metal_switch_vtable switch_vtable;
};
__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch)
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h
index cc56dc722..50314222d 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h
@@ -11,7 +11,7 @@ struct __metal_driver_vtable_sifive_gpio0 {
const struct __metal_gpio_vtable gpio;
};
-//struct __metal_driver_sifive_gpio0;
+// struct __metal_driver_sifive_gpio0;
__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0)
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h
new file mode 100644
index 000000000..8fbbe21e1
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h
@@ -0,0 +1,24 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_I2C0_H
+#define METAL__DRIVERS__SIFIVE_I2C0_H
+
+#include
+#include
+
+struct __metal_driver_vtable_sifive_i2c0 {
+ const struct metal_i2c_vtable i2c;
+};
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_i2c0)
+
+struct __metal_driver_sifive_i2c0 {
+ struct metal_i2c i2c;
+ unsigned int init_done;
+ unsigned int baud_rate;
+ metal_clock_callback pre_rate_change_callback;
+ metal_clock_callback post_rate_change_callback;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h
new file mode 100644
index 000000000..63c8e6536
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h
@@ -0,0 +1,78 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_L2PF0_H
+#define METAL__DRIVERS__SIFIVE_L2PF0_H
+
+/*!
+ * @file sifive_l2pf0.h
+ *
+ * @brief API for configuring the SiFive L2 prefetcher.
+ */
+
+#include
+
+/*! @brief L2 prefetcher configuration */
+typedef struct {
+ /* Enable L2 hardware prefetcher */
+ uint8_t HwPrefetchEnable;
+
+ /* Only works when CrossPageEn === 0.
+ Cross Page optimization disable:
+ 0 -> Entry goes into Pause state while crossing Page boundary.
+ Next time when the demand miss happens on the same page, it doesn’t need
+ to train again. 1 -> The entry is invalidated in case of a cross page. */
+ uint8_t CrossPageOptmDisable;
+
+ /* Enable prefetches to cross pages */
+ uint8_t CrossPageEn;
+
+ /* Age-out mechanism enable */
+ uint8_t AgeOutEn;
+
+ uint32_t PrefetchDistance;
+
+ uint32_t MaxAllowedDistance;
+
+ /* Linear to exponential threshold */
+ uint32_t LinToExpThreshold;
+
+ /* No. of non-matching loads to edge out an entry */
+ uint32_t NumLdsToAgeOut;
+
+ /* Threshold no. of Fullness (L2 MSHRs used/ total available) to stop
+ * sending hits */
+ uint32_t QFullnessThreshold;
+
+ /* Threshold no. of CacheHits for evicting SPF entry */
+ uint32_t HitCacheThreshold;
+
+ /* Threshold no. of MSHR hits for increasing SPF distance */
+ uint32_t hitMSHRThreshold;
+
+ /* Size of the comparison window for address matching */
+ uint32_t Window;
+
+} sifive_l2pf0_config;
+
+/*! @brief Enable L2 hardware prefetcher unit.
+ * @param None.
+ * @return None.*/
+void sifive_l2pf0_enable(void);
+
+/*! @brief Disable L2 hardware prefetcher unit.
+ * @param None.
+ * @return None.*/
+void sifive_l2pf0_disable(void);
+
+/*! @brief Get currently active L2 prefetcher configuration.
+ * @param config Pointer to user specified configuration structure.
+ * @return None.*/
+void sifive_l2pf0_get_config(sifive_l2pf0_config *config);
+
+/*! @brief Enables fine grain access to L2 prefetcher configuration.
+ * @param config Pointer to user structure with values to be set.
+ * @return None.*/
+void sifive_l2pf0_set_config(sifive_l2pf0_config *config);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h
index aa8d63078..320ab10d2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h
@@ -18,5 +18,4 @@ struct __metal_driver_sifive_local_external_interrupts0 {
int init_done;
};
-
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h
new file mode 100644
index 000000000..caa774401
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h
@@ -0,0 +1,29 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_PWM0_H
+#define METAL__DRIVERS__SIFIVE_PWM0_H
+
+#include
+#include
+
+struct __metal_driver_vtable_sifive_pwm0 {
+ const struct metal_pwm_vtable pwm;
+};
+
+/* Max possible PWM channel count */
+#define METAL_MAX_PWM_CHANNELS 16
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_pwm0)
+
+struct __metal_driver_sifive_pwm0 {
+ struct metal_pwm pwm;
+ unsigned int max_count;
+ unsigned int count_val;
+ unsigned int freq;
+ unsigned int duty[METAL_MAX_PWM_CHANNELS];
+ metal_clock_callback pre_rate_change_callback;
+ metal_clock_callback post_rate_change_callback;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h
new file mode 100644
index 000000000..a35ab9a09
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h
@@ -0,0 +1,26 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_RTC0_H
+#define METAL__DRIVERS__SIFIVE_RTC0_H
+
+#include
+#include
+
+#include
+#include
+#include
+
+struct __metal_driver_vtable_sifive_rtc0 {
+ const struct metal_rtc_vtable rtc;
+};
+
+struct __metal_driver_sifive_rtc0;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_rtc0)
+
+struct __metal_driver_sifive_rtc0 {
+ const struct metal_rtc rtc;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h
new file mode 100644
index 000000000..f6b739143
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h
@@ -0,0 +1,29 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_SIMUART0_H
+#define METAL__DRIVERS__SIFIVE_SIMUART0_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct __metal_driver_vtable_sifive_simuart0 {
+ const struct metal_uart_vtable uart;
+};
+
+struct __metal_driver_sifive_simuart0;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_simuart0)
+
+struct __metal_driver_sifive_simuart0 {
+ struct metal_uart uart;
+ unsigned long baud_rate;
+ metal_clock_callback pre_rate_change_callback;
+ metal_clock_callback post_rate_change_callback;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h
index 90d4c831e..73527944b 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h
@@ -4,9 +4,9 @@
#ifndef METAL__DRIVERS__SIFIVE_SPI0_H
#define METAL__DRIVERS__SIFIVE_SPI0_H
-#include
#include
#include
+#include
#include
#include
@@ -19,6 +19,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0)
struct __metal_driver_sifive_spi0 {
struct metal_spi spi;
unsigned long baud_rate;
+ metal_clock_callback pre_rate_change_callback;
+ metal_clock_callback post_rate_change_callback;
};
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h
index e87db2c83..debd3fb9d 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h
@@ -17,5 +17,4 @@ struct __metal_driver_sifive_test0 {
struct __metal_shutdown shutdown;
};
-
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h
new file mode 100644
index 000000000..3c67522f4
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h
@@ -0,0 +1,23 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_TRACE_H
+#define METAL__DRIVERS__SIFIVE_TRACE_H
+
+#include
+#include
+#include
+
+struct __metal_driver_vtable_sifive_trace {
+ const struct metal_uart_vtable uart;
+};
+
+struct __metal_driver_sifive_trace;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_trace)
+
+struct __metal_driver_sifive_trace {
+ struct metal_uart uart;
+};
+
+#endif /* METAL__DRIVERS__SIFIVE_TRACE_H */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h
index 11d954002..2b38e4631 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h
@@ -4,12 +4,12 @@
#ifndef METAL__DRIVERS__SIFIVE_UART0_H
#define METAL__DRIVERS__SIFIVE_UART0_H
-#include
-#include
#include
+#include
+#include
+#include
#include
#include
-#include
struct __metal_driver_vtable_sifive_uart0 {
const struct metal_uart_vtable uart;
@@ -22,7 +22,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0)
struct __metal_driver_sifive_uart0 {
struct metal_uart uart;
unsigned long baud_rate;
+ metal_clock_callback pre_rate_change_callback;
+ metal_clock_callback post_rate_change_callback;
};
-
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h
new file mode 100644
index 000000000..bb3424584
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h
@@ -0,0 +1,26 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__SIFIVE_WDOG0_H
+#define METAL__DRIVERS__SIFIVE_WDOG0_H
+
+#include
+#include
+
+#include
+#include
+#include
+
+struct __metal_driver_vtable_sifive_wdog0 {
+ const struct metal_watchdog_vtable watchdog;
+};
+
+struct __metal_driver_sifive_wdog0;
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_wdog0)
+
+struct __metal_driver_sifive_wdog0 {
+ const struct metal_watchdog watchdog;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h
new file mode 100644
index 000000000..210d0819b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h
@@ -0,0 +1,48 @@
+/* Copyright 2018 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__DRIVERS__UCB_HTIF0_H
+#define METAL__DRIVERS__UCB_HTIF0_H
+
+#include
+#include
+#include
+
+struct __metal_driver_vtable_ucb_htif0_shutdown {
+ const struct __metal_shutdown_vtable shutdown;
+};
+
+struct __metal_driver_vtable_ucb_htif0_uart {
+ const struct metal_uart_vtable uart;
+};
+
+struct __metal_driver_ucb_htif0;
+
+void __metal_driver_ucb_htif0_exit(const struct __metal_shutdown *test,
+ int code) __attribute__((noreturn));
+
+void __metal_driver_ucb_htif0_init(struct metal_uart *uart, int baud_rate);
+int __metal_driver_ucb_htif0_putc(struct metal_uart *uart, int c);
+int __metal_driver_ucb_htif0_getc(struct metal_uart *uart, int *c);
+int __metal_driver_ucb_htif0_get_baud_rate(struct metal_uart *guart);
+int __metal_driver_ucb_htif0_set_baud_rate(struct metal_uart *guart,
+ int baud_rate);
+struct metal_interrupt *
+__metal_driver_ucb_htif0_interrupt_controller(struct metal_uart *uart);
+int __metal_driver_ucb_htif0_get_interrupt_id(struct metal_uart *uart);
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_shutdown)
+
+__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_uart)
+
+struct __metal_driver_ucb_htif0_shutdown {
+ struct __metal_shutdown shutdown;
+ const struct __metal_driver_vtable_ucb_htif0_shutdown *vtable;
+};
+
+struct __metal_driver_ucb_htif0_uart {
+ struct metal_uart uart;
+ const struct __metal_driver_vtable_ucb_htif0_uart *vtable;
+};
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h
index 513687dd7..df9adb451 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h
@@ -5,6 +5,7 @@
#define METAL__GPIO_H
#include
+#include
/*!
* @file gpio.h
@@ -15,20 +16,37 @@ struct metal_gpio;
struct __metal_gpio_vtable {
int (*disable_input)(struct metal_gpio *, long pins);
+ int (*enable_input)(struct metal_gpio *, long pins);
+ long (*input)(struct metal_gpio *);
long (*output)(struct metal_gpio *);
+ int (*disable_output)(struct metal_gpio *, long pins);
int (*enable_output)(struct metal_gpio *, long pins);
int (*output_set)(struct metal_gpio *, long value);
int (*output_clear)(struct metal_gpio *, long value);
int (*output_toggle)(struct metal_gpio *, long value);
int (*enable_io)(struct metal_gpio *, long pins, long dest);
+ int (*disable_io)(struct metal_gpio *, long pins);
+ int (*config_int)(struct metal_gpio *, long pins, int intr_type);
+ int (*clear_int)(struct metal_gpio *, long pins, int intr_type);
+ struct metal_interrupt *(*interrupt_controller)(struct metal_gpio *gpio);
+ int (*get_interrupt_id)(struct metal_gpio *gpio, int pin);
};
+#define METAL_GPIO_INT_DISABLE 0
+#define METAL_GPIO_INT_RISING 1
+#define METAL_GPIO_INT_FALLING 2
+#define METAL_GPIO_INT_BOTH_EDGE 3
+#define METAL_GPIO_INT_LOW 4
+#define METAL_GPIO_INT_HIGH 5
+#define METAL_GPIO_INT_BOTH_LEVEL 6
+#define METAL_GPIO_INT_MAX 7
+
/*!
* @struct metal_gpio
* @brief The handle for a GPIO interface
*/
struct metal_gpio {
- const struct __metal_gpio_vtable *vtable;
+ const struct __metal_gpio_vtable *vtable;
};
/*!
@@ -36,7 +54,21 @@ struct metal_gpio {
* @param device_num The GPIO device index
* @return The GPIO device handle, or NULL if there is no device at that index
*/
-struct metal_gpio *metal_gpio_get_device(int device_num);
+struct metal_gpio *metal_gpio_get_device(unsigned int device_num);
+
+/*!
+ * @brief enable input on a pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the input is successfully enabled
+ */
+__inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->enable_input(gpio, (1 << pin));
+}
/*!
* @brief Disable input on a pin
@@ -44,9 +76,9 @@ struct metal_gpio *metal_gpio_get_device(int device_num);
* @param pin The pin number indexed from 0
* @return 0 if the input is successfully disabled
*/
-inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
}
return gpio->vtable->disable_input(gpio, (1 << pin));
@@ -58,14 +90,28 @@ inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
* @param pin The pin number indexed from 0
* @return 0 if the output is successfully enabled
*/
-inline int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
}
return gpio->vtable->enable_output(gpio, (1 << pin));
}
+/*!
+ * @brief Disable output on a pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return 0 if the output is successfully disabled
+ */
+__inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->disable_output(gpio, (1 << pin));
+}
+
/*!
* @brief Set the output value of a GPIO pin
* @param gpio The handle for the GPIO interface
@@ -73,15 +119,15 @@ inline int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
* @param value The value to set the pin to
* @return 0 if the output is successfully set
*/
-inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
+ if (!gpio) {
+ return 1;
}
- if(value == 0) {
- return gpio->vtable->output_clear(gpio, (1 << pin));
+ if (value == 0) {
+ return gpio->vtable->output_clear(gpio, (1 << pin));
} else {
- return gpio->vtable->output_set(gpio, (1 << pin));
+ return gpio->vtable->output_set(gpio, (1 << pin));
}
}
@@ -91,17 +137,37 @@ inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
* @param pin The pin number indexed from 0
* @return The value of the GPIO pin
*/
-inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 0;
+__inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 0;
+ }
+
+ long value = gpio->vtable->input(gpio);
+
+ if (value & (1 << pin)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ * @brief Get the value of the GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The pin number indexed from 0
+ * @return The value of the GPIO pin
+ */
+__inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 0;
}
long value = gpio->vtable->output(gpio);
- if(value & (1 << pin)) {
- return 1;
+ if (value & (1 << pin)) {
+ return 1;
} else {
- return 0;
+ return 0;
}
}
@@ -111,9 +177,9 @@ inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) {
* @param pin The pin number indexed from 0
* @return 0 if the pin is successfully cleared
*/
-inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
}
return gpio->vtable->output_clear(gpio, (1 << pin));
@@ -125,9 +191,9 @@ inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
* @param pin The pin number indexed from 0
* @return 0 if the pin is successfully toggled
*/
-inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
}
return gpio->vtable->output_toggle(gpio, (1 << pin));
@@ -140,12 +206,82 @@ inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
* @param io_function The IO function to set
* @return 0 if the pinmux is successfully set
*/
-inline int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) {
- if(!gpio) {
- return 1;
+__inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin,
+ int io_function) {
+ if (!gpio) {
+ return 1;
}
return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin));
}
+/*!
+ * @brief Disables the pinmux for a GPIO pin
+ * @param gpio The handle for the GPIO interface
+ * @param pin The bitmask for the pin to disable pinmux on
+ * @return 0 if the pinmux is successfully set
+ */
+__inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) {
+ if (!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->disable_io(gpio, (1 << pin));
+}
+
+/*!
+ * @brief Config gpio interrupt type
+ * @param gpio The handle for the GPIO interface
+ * @param pin The bitmask for the pin to enable gpio interrupt
+ * @param intr_type The interrupt type
+ * @return 0 if the interrupt mode is setup properly
+ */
+__inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin,
+ int intr_type) {
+ if (!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->config_int(gpio, (1 << pin), intr_type);
+}
+
+/*!
+ * @brief Clear gpio interrupt status
+ * @param gpio The handle for the GPIO interface
+ * @param pin The bitmask for the pin to clear gpio interrupt
+ * @param intr_type The interrupt type to be clear
+ * @return 0 if the interrupt is cleared
+ */
+__inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin,
+ int intr_type) {
+ if (!gpio) {
+ return 1;
+ }
+
+ return gpio->vtable->clear_int(gpio, (1 << pin), intr_type);
+}
+
+/*!
+ * @brief Get the interrupt controller for a gpio
+ *
+ * @param gpio The handle for the gpio
+ * @return A pointer to the interrupt controller responsible for handling
+ * gpio interrupts.
+ */
+__inline__ struct metal_interrupt *
+metal_gpio_interrupt_controller(struct metal_gpio *gpio) {
+ return gpio->vtable->interrupt_controller(gpio);
+}
+
+/*!
+ * @brief Get the interrupt id for a gpio
+ *
+ * @param gpio The handle for the gpio
+ * @param pin The bitmask for the pin to get gpio interrupt id
+ * @return The interrupt id corresponding to a gpio.
+ */
+__inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) {
+ return gpio->vtable->get_interrupt_id(gpio, pin);
+}
+
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h
new file mode 100644
index 000000000..290f7ec3f
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h
@@ -0,0 +1,146 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__HPM_H
+#define METAL__HPM_H
+
+#include
+
+/*! @brief Macros for valid Event IDs */
+#define METAL_HPM_EVENTID_8 (1UL << 8)
+#define METAL_HPM_EVENTID_9 (1UL << 9)
+#define METAL_HPM_EVENTID_10 (1UL << 10)
+#define METAL_HPM_EVENTID_11 (1UL << 11)
+#define METAL_HPM_EVENTID_12 (1UL << 12)
+#define METAL_HPM_EVENTID_13 (1UL << 13)
+#define METAL_HPM_EVENTID_14 (1UL << 14)
+#define METAL_HPM_EVENTID_15 (1UL << 15)
+#define METAL_HPM_EVENTID_16 (1UL << 16)
+#define METAL_HPM_EVENTID_17 (1UL << 17)
+#define METAL_HPM_EVENTID_18 (1UL << 18)
+#define METAL_HPM_EVENTID_19 (1UL << 19)
+#define METAL_HPM_EVENTID_20 (1UL << 20)
+#define METAL_HPM_EVENTID_21 (1UL << 21)
+#define METAL_HPM_EVENTID_22 (1UL << 22)
+#define METAL_HPM_EVENTID_23 (1UL << 23)
+#define METAL_HPM_EVENTID_24 (1UL << 24)
+#define METAL_HPM_EVENTID_25 (1UL << 25)
+#define METAL_HPM_EVENTID_26 (1UL << 26)
+#define METAL_HPM_EVENTID_27 (1UL << 27)
+#define METAL_HPM_EVENTID_28 (1UL << 28)
+#define METAL_HPM_EVENTID_29 (1UL << 29)
+#define METAL_HPM_EVENTID_30 (1UL << 30)
+#define METAL_HPM_EVENTID_31 (1UL << 31)
+
+/*! @brief Macros for valid Event Class */
+#define METAL_HPM_EVENTCLASS_0 (0UL)
+#define METAL_HPM_EVENTCLASS_1 (1UL)
+#define METAL_HPM_EVENTCLASS_2 (2UL)
+#define METAL_HPM_EVENTCLASS_3 (3UL)
+#define METAL_HPM_EVENTCLASS_4 (4UL)
+#define METAL_HPM_EVENTCLASS_5 (5UL)
+#define METAL_HPM_EVENTCLASS_6 (6UL)
+#define METAL_HPM_EVENTCLASS_7 (7UL)
+#define METAL_HPM_EVENTCLASS_8 (8UL)
+
+/*! @brief Enums for available HPM counters */
+typedef enum {
+ METAL_HPM_CYCLE = 0,
+ METAL_HPM_TIME = 1,
+ METAL_HPM_INSTRET = 2,
+ METAL_HPM_COUNTER_3 = 3,
+ METAL_HPM_COUNTER_4 = 4,
+ METAL_HPM_COUNTER_5 = 5,
+ METAL_HPM_COUNTER_6 = 6,
+ METAL_HPM_COUNTER_7 = 7,
+ METAL_HPM_COUNTER_8 = 8,
+ METAL_HPM_COUNTER_9 = 9,
+ METAL_HPM_COUNTER_10 = 10,
+ METAL_HPM_COUNTER_11 = 11,
+ METAL_HPM_COUNTER_12 = 12,
+ METAL_HPM_COUNTER_13 = 13,
+ METAL_HPM_COUNTER_14 = 14,
+ METAL_HPM_COUNTER_15 = 15,
+ METAL_HPM_COUNTER_16 = 16,
+ METAL_HPM_COUNTER_17 = 17,
+ METAL_HPM_COUNTER_18 = 18,
+ METAL_HPM_COUNTER_19 = 19,
+ METAL_HPM_COUNTER_20 = 20,
+ METAL_HPM_COUNTER_21 = 21,
+ METAL_HPM_COUNTER_22 = 22,
+ METAL_HPM_COUNTER_23 = 23,
+ METAL_HPM_COUNTER_24 = 24,
+ METAL_HPM_COUNTER_25 = 25,
+ METAL_HPM_COUNTER_26 = 26,
+ METAL_HPM_COUNTER_27 = 27,
+ METAL_HPM_COUNTER_28 = 28,
+ METAL_HPM_COUNTER_29 = 29,
+ METAL_HPM_COUNTER_30 = 30,
+ METAL_HPM_COUNTER_31 = 31
+} metal_hpm_counter;
+
+/*! @brief Initialize hardware performance monitor counters.
+ * @param cpu The CPU device handle.
+ * @return 0 If no error.*/
+int metal_hpm_init(struct metal_cpu *cpu);
+
+/*! @brief Disables hardware performance monitor counters.
+ * Note - Disabled HPM counters may reduce power consumption.
+ * @param cpu The CPU device handle.
+ * @return 0 If no error.*/
+int metal_hpm_disable(struct metal_cpu *cpu);
+
+/*! @brief Set events which will cause the specified counter to increment.
+ * Counter will start incrementing from the moment events are set.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter to be incremented by selected events.
+ * @param bitmask Bit-mask to select events for a particular counter,
+ * refer core reference manual for selection of events.
+ * Event bit mask is partitioned as follows:
+ * [XLEN-1:8] - Event selection mask [7:0] - Event class
+ * @return 0 If no error.*/
+int metal_hpm_set_event(struct metal_cpu *cpu, metal_hpm_counter counter,
+ unsigned int bitmask);
+
+/*! @brief Get events selection mask set for specified counter.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return Event selection bit mask. refer core reference manual for details.*/
+unsigned int metal_hpm_get_event(struct metal_cpu *cpu,
+ metal_hpm_counter counter);
+
+/*! @brief Clear event selector bits as per specified bit-mask.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return 0 If no error.*/
+int metal_hpm_clr_event(struct metal_cpu *cpu, metal_hpm_counter counter,
+ unsigned int bitmask);
+
+/*! @brief Enable counter access to next lower privilege mode.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return 0 If no error.*/
+int metal_hpm_enable_access(struct metal_cpu *cpu, metal_hpm_counter counter);
+
+/*! @brief Disable counter access to next lower privilege mode.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return 0 If no error.*/
+int metal_hpm_disable_access(struct metal_cpu *cpu, metal_hpm_counter counter);
+
+/*! @brief Reads current value of specified hardware counter.
+ * Note: 'mtime' register is memory mapped into CLINT block.
+ * Use CLINT APIs to access this register.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return Current value of hardware counter on success, 0 on failure.*/
+unsigned long long metal_hpm_read_counter(struct metal_cpu *cpu,
+ metal_hpm_counter counter);
+
+/*! @brief Clears off specified counter.
+ * @param cpu The CPU device handle.
+ * @param counter Hardware counter.
+ * @return 0 If no error.*/
+int metal_hpm_clear_counter(struct metal_cpu *cpu, metal_hpm_counter counter);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h
new file mode 100644
index 000000000..baf62e5d6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h
@@ -0,0 +1,112 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__I2C_H
+#define METAL__I2C_H
+
+/*! @brief Enums to enable/disable stop condition. */
+typedef enum {
+ METAL_I2C_STOP_DISABLE = 0,
+ METAL_I2C_STOP_ENABLE = 1
+} metal_i2c_stop_bit_t;
+
+/*! @brief Enums to set up I2C device modes. */
+typedef enum { METAL_I2C_SLAVE = 0, METAL_I2C_MASTER = 1 } metal_i2c_mode_t;
+
+struct metal_i2c;
+
+struct metal_i2c_vtable {
+ void (*init)(struct metal_i2c *i2c, unsigned int baud_rate,
+ metal_i2c_mode_t mode);
+ int (*write)(struct metal_i2c *i2c, unsigned int addr, unsigned int len,
+ unsigned char buf[], metal_i2c_stop_bit_t stop_bit);
+ int (*read)(struct metal_i2c *i2c, unsigned int addr, unsigned int len,
+ unsigned char buf[], metal_i2c_stop_bit_t stop_bit);
+ int (*transfer)(struct metal_i2c *i2c, unsigned int addr,
+ unsigned char txbuf[], unsigned int txlen,
+ unsigned char rxbuf[], unsigned int rxlen);
+ int (*get_baud_rate)(struct metal_i2c *i2c);
+ int (*set_baud_rate)(struct metal_i2c *i2c, unsigned int baud_rate);
+};
+
+/*! @brief A handle for a I2C device. */
+struct metal_i2c {
+ const struct metal_i2c_vtable *vtable;
+};
+
+/*! @brief Get a handle for a I2C device.
+ * @param device_num The index of the desired I2C device.
+ * @return A handle to the I2C device, or NULL if the device does not exist.*/
+struct metal_i2c *metal_i2c_get_device(unsigned int device_num);
+
+/*! @brief Initialize a I2C device with a certain baud rate.
+ * @param i2c The handle for the I2C device to initialize.
+ * @param baud_rate The baud rate for the I2C device to operate at.
+ * @param mode I2C operation mode.
+ */
+inline void metal_i2c_init(struct metal_i2c *i2c, unsigned int baud_rate,
+ metal_i2c_mode_t mode) {
+ i2c->vtable->init(i2c, baud_rate, mode);
+}
+
+/*! @brief Perform a I2C write.
+ * @param i2c The handle for the I2C device to perform the write operation.
+ * @param addr The I2C slave address for the write operation.
+ * @param len The number of bytes to transfer.
+ * @param buf The buffer to send over the I2C bus. Must be len bytes long.
+ * @param stop_bit Enable / Disable STOP condition.
+ * @return 0 if the write succeeds.
+ */
+inline int metal_i2c_write(struct metal_i2c *i2c, unsigned int addr,
+ unsigned int len, unsigned char buf[],
+ metal_i2c_stop_bit_t stop_bit) {
+ return i2c->vtable->write(i2c, addr, len, buf, stop_bit);
+}
+
+/*! @brief Perform a I2C read.
+ * @param i2c The handle for the I2C device to perform the read operation.
+ * @param addr The I2C slave address for the read operation.
+ * @param len The number of bytes to transfer.
+ * @param buf The buffer to store data from I2C bus. Must be len bytes long.
+ * @param stop_bit Enable / Disable STOP condition.
+ * @return 0 if the read succeeds.
+ */
+inline int metal_i2c_read(struct metal_i2c *i2c, unsigned int addr,
+ unsigned int len, unsigned char buf[],
+ metal_i2c_stop_bit_t stop_bit) {
+ return i2c->vtable->read(i2c, addr, len, buf, stop_bit);
+}
+
+/*! @brief Performs back to back I2C write and read operations.
+ * @param i2c The handle for the I2C device to perform the transfer operation.
+ * @param addr The I2C slave address for the transfer operation.
+ * @param txbuf The data buffer to be transmitted over I2C bus.
+ * @param txlen The number of bytes to write over I2C.
+ * @param rxbuf The buffer to store data received over I2C bus.
+ * @param rxlen The number of bytes to read over I2C.
+ * @return 0 if the transfer succeeds.
+ */
+inline int metal_i2c_transfer(struct metal_i2c *i2c, unsigned int addr,
+ unsigned char txbuf[], unsigned int txlen,
+ unsigned char rxbuf[], unsigned int rxlen) {
+ return i2c->vtable->transfer(i2c, addr, txbuf, txlen, rxbuf, rxlen);
+}
+
+/*! @brief Get the current baud rate of the I2C device.
+ * @param i2c The handle for the I2C device.
+ * @return The baud rate in Hz.
+ */
+inline int metal_i2c_get_baud_rate(struct metal_i2c *i2c) {
+ return i2c->vtable->get_baud_rate(i2c);
+}
+
+/*! @brief Set the current baud rate of the I2C device.
+ * @param i2c The handle for the I2C device.
+ * @param baud_rate The desired baud rate of the I2C device.
+ * @return 0 If the baud rate is successfully changed.
+ */
+inline int metal_i2c_set_baud_rate(struct metal_i2c *i2c, int baud_rate) {
+ return i2c->vtable->set_baud_rate(i2c, baud_rate);
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h
new file mode 100644
index 000000000..0214d0add
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h
@@ -0,0 +1,130 @@
+/* Copyright 2019 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL_INIT
+#define METAL_INIT
+
+/*!
+ * @file init.h
+ * API for Metal constructors and destructors
+ */
+
+typedef void (*metal_constructor_t)(void);
+typedef void (*metal_destructor_t)(void);
+
+#define METAL_INIT_HIGHEST_PRIORITY 0
+#define METAL_INIT_DEFAULT_PRIORITY 5000
+#define METAL_INIT_LOWEST_PRIORITY 9999
+
+/*! @def METAL_CONSTRUCTOR
+ * @brief Define a Metal constructor
+ *
+ * Functions defined with METAL_CONSTRUCTOR will be added to the list of
+ * Metal constructors. By default, these functions are called before main by
+ * the metal_init() function.
+ */
+#define METAL_CONSTRUCTOR(function_name) \
+ METAL_CONSTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY)
+
+/*! @def METAL_CONSTRUCTOR_PRIO
+ * @brief Define a Metal constructor with a given priority
+ *
+ * The priority argument should be an integer between 0 and 9999, where 0
+ * is the highest priority (runs first) and 9999 is the lowest priority
+ * (runs last).
+ *
+ * Functions defined with METAL_CONSTRUCTOR_PRIO will be added to the list of
+ * Metal constructors. By default, these functions are called before main by
+ * the metal_init() function.
+ */
+#define METAL_CONSTRUCTOR_PRIO(function_name, priority) \
+ __METAL_CONSTRUCTOR_PRIO(function_name, priority)
+
+/* We use this wrapper for METAL_CONSTRUCTOR_PRIORITY so that macros passed
+ * as 'priority' are expanded before being stringified by the # operator.
+ * If we don't do this, then
+ * METAL_CONSTRUCTOR(my_fn_name, METAL_INIT_DEFAULT_PRIORITY)
+ * results in .metal.init_array.METAL_INIT_DEFAULT_PRIORITY instead of
+ * .metal.init_array.5000 */
+#define __METAL_CONSTRUCTOR_PRIO(function_name, priority) \
+ __attribute__((section(".metal.ctors"))) void function_name(void); \
+ __attribute__((section(".metal.init_array." #priority))) \
+ metal_constructor_t _##function_name##_ptr = &function_name; \
+ void function_name(void)
+
+/*! @def METAL_DESTRUCTOR
+ * @brief Define a Metal destructor
+ *
+ * Functions defined with METAL_DESTRUCTOR will be added to the list of
+ * Metal destructors. By default, these functions are called on exit by
+ * the metal_fini() function.
+ */
+#define METAL_DESTRUCTOR(function_name) \
+ METAL_DESTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY)
+
+/*! @def METAL_DESTRUCTOR_PRIO
+ * @brief Define a Metal destructor with a given priority
+ *
+ * The priority argument should be an integer between 0 and 9999, where 0
+ * is the highest priority (runs first) and 9999 is the lowest priority
+ * (runs last).
+ *
+ * Functions defined with METAL_DESTRUCTOR_PRIO will be added to the list of
+ * Metal destructors. By default, these functions are called on exit by
+ * the metal_fini() function.
+ */
+#define METAL_DESTRUCTOR_PRIO(function_name, priority) \
+ __METAL_DESTRUCTOR_PRIO(function_name, priority)
+#define __METAL_DESTRUCTOR_PRIO(function_name, priority) \
+ __attribute__((section(".metal.dtors"))) void function_name(void); \
+ __attribute__((section(".metal.fini_array." #priority))) \
+ metal_destructor_t _##function_name##_ptr = &function_name; \
+ void function_name(void)
+
+/*!
+ * @brief Call all Metal constructors
+ *
+ * Devices supported by Metal may define Metal constructors to perform
+ * initialization before main. This function iterates over the constructors
+ * and calls them in turn.
+ *
+ * You can add your own constructors to the functions called by metal_init()
+ * by defining functions with the METAL_CONSTRUCTOR() macro.
+ *
+ * This function is called before main by default by metal_init_run().
+ */
+void metal_init(void);
+
+/*!
+ * @brief Call all Metal destructors
+ *
+ * Devices supported by Metal may define Metal destructors to perform
+ * initialization on exit. This function iterates over the destructors
+ * and calls them in turn.
+ *
+ * You can add your own destructors to the functions called by metal_fini()
+ * by defining functions with the METAL_DESTRUCTOR() macro.
+ *
+ * This function is called on exit by default by metal_fini_run().
+ */
+void metal_fini(void);
+
+/*!
+ * @brief Weak function to call metal_init() before main
+ *
+ * This function calls metal_init() before main by default. If you wish to
+ * replace or augment this call to the Metal constructors, you can redefine
+ * metal_init_run()
+ */
+void metal_init_run(void);
+
+/*!
+ * @brief Weak function to call metal_fini() before main
+ *
+ * This function calls metal_fini() at exit by default. If you wish to
+ * replace or augment this call to the Metal destructors, you can redefine
+ * metal_fini_run()
+ */
+void metal_fini_run(void);
+
+#endif /* METAL_INIT */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h
index 43f587aca..11df019de 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h
@@ -10,34 +10,105 @@
#include
+/*!
+ * @brief Possible interrupt controllers
+ */
+typedef enum metal_interrupt_controller_ {
+ METAL_CPU_CONTROLLER = 0,
+ METAL_CLINT_CONTROLLER = 1,
+ METAL_CLIC_CONTROLLER = 2,
+ METAL_PLIC_CONTROLLER = 3
+} metal_intr_cntrl_type;
+
/*!
* @brief Possible mode of interrupts to operate
*/
typedef enum metal_vector_mode_ {
METAL_DIRECT_MODE = 0,
METAL_VECTOR_MODE = 1,
- METAL_SELECTIVE_VECTOR_MODE = 2,
- METAL_HARDWARE_VECTOR_MODE = 3
+ METAL_SELECTIVE_NONVECTOR_MODE = 2,
+ METAL_SELECTIVE_VECTOR_MODE = 3,
+ METAL_HARDWARE_VECTOR_MODE = 4
} metal_vector_mode;
+/*!
+ * @brief Possible mode of privilege interrupts to operate
+ */
+typedef enum metal_intr_priv_mode_ {
+ METAL_INTR_PRIV_M_MODE = 0,
+ METAL_INTR_PRIV_MU_MODE = 1,
+ METAL_INTR_PRIV_MSU_MODE = 2
+} metal_intr_priv_mode;
+
+/*!
+ * @brief The bitmask of hart context
+ */
+typedef struct metal_affinity_ {
+ unsigned long bitmask;
+} metal_affinity;
+
+#define for_each_metal_affinity(bit, metal_affinity) \
+ for (bit = 0; metal_affinity.bitmask; bit++, metal_affinity.bitmask >>= 1)
+
+#define metal_affinity_set_val(metal_affinity, val) \
+ metal_affinity.bitmask = val;
+
+#define metal_affinity_set_bit(metal_affinity, bit, val) \
+ metal_affinity.bitmask |= ((val & 0x1) << bit);
+
/*!
* @brief Function signature for interrupt callback handlers
*/
-typedef void (*metal_interrupt_handler_t) (int, void *);
+typedef void (*metal_interrupt_handler_t)(int, void *);
+typedef void (*metal_interrupt_vector_handler_t)(void);
struct metal_interrupt;
struct metal_interrupt_vtable {
void (*interrupt_init)(struct metal_interrupt *controller);
+ int (*interrupt_set_vector_mode)(struct metal_interrupt *controller,
+ metal_vector_mode mode);
+ metal_vector_mode (*interrupt_get_vector_mode)(
+ struct metal_interrupt *controller);
+ int (*interrupt_set_privilege)(struct metal_interrupt *controller,
+ metal_intr_priv_mode priv);
+ metal_intr_priv_mode (*interrupt_get_privilege)(
+ struct metal_interrupt *controller);
+ int (*interrupt_clear)(struct metal_interrupt *controller, int id);
+ int (*interrupt_set)(struct metal_interrupt *controller, int id);
int (*interrupt_register)(struct metal_interrupt *controller, int id,
- metal_interrupt_handler_t isr, void *priv_data);
+ metal_interrupt_handler_t isr, void *priv_data);
+ int (*interrupt_vector_register)(struct metal_interrupt *controller, int id,
+ metal_interrupt_vector_handler_t isr,
+ void *priv_data);
int (*interrupt_enable)(struct metal_interrupt *controller, int id);
int (*interrupt_disable)(struct metal_interrupt *controller, int id);
- int (*interrupt_vector_enable)(struct metal_interrupt *controller,
- int id, metal_vector_mode mode);
+ int (*interrupt_vector_enable)(struct metal_interrupt *controller, int id);
int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id);
- int (*command_request)(struct metal_interrupt *controller, int cmd, void *data);
- int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time);
+ unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller);
+ int (*interrupt_set_threshold)(struct metal_interrupt *controller,
+ unsigned int threshold);
+ unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller,
+ int id);
+ int (*interrupt_set_priority)(struct metal_interrupt *controller, int id,
+ unsigned int priority);
+ unsigned int (*interrupt_get_preemptive_level)(
+ struct metal_interrupt *controller, int id);
+ int (*interrupt_set_preemptive_level)(struct metal_interrupt *controller,
+ int id, unsigned int level);
+ int (*command_request)(struct metal_interrupt *controller, int cmd,
+ void *data);
+ int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid,
+ unsigned long long time);
+ metal_affinity (*interrupt_affinity_enable)(
+ struct metal_interrupt *controller, metal_affinity bitmask, int id);
+ metal_affinity (*interrupt_affinity_disable)(
+ struct metal_interrupt *controller, metal_affinity bitmask, int id);
+ metal_affinity (*interrupt_affinity_set_threshold)(
+ struct metal_interrupt *controller, metal_affinity bitmask,
+ unsigned int threshold);
+ unsigned int (*interrupt_affinity_get_threshold)(
+ struct metal_interrupt *controller, int context_id);
};
/*!
@@ -56,11 +127,104 @@ struct metal_interrupt {
*
* @param controller The handle for the interrupt controller
*/
-inline void metal_interrupt_init(struct metal_interrupt *controller)
-{
- return controller->vtable->interrupt_init(controller);
+__inline__ void metal_interrupt_init(struct metal_interrupt *controller) {
+ controller->vtable->interrupt_init(controller);
}
+/*!
+ * @brief Get the handle for an given interrupt controller type
+ * @param cntrl The type ofinterrupt controller
+ * @param id The instance of the interrupt controller
+ * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or
+ * NULL if none is found for the requested label
+ */
+struct metal_interrupt *
+metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, int id);
+
+/*!
+ * @brief Configure vector mode for an interrupt controller
+ *
+ * Configure vector mode for an interrupt controller.
+ * This function must be called after initialization and before
+ * configuring individual interrupts, registering ISR.
+ *
+ * @param controller The handle for the interrupt controller
+ * @param mode The vector mode of the interrupt controller.
+ * @return 0 upon success
+ */
+__inline__ int
+metal_interrupt_set_vector_mode(struct metal_interrupt *controller,
+ metal_vector_mode mode) {
+ return controller->vtable->interrupt_set_vector_mode(controller, mode);
+}
+
+/*!
+ * @brief Get vector mode of a given an interrupt controller
+ *
+ * Configure vector mode for an interrupt controller.
+ * This function must be called after initialization and before
+ * configuring individual interrupts, registering ISR.
+ *
+ * @param controller The handle for the interrupt controller
+ * @param mode The vector mode of the interrupt controller.
+ * @return The interrupt vector mode
+ */
+__inline__ metal_vector_mode
+metal_interrupt_get_vector_mode(struct metal_interrupt *controller) {
+ return controller->vtable->interrupt_get_vector_mode(controller);
+}
+
+/*!
+ * @brief Configure privilege mode a of given interrupt controller
+ *
+ * Configure privilege mode for a given interrupt controller.
+ * This function must be called after initialization and before
+ * configuring individual interrupts, registering ISR.
+ *
+ * @param controller The handle for the interrupt controller
+ * @param privilege The privilege mode of the interrupt controller.
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller,
+ metal_intr_priv_mode privilege) {
+ return controller->vtable->interrupt_set_privilege(controller, privilege);
+}
+
+/*!
+ * @brief Get privilege mode a of given interrupt controller
+ *
+ * Get privilege mode for a given interrupt controller.
+ * This function must be called after initialization and before
+ * configuring individual interrupts, registering ISR.
+ *
+ * @param controller The handle for the interrupt controller
+ * @return The interrupt privilege mode
+ */
+__inline__ metal_intr_priv_mode
+metal_interrupt_get_privilege(struct metal_interrupt *controller) {
+ return controller->vtable->interrupt_get_privilege(controller);
+}
+
+/*!
+ * @brief clear an interrupt
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to trigger
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_clear(struct metal_interrupt *controller,
+ int id) {
+ return controller->vtable->interrupt_clear(controller, id);
+}
+
+/*!
+ * @brief Set an interrupt
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to trigger
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) {
+ return controller->vtable->interrupt_set(controller, id);
+}
/*!
* @brief Register an interrupt handler
@@ -70,12 +234,27 @@ inline void metal_interrupt_init(struct metal_interrupt *controller)
* @param priv_data Private data for the interrupt handler
* @return 0 upon success
*/
-inline int metal_interrupt_register_handler(struct metal_interrupt *controller,
- int id,
- metal_interrupt_handler_t handler,
- void *priv_data)
-{
- return controller->vtable->interrupt_register(controller, id, handler, priv_data);
+__inline__ int
+metal_interrupt_register_handler(struct metal_interrupt *controller, int id,
+ metal_interrupt_handler_t handler,
+ void *priv_data) {
+ return controller->vtable->interrupt_register(controller, id, handler,
+ priv_data);
+}
+
+/*!
+ * @brief Register an interrupt vector handler
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to register
+ * @param handler The interrupt vector handler callback
+ * @param priv_data Private data for the interrupt handler
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_register_vector_handler(
+ struct metal_interrupt *controller, int id,
+ metal_interrupt_vector_handler_t handler, void *priv_data) {
+ return controller->vtable->interrupt_vector_register(controller, id,
+ handler, priv_data);
}
/*!
@@ -84,8 +263,8 @@ inline int metal_interrupt_register_handler(struct metal_interrupt *controller,
* @param id The interrupt ID to enable
* @return 0 upon success
*/
-inline int metal_interrupt_enable(struct metal_interrupt *controller, int id)
-{
+__inline__ int metal_interrupt_enable(struct metal_interrupt *controller,
+ int id) {
return controller->vtable->interrupt_enable(controller, id);
}
@@ -95,22 +274,100 @@ inline int metal_interrupt_enable(struct metal_interrupt *controller, int id)
* @param id The interrupt ID to disable
* @return 0 upon success
*/
-inline int metal_interrupt_disable(struct metal_interrupt *controller, int id)
-{
+__inline__ int metal_interrupt_disable(struct metal_interrupt *controller,
+ int id) {
return controller->vtable->interrupt_disable(controller, id);
}
+/*!
+ * @brief Set interrupt threshold level
+ * @param controller The handle for the interrupt controller
+ * @param threshold The interrupt threshold level
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller,
+ unsigned int level) {
+ return controller->vtable->interrupt_set_threshold(controller, level);
+}
+
+/*!
+ * @brief Get an interrupt threshold level
+ * @param controller The handle for the interrupt controller
+ * @return The interrupt threshold level
+ */
+__inline__ unsigned int
+metal_interrupt_get_threshold(struct metal_interrupt *controller) {
+ return controller->vtable->interrupt_get_threshold(controller);
+}
+
+/*!
+ * @brief Set an interrupt priority level
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @param priority The interrupt priority level
+ * @return 0 upon success
+ */
+__inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller,
+ int id, unsigned int priority) {
+ return controller->vtable->interrupt_set_priority(controller, id, priority);
+}
+
+/*!
+ * @brief Get an interrupt priority level
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @return The interrupt priority level
+ */
+__inline__ unsigned int
+metal_interrupt_get_priority(struct metal_interrupt *controller, int id) {
+ return controller->vtable->interrupt_get_priority(controller, id);
+}
+
+/*!
+ * @brief Set preemptive level and priority for a given interrupt ID
+ *
+ * Set the preemptive level and priority for a given interrupt ID.
+ *
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @param level The interrupt level and priority are encoded together
+ * @return 0 upon success
+ */
+__inline__ int
+metal_interrupt_set_preemptive_level(struct metal_interrupt *controller, int id,
+ unsigned int level) {
+ if (controller->vtable->interrupt_set_preemptive_level)
+ return controller->vtable->interrupt_set_preemptive_level(controller,
+ id, level);
+ else
+ return 0;
+}
+
+/*!
+ * @brief Get an interrupt preemptive level
+ * @param controller The handle for the interrupt controller
+ * @param id The interrupt ID to enable
+ * @return The interrupt level
+ */
+__inline__ unsigned int
+metal_interrupt_get_preemptive_level(struct metal_interrupt *controller,
+ int id) {
+ if (controller->vtable->interrupt_get_preemptive_level)
+ return controller->vtable->interrupt_get_preemptive_level(controller,
+ id);
+ else
+ return 0;
+}
+
/*!
* @brief Enable an interrupt vector
* @param controller The handle for the interrupt controller
* @param id The interrupt ID to enable
- * @param mode The interrupt mode type to enable
* @return 0 upon success
*/
-inline int metal_interrupt_vector_enable(struct metal_interrupt *controller,
- int id, metal_vector_mode mode)
-{
- return controller->vtable->interrupt_vector_enable(controller, id, mode);
+__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller,
+ int id) {
+ return controller->vtable->interrupt_vector_enable(controller, id);
}
/*!
@@ -119,16 +376,215 @@ inline int metal_interrupt_vector_enable(struct metal_interrupt *controller,
* @param id The interrupt ID to disable
* @return 0 upon success
*/
-inline int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id)
-{
+__inline__ int
+metal_interrupt_vector_disable(struct metal_interrupt *controller, int id) {
return controller->vtable->interrupt_vector_disable(controller, id);
}
-/* Utilities function to controll, manages devices via a given interrupt controller */
-inline int _metal_interrupt_command_request(struct metal_interrupt *controller,
- int cmd, void *data)
-{
+/*!
+ * @brief Default interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Software interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt))
+metal_software_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Timer interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt))
+metal_timer_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal External interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt))
+metal_external_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 0 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 1 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 2 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 3 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 4 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 5 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 6 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 7 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 8 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 9 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 10 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 11 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 12 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 13 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 14 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void);
+
+/*!
+ * @brief Metal Local 15 interrupt vector handler, that can be overriden by user
+ * @param None
+ * @return None
+ */
+void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void);
+
+/* Utilities function to controll, manages devices via a given interrupt
+ * controller */
+__inline__ int
+_metal_interrupt_command_request(struct metal_interrupt *controller, int cmd,
+ void *data) {
return controller->vtable->command_request(controller, cmd, data);
}
+/*!
+ * @brief Enable an interrupt for the hart contexts
+ * @param controller The handle for the interrupt controller
+ * @param bitmask The bit mask of hart contexts to enable
+ * @param id The interrupt ID to enable
+ * @return The result of each hart context. 0 upon success at relevant bit.
+ */
+__inline__ metal_affinity
+metal_interrupt_affinity_enable(struct metal_interrupt *controller,
+ metal_affinity bitmask, int id) {
+ return controller->vtable->interrupt_affinity_enable(controller, bitmask,
+ id);
+}
+
+/*!
+ * @brief Disable an interrupt for the hart contexts
+ * @param controller The handle for the interrupt controller
+ * @param bitmask The bit mask of hart contexts to disable
+ * @param id The interrupt ID to disable
+ * @return The result of each hart context. 0 upon success at relevant bit.
+ */
+__inline__ metal_affinity
+metal_interrupt_affinity_disable(struct metal_interrupt *controller,
+ metal_affinity bitmask, int id) {
+ return controller->vtable->interrupt_affinity_disable(controller, bitmask,
+ id);
+}
+
+/*!
+ * @brief Set interrupt threshold level for the hart contexts
+ * @param controller The handle for the interrupt controller
+ * @param bitmask The bit mask of hart contexts to set threshold
+ * @param threshold The interrupt threshold level
+ * @return The result of each hart context. 0 upon success at relevant bit.
+ */
+__inline__ metal_affinity
+metal_interrupt_affinity_set_threshold(struct metal_interrupt *controller,
+ metal_affinity bitmask,
+ unsigned int level) {
+ return controller->vtable->interrupt_affinity_set_threshold(controller,
+ bitmask, level);
+}
+
+/*!
+ * @brief Get an interrupt threshold level from the hart context
+ * @param controller The handle for the interrupt controller
+ * @param context_id The hart context ID to get threshold
+ * @return The interrupt threshold level
+ */
+__inline__ unsigned int
+metal_interrupt_affinity_get_threshold(struct metal_interrupt *controller,
+ int context_id) {
+ return controller->vtable->interrupt_affinity_get_threshold(controller,
+ context_id);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h
index 450054142..f1df85518 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h
@@ -5,18 +5,19 @@
#define METAL__IO_H
/* This macro enforces that the compiler will not elide the given access. */
-#define __METAL_ACCESS_ONCE(x) (*(typeof(*x) volatile *)(x))
+#define __METAL_ACCESS_ONCE(x) (*(__typeof__(*x) volatile *)(x))
/* Allows users to specify arbitrary fences. */
-#define __METAL_IO_FENCE(pred, succ) __asm__ volatile ("fence " #pred "," #succ ::: "memory");
+#define __METAL_IO_FENCE(pred, succ) \
+ __asm__ volatile("fence " #pred "," #succ ::: "memory");
/* Types that explicitly describe an address as being used for memory-mapped
* IO. These should only be accessed via __METAL_ACCESS_ONCE. */
-typedef unsigned char __metal_io_u8;
+typedef unsigned char __metal_io_u8;
typedef unsigned short __metal_io_u16;
-typedef unsigned int __metal_io_u32;
+typedef unsigned int __metal_io_u32;
#if __riscv_xlen >= 64
-typedef unsigned long __metal_io_u64;
+typedef unsigned long __metal_io_u64;
#endif
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h
index 1a2a05b8b..3decefff2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h
@@ -9,13 +9,12 @@
* API for manipulating ITIM allocation
*/
-
/*! @def METAL_PLACE_IN_ITIM
* @brief Link a function into the ITIM
*
* Link a function into the ITIM (Instruction Tightly Integrated
* Memory) if the ITIM is present on the target device.
*/
-#define METAL_PLACE_IN_ITIM __attribute__((section(".itim")))
+#define METAL_PLACE_IN_ITIM __attribute__((section(".itim")))
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h
index a430b84c2..da2555fb8 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h
@@ -31,38 +31,47 @@ struct metal_led {
* @param label The DeviceTree label for the desired LED
* @return A handle to the LED, or NULL if none is found for the requested label
*/
-struct metal_led* metal_led_get(char *label);
+struct metal_led *metal_led_get(char *label);
/*!
* @brief Get a handle for a channel of an RGB LED
* @param label The DeviceTree label for the desired LED
* @param color The color for the LED in the DeviceTree
- * @return A handle to the LED, or NULL if none is found for the requested label and color
+ * @return A handle to the LED, or NULL if none is found for the requested label
+ * and color
*/
-struct metal_led* metal_led_get_rgb(char *label, char *color);
+struct metal_led *metal_led_get_rgb(char *label, char *color);
/*!
* @brief Enable an LED
* @param led The handle for the LED
*/
-inline void metal_led_enable(struct metal_led *led) { led->vtable->led_enable(led); }
+__inline__ void metal_led_enable(struct metal_led *led) {
+ led->vtable->led_enable(led);
+}
/*!
* @brief Turn an LED on
* @param led The handle for the LED
*/
-inline void metal_led_on(struct metal_led *led) { led->vtable->led_on(led); }
+__inline__ void metal_led_on(struct metal_led *led) {
+ led->vtable->led_on(led);
+}
/*!
* @brief Turn an LED off
* @param led The handle for the LED
*/
-inline void metal_led_off(struct metal_led *led) { led->vtable->led_off(led); }
+__inline__ void metal_led_off(struct metal_led *led) {
+ led->vtable->led_off(led);
+}
/*!
* @brief Toggle the on/off state of an LED
* @param led The handle for the LED
*/
-inline void metal_led_toggle(struct metal_led *led) { led->vtable->led_toggle(led); }
+__inline__ void metal_led_toggle(struct metal_led *led) {
+ led->vtable->led_toggle(led);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h
new file mode 100644
index 000000000..1e573cad6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h
@@ -0,0 +1,20 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__LIM_H
+#define METAL__LIM_H
+
+/*! @file lim.h
+ *
+ * API for manipulating LIM allocation
+ */
+
+/*! @def METAL_PLACE_IN_LIM
+ * @brief Link a function into the LIM
+ *
+ * Link a function into the LIM (Loosely Integrated
+ * Memory) if the LIM is present on the target device.
+ */
+#define METAL_PLACE_IN_LIM __attribute__((section(".lim")))
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h
index d863aa96e..e591eaefa 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h
@@ -4,8 +4,9 @@
#ifndef METAL__LOCK_H
#define METAL__LOCK_H
-#include
#include
+#include
+#include
/*!
* @file lock.h
@@ -15,6 +16,9 @@
/* TODO: How can we make the exception code platform-independant? */
#define _METAL_STORE_AMO_ACCESS_FAULT 7
+#define METAL_LOCK_BACKOFF_CYCLES 32
+#define METAL_LOCK_BACKOFF_EXPONENT 2
+
/*!
* @def METAL_LOCK_DECLARE
* @brief Declare a lock
@@ -22,35 +26,36 @@
* Locks must be declared with METAL_LOCK_DECLARE to ensure that the lock
* is linked into a memory region which supports atomic memory operations.
*/
-#define METAL_LOCK_DECLARE(name) \
- __attribute__((section(".data.locks"))) \
- struct metal_lock name
+#define METAL_LOCK_DECLARE(name) \
+ __attribute__((section(".data.locks"))) struct metal_lock name
/*!
* @brief A handle for a lock
*/
struct metal_lock {
- int _state;
+ int _state;
};
/*!
* @brief Initialize a lock
* @param lock The handle for a lock
- * @return 0 if the lock is successfully initialized. A non-zero code indicates failure.
+ * @return 0 if the lock is successfully initialized. A non-zero code indicates
+ * failure.
*
* If the lock cannot be initialized, attempts to take or give the lock
* will result in a Store/AMO access fault.
*/
-inline int metal_lock_init(struct metal_lock *lock) {
+__inline__ int metal_lock_init(struct metal_lock *lock) {
#ifdef __riscv_atomic
/* Get a handle for the memory which holds the lock state */
- struct metal_memory *lock_mem = metal_get_memory_from_address((uintptr_t) &(lock->_state));
- if(!lock_mem) {
+ struct metal_memory *lock_mem =
+ metal_get_memory_from_address((uintptr_t) & (lock->_state));
+ if (!lock_mem) {
return 1;
}
/* If the memory doesn't support atomics, report an error */
- if(!metal_memory_supports_atomics(lock_mem)) {
+ if (!metal_memory_supports_atomics(lock_mem)) {
return 2;
}
@@ -70,23 +75,37 @@ inline int metal_lock_init(struct metal_lock *lock) {
* If the lock initialization failed, attempts to take a lock will result in
* a Store/AMO access fault.
*/
-inline int metal_lock_take(struct metal_lock *lock) {
+__inline__ int metal_lock_take(struct metal_lock *lock) {
#ifdef __riscv_atomic
int old = 1;
int new = 1;
- while(old != 0) {
+ int backoff = 1;
+ const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES;
+
+ while (1) {
__asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])"
- : [old] "=r" (old)
- : [new] "r" (new), [state] "r" (&(lock->_state))
+ : [old] "=r"(old)
+ : [new] "r"(new), [state] "r"(&(lock->_state))
: "memory");
+
+ if (old == 0) {
+ break;
+ }
+
+ for (int i = 0; i < backoff; i++) {
+ __asm__ volatile("");
+ }
+
+ if (backoff < max_backoff) {
+ backoff *= METAL_LOCK_BACKOFF_EXPONENT;
+ }
}
return 0;
#else
/* Store the memory address in mtval like a normal store/amo access fault */
- __asm__ ("csrw mtval, %[state]"
- :: [state] "r" (&(lock->_state)));
+ __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state)));
/* Trigger a Store/AMO access fault */
_metal_trap(_METAL_STORE_AMO_ACCESS_FAULT);
@@ -104,17 +123,16 @@ inline int metal_lock_take(struct metal_lock *lock) {
* If the lock initialization failed, attempts to give a lock will result in
* a Store/AMO access fault.
*/
-inline int metal_lock_give(struct metal_lock *lock) {
+__inline__ int metal_lock_give(struct metal_lock *lock) {
#ifdef __riscv_atomic
- __asm__ volatile("amoswap.w.rl x0, x0, (%[state])"
- :: [state] "r" (&(lock->_state))
- : "memory");
+ __asm__ volatile(
+ "amoswap.w.rl x0, x0, (%[state])" ::[state] "r"(&(lock->_state))
+ : "memory");
return 0;
#else
/* Store the memory address in mtval like a normal store/amo access fault */
- __asm__ ("csrw mtval, %[state]"
- :: [state] "r" (&(lock->_state)));
+ __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state)));
/* Trigger a Store/AMO access fault */
_metal_trap(_METAL_STORE_AMO_ACCESS_FAULT);
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h
index f76dbd632..74c361b4b 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h
@@ -9,15 +9,15 @@
#ifdef __METAL_MACHINE_MACROS
-#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
-#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
+#ifndef MACROS_IF_METAL_H
+#define MACROS_IF_METAL_H
#define __METAL_CLINT_NUM_PARENTS 2
#ifndef __METAL_CLINT_NUM_PARENTS
#define __METAL_CLINT_NUM_PARENTS 0
#endif
-#define __METAL_PLIC_SUBINTERRUPTS 27
+#define __METAL_PLIC_SUBINTERRUPTS 53
#define __METAL_PLIC_NUM_PARENTS 1
@@ -31,12 +31,12 @@
#define __METAL_CLIC_SUBINTERRUPTS 0
#endif
-#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/
+#endif /* MACROS_IF_METAL_H*/
#else /* ! __METAL_MACHINE_MACROS */
-#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
-#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
+#ifndef MACROS_ELSE_METAL_H
+#define MACROS_ELSE_METAL_H
#define __METAL_CLINT_2000000_INTERRUPTS 2
@@ -46,7 +46,7 @@
#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1
-#define __METAL_PLIC_SUBINTERRUPTS 27
+#define __METAL_PLIC_SUBINTERRUPTS 53
#define METAL_MAX_PLIC_INTERRUPTS 1
@@ -55,20 +55,36 @@
#define __METAL_CLIC_SUBINTERRUPTS 0
#define METAL_MAX_CLIC_INTERRUPTS 0
-#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16
-
-#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16
+#define METAL_MAX_LOCAL_EXT_INTERRUPTS 0
#define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0
-#define __METAL_GPIO_10012000_INTERRUPTS 16
+#define __METAL_GPIO_10012000_INTERRUPTS 32
-#define METAL_MAX_GPIO_INTERRUPTS 16
+#define METAL_MAX_GPIO_INTERRUPTS 32
+
+#define __METAL_I2C_10016000_INTERRUPTS 1
+
+#define METAL_MAX_I2C0_INTERRUPTS 1
+
+#define __METAL_PWM_10015000_INTERRUPTS 4
+
+#define __METAL_PWM_10025000_INTERRUPTS 4
+
+#define __METAL_PWM_10035000_INTERRUPTS 4
+
+#define METAL_MAX_PWM0_INTERRUPTS 4
+
+#define METAL_MAX_PWM0_NCMP 4
#define __METAL_SERIAL_10013000_INTERRUPTS 1
+#define __METAL_SERIAL_10023000_INTERRUPTS 1
+
#define METAL_MAX_UART_INTERRUPTS 1
+#define METAL_MAX_SIMUART_INTERRUPTS 0
+
#include
#include
@@ -76,79 +92,119 @@
#include
#include
#include
-#include
#include
#include
+#include
+#include
+#include
#include
#include
+#include
#include
#include
+#include
#include
#include
/* From clock@0 */
-struct __metal_driver_fixed_clock __metal_dt_clock_0;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_0;
/* From clock@2 */
-struct __metal_driver_fixed_clock __metal_dt_clock_2;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_2;
/* From clock@5 */
-struct __metal_driver_fixed_clock __metal_dt_clock_5;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_5;
-struct metal_memory __metal_dt_mem_dtim_80000000;
+/* From clock@6 */
+extern struct __metal_driver_fixed_clock __metal_dt_clock_6;
-struct metal_memory __metal_dt_mem_spi_10014000;
+extern struct metal_memory __metal_dt_mem_dtim_80000000;
+
+extern struct metal_memory __metal_dt_mem_itim_8000000;
+
+extern struct metal_memory __metal_dt_mem_spi_10014000;
+
+extern struct metal_memory __metal_dt_mem_spi_10024000;
+
+extern struct metal_memory __metal_dt_mem_spi_10034000;
/* From clint@2000000 */
-struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
+extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
/* From cpu@0 */
-struct __metal_driver_cpu __metal_dt_cpu_0;
+extern struct __metal_driver_cpu __metal_dt_cpu_0;
-struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
/* From interrupt_controller@c000000 */
-struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
+extern struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
-struct metal_pmp __metal_dt_pmp;
-
-/* From local_external_interrupts_0 */
-struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0;
+extern struct metal_pmp __metal_dt_pmp;
/* From gpio@10012000 */
-struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000;
+extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000;
-/* From led@0red */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0red;
+/* From led@0 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0;
-/* From led@0green */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0green;
+/* From led@1 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1;
-/* From led@0blue */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue;
+/* From led@2 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2;
+
+/* From i2c@10016000 */
+extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000;
+
+/* From pwm@10015000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000;
+
+/* From pwm@10025000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000;
+
+/* From pwm@10035000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000;
+
+/* From aon@10000000 */
+extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000;
/* From spi@10014000 */
-struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000;
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000;
+
+/* From spi@10024000 */
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000;
+
+/* From spi@10034000 */
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000;
/* From serial@10013000 */
-struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000;
+extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000;
+
+/* From serial@10023000 */
+extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000;
+
+/* From aon@10000000 */
+extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000;
/* From clock@3 */
-struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3;
+extern struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3;
/* From clock@1 */
-struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1;
+extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1;
+
+/* From clock@7 */
+extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7;
/* From clock@4 */
-struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4;
+extern struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4;
/* From prci@10008000 */
-struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000;
+extern struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000;
/* --------------------- fixed_clock ------------ */
-static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
+static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
{
if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) {
return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY;
@@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c
else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) {
return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY;
}
+ else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) {
+ return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY;
+ }
else {
return 0;
}
@@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c
/* --------------------- sifive_clint0 ------------ */
-static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS;
@@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met
}
}
-static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_RISCV_CLINT0_2000000_SIZE;
@@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met
}
}
-static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_MAX_CLINT_INTERRUPTS;
@@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
@@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa
}
}
-static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
+static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return 3;
@@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte
/* --------------------- cpu ------------ */
-static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return 0;
@@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
}
}
-static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
- return 1000000;
+ return 16000000;
}
else {
return 0;
}
}
-static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
+static __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return &__metal_dt_cpu_0_interrupt_controller.controller;
@@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s
}
}
-static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return 8;
@@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
}
}
+static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return NULL;
+ }
+ else {
+ return NULL;
+ }
+}
+
/* --------------------- sifive_plic0 ------------ */
-static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS;
@@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta
}
}
-static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_SIZE;
@@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta
}
}
-static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_RISCV_NDEV;
@@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr
}
}
-static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY;
@@ -312,120 +381,52 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
}
- else if (idx == 0) {
- return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
- }
else {
return NULL;
}
}
-static inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
+static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return 11;
}
- else if (idx == 0) {
- return 11;
- }
else {
return 0;
}
}
+static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid)
+{
+ if (hartid == 0) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+
+
+/* --------------------- sifive_buserror0 ------------ */
/* --------------------- sifive_clic0 ------------ */
/* --------------------- sifive_local_external_interrupts0 ------------ */
-static inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller)
-{
- if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
- return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
- }
- else {
- return NULL;
- }
-}
-
-static inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller)
-{
- if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
- return METAL_MAX_LOCAL_EXT_INTERRUPTS;
- }
- else {
- return 0;
- }
-}
-
-static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx)
-{
- if (idx == 0) {
- return 16;
- }
- else if (idx == 1) {
- return 17;
- }
- else if (idx == 2) {
- return 18;
- }
- else if (idx == 3) {
- return 19;
- }
- else if (idx == 4) {
- return 20;
- }
- else if (idx == 5) {
- return 21;
- }
- else if (idx == 6) {
- return 22;
- }
- else if (idx == 7) {
- return 23;
- }
- else if (idx == 8) {
- return 24;
- }
- else if (idx == 9) {
- return 25;
- }
- else if (idx == 10) {
- return 26;
- }
- else if (idx == 11) {
- return 27;
- }
- else if (idx == 12) {
- return 28;
- }
- else if (idx == 13) {
- return 29;
- }
- else if (idx == 14) {
- return 30;
- }
- else if (idx == 15) {
- return 31;
- }
- else {
- return 0;
- }
-}
-
/* --------------------- sifive_global_external_interrupts0 ------------ */
/* --------------------- sifive_gpio0 ------------ */
-static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio)
+static __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS;
@@ -435,7 +436,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *
}
}
-static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio)
+static __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_SIFIVE_GPIO0_10012000_SIZE;
@@ -445,7 +446,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *
}
}
-static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio)
+static __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_MAX_GPIO_INTERRUPTS;
@@ -455,7 +456,7 @@ static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
@@ -465,56 +466,104 @@ static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_par
}
}
-static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx)
+static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx)
{
if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) {
- return 7;
- }
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) {
return 8;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) {
return 9;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) {
return 10;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) {
return 11;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) {
return 12;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) {
return 13;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) {
return 14;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) {
return 15;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) {
return 16;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) {
return 17;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) {
return 18;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) {
return 19;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) {
return 20;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) {
return 21;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) {
return 22;
}
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) {
+ return 23;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) {
+ return 24;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) {
+ return 25;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) {
+ return 26;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) {
+ return 27;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) {
+ return 28;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) {
+ return 29;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) {
+ return 30;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) {
+ return 31;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) {
+ return 32;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) {
+ return 33;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) {
+ return 34;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) {
+ return 35;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) {
+ return 36;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) {
+ return 27;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) {
+ return 28;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) {
+ return 29;
+ }
else {
return 0;
}
@@ -526,15 +575,15 @@ static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio
/* --------------------- sifive_gpio_led ------------ */
-static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led)
+static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
else {
@@ -542,15 +591,15 @@ static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct met
}
}
-static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
+static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return 22;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return 19;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return 21;
}
else {
@@ -558,15 +607,15 @@ static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
}
}
-static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
+static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return "LD0red";
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return "LD0green";
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return "LD0blue";
}
else {
@@ -579,45 +628,430 @@ static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
/* --------------------- sifive_gpio_switch ------------ */
-/* --------------------- sifive_spi0 ------------ */
-static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi)
+/* --------------------- sifive_i2c0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return METAL_SIFIVE_I2C0_10016000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 12288;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c)
+{
+ return METAL_MAX_I2C0_INTERRUPTS;
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c)
+{
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+}
+
+static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 52;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_pwm0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return METAL_SIFIVE_PWM0_10015000_SIZE;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return METAL_SIFIVE_PWM0_10025000_SIZE;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return METAL_SIFIVE_PWM0_10035000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 15;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 7864320;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 15360;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 15;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 7864320;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 15360;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return __METAL_PWM_10015000_INTERRUPTS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return __METAL_PWM_10025000_INTERRUPTS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return __METAL_PWM_10035000_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm)
+{
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx)
+{
+ if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) {
+ return 40;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) {
+ return 41;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) {
+ return 42;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) {
+ return 43;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) {
+ return 44;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) {
+ return 45;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) {
+ return 46;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) {
+ return 47;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) {
+ return 48;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) {
+ return 49;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) {
+ return 50;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) {
+ return 51;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 8;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 16;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 16;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 4;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 4;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_rtc0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return METAL_SIFIVE_AON0_10000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return 2;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return (struct metal_clock *)&__metal_dt_clock_7.clock;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi)
{
if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS;
}
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS;
+ }
else {
return 0;
}
}
-static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi)
{
if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return METAL_SIFIVE_SPI0_10014000_SIZE;
}
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return METAL_SIFIVE_SPI0_10024000_SIZE;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return METAL_SIFIVE_SPI0_10034000_SIZE;
+ }
else {
return 0;
}
}
-static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi)
+static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi)
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi)
{
- return 60;
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
return 60;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return 4227858432;
+ }
+ else {
+ return 0;
+ }
}
@@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st
/* --------------------- sifive_test0 ------------ */
+/* --------------------- sifive_trace ------------ */
+
/* --------------------- sifive_uart0 ------------ */
-static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS;
+ }
else {
return 0;
}
}
-static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_SIFIVE_UART0_10013000_SIZE;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_SIFIVE_UART0_10023000_SIZE;
+ }
else {
return 0;
}
}
-static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart)
+static __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_MAX_UART_INTERRUPTS;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_MAX_UART_INTERRUPTS;
+ }
else {
return 0;
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
else {
- return NULL;
+ return 0;
}
}
-static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart)
+static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart)
{
- return 5;
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return 3;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart)
+static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart)
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart)
{
- return 196608;
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return 0;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return 196608;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 8650752;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_simuart0 ------------ */
+
+
+/* --------------------- sifive_wdog0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return METAL_SIFIVE_AON0_10000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return (struct metal_clock *)&__metal_dt_clock_7.clock;
+ }
+ else {
+ return 0;
+ }
}
/* --------------------- sifive_fe310_g000_hfrosc ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_2.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock)
+static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock)
{
return &__metal_driver_vtable_sifive_fe310_g000_prci;
}
-static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG;
}
@@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s
/* --------------------- sifive_fe310_g000_hfxosc ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_0.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG;
}
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return (struct metal_clock *)&__metal_dt_clock_5.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return (struct metal_clock *)&__metal_dt_clock_6.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return 112;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return 124;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
/* --------------------- sifive_fe310_g000_pll ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_3.clock;
}
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_1.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( )
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( )
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_config_offset( )
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( )
{
return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( )
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( )
{
return 16000000;
}
@@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( )
/* --------------------- sifive_fe310_g000_prci ------------ */
-static inline long __metal_driver_sifive_fe310_g000_prci_base( )
+static __inline__ long __metal_driver_sifive_fe310_g000_prci_base( )
{
return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS;
}
-static inline long __metal_driver_sifive_fe310_g000_prci_size( )
+static __inline__ long __metal_driver_sifive_fe310_g000_prci_size( )
{
return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE;
}
-static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( )
+static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( )
{
return &__metal_driver_vtable_sifive_fe310_g000_prci;
}
-/* --------------------- sifive_fu540_c000_l2 ------------ */
+#define __METAL_DT_MAX_MEMORIES 3
-
-#define __METAL_DT_MAX_MEMORIES 2
-
-asm (".weak __metal_memory_table");
+__asm__ (".weak __metal_memory_table");
struct metal_memory *__metal_memory_table[] = {
&__metal_dt_mem_dtim_80000000,
+ &__metal_dt_mem_itim_8000000,
&__metal_dt_mem_spi_10014000};
/* From serial@10013000 */
@@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = {
#define __METAL_DT_MAX_HARTS 1
-asm (".weak __metal_cpu_table");
+#define __METAL_CPU_0_ICACHE_HANDLE 1
+
+__asm__ (".weak __metal_cpu_table");
struct __metal_driver_cpu *__metal_cpu_table[] = {
&__metal_dt_cpu_0};
@@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = {
#define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp)
-/* From local_external_interrupts_0 */
-#define __METAL_DT_SIFIVE_LOCAL_EXINTR0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
-
-#define __METAL_DT_LOCAL_EXTERNAL_INTERRUPTS_0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
-
#define __MEE_DT_MAX_GPIOS 1
-asm (".weak __metal_gpio_table");
+__asm__ (".weak __metal_gpio_table");
struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = {
&__metal_dt_gpio_10012000};
#define __METAL_DT_MAX_BUTTONS 0
-asm (".weak __metal_button_table");
+__asm__ (".weak __metal_button_table");
struct __metal_driver_sifive_gpio_button *__metal_button_table[] = {
NULL };
#define __METAL_DT_MAX_LEDS 3
-asm (".weak __metal_led_table");
+__asm__ (".weak __metal_led_table");
struct __metal_driver_sifive_gpio_led *__metal_led_table[] = {
- &__metal_dt_led_0red,
- &__metal_dt_led_0green,
- &__metal_dt_led_0blue};
+ &__metal_dt_led_0,
+ &__metal_dt_led_1,
+ &__metal_dt_led_2};
#define __METAL_DT_MAX_SWITCHES 0
-asm (".weak __metal_switch_table");
+__asm__ (".weak __metal_switch_table");
struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = {
NULL };
-#define __METAL_DT_MAX_SPIS 1
+#define __METAL_DT_MAX_I2CS 1
-asm (".weak __metal_spi_table");
+__asm__ (".weak __metal_i2c_table");
+struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = {
+ &__metal_dt_i2c_10016000};
+
+#define __METAL_DT_MAX_PWMS 3
+
+__asm__ (".weak __metal_pwm_table");
+struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = {
+ &__metal_dt_pwm_10015000,
+ &__metal_dt_pwm_10025000,
+ &__metal_dt_pwm_10035000};
+
+#define __METAL_DT_MAX_RTCS 1
+
+__asm__ (".weak __metal_rtc_table");
+struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = {
+ &__metal_dt_rtc_10000000};
+
+#define __METAL_DT_MAX_SPIS 3
+
+__asm__ (".weak __metal_spi_table");
struct __metal_driver_sifive_spi0 *__metal_spi_table[] = {
- &__metal_dt_spi_10014000};
+ &__metal_dt_spi_10014000,
+ &__metal_dt_spi_10024000,
+ &__metal_dt_spi_10034000};
+
+#define __METAL_DT_MAX_UARTS 2
+
+__asm__ (".weak __metal_uart_table");
+struct __metal_driver_sifive_uart0 *__metal_uart_table[] = {
+ &__metal_dt_serial_10013000,
+ &__metal_dt_serial_10023000};
+
+#define __METAL_DT_MAX_SIMUARTS 0
+
+__asm__ (".weak __metal_simuart_table");
+struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = {
+ NULL };
+#define __METAL_DT_MAX_WDOGS 1
+
+__asm__ (".weak __metal_wdog_table");
+struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = {
+ &__metal_dt_aon_10000000};
/* From clock@4 */
#define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4)
#define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4)
-#endif /* MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H*/
+#endif /* MACROS_ELSE_METAL_H*/
#endif /* ! __METAL_MACHINE_MACROS */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h
index 8c0cd048b..fd05ab065 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h
@@ -5,128 +5,181 @@
#ifndef ASSEMBLY
-#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
-#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
+#ifndef METAL_INLINE_H
+#define METAL_INLINE_H
#include
/* --------------------- fixed_clock ------------ */
-extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
+extern __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
/* --------------------- fixed_factor_clock ------------ */
/* --------------------- sifive_clint0 ------------ */
-extern inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
-extern inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
-extern inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
-extern inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
/* --------------------- cpu ------------ */
-extern inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
-extern inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
-extern inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
-extern inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
+extern __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu);
/* --------------------- sifive_plic0 ------------ */
-extern inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
-extern inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
-extern inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
-extern inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid);
+
+
+/* --------------------- sifive_buserror0 ------------ */
/* --------------------- sifive_clic0 ------------ */
/* --------------------- sifive_local_external_interrupts0 ------------ */
-extern inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx);
/* --------------------- sifive_global_external_interrupts0 ------------ */
/* --------------------- sifive_gpio0 ------------ */
-extern inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio);
-extern inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio);
-extern inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio);
-extern inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio);
-extern inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio);
+extern __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio);
+extern __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio);
+extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx);
/* --------------------- sifive_gpio_button ------------ */
/* --------------------- sifive_gpio_led ------------ */
-extern inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led);
-extern inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led);
-extern inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led);
+extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led);
+extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led);
+extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led);
/* --------------------- sifive_gpio_switch ------------ */
+/* --------------------- sifive_i2c0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c);
+extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c);
+extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c);
+extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c);
+
+
+/* --------------------- sifive_pwm0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx);
+extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm);
+
+
+/* --------------------- sifive_rtc0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc);
+extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc);
+extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc);
+extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc);
+
+
/* --------------------- sifive_spi0 ------------ */
-extern inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi);
-extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi);
/* --------------------- sifive_test0 ------------ */
+/* --------------------- sifive_trace ------------ */
+
/* --------------------- sifive_uart0 ------------ */
-extern inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart);
-extern inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart);
-extern inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart);
-extern inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart);
-extern inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart);
-extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart);
+extern __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart);
+
+
+/* --------------------- sifive_simuart0 ------------ */
+
+
+/* --------------------- sifive_wdog0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog);
+extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog);
+extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog);
/* --------------------- sifive_fe310_g000_hfrosc ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock);
-extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock);
+extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock);
/* --------------------- sifive_fe310_g000_hfxosc ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock);
+
+
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock);
+extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock);
+extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock);
/* --------------------- sifive_fe310_g000_pll ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock);
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( );
-extern inline long __metal_driver_sifive_fe310_g000_pll_config_offset( );
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_pll_init_rate( );
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( );
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( );
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( );
/* --------------------- fe310_g000_prci ------------ */
-extern inline long __metal_driver_sifive_fe310_g000_prci_base( );
-extern inline long __metal_driver_sifive_fe310_g000_prci_size( );
-extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( );
-
-
-/* --------------------- sifive_fu540_c000_l2 ------------ */
+extern __inline__ long __metal_driver_sifive_fe310_g000_prci_base( );
+extern __inline__ long __metal_driver_sifive_fe310_g000_prci_size( );
+extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( );
/* From clock@0 */
@@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = {
.clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
};
+/* From clock@6 */
+struct __metal_driver_fixed_clock __metal_dt_clock_6 = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
struct metal_memory __metal_dt_mem_dtim_80000000 = {
._base_address = 2147483648UL,
._size = 16384UL,
@@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = {
.A = 1},
};
+struct metal_memory __metal_dt_mem_itim_8000000 = {
+ ._base_address = 134217728UL,
+ ._size = 8192UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
struct metal_memory __metal_dt_mem_spi_10014000 = {
._base_address = 536870912UL,
._size = 500000UL,
@@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = {
.A = 1},
};
+struct metal_memory __metal_dt_mem_spi_10024000 = {
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+struct metal_memory __metal_dt_mem_spi_10034000 = {
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
/* From clint@2000000 */
struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
.controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable,
@@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
/* From cpu@0 */
struct __metal_driver_cpu __metal_dt_cpu_0 = {
.cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
};
/* From interrupt_controller */
@@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = {
.init_done = 0,
};
-/* From local_external_interrupts_0 */
-struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = {
- .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
- .init_done = 0,
-};
+struct metal_pmp __metal_dt_pmp;
/* From gpio@10012000 */
struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = {
.gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio,
};
-/* From led@0red */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = {
+/* From led@0 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
-/* From led@0green */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = {
+/* From led@1 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
-/* From led@0blue */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = {
+/* From led@2 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
+/* From i2c@10016000 */
+struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = {
+ .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c,
+};
+
+/* From pwm@10015000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From pwm@10025000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From pwm@10035000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From aon@10000000 */
+struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = {
+ .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc,
+};
+
/* From spi@10014000 */
struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = {
.spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
};
+/* From spi@10024000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = {
+ .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
+};
+
+/* From spi@10034000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = {
+ .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
+};
+
/* From serial@10013000 */
struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = {
.uart.vtable = &__metal_driver_vtable_sifive_uart0.uart,
};
+/* From serial@10023000 */
+struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart,
+};
+
+/* From aon@10000000 */
+struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = {
+ .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog,
+};
+
/* From clock@3 */
struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock,
@@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock,
};
+/* From clock@7 */
+struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = {
+ .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.clock,
+};
+
/* From clock@4 */
struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock,
@@ -242,8 +376,9 @@ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = {
/* From prci@10008000 */
struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = {
+ .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci,
};
-#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/
+#endif /* METAL_INLINE_H*/
#endif /* ! ASSEMBLY */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h
index 4ecd3e336..d517b5859 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h
@@ -3,8 +3,8 @@
/* ----------------------------------- */
/* ----------------------------------- */
-#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
-#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
+#ifndef METAL_PLATFORM_H
+#define METAL_PLATFORM_H
/* From clock@0 */
#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL
@@ -13,7 +13,10 @@
#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL
/* From clock@5 */
-#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL
+#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL
+
+/* From clock@6 */
+#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL
#define METAL_FIXED_CLOCK
@@ -35,15 +38,18 @@
#define METAL_RISCV_PLIC0_0_SIZE 67108864UL
#define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL
#define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL
-#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 27UL
-#define METAL_RISCV_PLIC0_0_RISCV_NDEV 27UL
+#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 53UL
+#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL
#define METAL_RISCV_PLIC0
#define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL
#define METAL_RISCV_PLIC0_PENDING_BASE 4096UL
#define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL
-#define METAL_RISCV_PLIC0_THRESHOLD 2097152UL
-#define METAL_RISCV_PLIC0_CLAIM 2097156UL
+#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL
+#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL
+#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL
+#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL
+#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL
/* From aon@10000000 */
#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
@@ -111,6 +117,10 @@
#define METAL_SIFIVE_FE310_G000_HFXOSC
+/* From clock@7 */
+
+#define METAL_SIFIVE_FE310_G000_LFROSC
+
/* From prci@10008000 */
#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL
#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL
@@ -153,11 +163,11 @@
#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL
#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL
-/* From led@0red */
+/* From led@0 */
-/* From led@0green */
+/* From led@1 */
-/* From led@0blue */
+/* From led@2 */
#define METAL_SIFIVE_GPIO_LEDS
@@ -176,16 +186,24 @@
#define METAL_SIFIVE_I2C0_COMMAND 16UL
#define METAL_SIFIVE_I2C0_STATUS 16UL
-/* From local_external_interrupts_0 */
-
-#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0
-
/* From pwm@10015000 */
#define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL
#define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL
#define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL
#define METAL_SIFIVE_PWM0_0_SIZE 4096UL
+/* From pwm@10025000 */
+#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL
+#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL
+#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL
+#define METAL_SIFIVE_PWM0_1_SIZE 4096UL
+
+/* From pwm@10035000 */
+#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL
+#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL
+#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL
+#define METAL_SIFIVE_PWM0_2_SIZE 4096UL
+
#define METAL_SIFIVE_PWM0
#define METAL_SIFIVE_PWM0_PWMCFG 0UL
#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL
@@ -195,12 +213,37 @@
#define METAL_SIFIVE_PWM0_PWMCMP2 40UL
#define METAL_SIFIVE_PWM0_PWMCMP3 44UL
+/* From aon@10000000 */
+#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL
+#define METAL_SIFIVE_AON0_0_SIZE 32768UL
+
+#define METAL_SIFIVE_RTC0
+#define METAL_SIFIVE_RTC0_RTCCFG 64UL
+#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL
+#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL
+#define METAL_SIFIVE_RTC0_RTCS 80UL
+#define METAL_SIFIVE_RTC0_RTCCMP0 96UL
+
/* From spi@10014000 */
#define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL
#define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL
#define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL
#define METAL_SIFIVE_SPI0_0_SIZE 4096UL
+/* From spi@10024000 */
+#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL
+#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL
+#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL
+#define METAL_SIFIVE_SPI0_1_SIZE 4096UL
+
+/* From spi@10034000 */
+#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL
+#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL
+#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL
+#define METAL_SIFIVE_SPI0_2_SIZE 4096UL
+
#define METAL_SIFIVE_SPI0
#define METAL_SIFIVE_SPI0_SCKDIV 0UL
#define METAL_SIFIVE_SPI0_SCKMODE 4UL
@@ -225,6 +268,12 @@
#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL
#define METAL_SIFIVE_UART0_0_SIZE 4096UL
+/* From serial@10023000 */
+#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL
+#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL
+#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL
+#define METAL_SIFIVE_UART0_1_SIZE 4096UL
+
#define METAL_SIFIVE_UART0
#define METAL_SIFIVE_UART0_TXDATA 0UL
#define METAL_SIFIVE_UART0_RXDATA 4UL
@@ -234,4 +283,20 @@
#define METAL_SIFIVE_UART0_IP 20UL
#define METAL_SIFIVE_UART0_DIV 24UL
-#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/
+/* From aon@10000000 */
+#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL
+#define METAL_SIFIVE_AON0_0_SIZE 32768UL
+
+#define METAL_SIFIVE_WDOG0
+#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL
+#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL
+#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL
+#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL
+#define METAL_SIFIVE_WDOG0_WDOGS 16UL
+#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL
+#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL
+#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL
+
+#endif /* METAL_PLATFORM_H*/
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h
index b62d8b25a..f009e9ecc 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h
@@ -4,8 +4,8 @@
#ifndef METAL__MEMORY_H
#define METAL__MEMORY_H
-#include
#include
+#include
/*!
* @file memory.h
@@ -14,20 +14,20 @@
*/
struct _metal_memory_attributes {
- int R : 1;
- int W : 1;
- int X : 1;
- int C : 1;
- int A : 1;
+ unsigned int R : 1;
+ unsigned int W : 1;
+ unsigned int X : 1;
+ unsigned int C : 1;
+ unsigned int A : 1;
};
/*!
* @brief A handle for a memory block
*/
struct metal_memory {
- const uintptr_t _base_address;
- const size_t _size;
- const struct _metal_memory_attributes _attrs;
+ const uintptr_t _base_address;
+ const size_t _size;
+ const struct _metal_memory_attributes _attrs;
};
/*!
@@ -37,7 +37,8 @@ struct metal_memory {
* that address is mapped.
*
* @param address The address to query
- * @return The memory block handle, or NULL if the address is not mapped to a memory block
+ * @return The memory block handle, or NULL if the address is not mapped to a
+ * memory block
*/
struct metal_memory *metal_get_memory_from_address(const uintptr_t address);
@@ -46,8 +47,9 @@ struct metal_memory *metal_get_memory_from_address(const uintptr_t address);
* @param memory The handle for the memory block
* @return The base address of the memory block
*/
-inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory) {
- return memory->_base_address;
+__inline__ uintptr_t
+metal_memory_get_base_address(const struct metal_memory *memory) {
+ return memory->_base_address;
}
/*!
@@ -55,8 +57,8 @@ inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory
* @param memory The handle for the memory block
* @return The size of the memory block
*/
-inline size_t metal_memory_get_size(const struct metal_memory *memory) {
- return memory->_size;
+__inline__ size_t metal_memory_get_size(const struct metal_memory *memory) {
+ return memory->_size;
}
/*!
@@ -64,8 +66,9 @@ inline size_t metal_memory_get_size(const struct metal_memory *memory) {
* @param memory The handle for the memory block
* @return nonzero if the memory block supports atomic operations
*/
-inline int metal_memory_supports_atomics(const struct metal_memory *memory) {
- return memory->_attrs.A;
+__inline__ int
+metal_memory_supports_atomics(const struct metal_memory *memory) {
+ return memory->_attrs.A;
}
/*!
@@ -73,9 +76,8 @@ inline int metal_memory_supports_atomics(const struct metal_memory *memory) {
* @param memory The handle for the memory block
* @return nonzero if the memory block is cachable
*/
-inline int metal_memory_is_cachable(const struct metal_memory *memory) {
- return memory->_attrs.C;
+__inline__ int metal_memory_is_cachable(const struct metal_memory *memory) {
+ return memory->_attrs.C;
}
#endif /* METAL__MEMORY_H */
-
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h
index 9121b10a1..38ab1b9a4 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h
@@ -12,14 +12,14 @@
* The Physical Memory Protection (PMP) interface on RISC-V cores
* is a form of memory protection unit which allows for a finite number
* of physical memory regions to be configured with certain access
- * permissions.
+ * permissions.
*
* Additional information about the use and configuration rules for PMPs
* can be found by reading the RISC-V Privileged Architecture Specification.
*/
-#include
#include
+#include
struct metal_pmp;
@@ -28,11 +28,11 @@ struct metal_pmp;
*/
enum metal_pmp_address_mode {
/*! @brief Disable the PMP region */
- METAL_PMP_OFF = 0,
+ METAL_PMP_OFF = 0,
/*! @brief Use Top-of-Range mode */
- METAL_PMP_TOR = 1,
+ METAL_PMP_TOR = 1,
/*! @brief Use naturally-aligned 4-byte region mode */
- METAL_PMP_NA4 = 2,
+ METAL_PMP_NA4 = 2,
/*! @brief Use naturally-aligned power-of-two mode */
METAL_PMP_NAPOT = 3
};
@@ -42,11 +42,11 @@ enum metal_pmp_address_mode {
*/
struct metal_pmp_config {
/*! @brief Sets whether reads to the PMP region succeed */
- int R : 1;
+ unsigned int R : 1;
/*! @brief Sets whether writes to the PMP region succeed */
- int W : 1;
+ unsigned int W : 1;
/*! @brief Sets whether the PMP region is executable */
- int X : 1;
+ unsigned int X : 1;
/*! @brief Sets the addressing mode of the PMP region */
enum metal_pmp_address_mode A : 2;
@@ -56,7 +56,7 @@ struct metal_pmp_config {
/*! @brief Sets whether the PMP region is locked */
enum metal_pmp_locked {
METAL_PMP_UNLOCKED = 0,
- METAL_PMP_LOCKED = 1
+ METAL_PMP_LOCKED = 1
} L : 1;
};
@@ -73,6 +73,11 @@ struct metal_pmp {
*/
struct metal_pmp *metal_pmp_get_device(void);
+/*!
+ * @brief Get the number of pmp regions for the hartid
+ */
+int metal_pmp_num_regions(int hartid);
+
/*!
* @brief Initialize the PMP
* @param pmp The PMP device handle to be initialized
@@ -96,9 +101,10 @@ void metal_pmp_init(struct metal_pmp *pmp);
* @param address The desired address of the PMP region
* @return 0 upon success
*/
-int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address);
+int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region,
+ struct metal_pmp_config config, size_t address);
-/*!
+/*!
* @brief Get the configuration for a PMP region
* @param pmp The PMP device handle
* @param region The PMP region to read
@@ -106,7 +112,8 @@ int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct meta
* @param address Variable to store the PMP region address
* @return 0 if the region is read successfully
*/
-int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address);
+int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region,
+ struct metal_pmp_config *config, size_t *address);
/*!
* @brief Lock a PMP region
@@ -123,7 +130,8 @@ int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region);
* @param address The desired address of the PMP region
* @return 0 if the address is successfully set
*/
-int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address);
+int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region,
+ size_t address);
/*!
* @brief Get the address of a PMP region
@@ -140,7 +148,8 @@ size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region);
* @param mode The PMP addressing mode to set
* @return 0 if the addressing mode is successfully set
*/
-int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode);
+int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region,
+ enum metal_pmp_address_mode mode);
/*!
* @brief Get the addressing mode of a PMP region
@@ -148,7 +157,8 @@ int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum
* @param region The PMP region to read
* @return The address mode of the PMP region
*/
-enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region);
+enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp,
+ unsigned int region);
/*!
* @brief Set the executable bit for a PMP region
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h
index c5212e5d1..522e7efe0 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h
@@ -16,9 +16,9 @@
#include
enum metal_privilege_mode {
- METAL_PRIVILEGE_USER = 0,
- METAL_PRIVILEGE_SUPERVISOR = 1,
- METAL_PRIVELEGE_MACHINE = 3,
+ METAL_PRIVILEGE_USER = 0,
+ METAL_PRIVILEGE_SUPERVISOR = 1,
+ METAL_PRIVILEGE_MACHINE = 3,
};
#if __riscv_xlen == 32
@@ -34,89 +34,89 @@ typedef uint64_t metal_freg_t;
#endif
struct metal_register_file {
- metal_xreg_t ra;
- metal_xreg_t sp;
- metal_xreg_t gp;
- metal_xreg_t tp;
+ metal_xreg_t ra;
+ metal_xreg_t sp;
+ metal_xreg_t gp;
+ metal_xreg_t tp;
- metal_xreg_t t0;
- metal_xreg_t t1;
- metal_xreg_t t2;
+ metal_xreg_t t0;
+ metal_xreg_t t1;
+ metal_xreg_t t2;
- metal_xreg_t s0;
- metal_xreg_t s1;
+ metal_xreg_t s0;
+ metal_xreg_t s1;
- metal_xreg_t a0;
- metal_xreg_t a1;
- metal_xreg_t a2;
- metal_xreg_t a3;
- metal_xreg_t a4;
- metal_xreg_t a5;
+ metal_xreg_t a0;
+ metal_xreg_t a1;
+ metal_xreg_t a2;
+ metal_xreg_t a3;
+ metal_xreg_t a4;
+ metal_xreg_t a5;
#ifndef __riscv_32e
- metal_xreg_t a6;
- metal_xreg_t a7;
+ metal_xreg_t a6;
+ metal_xreg_t a7;
- metal_xreg_t s2;
- metal_xreg_t s3;
- metal_xreg_t s4;
- metal_xreg_t s5;
- metal_xreg_t s6;
- metal_xreg_t s7;
- metal_xreg_t s8;
- metal_xreg_t s9;
- metal_xreg_t s10;
- metal_xreg_t s11;
+ metal_xreg_t s2;
+ metal_xreg_t s3;
+ metal_xreg_t s4;
+ metal_xreg_t s5;
+ metal_xreg_t s6;
+ metal_xreg_t s7;
+ metal_xreg_t s8;
+ metal_xreg_t s9;
+ metal_xreg_t s10;
+ metal_xreg_t s11;
- metal_xreg_t t3;
- metal_xreg_t t4;
- metal_xreg_t t5;
- metal_xreg_t t6;
+ metal_xreg_t t3;
+ metal_xreg_t t4;
+ metal_xreg_t t5;
+ metal_xreg_t t6;
#endif /* __riscv_32e */
#ifdef __riscv_flen
- metal_freg_t ft0;
- metal_freg_t ft1;
- metal_freg_t ft2;
- metal_freg_t ft3;
- metal_freg_t ft4;
- metal_freg_t ft5;
- metal_freg_t ft6;
- metal_freg_t ft7;
+ metal_freg_t ft0;
+ metal_freg_t ft1;
+ metal_freg_t ft2;
+ metal_freg_t ft3;
+ metal_freg_t ft4;
+ metal_freg_t ft5;
+ metal_freg_t ft6;
+ metal_freg_t ft7;
- metal_freg_t fs0;
- metal_freg_t fs1;
+ metal_freg_t fs0;
+ metal_freg_t fs1;
- metal_freg_t fa0;
- metal_freg_t fa1;
- metal_freg_t fa2;
- metal_freg_t fa3;
- metal_freg_t fa4;
- metal_freg_t fa5;
- metal_freg_t fa6;
- metal_freg_t fa7;
+ metal_freg_t fa0;
+ metal_freg_t fa1;
+ metal_freg_t fa2;
+ metal_freg_t fa3;
+ metal_freg_t fa4;
+ metal_freg_t fa5;
+ metal_freg_t fa6;
+ metal_freg_t fa7;
- metal_freg_t fs2;
- metal_freg_t fs3;
- metal_freg_t fs4;
- metal_freg_t fs5;
- metal_freg_t fs6;
- metal_freg_t fs7;
- metal_freg_t fs8;
- metal_freg_t fs9;
- metal_freg_t fs10;
- metal_freg_t fs11;
+ metal_freg_t fs2;
+ metal_freg_t fs3;
+ metal_freg_t fs4;
+ metal_freg_t fs5;
+ metal_freg_t fs6;
+ metal_freg_t fs7;
+ metal_freg_t fs8;
+ metal_freg_t fs9;
+ metal_freg_t fs10;
+ metal_freg_t fs11;
- metal_freg_t ft8;
- metal_freg_t ft9;
- metal_freg_t ft10;
- metal_freg_t ft11;
+ metal_freg_t ft8;
+ metal_freg_t ft9;
+ metal_freg_t ft10;
+ metal_freg_t ft11;
#endif /* __riscv_flen */
};
-typedef void (*metal_privilege_entry_point_t)();
+typedef void (*metal_privilege_entry_point_t)(void);
void metal_privilege_drop_to_mode(enum metal_privilege_mode mode,
- struct metal_register_file regfile,
- metal_privilege_entry_point_t entry_point);
+ struct metal_register_file regfile,
+ metal_privilege_entry_point_t entry_point);
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h
new file mode 100644
index 000000000..600d5a02b
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h
@@ -0,0 +1,162 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__PWM_H
+#define METAL__PWM_H
+
+/*! @brief Enums for PWM running modes. */
+typedef enum {
+ METAL_PWM_CONTINUOUS = 0,
+ METAL_PWM_ONE_SHOT = 1
+} metal_pwm_run_mode_t;
+
+/*! @brief Enums for Phase correct PWM. */
+typedef enum {
+ METAL_PWM_PHASE_CORRECT_DISABLE = 0,
+ METAL_PWM_PHASE_CORRECT_ENABLE = 1,
+} metal_pwm_phase_correct_t;
+
+/*! @brief Enums for Interrupts enable/disable. */
+typedef enum {
+ METAL_PWM_INTERRUPT_DISABLE = 0,
+ METAL_PWM_INTERRUPT_ENABLE = 1,
+} metal_pwm_interrupt_t;
+
+struct metal_pwm;
+
+/*! @brief vtable for PWM. */
+struct metal_pwm_vtable {
+ int (*enable)(struct metal_pwm *pwm);
+ int (*disable)(struct metal_pwm *pwm);
+ int (*set_freq)(struct metal_pwm *pwm, unsigned int idx, unsigned int freq);
+ int (*set_duty)(struct metal_pwm *pwm, unsigned int idx, unsigned int duty,
+ metal_pwm_phase_correct_t phase_corr);
+ unsigned int (*get_duty)(struct metal_pwm *pwm, unsigned int idx);
+ unsigned int (*get_freq)(struct metal_pwm *pwm, unsigned int idx);
+ int (*trigger)(struct metal_pwm *pwm, unsigned int idx,
+ metal_pwm_run_mode_t mode);
+ int (*stop)(struct metal_pwm *pwm, unsigned int idx);
+ int (*cfg_interrupt)(struct metal_pwm *pwm, metal_pwm_interrupt_t flag);
+ int (*clr_interrupt)(struct metal_pwm *pwm, unsigned int idx);
+ struct metal_interrupt *(*get_interrupt_controller)(struct metal_pwm *pwm);
+ int (*get_interrupt_id)(struct metal_pwm *pwm, unsigned int idx);
+};
+
+/*! @brief A handle for a PWM device. */
+struct metal_pwm {
+ const struct metal_pwm_vtable *vtable;
+};
+
+/*! @brief Gets a PWM device handle.
+ * @param device_num The index of the desired PWM device.
+ * @return A handle to the PWM device, or NULL if the device does not exist.*/
+struct metal_pwm *metal_pwm_get_device(unsigned int device_num);
+
+/*! @brief Enables PWM operation.
+ * @param pwm The handle for the PWM device to initialize.
+ * @return 0 If no error.*/
+inline int metal_pwm_enable(struct metal_pwm *pwm) {
+ return pwm->vtable->enable(pwm);
+}
+
+/*! @brief Disables PWM operation.
+ * @param pwm The handle for the PWM device to be disabled.
+ * @return 0 If no error.*/
+inline int metal_pwm_disable(struct metal_pwm *pwm) {
+ return pwm->vtable->disable(pwm);
+}
+
+/*! @brief Sets frequency in Hz for a given PWM instance.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @param freq PWM frequency in Hz.
+ * @return 0 If no error.*/
+inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx,
+ unsigned int freq) {
+ return pwm->vtable->set_freq(pwm, idx, freq);
+}
+
+/*! @brief Sets duty cycle in percent values [0 - 100] for a given PWM instance.
+ * Phase correct mode provides center aligned PWM waveform output.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @param duty PWM duty cycle value.
+ * @param phase_corr Enable / Disable phase correct mode.
+ * @return 0 If no error.*/
+inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx,
+ unsigned int duty,
+ metal_pwm_phase_correct_t phase_corr) {
+ return pwm->vtable->set_duty(pwm, idx, duty, phase_corr);
+}
+
+/*! @brief Gets duty cycle in percent values [0 - 100] for a given PWM instance.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return PWM duty cycle value.*/
+inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm,
+ unsigned int idx) {
+ return pwm->vtable->get_duty(pwm, idx);
+}
+
+/*! @brief Gets frequency in Hz for a given PWM instance.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return PWM frequency in Hz.*/
+inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm,
+ unsigned int idx) {
+ return pwm->vtable->get_freq(pwm, idx);
+}
+
+/*! @brief Starts a PWM instance in selected run mode (continuous/one shot).
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return 0 If no error.*/
+inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx,
+ metal_pwm_run_mode_t mode) {
+ return pwm->vtable->trigger(pwm, idx, mode);
+}
+
+/*! @brief Stops a running PWM instance in continuous mode.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return 0 If no error.*/
+inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx) {
+ return pwm->vtable->stop(pwm, idx);
+}
+
+/*! @brief Enable or Disable PWM interrupts.
+ * @param pwm PWM device handle.
+ * @param flag PWM interrupt enable flag.
+ * @return 0 If no error.*/
+inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm,
+ metal_pwm_interrupt_t flag) {
+ return pwm->vtable->cfg_interrupt(pwm, flag);
+}
+
+/*! @brief Clears pending interrupt flags.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return 0 If no error.*/
+inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, unsigned int idx) {
+ return pwm->vtable->clr_interrupt(pwm, idx);
+}
+
+/*! @brief Get the interrupt controller of the PWM peripheral.
+ * The interrupt controller must be initialized before any interrupts can be
+ * registered or enabled with it.
+ * @param pwm PWM device handle.
+ * @return The handle for the PWM interrupt controller.*/
+inline struct metal_interrupt *
+metal_pwm_interrupt_controller(struct metal_pwm *pwm) {
+ return pwm->vtable->get_interrupt_controller(pwm);
+}
+
+/*! @brief Get the interrupt ID of the PWM peripheral.
+ * @param pwm PWM device handle.
+ * @param idx PWM channel id.
+ * @return The PWM interrupt id.*/
+inline int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx) {
+ return pwm->vtable->get_interrupt_id(pwm, idx);
+}
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h
new file mode 100644
index 000000000..e1b798268
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h
@@ -0,0 +1,137 @@
+/* Copyright 2019 SiFive, Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__RTC_H
+#define METAL__RTC_H
+
+#include
+
+/*!
+ * @file rtc.h
+ * @brief API for Real-Time Clocks
+ */
+
+struct metal_rtc;
+
+/*!
+ * @brief List of RTC run behaviors
+ */
+enum metal_rtc_run_option {
+ METAL_RTC_STOP = 0,
+ METAL_RTC_RUN,
+};
+
+struct metal_rtc_vtable {
+ uint64_t (*get_rate)(const struct metal_rtc *const rtc);
+ uint64_t (*set_rate)(const struct metal_rtc *const rtc,
+ const uint64_t rate);
+ uint64_t (*get_compare)(const struct metal_rtc *const rtc);
+ uint64_t (*set_compare)(const struct metal_rtc *const rtc,
+ const uint64_t compare);
+ uint64_t (*get_count)(const struct metal_rtc *const rtc);
+ uint64_t (*set_count)(const struct metal_rtc *const rtc,
+ const uint64_t count);
+ int (*run)(const struct metal_rtc *const rtc,
+ const enum metal_rtc_run_option option);
+ struct metal_interrupt *(*get_interrupt)(const struct metal_rtc *const rtc);
+ int (*get_interrupt_id)(const struct metal_rtc *const rtc);
+};
+
+/*!
+ * @brief Handle for a Real-Time Clock
+ */
+struct metal_rtc {
+ const struct metal_rtc_vtable *vtable;
+};
+
+/*!
+ * @brief Get the rate of the RTC
+ * @return The rate in Hz
+ */
+inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc) {
+ return rtc->vtable->get_rate(rtc);
+}
+
+/*!
+ * @brief Set (if possible) the rate of the RTC
+ * @return The new rate of the RTC (not guaranteed to be the same as requested)
+ */
+inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc,
+ const uint64_t rate) {
+ return rtc->vtable->set_rate(rtc, rate);
+}
+
+/*!
+ * @brief Get the compare value of the RTC
+ * @return The compare value
+ */
+inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc) {
+ return rtc->vtable->get_compare(rtc);
+}
+
+/*!
+ * @brief Set the compare value of the RTC
+ * @return The set compare value (not guaranteed to be exactly the requested
+ * value)
+ *
+ * The RTC device might impose limits on the maximum compare value or the
+ * granularity of the compare value.
+ */
+inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc,
+ const uint64_t compare) {
+ return rtc->vtable->set_compare(rtc, compare);
+}
+
+/*!
+ * @brief Get the current count of the RTC
+ * @return The count
+ */
+inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc) {
+ return rtc->vtable->get_count(rtc);
+}
+
+/*!
+ * @brief Set the current count of the RTC
+ * @return The set value of the count (not guaranteed to be exactly the
+ * requested value)
+ *
+ * The RTC device might impose limits on the maximum value of the count
+ */
+inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc,
+ const uint64_t count) {
+ return rtc->vtable->set_count(rtc, count);
+}
+
+/*!
+ * @brief Start or stop the RTC
+ * @return 0 if the RTC was successfully started/stopped
+ */
+inline int metal_rtc_run(const struct metal_rtc *const rtc,
+ const enum metal_rtc_run_option option) {
+ return rtc->vtable->run(rtc, option);
+}
+
+/*!
+ * @brief Get the interrupt handle for the RTC compare
+ * @return The interrupt handle
+ */
+inline struct metal_interrupt *
+metal_rtc_get_interrupt(const struct metal_rtc *const rtc) {
+ return rtc->vtable->get_interrupt(rtc);
+}
+
+/*!
+ * @brief Get the interrupt ID for the RTC compare
+ * @return The interrupt ID
+ */
+inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc) {
+ return rtc->vtable->get_interrupt_id(rtc);
+}
+
+/*!
+ * @brief Get the handle for an RTC by index
+ * @return The RTC handle, or NULL if none is available at that index
+ */
+struct metal_rtc *metal_rtc_get_device(int index);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h
new file mode 100644
index 000000000..51683cc76
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h
@@ -0,0 +1,13 @@
+/* Copyright 2020 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__SCRUB_H
+#define METAL__SCRUB_H
+
+/*! @brief Writes specified memory region with zeros.
+ * @param address Start memory address for zero-scrub.
+ * @param size Memory region size in bytes.
+ * @return None.*/
+void metal_mem_scrub(void *address, int size);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h
index 3bebfa742..7a43437b7 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h
@@ -12,15 +12,20 @@
struct __metal_shutdown;
struct __metal_shutdown_vtable {
- void (*exit)(const struct __metal_shutdown *sd, int code) __attribute__((noreturn));
+ void (*exit)(const struct __metal_shutdown *sd, int code)
+ __attribute__((noreturn));
};
struct __metal_shutdown {
const struct __metal_shutdown_vtable *vtable;
};
-inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn));
-inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) { sd->vtable->exit(sd, code); }
+__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd,
+ int code) __attribute__((noreturn));
+__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd,
+ int code) {
+ sd->vtable->exit(sd, code);
+}
/*!
* @brief The public METAL shutdown interface
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h
index b011fe3ce..7e4b04ae2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h
@@ -9,11 +9,7 @@ struct metal_spi;
/*! @brief The configuration for a SPI transfer */
struct metal_spi_config {
/*! @brief The protocol for the SPI transfer */
- enum {
- METAL_SPI_SINGLE,
- METAL_SPI_DUAL,
- METAL_SPI_QUAD
- } protocol;
+ enum { METAL_SPI_SINGLE, METAL_SPI_DUAL, METAL_SPI_QUAD } protocol;
/*! @brief The polarity of the SPI transfer, equivalent to CPOL */
unsigned int polarity : 1;
@@ -25,11 +21,24 @@ struct metal_spi_config {
unsigned int cs_active_high : 1;
/*! @brief The chip select ID to activate for the SPI transfer */
unsigned int csid;
+ /*! @brief The spi command frame number (cycles = num * frame_len) */
+ unsigned int cmd_num;
+ /*! @brief The spi address frame number */
+ unsigned int addr_num;
+ /*! @brief The spi dummy frame number */
+ unsigned int dummy_num;
+ /*! @brief The Dual/Quad spi mode selection.*/
+ enum {
+ MULTI_WIRE_ALL,
+ MULTI_WIRE_DATA_ONLY,
+ MULTI_WIRE_ADDR_DATA
+ } multi_wire;
};
struct metal_spi_vtable {
void (*init)(struct metal_spi *spi, int baud_rate);
- int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf);
+ int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config,
+ size_t len, char *tx_buf, char *rx_buf);
int (*get_baud_rate)(struct metal_spi *spi);
int (*set_baud_rate)(struct metal_spi *spi, int baud_rate);
};
@@ -42,23 +51,29 @@ struct metal_spi {
/*! @brief Get a handle for a SPI device
* @param device_num The index of the desired SPI device
* @return A handle to the SPI device, or NULL if the device does not exist*/
-struct metal_spi *metal_spi_get_device(int device_num);
+struct metal_spi *metal_spi_get_device(unsigned int device_num);
/*! @brief Initialize a SPI device with a certain baud rate
* @param spi The handle for the SPI device to initialize
* @param baud_rate The baud rate to set the SPI device to
*/
-inline void metal_spi_init(struct metal_spi *spi, int baud_rate) { spi->vtable->init(spi, baud_rate); }
+__inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate) {
+ spi->vtable->init(spi, baud_rate);
+}
/*! @brief Perform a SPI transfer
* @param spi The handle for the SPI device to perform the transfer
* @param config The configuration for the SPI transfer.
* @param len The number of bytes to transfer
- * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If NULL, the SPI will transfer the value 0.
- * @param rx_buf The buffer to receive data into. Must be len bytes long. If NULL, the SPI will ignore received bytes.
+ * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If
+ * NULL, the SPI will transfer the value 0.
+ * @param rx_buf The buffer to receive data into. Must be len bytes long. If
+ * NULL, the SPI will ignore received bytes.
* @return 0 if the transfer succeeds
*/
-inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf) {
+__inline__ int metal_spi_transfer(struct metal_spi *spi,
+ struct metal_spi_config *config, size_t len,
+ char *tx_buf, char *rx_buf) {
return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf);
}
@@ -66,13 +81,17 @@ inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *co
* @param spi The handle for the SPI device
* @return The baud rate in Hz
*/
-inline int metal_spi_get_baud_rate(struct metal_spi *spi) { return spi->vtable->get_baud_rate(spi); }
+__inline__ int metal_spi_get_baud_rate(struct metal_spi *spi) {
+ return spi->vtable->get_baud_rate(spi);
+}
/*! @brief Set the current baud rate of the SPI device
* @param spi The handle for the SPI device
* @param baud_rate The desired baud rate of the SPI device
* @return 0 if the baud rate is successfully changed
*/
-inline int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { return spi->vtable->set_baud_rate(spi, baud_rate); }
+__inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) {
+ return spi->vtable->set_baud_rate(spi, baud_rate);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h
index d1c35bc93..695b21ae3 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h
@@ -15,7 +15,7 @@ struct metal_switch;
struct metal_switch_vtable {
int (*switch_exist)(struct metal_switch *sw, char *label);
- struct metal_interrupt* (*interrupt_controller)(struct metal_switch *sw);
+ struct metal_interrupt *(*interrupt_controller)(struct metal_switch *sw);
int (*get_interrupt_id)(struct metal_switch *sw);
};
@@ -29,23 +29,28 @@ struct metal_switch {
/*!
* @brief Get a handle for a switch
* @param label The DeviceTree label for the desired switch
- * @return A handle to the switch, or NULL if none is found for the requested label
+ * @return A handle to the switch, or NULL if none is found for the requested
+ * label
*/
-struct metal_switch* metal_switch_get(char *label);
+struct metal_switch *metal_switch_get(char *label);
/*!
* @brief Get the interrupt controller for a switch
* @param sw The handle for the switch
* @return The interrupt controller handle
*/
-inline struct metal_interrupt*
- metal_switch_interrupt_controller(struct metal_switch *sw) { return sw->vtable->interrupt_controller(sw); }
+__inline__ struct metal_interrupt *
+metal_switch_interrupt_controller(struct metal_switch *sw) {
+ return sw->vtable->interrupt_controller(sw);
+}
/*!
* @brief Get the interrupt id for a switch
* @param sw The handle for the switch
* @return The interrupt ID for the switch
*/
-inline int metal_switch_get_interrupt_id(struct metal_switch *sw) { return sw->vtable->get_interrupt_id(sw); }
+__inline__ int metal_switch_get_interrupt_id(struct metal_switch *sw) {
+ return sw->vtable->get_interrupt_id(sw);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h
new file mode 100644
index 000000000..a5a880f0d
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h
@@ -0,0 +1,21 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__TIME_H
+#define METAL__TIME_H
+
+#include
+#ifndef __SEGGER_LIBC__
+#include
+#endif
+
+/*!
+ * @file time.h
+ * @brief API for dealing with time
+ */
+
+int metal_gettimeofday(struct timeval *tp, void *tzp);
+
+time_t metal_time(void);
+
+#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h
index eeae1f60b..5d5132de5 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h
@@ -23,9 +23,10 @@ int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount);
* @param timebase The variable to hold the value
* @return 0 upon success
*/
-int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase);
+int metal_timer_get_timebase_frequency(int hartid,
+ unsigned long long *timebase);
-/*!
+/*!
* @brief Set the machine timer tick interval in seconds
* @param hartid The hart ID to read the timebase of
* @param second The number of seconds to set the tick interval to
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h
index d2583e3be..5d41783ae 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h
@@ -14,10 +14,22 @@
*
* Write a character to the default output device, which for most
* targets is the UART serial port.
- *
+ *
* @param c The character to write to the terminal
* @return 0 on success, or -1 on failure.
*/
-int metal_tty_putc(unsigned char c);
+int metal_tty_putc(int c);
+
+/*!
+ * @brief Get a byte from the default output device
+ *
+ * The default output device, is typically the UART serial port.
+ *
+ * This call is non-blocking, if nothing is ready c==-1
+ * if something is ready, then c=[0x00 to 0xff] byte value.
+ *
+ * @return 0 on success, or -1 on failure.
+ */
+int metal_tty_getc(int *c);
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h
index 611792a6c..856970ac2 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h
@@ -12,15 +12,25 @@
#include
struct metal_uart;
-
+#undef getc
+#undef putc
struct metal_uart_vtable {
void (*init)(struct metal_uart *uart, int baud_rate);
- int (*putc)(struct metal_uart *uart, unsigned char c);
- int (*getc)(struct metal_uart *uart, unsigned char *c);
+ int (*putc)(struct metal_uart *uart, int c);
+ int (*txready)(struct metal_uart *uart);
+ int (*getc)(struct metal_uart *uart, int *c);
int (*get_baud_rate)(struct metal_uart *uart);
int (*set_baud_rate)(struct metal_uart *uart, int baud_rate);
- struct metal_interrupt* (*controller_interrupt)(struct metal_uart *uart);
+ struct metal_interrupt *(*controller_interrupt)(struct metal_uart *uart);
int (*get_interrupt_id)(struct metal_uart *uart);
+ int (*tx_interrupt_enable)(struct metal_uart *uart);
+ int (*tx_interrupt_disable)(struct metal_uart *uart);
+ int (*rx_interrupt_enable)(struct metal_uart *uart);
+ int (*rx_interrupt_disable)(struct metal_uart *uart);
+ int (*set_tx_watermark)(struct metal_uart *uart, size_t length);
+ size_t (*get_tx_watermark)(struct metal_uart *uart);
+ int (*set_rx_watermark)(struct metal_uart *uart, size_t length);
+ size_t (*get_rx_watermark)(struct metal_uart *uart);
};
/*!
@@ -30,16 +40,25 @@ struct metal_uart {
const struct metal_uart_vtable *vtable;
};
+/*! @brief Get a handle for a UART device
+ * @param device_num The index of the desired UART device
+ * @return A handle to the UART device, or NULL if the device does not exist*/
+struct metal_uart *metal_uart_get_device(unsigned int device_num);
+
/*!
* @brief Initialize UART device
-
- * Initialize the UART device described by the UART handle. This function must be called before any
- * other method on the UART can be invoked. It is invalid to initialize a UART more than once.
+
+ * Initialize the UART device described by the UART handle. This function must
+ be called before any
+ * other method on the UART can be invoked. It is invalid to initialize a UART
+ more than once.
*
* @param uart The UART device handle
* @param baud_rate the baud rate to set the UART to
*/
-inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uart->vtable->init(uart, baud_rate); }
+__inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) {
+ uart->vtable->init(uart, baud_rate);
+}
/*!
* @brief Output a character over the UART
@@ -47,22 +66,40 @@ inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uar
* @param c The character to send over the UART
* @return 0 upon success
*/
-inline int metal_uart_putc(struct metal_uart *uart, unsigned char c) { return uart->vtable->putc(uart, c); }
+__inline__ int metal_uart_putc(struct metal_uart *uart, int c) {
+ return uart->vtable->putc(uart, c);
+}
+
+/*!
+ * @brief Test, determine if tx output is blocked(full/busy)
+ * @param uart The UART device handle
+ * @return 0 not blocked
+ */
+__inline__ int metal_uart_txready(struct metal_uart *uart) {
+ return uart->vtable->txready(uart);
+}
/*!
* @brief Read a character sent over the UART
* @param uart The UART device handle
* @param c The varible to hold the read character
* @return 0 upon success
+ *
+ * If "c == -1" no char was ready.
+ * If "c != -1" then C == byte value (0x00 to 0xff)
*/
-inline int metal_uart_getc(struct metal_uart *uart, unsigned char *c) { return uart->vtable->getc(uart, c); }
+__inline__ int metal_uart_getc(struct metal_uart *uart, int *c) {
+ return uart->vtable->getc(uart, c);
+}
/*!
* @brief Get the baud rate of the UART peripheral
* @param uart The UART device handle
* @return The current baud rate of the UART
*/
-inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtable->get_baud_rate(uart); }
+__inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) {
+ return uart->vtable->get_baud_rate(uart);
+}
/*!
* @brief Set the baud rate of the UART peripheral
@@ -70,7 +107,10 @@ inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtab
* @param baud_rate The baud rate to configure
* @return the new baud rate of the UART
*/
-inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { return uart->vtable->set_baud_rate(uart, baud_rate); }
+__inline__ int metal_uart_set_baud_rate(struct metal_uart *uart,
+ int baud_rate) {
+ return uart->vtable->set_baud_rate(uart, baud_rate);
+}
/*!
* @brief Get the interrupt controller of the UART peripheral
@@ -82,13 +122,94 @@ inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { re
* @param uart The UART device handle
* @return The handle for the UART interrupt controller
*/
-inline struct metal_interrupt* metal_uart_interrupt_controller(struct metal_uart *uart) { return uart->vtable->controller_interrupt(uart); }
+__inline__ struct metal_interrupt *
+metal_uart_interrupt_controller(struct metal_uart *uart) {
+ return uart->vtable->controller_interrupt(uart);
+}
/*!
* @brief Get the interrupt ID of the UART controller
* @param uart The UART device handle
* @return The UART interrupt id
*/
-inline int metal_uart_get_interrupt_id(struct metal_uart *uart) { return uart->vtable->get_interrupt_id(uart); }
+__inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) {
+ return uart->vtable->get_interrupt_id(uart);
+}
+
+/*!
+ * @brief Enable the UART transmit interrupt
+ * @param uart The UART device handle
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_transmit_interrupt_enable(struct metal_uart *uart) {
+ return uart->vtable->tx_interrupt_enable(uart);
+}
+
+/*!
+ * @brief Disable the UART transmit interrupt
+ * @param uart The UART device handle
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_transmit_interrupt_disable(struct metal_uart *uart) {
+ return uart->vtable->tx_interrupt_disable(uart);
+}
+
+/*!
+ * @brief Enable the UART receive interrupt
+ * @param uart The UART device handle
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_receive_interrupt_enable(struct metal_uart *uart) {
+ return uart->vtable->rx_interrupt_enable(uart);
+}
+
+/*!
+ * @brief Disable the UART receive interrupt
+ * @param uart The UART device handle
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_receive_interrupt_disable(struct metal_uart *uart) {
+ return uart->vtable->rx_interrupt_disable(uart);
+}
+
+/*!
+ * @brief Set the transmit watermark level of the UART controller
+ * @param uart The UART device handle
+ * @param level The UART transmit watermark level
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart,
+ size_t level) {
+ return uart->vtable->set_tx_watermark(uart, level);
+}
+
+/*!
+ * @brief Get the transmit watermark level of the UART controller
+ * @param uart The UART device handle
+ * @return The UART transmit watermark level
+ */
+__inline__ size_t metal_uart_get_transmit_watermark(struct metal_uart *uart) {
+ return uart->vtable->get_tx_watermark(uart);
+}
+
+/*!
+ * @brief Set the receive watermark level of the UART controller
+ * @param uart The UART device handle
+ * @param level The UART transmit watermark level
+ * @return 0 upon success
+ */
+__inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart,
+ size_t level) {
+ return uart->vtable->set_rx_watermark(uart, level);
+}
+
+/*!
+ * @brief Get the receive watermark level of the UART controller
+ * @param uart The UART device handle
+ * @return The UART transmit watermark level
+ */
+__inline__ size_t metal_uart_get_receive_watermark(struct metal_uart *uart) {
+ return uart->vtable->get_rx_watermark(uart);
+}
#endif
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h
new file mode 100644
index 000000000..2f84d3b49
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h
@@ -0,0 +1,168 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+
+#ifndef METAL__WATCHDOG_H
+#define METAL__WATCHDOG_H
+
+/*!
+ * @file watchdog.h
+ *
+ * @brief API for configuring watchdog timers
+ */
+
+#include
+
+struct metal_watchdog;
+
+/*!
+ * @brief List of watchdog timer count behaviors
+ */
+enum metal_watchdog_run_option {
+ METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */
+ METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during
+ sleep */
+ METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake
+ */
+};
+
+/*!
+ * @brief List of behaviors when a watchdog triggers
+ */
+enum metal_watchdog_result {
+ METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */
+ METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt
+ */
+ METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full
+ system reset */
+};
+
+struct metal_watchdog_vtable {
+ int (*feed)(const struct metal_watchdog *const wdog);
+ long int (*get_rate)(const struct metal_watchdog *const wdog);
+ long int (*set_rate)(const struct metal_watchdog *const wdog,
+ const long int rate);
+ long int (*get_timeout)(const struct metal_watchdog *const wdog);
+ long int (*set_timeout)(const struct metal_watchdog *const wdog,
+ const long int timeout);
+ int (*set_result)(const struct metal_watchdog *const wdog,
+ const enum metal_watchdog_result result);
+ int (*run)(const struct metal_watchdog *const wdog,
+ const enum metal_watchdog_run_option option);
+ struct metal_interrupt *(*get_interrupt)(
+ const struct metal_watchdog *const wdog);
+ int (*get_interrupt_id)(const struct metal_watchdog *const wdog);
+ int (*clear_interrupt)(const struct metal_watchdog *const wdog);
+};
+
+/*!
+ * @brief Handle for a Watchdog Timer
+ */
+struct metal_watchdog {
+ const struct metal_watchdog_vtable *vtable;
+};
+
+/*!
+ * @brief Feed the watchdog timer
+ */
+inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->feed(wdog);
+}
+
+/*!
+ * @brief Get the rate of the watchdog timer in Hz
+ *
+ * @return the rate of the watchdog timer
+ */
+inline long int
+metal_watchdog_get_rate(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->get_rate(wdog);
+}
+
+/*!
+ * @brief Set the rate of the watchdog timer in Hz
+ *
+ * There is no guarantee that the new rate will match the requested rate.
+ *
+ * @return the new rate of the watchdog timer
+ */
+inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog,
+ const long int rate) {
+ return wdog->vtable->set_rate(wdog, rate);
+}
+
+/*!
+ * @brief Get the timeout of the watchdog timer
+ *
+ * @return the watchdog timeout value
+ */
+inline long int
+metal_watchdog_get_timeout(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->get_timeout(wdog);
+}
+
+/*!
+ * @brief Set the timeout of the watchdog timer
+ *
+ * The set rate will be the minimimum of the requested and maximum supported
+ * rates.
+ *
+ * @return the new watchdog timeout value
+ */
+inline long int
+metal_watchdog_set_timeout(const struct metal_watchdog *const wdog,
+ const long int timeout) {
+ return wdog->vtable->set_timeout(wdog, timeout);
+}
+
+/*!
+ * @brief Sets the result behavior of a watchdog timer timeout
+ *
+ * @return 0 if the requested result behavior is supported
+ */
+inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog,
+ const enum metal_watchdog_result result) {
+ return wdog->vtable->set_result(wdog, result);
+}
+
+/*!
+ * @brief Set the run behavior of the watchdog
+ *
+ * Used to enable/disable the watchdog timer
+ *
+ * @return 0 if the watchdog was successfully started/stopped
+ */
+inline int metal_watchdog_run(const struct metal_watchdog *const wdog,
+ const enum metal_watchdog_run_option option) {
+ return wdog->vtable->run(wdog, option);
+}
+
+/*!
+ * @brief Get the interrupt controller for the watchdog interrupt
+ */
+inline struct metal_interrupt *
+metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->get_interrupt(wdog);
+}
+
+/*!
+ * @Brief Get the interrupt id for the watchdog interrupt
+ */
+inline int
+metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->get_interrupt_id(wdog);
+}
+
+/*!
+ * @brief Clear the watchdog interrupt
+ */
+inline int
+metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog) {
+ return wdog->vtable->clear_interrupt(wdog);
+}
+
+/*!
+ * @brief Get a watchdog handle
+ */
+struct metal_watchdog *metal_watchdog_get_device(const int index);
+
+#endif /* METAL__WATCHDOG_H */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h
index 8c0cd048b..fd05ab065 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h
@@ -5,128 +5,181 @@
#ifndef ASSEMBLY
-#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
-#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H
+#ifndef METAL_INLINE_H
+#define METAL_INLINE_H
#include
/* --------------------- fixed_clock ------------ */
-extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
+extern __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
/* --------------------- fixed_factor_clock ------------ */
/* --------------------- sifive_clint0 ------------ */
-extern inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
-extern inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
-extern inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
-extern inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
/* --------------------- cpu ------------ */
-extern inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
-extern inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
-extern inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
-extern inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
+extern __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu);
/* --------------------- sifive_plic0 ------------ */
-extern inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
-extern inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
-extern inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
-extern inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid);
+
+
+/* --------------------- sifive_buserror0 ------------ */
/* --------------------- sifive_clic0 ------------ */
/* --------------------- sifive_local_external_interrupts0 ------------ */
-extern inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller);
-extern inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx);
/* --------------------- sifive_global_external_interrupts0 ------------ */
/* --------------------- sifive_gpio0 ------------ */
-extern inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio);
-extern inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio);
-extern inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio);
-extern inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio);
-extern inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx);
+extern __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio);
+extern __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio);
+extern __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio);
+extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx);
/* --------------------- sifive_gpio_button ------------ */
/* --------------------- sifive_gpio_led ------------ */
-extern inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led);
-extern inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led);
-extern inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led);
+extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led);
+extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led);
+extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led);
/* --------------------- sifive_gpio_switch ------------ */
+/* --------------------- sifive_i2c0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c);
+extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c);
+extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c);
+extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c);
+extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c);
+
+
+/* --------------------- sifive_pwm0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx);
+extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm);
+extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm);
+extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm);
+
+
+/* --------------------- sifive_rtc0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc);
+extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc);
+extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc);
+extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc);
+
+
/* --------------------- sifive_spi0 ------------ */
-extern inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi);
-extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi);
-extern inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi);
+extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi);
/* --------------------- sifive_test0 ------------ */
+/* --------------------- sifive_trace ------------ */
+
/* --------------------- sifive_uart0 ------------ */
-extern inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart);
-extern inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart);
-extern inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart);
-extern inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart);
-extern inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart);
-extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart);
-extern inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart);
+extern __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart);
+extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart);
+
+
+/* --------------------- sifive_simuart0 ------------ */
+
+
+/* --------------------- sifive_wdog0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog);
+extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog);
+extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog);
/* --------------------- sifive_fe310_g000_hfrosc ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock);
-extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock);
+extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock);
/* --------------------- sifive_fe310_g000_hfxosc ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock);
+
+
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock);
+extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock);
+extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock);
/* --------------------- sifive_fe310_g000_pll ------------ */
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock);
-extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock);
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( );
-extern inline long __metal_driver_sifive_fe310_g000_pll_config_offset( );
-extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock);
-extern inline long __metal_driver_sifive_fe310_g000_pll_init_rate( );
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock);
+extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock);
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( );
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( );
+extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock);
+extern __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( );
/* --------------------- fe310_g000_prci ------------ */
-extern inline long __metal_driver_sifive_fe310_g000_prci_base( );
-extern inline long __metal_driver_sifive_fe310_g000_prci_size( );
-extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( );
-
-
-/* --------------------- sifive_fu540_c000_l2 ------------ */
+extern __inline__ long __metal_driver_sifive_fe310_g000_prci_base( );
+extern __inline__ long __metal_driver_sifive_fe310_g000_prci_size( );
+extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( );
/* From clock@0 */
@@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = {
.clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
};
+/* From clock@6 */
+struct __metal_driver_fixed_clock __metal_dt_clock_6 = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
struct metal_memory __metal_dt_mem_dtim_80000000 = {
._base_address = 2147483648UL,
._size = 16384UL,
@@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = {
.A = 1},
};
+struct metal_memory __metal_dt_mem_itim_8000000 = {
+ ._base_address = 134217728UL,
+ ._size = 8192UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
struct metal_memory __metal_dt_mem_spi_10014000 = {
._base_address = 536870912UL,
._size = 500000UL,
@@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = {
.A = 1},
};
+struct metal_memory __metal_dt_mem_spi_10024000 = {
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+struct metal_memory __metal_dt_mem_spi_10034000 = {
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
/* From clint@2000000 */
struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
.controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable,
@@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
/* From cpu@0 */
struct __metal_driver_cpu __metal_dt_cpu_0 = {
.cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
};
/* From interrupt_controller */
@@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = {
.init_done = 0,
};
-/* From local_external_interrupts_0 */
-struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = {
- .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
- .init_done = 0,
-};
+struct metal_pmp __metal_dt_pmp;
/* From gpio@10012000 */
struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = {
.gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio,
};
-/* From led@0red */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = {
+/* From led@0 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
-/* From led@0green */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = {
+/* From led@1 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
-/* From led@0blue */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = {
+/* From led@2 */
+struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = {
.led.vtable = &__metal_driver_vtable_sifive_led.led_vtable,
};
+/* From i2c@10016000 */
+struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = {
+ .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c,
+};
+
+/* From pwm@10015000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From pwm@10025000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From pwm@10035000 */
+struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = {
+ .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm,
+};
+
+/* From aon@10000000 */
+struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = {
+ .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc,
+};
+
/* From spi@10014000 */
struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = {
.spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
};
+/* From spi@10024000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = {
+ .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
+};
+
+/* From spi@10034000 */
+struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = {
+ .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi,
+};
+
/* From serial@10013000 */
struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = {
.uart.vtable = &__metal_driver_vtable_sifive_uart0.uart,
};
+/* From serial@10023000 */
+struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart,
+};
+
+/* From aon@10000000 */
+struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = {
+ .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog,
+};
+
/* From clock@3 */
struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock,
@@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock,
};
+/* From clock@7 */
+struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = {
+ .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.clock,
+};
+
/* From clock@4 */
struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = {
.clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock,
@@ -242,8 +376,9 @@ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = {
/* From prci@10008000 */
struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = {
+ .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci,
};
-#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/
+#endif /* METAL_INLINE_H*/
#endif /* ! ASSEMBLY */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h
index 4ecd3e336..d517b5859 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h
@@ -3,8 +3,8 @@
/* ----------------------------------- */
/* ----------------------------------- */
-#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
-#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H
+#ifndef METAL_PLATFORM_H
+#define METAL_PLATFORM_H
/* From clock@0 */
#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL
@@ -13,7 +13,10 @@
#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL
/* From clock@5 */
-#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL
+#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL
+
+/* From clock@6 */
+#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL
#define METAL_FIXED_CLOCK
@@ -35,15 +38,18 @@
#define METAL_RISCV_PLIC0_0_SIZE 67108864UL
#define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL
#define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL
-#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 27UL
-#define METAL_RISCV_PLIC0_0_RISCV_NDEV 27UL
+#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 53UL
+#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL
#define METAL_RISCV_PLIC0
#define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL
#define METAL_RISCV_PLIC0_PENDING_BASE 4096UL
#define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL
-#define METAL_RISCV_PLIC0_THRESHOLD 2097152UL
-#define METAL_RISCV_PLIC0_CLAIM 2097156UL
+#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL
+#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL
+#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL
+#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL
+#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL
/* From aon@10000000 */
#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
@@ -111,6 +117,10 @@
#define METAL_SIFIVE_FE310_G000_HFXOSC
+/* From clock@7 */
+
+#define METAL_SIFIVE_FE310_G000_LFROSC
+
/* From prci@10008000 */
#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL
#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL
@@ -153,11 +163,11 @@
#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL
#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL
-/* From led@0red */
+/* From led@0 */
-/* From led@0green */
+/* From led@1 */
-/* From led@0blue */
+/* From led@2 */
#define METAL_SIFIVE_GPIO_LEDS
@@ -176,16 +186,24 @@
#define METAL_SIFIVE_I2C0_COMMAND 16UL
#define METAL_SIFIVE_I2C0_STATUS 16UL
-/* From local_external_interrupts_0 */
-
-#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0
-
/* From pwm@10015000 */
#define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL
#define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL
#define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL
#define METAL_SIFIVE_PWM0_0_SIZE 4096UL
+/* From pwm@10025000 */
+#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL
+#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL
+#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL
+#define METAL_SIFIVE_PWM0_1_SIZE 4096UL
+
+/* From pwm@10035000 */
+#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL
+#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL
+#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL
+#define METAL_SIFIVE_PWM0_2_SIZE 4096UL
+
#define METAL_SIFIVE_PWM0
#define METAL_SIFIVE_PWM0_PWMCFG 0UL
#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL
@@ -195,12 +213,37 @@
#define METAL_SIFIVE_PWM0_PWMCMP2 40UL
#define METAL_SIFIVE_PWM0_PWMCMP3 44UL
+/* From aon@10000000 */
+#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL
+#define METAL_SIFIVE_AON0_0_SIZE 32768UL
+
+#define METAL_SIFIVE_RTC0
+#define METAL_SIFIVE_RTC0_RTCCFG 64UL
+#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL
+#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL
+#define METAL_SIFIVE_RTC0_RTCS 80UL
+#define METAL_SIFIVE_RTC0_RTCCMP0 96UL
+
/* From spi@10014000 */
#define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL
#define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL
#define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL
#define METAL_SIFIVE_SPI0_0_SIZE 4096UL
+/* From spi@10024000 */
+#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL
+#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL
+#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL
+#define METAL_SIFIVE_SPI0_1_SIZE 4096UL
+
+/* From spi@10034000 */
+#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL
+#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL
+#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL
+#define METAL_SIFIVE_SPI0_2_SIZE 4096UL
+
#define METAL_SIFIVE_SPI0
#define METAL_SIFIVE_SPI0_SCKDIV 0UL
#define METAL_SIFIVE_SPI0_SCKMODE 4UL
@@ -225,6 +268,12 @@
#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL
#define METAL_SIFIVE_UART0_0_SIZE 4096UL
+/* From serial@10023000 */
+#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL
+#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL
+#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL
+#define METAL_SIFIVE_UART0_1_SIZE 4096UL
+
#define METAL_SIFIVE_UART0
#define METAL_SIFIVE_UART0_TXDATA 0UL
#define METAL_SIFIVE_UART0_RXDATA 4UL
@@ -234,4 +283,20 @@
#define METAL_SIFIVE_UART0_IP 20UL
#define METAL_SIFIVE_UART0_DIV 24UL
-#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/
+/* From aon@10000000 */
+#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL
+#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL
+#define METAL_SIFIVE_AON0_0_SIZE 32768UL
+
+#define METAL_SIFIVE_WDOG0
+#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL
+#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL
+#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL
+#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL
+#define METAL_SIFIVE_WDOG0_WDOGS 16UL
+#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL
+#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL
+#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL
+
+#endif /* METAL_PLATFORM_H*/
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds
index 7070af7e8..be7f84c71 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds
@@ -1,236 +1,302 @@
-/* Copyright 2019 SiFive, Inc */
+/* Copyright (c) 2020 SiFive Inc. */
/* SPDX-License-Identifier: Apache-2.0 */
-/* ----------------------------------- */
-/* ----------------------------------- */
-
OUTPUT_ARCH("riscv")
+/* Default Linker Script
+ *
+ * This is the default linker script for all Freedom Metal applications.
+ */
+
ENTRY(_enter)
MEMORY
{
- ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000
- flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120
+ itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000
+ ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000
+ rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120
}
PHDRS
{
- flash PT_LOAD;
- ram_init PT_LOAD;
- itim_init PT_LOAD;
- ram PT_NULL;
- itim PT_NULL;
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
}
SECTIONS
{
- __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
- PROVIDE(__stack_size = __stack_size);
- __heap_size = DEFINED(__heap_size) ? __heap_size : 0x4;
- PROVIDE(__metal_boot_hart = 0);
- PROVIDE(__metal_chicken_bit = 0);
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
- .init :
- {
- KEEP (*(.text.metal.init.enter))
- KEEP (*(SORT_NONE(.init)))
- KEEP (*(.text.libgloss.start))
- } >flash AT>flash :flash
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 0);
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
- .text :
- {
- *(.text.unlikely .text.unlikely.*)
- *(.text.startup .text.startup.*)
- *(.text .text.*)
- *(.itim .itim.*)
- *(.gnu.linkonce.t.*)
- } >flash AT>flash :flash
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 0);
+ /* The RAM memories map for ECC scrubbing */
+ PROVIDE( metal_dtim_0_memory_start = 0x80000000 );
+ PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 );
+ PROVIDE( metal_itim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 );
- .fini :
- {
- KEEP (*(SORT_NONE(.fini)))
- } >flash AT>flash :flash
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
- PROVIDE (__etext = .);
- PROVIDE (_etext = .);
- PROVIDE (etext = .);
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
- .rodata :
- {
- *(.rdata)
- *(.rodata .rodata.*)
- *(.gnu.linkonce.r.*)
- . = ALIGN(8);
- *(.srodata.cst16)
- *(.srodata.cst8)
- *(.srodata.cst4)
- *(.srodata.cst2)
- *(.srodata .srodata.*)
- } >flash AT>flash :flash
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
- . = ALIGN(4);
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
- .preinit_array :
- {
- PROVIDE_HIDDEN (__preinit_array_start = .);
- KEEP (*(.preinit_array))
- PROVIDE_HIDDEN (__preinit_array_end = .);
- } >flash AT>flash :flash
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >rom :rom
- .init_array :
- {
- PROVIDE_HIDDEN (__init_array_start = .);
- KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
- KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
- PROVIDE_HIDDEN (__init_array_end = .);
- } >flash AT>flash :flash
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >itim AT>rom :itim_init
- .fini_array :
- {
- PROVIDE_HIDDEN (__fini_array_start = .);
- KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
- KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
- PROVIDE_HIDDEN (__fini_array_end = .);
- } >flash AT>flash :flash
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
- .ctors :
- {
- /* gcc uses crtbegin.o to find the start of
- the constructors, so we make sure it is
- first. Because this is a wildcard, it
- doesn't matter if the user does not
- actually link against crtbegin.o; the
- linker won't look for a file to match a
- wildcard. The wildcard also means that it
- doesn't matter which directory crtbegin.o
- is in. */
- KEEP (*crtbegin.o(.ctors))
- KEEP (*crtbegin?.o(.ctors))
- /* We don't want to include the .ctor section from
- the crtend.o file until after the sorted ctors.
- The .ctor section from the crtend file contains the
- end of ctors marker and it must be last */
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*(.ctors))
- } >flash AT>flash :flash
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >ram AT>rom :lim_init
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
- .dtors :
- {
- KEEP (*crtbegin.o(.dtors))
- KEEP (*crtbegin?.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*(.dtors))
- } >flash AT>flash :flash
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom :text
- .litimalign :
- {
- . = ALIGN(4);
- PROVIDE( metal_segment_itim_source_start = . );
- } >flash AT>flash :flash
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>rom :ram_init
- .ditimalign :
- {
- . = ALIGN(4);
- PROVIDE( metal_segment_itim_target_start = . );
- } >ram AT>flash :ram_init
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
- .itim :
- {
- *(.itim .itim.*)
- } >flash AT>flash :flash
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
- . = ALIGN(8);
- PROVIDE( metal_segment_itim_target_end = . );
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
- .lalign :
- {
- . = ALIGN(4);
- PROVIDE( _data_lma = . );
- PROVIDE( metal_segment_data_source_start = . );
- } >flash AT>flash :flash
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
- .dalign :
- {
- . = ALIGN(4);
- PROVIDE( metal_segment_data_target_start = . );
- } >ram AT>flash :ram_init
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ __freertos_irq_stack_top = .;
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
- .data :
- {
- *(.data .data.*)
- *(.gnu.linkonce.d.*)
- . = ALIGN(8);
- PROVIDE( __global_pointer$ = . + 0x800 );
- *(.sdata .sdata.* .sdata2.*)
- *(.gnu.linkonce.s.*)
- } >ram AT>flash :ram_init
-
-
- . = ALIGN(4);
- PROVIDE( _edata = . );
- PROVIDE( edata = . );
- PROVIDE( metal_segment_data_target_end = . );
- PROVIDE( _fbss = . );
- PROVIDE( __bss_start = . );
- PROVIDE( metal_segment_bss_target_start = . );
-
-
- .bss :
- {
- *(.sbss*)
- *(.gnu.linkonce.sb.*)
- *(.bss .bss.*)
- *(.gnu.linkonce.b.*)
- *(COMMON)
- . = ALIGN(4);
- } >ram AT>ram :ram
-
-
- . = ALIGN(8);
- PROVIDE( _end = . );
- PROVIDE( end = . );
- PROVIDE( metal_segment_bss_target_end = . );
-
- .stack :
- {
- . = ALIGN(16);
- metal_segment_stack_begin = .;
- . += __stack_size;
- . = ALIGN(16);
- _sp = .;
- PROVIDE(metal_segment_stack_end = .);
- __freertos_irq_stack_top = .;
- } >ram AT>ram :ram
-
-
- .heap :
- {
- PROVIDE( metal_segment_heap_target_start = . );
- . = __heap_size;
- PROVIDE( metal_segment_heap_target_end = . );
- PROVIDE( _heap_end = . );
- } >ram AT>ram :ram
-
-
-}
-
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds
new file mode 100644
index 000000000..4798504ed
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds
@@ -0,0 +1,327 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* Privileged mode Linker Script
+ *
+ * This linker script is based on metal.default.lds. It introduce specific
+ * section to isolate (acessible only from machine mode) and others that can be
+ * used in every execution mode. This linker script it tailored for FreeRTOS
+ * applications.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000
+ ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000
+ rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 0);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 0);
+
+ /* The RAM memories map for ECC scrubbing */
+ PROVIDE( metal_dtim_0_memory_start = 0x80000000 );
+ PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 );
+ PROVIDE( metal_itim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 );
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
+
+ .privileged_functions : ALIGN (32) {
+ __privileged_functions_start__ = .;
+ KEEP(*(privileged_functions))
+ . = ALIGN(32);
+ __privileged_functions_end__ = .;
+ } >rom
+
+
+ .ctors : {
+ . = ALIGN(32);
+ __unprivileged_section_start__ = .;
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >rom :rom
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >itim AT>rom :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >ram AT>rom :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ *(freertos_system_calls)
+ . = ALIGN(32);
+ __unprivileged_section_end__ = .;
+ } >rom :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ . = ALIGN(32);
+ __unprivileged_data_section_start__ = .;
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>rom :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(32);
+ __unprivileged_data_section_end__ = .;
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+ .privileged_data (NOLOAD) : ALIGN(32) {
+ __privileged_data_start__ = .;
+ *(privileged_data)
+ /* Non kernel data is kept out of the first _Privileged_Data_Region_Size
+ bytes of SRAM. */
+ . = ALIGN(32);
+ __privileged_data_end__ = .;
+ } >ram
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h
index f76dbd632..74c361b4b 100644
--- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h
@@ -9,15 +9,15 @@
#ifdef __METAL_MACHINE_MACROS
-#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
-#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H
+#ifndef MACROS_IF_METAL_H
+#define MACROS_IF_METAL_H
#define __METAL_CLINT_NUM_PARENTS 2
#ifndef __METAL_CLINT_NUM_PARENTS
#define __METAL_CLINT_NUM_PARENTS 0
#endif
-#define __METAL_PLIC_SUBINTERRUPTS 27
+#define __METAL_PLIC_SUBINTERRUPTS 53
#define __METAL_PLIC_NUM_PARENTS 1
@@ -31,12 +31,12 @@
#define __METAL_CLIC_SUBINTERRUPTS 0
#endif
-#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/
+#endif /* MACROS_IF_METAL_H*/
#else /* ! __METAL_MACHINE_MACROS */
-#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
-#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H
+#ifndef MACROS_ELSE_METAL_H
+#define MACROS_ELSE_METAL_H
#define __METAL_CLINT_2000000_INTERRUPTS 2
@@ -46,7 +46,7 @@
#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1
-#define __METAL_PLIC_SUBINTERRUPTS 27
+#define __METAL_PLIC_SUBINTERRUPTS 53
#define METAL_MAX_PLIC_INTERRUPTS 1
@@ -55,20 +55,36 @@
#define __METAL_CLIC_SUBINTERRUPTS 0
#define METAL_MAX_CLIC_INTERRUPTS 0
-#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16
-
-#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16
+#define METAL_MAX_LOCAL_EXT_INTERRUPTS 0
#define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0
-#define __METAL_GPIO_10012000_INTERRUPTS 16
+#define __METAL_GPIO_10012000_INTERRUPTS 32
-#define METAL_MAX_GPIO_INTERRUPTS 16
+#define METAL_MAX_GPIO_INTERRUPTS 32
+
+#define __METAL_I2C_10016000_INTERRUPTS 1
+
+#define METAL_MAX_I2C0_INTERRUPTS 1
+
+#define __METAL_PWM_10015000_INTERRUPTS 4
+
+#define __METAL_PWM_10025000_INTERRUPTS 4
+
+#define __METAL_PWM_10035000_INTERRUPTS 4
+
+#define METAL_MAX_PWM0_INTERRUPTS 4
+
+#define METAL_MAX_PWM0_NCMP 4
#define __METAL_SERIAL_10013000_INTERRUPTS 1
+#define __METAL_SERIAL_10023000_INTERRUPTS 1
+
#define METAL_MAX_UART_INTERRUPTS 1
+#define METAL_MAX_SIMUART_INTERRUPTS 0
+
#include
#include
@@ -76,79 +92,119 @@
#include
#include
#include
-#include
#include
#include
+#include
+#include
+#include
#include
#include
+#include
#include
#include
+#include
#include
#include
/* From clock@0 */
-struct __metal_driver_fixed_clock __metal_dt_clock_0;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_0;
/* From clock@2 */
-struct __metal_driver_fixed_clock __metal_dt_clock_2;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_2;
/* From clock@5 */
-struct __metal_driver_fixed_clock __metal_dt_clock_5;
+extern struct __metal_driver_fixed_clock __metal_dt_clock_5;
-struct metal_memory __metal_dt_mem_dtim_80000000;
+/* From clock@6 */
+extern struct __metal_driver_fixed_clock __metal_dt_clock_6;
-struct metal_memory __metal_dt_mem_spi_10014000;
+extern struct metal_memory __metal_dt_mem_dtim_80000000;
+
+extern struct metal_memory __metal_dt_mem_itim_8000000;
+
+extern struct metal_memory __metal_dt_mem_spi_10014000;
+
+extern struct metal_memory __metal_dt_mem_spi_10024000;
+
+extern struct metal_memory __metal_dt_mem_spi_10034000;
/* From clint@2000000 */
-struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
+extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
/* From cpu@0 */
-struct __metal_driver_cpu __metal_dt_cpu_0;
+extern struct __metal_driver_cpu __metal_dt_cpu_0;
-struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
/* From interrupt_controller@c000000 */
-struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
+extern struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
-struct metal_pmp __metal_dt_pmp;
-
-/* From local_external_interrupts_0 */
-struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0;
+extern struct metal_pmp __metal_dt_pmp;
/* From gpio@10012000 */
-struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000;
+extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000;
-/* From led@0red */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0red;
+/* From led@0 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0;
-/* From led@0green */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0green;
+/* From led@1 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1;
-/* From led@0blue */
-struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue;
+/* From led@2 */
+extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2;
+
+/* From i2c@10016000 */
+extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000;
+
+/* From pwm@10015000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000;
+
+/* From pwm@10025000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000;
+
+/* From pwm@10035000 */
+extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000;
+
+/* From aon@10000000 */
+extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000;
/* From spi@10014000 */
-struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000;
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000;
+
+/* From spi@10024000 */
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000;
+
+/* From spi@10034000 */
+extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000;
/* From serial@10013000 */
-struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000;
+extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000;
+
+/* From serial@10023000 */
+extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000;
+
+/* From aon@10000000 */
+extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000;
/* From clock@3 */
-struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3;
+extern struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3;
/* From clock@1 */
-struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1;
+extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1;
+
+/* From clock@7 */
+extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7;
/* From clock@4 */
-struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4;
+extern struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4;
/* From prci@10008000 */
-struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000;
+extern struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000;
/* --------------------- fixed_clock ------------ */
-static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
+static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
{
if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) {
return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY;
@@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c
else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) {
return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY;
}
+ else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) {
+ return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY;
+ }
else {
return 0;
}
@@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c
/* --------------------- sifive_clint0 ------------ */
-static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS;
@@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met
}
}
-static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_RISCV_CLINT0_2000000_SIZE;
@@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met
}
}
-static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
return METAL_MAX_CLINT_INTERRUPTS;
@@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
@@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa
}
}
-static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
+static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return 3;
@@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte
/* --------------------- cpu ------------ */
-static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return 0;
@@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
}
}
-static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
- return 1000000;
+ return 16000000;
}
else {
return 0;
}
}
-static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
+static __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return &__metal_dt_cpu_0_interrupt_controller.controller;
@@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s
}
}
-static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
+static __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
{
if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
return 8;
@@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
}
}
+static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return NULL;
+ }
+ else {
+ return NULL;
+ }
+}
+
/* --------------------- sifive_plic0 ------------ */
-static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS;
@@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta
}
}
-static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_SIZE;
@@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta
}
}
-static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_RISCV_NDEV;
@@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr
}
}
-static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
+static __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
{
if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY;
@@ -312,120 +381,52 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
}
- else if (idx == 0) {
- return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
- }
else {
return NULL;
}
}
-static inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
+static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
{
if (idx == 0) {
return 11;
}
- else if (idx == 0) {
- return 11;
- }
else {
return 0;
}
}
+static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid)
+{
+ if (hartid == 0) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+
+
+/* --------------------- sifive_buserror0 ------------ */
/* --------------------- sifive_clic0 ------------ */
/* --------------------- sifive_local_external_interrupts0 ------------ */
-static inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller)
-{
- if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
- return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
- }
- else {
- return NULL;
- }
-}
-
-static inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller)
-{
- if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
- return METAL_MAX_LOCAL_EXT_INTERRUPTS;
- }
- else {
- return 0;
- }
-}
-
-static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx)
-{
- if (idx == 0) {
- return 16;
- }
- else if (idx == 1) {
- return 17;
- }
- else if (idx == 2) {
- return 18;
- }
- else if (idx == 3) {
- return 19;
- }
- else if (idx == 4) {
- return 20;
- }
- else if (idx == 5) {
- return 21;
- }
- else if (idx == 6) {
- return 22;
- }
- else if (idx == 7) {
- return 23;
- }
- else if (idx == 8) {
- return 24;
- }
- else if (idx == 9) {
- return 25;
- }
- else if (idx == 10) {
- return 26;
- }
- else if (idx == 11) {
- return 27;
- }
- else if (idx == 12) {
- return 28;
- }
- else if (idx == 13) {
- return 29;
- }
- else if (idx == 14) {
- return 30;
- }
- else if (idx == 15) {
- return 31;
- }
- else {
- return 0;
- }
-}
-
/* --------------------- sifive_global_external_interrupts0 ------------ */
/* --------------------- sifive_gpio0 ------------ */
-static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio)
+static __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS;
@@ -435,7 +436,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *
}
}
-static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio)
+static __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_SIFIVE_GPIO0_10012000_SIZE;
@@ -445,7 +446,7 @@ static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *
}
}
-static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio)
+static __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return METAL_MAX_GPIO_INTERRUPTS;
@@ -455,7 +456,7 @@ static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio)
{
if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) {
return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
@@ -465,56 +466,104 @@ static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_par
}
}
-static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx)
+static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx)
{
if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) {
- return 7;
- }
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) {
return 8;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) {
return 9;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) {
return 10;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) {
return 11;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) {
return 12;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) {
return 13;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) {
return 14;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) {
return 15;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) {
return 16;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) {
return 17;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) {
return 18;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) {
return 19;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) {
return 20;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) {
return 21;
}
- else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) {
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) {
return 22;
}
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) {
+ return 23;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) {
+ return 24;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) {
+ return 25;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) {
+ return 26;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) {
+ return 27;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) {
+ return 28;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) {
+ return 29;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) {
+ return 30;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) {
+ return 31;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) {
+ return 32;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) {
+ return 33;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) {
+ return 34;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) {
+ return 35;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) {
+ return 36;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) {
+ return 27;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) {
+ return 28;
+ }
+ else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) {
+ return 29;
+ }
else {
return 0;
}
@@ -526,15 +575,15 @@ static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio
/* --------------------- sifive_gpio_led ------------ */
-static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led)
+static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return (struct metal_gpio *)&__metal_dt_gpio_10012000;
}
else {
@@ -542,15 +591,15 @@ static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct met
}
}
-static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
+static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return 22;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return 19;
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return 21;
}
else {
@@ -558,15 +607,15 @@ static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led)
}
}
-static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
+static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
{
- if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) {
+ if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) {
return "LD0red";
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) {
return "LD0green";
}
- else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) {
+ else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) {
return "LD0blue";
}
else {
@@ -579,45 +628,430 @@ static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led)
/* --------------------- sifive_gpio_switch ------------ */
-/* --------------------- sifive_spi0 ------------ */
-static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi)
+/* --------------------- sifive_i2c0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return METAL_SIFIVE_I2C0_10016000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 12288;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c)
+{
+ return METAL_MAX_I2C0_INTERRUPTS;
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c)
+{
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+}
+
+static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c)
+{
+ if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) {
+ return 52;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_pwm0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return METAL_SIFIVE_PWM0_10015000_SIZE;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return METAL_SIFIVE_PWM0_10025000_SIZE;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return METAL_SIFIVE_PWM0_10035000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 15;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 7864320;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 15360;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 15;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 7864320;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 15360;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return __METAL_PWM_10015000_INTERRUPTS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return __METAL_PWM_10025000_INTERRUPTS;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return __METAL_PWM_10035000_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm)
+{
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx)
+{
+ if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) {
+ return 40;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) {
+ return 41;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) {
+ return 42;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) {
+ return 43;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) {
+ return 44;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) {
+ return 45;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) {
+ return 46;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) {
+ return 47;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) {
+ return 48;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) {
+ return 49;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) {
+ return 50;
+ }
+ else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) {
+ return 51;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 8;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 16;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 16;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm)
+{
+ if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) {
+ return 4;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) {
+ return 4;
+ }
+ else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_rtc0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return METAL_SIFIVE_AON0_10000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return 2;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc)
+{
+ if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) {
+ return (struct metal_clock *)&__metal_dt_clock_7.clock;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi)
{
if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS;
}
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS;
+ }
else {
return 0;
}
}
-static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi)
{
if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return METAL_SIFIVE_SPI0_10014000_SIZE;
}
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return METAL_SIFIVE_SPI0_10024000_SIZE;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return METAL_SIFIVE_SPI0_10034000_SIZE;
+ }
else {
return 0;
}
}
-static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi)
+static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi)
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi)
{
- return 60;
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi)
+static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi)
{
+ if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) {
+ return 0;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) {
return 60;
+ }
+ else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) {
+ return 4227858432;
+ }
+ else {
+ return 0;
+ }
}
@@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st
/* --------------------- sifive_test0 ------------ */
+/* --------------------- sifive_trace ------------ */
+
/* --------------------- sifive_uart0 ------------ */
-static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS;
+ }
else {
return 0;
}
}
-static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_SIFIVE_UART0_10013000_SIZE;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_SIFIVE_UART0_10023000_SIZE;
+ }
else {
return 0;
}
}
-static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart)
+static __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return METAL_MAX_UART_INTERRUPTS;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return METAL_MAX_UART_INTERRUPTS;
+ }
else {
return 0;
}
}
-static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart)
+static __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart)
{
if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
}
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
else {
- return NULL;
+ return 0;
}
}
-static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart)
+static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart)
{
- return 5;
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return 3;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart)
+static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct metal_clock *)&__metal_dt_clock_4.clock;
+ }
+ else {
+ return 0;
+ }
}
-static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart)
+static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart)
{
- return 196608;
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
+ return 0;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
}
-static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart)
+static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart)
{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) {
return 196608;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) {
+ return 8650752;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_simuart0 ------------ */
+
+
+/* --------------------- sifive_wdog0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return METAL_SIFIVE_AON0_10000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) {
+ return (struct metal_clock *)&__metal_dt_clock_7.clock;
+ }
+ else {
+ return 0;
+ }
}
/* --------------------- sifive_fe310_g000_hfrosc ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_2.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock)
+static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock)
{
return &__metal_driver_vtable_sifive_fe310_g000_prci;
}
-static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG;
}
@@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s
/* --------------------- sifive_fe310_g000_hfxosc ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_0.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG;
}
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return (struct metal_clock *)&__metal_dt_clock_5.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return (struct metal_clock *)&__metal_dt_clock_6.clock;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return 112;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) {
+ return 124;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
/* --------------------- sifive_fe310_g000_pll ------------ */
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_3.clock;
}
-static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock)
+static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock)
{
return (struct metal_clock *)&__metal_dt_clock_1.clock;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock)
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock)
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock)
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock)
{
return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV;
}
-static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( )
+static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( )
{
return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_config_offset( )
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( )
{
return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG;
}
-static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( )
+static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( )
{
return 16000000;
}
@@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( )
/* --------------------- sifive_fe310_g000_prci ------------ */
-static inline long __metal_driver_sifive_fe310_g000_prci_base( )
+static __inline__ long __metal_driver_sifive_fe310_g000_prci_base( )
{
return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS;
}
-static inline long __metal_driver_sifive_fe310_g000_prci_size( )
+static __inline__ long __metal_driver_sifive_fe310_g000_prci_size( )
{
return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE;
}
-static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( )
+static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( )
{
return &__metal_driver_vtable_sifive_fe310_g000_prci;
}
-/* --------------------- sifive_fu540_c000_l2 ------------ */
+#define __METAL_DT_MAX_MEMORIES 3
-
-#define __METAL_DT_MAX_MEMORIES 2
-
-asm (".weak __metal_memory_table");
+__asm__ (".weak __metal_memory_table");
struct metal_memory *__metal_memory_table[] = {
&__metal_dt_mem_dtim_80000000,
+ &__metal_dt_mem_itim_8000000,
&__metal_dt_mem_spi_10014000};
/* From serial@10013000 */
@@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = {
#define __METAL_DT_MAX_HARTS 1
-asm (".weak __metal_cpu_table");
+#define __METAL_CPU_0_ICACHE_HANDLE 1
+
+__asm__ (".weak __metal_cpu_table");
struct __metal_driver_cpu *__metal_cpu_table[] = {
&__metal_dt_cpu_0};
@@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = {
#define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp)
-/* From local_external_interrupts_0 */
-#define __METAL_DT_SIFIVE_LOCAL_EXINTR0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
-
-#define __METAL_DT_LOCAL_EXTERNAL_INTERRUPTS_0_HANDLE (&__metal_dt_local_external_interrupts_0.irc)
-
#define __MEE_DT_MAX_GPIOS 1
-asm (".weak __metal_gpio_table");
+__asm__ (".weak __metal_gpio_table");
struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = {
&__metal_dt_gpio_10012000};
#define __METAL_DT_MAX_BUTTONS 0
-asm (".weak __metal_button_table");
+__asm__ (".weak __metal_button_table");
struct __metal_driver_sifive_gpio_button *__metal_button_table[] = {
NULL };
#define __METAL_DT_MAX_LEDS 3
-asm (".weak __metal_led_table");
+__asm__ (".weak __metal_led_table");
struct __metal_driver_sifive_gpio_led *__metal_led_table[] = {
- &__metal_dt_led_0red,
- &__metal_dt_led_0green,
- &__metal_dt_led_0blue};
+ &__metal_dt_led_0,
+ &__metal_dt_led_1,
+ &__metal_dt_led_2};
#define __METAL_DT_MAX_SWITCHES 0
-asm (".weak __metal_switch_table");
+__asm__ (".weak __metal_switch_table");
struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = {
NULL };
-#define __METAL_DT_MAX_SPIS 1
+#define __METAL_DT_MAX_I2CS 1
-asm (".weak __metal_spi_table");
+__asm__ (".weak __metal_i2c_table");
+struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = {
+ &__metal_dt_i2c_10016000};
+
+#define __METAL_DT_MAX_PWMS 3
+
+__asm__ (".weak __metal_pwm_table");
+struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = {
+ &__metal_dt_pwm_10015000,
+ &__metal_dt_pwm_10025000,
+ &__metal_dt_pwm_10035000};
+
+#define __METAL_DT_MAX_RTCS 1
+
+__asm__ (".weak __metal_rtc_table");
+struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = {
+ &__metal_dt_rtc_10000000};
+
+#define __METAL_DT_MAX_SPIS 3
+
+__asm__ (".weak __metal_spi_table");
struct __metal_driver_sifive_spi0 *__metal_spi_table[] = {
- &__metal_dt_spi_10014000};
+ &__metal_dt_spi_10014000,
+ &__metal_dt_spi_10024000,
+ &__metal_dt_spi_10034000};
+
+#define __METAL_DT_MAX_UARTS 2
+
+__asm__ (".weak __metal_uart_table");
+struct __metal_driver_sifive_uart0 *__metal_uart_table[] = {
+ &__metal_dt_serial_10013000,
+ &__metal_dt_serial_10023000};
+
+#define __METAL_DT_MAX_SIMUARTS 0
+
+__asm__ (".weak __metal_simuart_table");
+struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = {
+ NULL };
+#define __METAL_DT_MAX_WDOGS 1
+
+__asm__ (".weak __metal_wdog_table");
+struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = {
+ &__metal_dt_aon_10000000};
/* From clock@4 */
#define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4)
#define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4)
-#endif /* MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H*/
+#endif /* MACROS_ELSE_METAL_H*/
#endif /* ! __METAL_MACHINE_MACROS */
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds
new file mode 100644
index 000000000..6803873ce
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds
@@ -0,0 +1,306 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* RAM Read-Only Data Linker Script
+ *
+ * This linker script places application code and read-only data into writable
+ * memories in an attempt to improve performance, since writable memories
+ * are generally lower-latency. This linker script may cause your application
+ * to overflow RAM, since it dramatically increases the quantity of data vying
+ * for space there.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000
+ ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000
+ rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 0);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 0);
+
+ /* The RAM memories map for ECC scrubbing */
+ PROVIDE( metal_dtim_0_memory_start = 0x80000000 );
+ PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 );
+ PROVIDE( metal_itim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 );
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
+
+
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >itim AT>rom :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >ram AT>rom :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ /* Read-only data is placed in RAM to improve performance, since
+ * read-only memory generally has higher latency than RAM */
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ . = ALIGN(8);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } >ram AT>rom :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds
new file mode 100644
index 000000000..356726912
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds
@@ -0,0 +1,294 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* Scratchpad Linker Script
+ *
+ * This linker script is for executing in "scratchpad" mode, where all
+ * application code and data is placed in writable memory.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000
+ ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000
+ rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 0);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ PROVIDE(__metal_eccscrub_bit = 0);
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >ram :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >ram :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >ram :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >ram :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >ram :rom
+
+
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >ram :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >ram : rom
+
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >ram :rom
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >itim AT>ram :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >ram AT>ram :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >ram :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>ram :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>ram :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk
new file mode 100644
index 000000000..a8ddd99f2
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk
@@ -0,0 +1,13 @@
+# Copyright (C) 2020 SiFive Inc
+# SPDX-License-Identifier: Apache-2.0
+
+RISCV_ARCH = rv32imac
+RISCV_ABI = ilp32
+RISCV_CMODEL = medlow
+RISCV_SERIES = sifive-3-series
+
+TARGET_TAGS = board jlink
+TARGET_DHRY_ITERS = 20000000
+TARGET_CORE_ITERS = 5000
+TARGET_FREERTOS_WAIT_MS = 1000
+TARGET_INTR_WAIT_CYCLE = 0
\ No newline at end of file
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format
new file mode 100644
index 000000000..f9d627fe6
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format
@@ -0,0 +1,5 @@
+BasedOnStyle: LLVM
+Language: Cpp
+
+IndentWidth: 4
+
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml
new file mode 100644
index 000000000..04ce26935
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml
@@ -0,0 +1,35 @@
+sudo: required
+
+# Travis doesn't provide a wide variety of host environments to run on, so we
+# rely on Docker to provide these instead.
+services:
+ - docker
+
+# It is not really needed, other than for showing correct language tag in
+# Travis CI build log.
+language: c
+
+# The matrix of targets that we're interested in.
+env:
+ - HOST="ubuntu:16.04"
+
+# Before running the install phase we need to set up docker container that runs
+# the target machine.
+before_install:
+ - docker run -d --name host -v $(pwd):/travis $HOST tail -f /dev/null
+ - docker ps
+
+# Update the container and install dependencies
+install:
+ - docker exec -t host bash -c "yes | apt-get update"
+ - docker exec -t host bash -c "yes | apt-get upgrade"
+ - docker exec -t host bash -c "yes | apt-get install git clang-format-6.0"
+ - sudo curl -L -o /tmp/wake.deb https://github.com/sifive/wake/releases/download/v0.19.0/ubuntu-16-04-wake_0.19.0-1_amd64.deb
+ - sudo apt install /tmp/wake.deb
+
+# Here's where we actually run the test.
+script:
+# Check source code formatting
+ - docker exec -t host bash -c "cd /travis && ./scripts/check-format"
+# Run dummy Wake program in order to run Wake type checker.
+ - wake --init . && wake -x Unit
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile
new file mode 100644
index 000000000..22c8f7845
--- /dev/null
+++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile
@@ -0,0 +1,2537 @@
+# Doxyfile 1.8.15
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the configuration
+# file that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME = "Freedom Metal"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF = "Bare Metal Compatibility Library for the Freedom Platform"
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = "doc"
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE = English
+
+# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all generated output in the proper direction.
+# Possible values are: None, LTR, RTL and Context.
+# The default value is: None.
+
+OUTPUT_TEXT_DIRECTION = None
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines (in the resulting output). You can put ^^ in the value part of an
+# alias to insert a newline as if a physical newline was in the original file.
+# When you need a literal { or } or , in the value part of an alias you have to
+# escape them by means of a backslash (\), this can lead to conflicts with the
+# commands \{ and \} for these it is advised to use the version @{ and @} or use
+# a double escape (\\{ and \\})
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
+# sources only. Doxygen will then generate output that is more tailored for that
+# language. For instance, namespaces will be presented as modules, types will be
+# separated into more groups, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_SLICE = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
+# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
+# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
+# tries to guess whether the code is fixed or free formatted code, this is the
+# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is
+# Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if ... \endif and \cond
+# ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation. If
+# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = metal
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.idl \
+ *.ddl \
+ *.odl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.cs \
+ *.d \
+ *.php \
+ *.php4 \
+ *.php5 \
+ *.phtml \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.pyw \
+ *.f90 \
+ *.f95 \
+ *.f03 \
+ *.f08 \
+ *.f \
+ *.for \
+ *.tcl \
+ *.vhd \
+ *.vhdl \
+ *.ucf \
+ *.qsf \
+ *.ice
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE = metal/compiler.h metal/io.h metal/machine.h
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS = _* __* *vtable
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+#
+#
+# where is the value of the INPUT_FILTER tag, and is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# entity all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see https://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML = NO
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP = NO
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via Javascript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have Javascript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: https://developer.apple.com/xcode/), introduced with OSX
+# 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
+# genXcode/_index.html for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# https://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use + S
+# (what the is depends on the OS and browser, but it is typically
+# , /