From: rtel Date: Wed, 1 Jan 2020 22:05:35 +0000 (+0000) Subject: Rename RISC-V_RV32_SiFive_HiFive1-FreedomStudio directory to RISC-V_RV32_SiFive_HiFiv... X-Git-Tag: V10.3.0~33 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=d38142e468c2f407c9cbbb271f487fc35879bdef;p=freertos Rename RISC-V_RV32_SiFive_HiFive1-FreedomStudio directory to RISC-V_RV32_SiFive_HiFive1-RevB-FreedomStudio as it targets Rev B of the hardware. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2790 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject new file mode 100644 index 000000000..8efeeeefd --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project new file mode 100644 index 000000000..f22f74077 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project @@ -0,0 +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 + + + 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 new file mode 100644 index 000000000..b0d04ea76 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000..a7a0c1180 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h @@ -0,0 +1,101 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 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 configCLINT_BASE_ADDRESS CLINT_CTRL_ADDR +#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 */ 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 new file mode 100644 index 000000000..30aeb1baa --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c @@ -0,0 +1,197 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 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/design.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts new file mode 100644 index 000000000..970d3be72 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts @@ -0,0 +1,209 @@ +/dts-v1/; + +/ { + #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"; + }; + }; +}; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist new file mode 100644 index 000000000..921dd83ac --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.reglist @@ -0,0 +1,54 @@ +zero +ra +sp +gp +tp +t0 +t1 +t2 +fp +s1 +a0 +a1 +a2 +a3 +a4 +a5 +a6 +a7 +s2 +s3 +s4 +s5 +s6 +s7 +s8 +s9 +s10 +s11 +t3 +t4 +t5 +t6 +pc +mstatus +misa +mie +mtvec +mscratch +mepc +mcause +mtval +mip +mvendorid +marchid +mimpid +mhartid +tselect +tdata1 +tdata2 +tdata3 +dcsr +dpc +dscratch +priv 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 new file mode 100644 index 000000000..0c26f435a --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h @@ -0,0 +1,59 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__BUTTON_H +#define METAL__BUTTON_H + +/*! + * @file button.h + * API for interfacing with physical buttons + */ + +#include + +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); + int (*get_interrupt_id)(struct metal_button *button); +}; + +/*! + * @brief A button device handle + * + * A `struct metal_button` is an implementation-defined object which represents + * a button on a development board. + */ +struct metal_button { + const struct metal_button_vtable *vtable; +}; + +/*! + * @brief Get a reference to a button + * + * @param label The DeviceTree label for the button + * @return A handle for the button + */ +struct metal_button* metal_button_get(char *label); + + +/*! + * @brief Get the interrupt controller for a button + * + * @param button The handle for the button + * @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); } + +/*! + * @brief Get the interrupt id for a button + * + * @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); } + +#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 new file mode 100644 index 000000000..a8a60ada6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h @@ -0,0 +1,58 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__CACHE_H +#define METAL__CACHE_H + +/*! + * @file cache.h + * + * @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); +}; + +/*! + * @brief a handle for a cache + */ +struct metal_cache { + const struct __metal_cache_vtable *vtable; +}; + +/*! + * @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. + */ +inline void metal_cache_init(struct metal_cache *cache, int ways) { + return cache->vtable->init(cache, ways); +} + +/*! + * @brief Get the current number of enabled cache ways + * @param cache The handle for the cache + * @return The current number of enabled cache ways + */ +inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { + return cache->vtable->get_enabled_ways(cache); +} + +/*! + * @brief Enable the requested number of cache ways + * @param cache The handle for the cache + * @param ways The number of ways to enabled + * @return 0 if the ways are successfully enabled + */ +inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { + return cache->vtable->set_enabled_ways(cache, ways); +} + +#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 new file mode 100644 index 000000000..277841e01 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h @@ -0,0 +1,119 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#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. + */ + +struct metal_clock; + +#include + +/* The generic interface to all clocks. */ +struct __metal_clock_vtable { + long (*get_rate_hz)(const struct metal_clock *clk); + long (*set_rate_hz)(struct metal_clock *clk, long hz); +}; + +/*! + * @brief Function signature of clock pre-rate change callbacks + */ +typedef void (*metal_clock_pre_rate_change_callback)(void *priv); + +/*! + * @brief Function signature of clock post-rate change callbacks + */ +typedef void (*metal_clock_post_rate_change_callback)(void *priv); + +/*! + * @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. + * + * 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; + + /* Post-rate change callback */ + metal_clock_post_rate_change_callback _post_rate_change_callback; + void *_post_rate_change_callback_priv; +}; + +/*! + * @brief Returns the current rate of the given 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); } + +/*! + * @brief Set the current rate of a clock + * + * @param clk The handle for the clock + * @param hz The desired rate in Hz + * @return The new rate of the clock in Hz. + * + * Attempts to set the current rate of the given clock to as close as possible + * 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. + */ +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); + + 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); + + return out; +} + +/*! + * @brief Register a callback that must be called before a rate change + * + * @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; +} + +/*! + * @brief Registers a callback that must be called after a rate change + * + * @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; +} + +#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 new file mode 100644 index 000000000..62c0ea975 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__COMPILER_H +#define METAL__COMPILER_H + +#define __METAL_DECLARE_VTABLE(type) \ + extern const struct type type; + +#define __METAL_DEFINE_VTABLE(type) \ + const struct type type + +#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))) + +void _metal_trap(int ecode); + +#endif 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 new file mode 100644 index 000000000..453bd12de --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h @@ -0,0 +1,271 @@ +/* Copyright 2018 SiFive, Inc */ + +/* SPDX-License-Identifier: Apache-2.0 */ + +/*! @file cpu.h + * @brief API for accessing CPU capabilities. + */ + +#ifndef METAL__CPU_H +#define METAL__CPU_H + +#include +#include + +struct metal_cpu; + +/*! + * @brief Function signature for exception handlers + */ +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 (*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); + int (*get_tmr_interrupt_id)(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); + 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); +}; + +/*! @brief A device handle for a CPU hart + */ +struct metal_cpu { + const struct metal_cpu_vtable *vtable; +}; + +/*! @brief Get a reference to a CPU hart + * + * @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); + +/*! @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(); + +/*! @brief Get the number of CPU harts + * + * @return The number of CPU harts */ +int metal_cpu_get_num_harts(); + +/*! @brief Get the CPU cycle count timer value + * + * Get the value of the cycle count timer for a given CPU + * + * @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); } + +/*! @brief Get the timebase of the CPU + * + * Get the value of the timebase of the cycle count timer + * + * @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); } + +/*! @brief Get the value of the mtime RTC + * + * Get the value of the mtime real-time clock. The CPU interrupt controller + * must be initialized before this function is called or the return value + * will be 0. + * + * @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); } + +/*! @brief Set the value of the RTC mtimecmp RTC + * + * Set the value of the mtime real-time clock compare register. The CPU + * interrupt controller must be initialized before this function is called + * or the return value will be -1; + * + * @param cpu The CPU device handle + * @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); } + +/*! @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. + * + * @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); } + +/*! @brief Get the RTC timer interrupt id + * + * Get the interrupt ID of the real-time clock interrupt + * + * @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); } + +/*! @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. + * + * @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); } + +/*! @brief Get the software interrupt id + * + * Get the interrupt ID for the software/inter-process interrupt + * + * @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); } + +/*! + * @brief Set the inter-process interrupt for a hart + * + * Trigger a software/inter-process interrupt for a hart. The CPU interrupt + * controller for the CPU handle passed to this function must be initialized + * before this function is called. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Clear the inter-process interrupt for a hart + * + * Clear the software/inter-process interrupt for a hart. The CPU interrupt + * controller for the CPU handle passed to this function must be initialized + * before this function is called. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Get the value of MSIP for the given hart + * + * Get the value of the machine software interrupt pending bit for + * the given hart. The CPU interrupt controller for the CPU handle passed + * as argument to this function must be initialized before this function + * is called. + * + * @param cpu the CPU device handle + * @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); } + +/*! + * @brief Get the interrupt controller for the CPU + * + * Get the CPU interrupt controller. The controller returned by this + * function must be initialized before any interrupts are registered + * or enabled and before any exception handlers are registered with + * this CPU. + * + * @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); } + +/*! + * @brief Register an exception handler + * + * 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); } + +/*! + * @brief Get the length of an instruction in bytes + * + * Get the length of an instruction in bytes. + * + * On RISC-V platforms, this is useful for detecting whether an instruction is + * compressed (2 bytes long) or uncompressed (4 bytes long). + * + * This function is useful in conjuction with `metal_cpu_get_exception_pc()` + * and `metal_cpu_set_exception_pc()` in order to cause the exception handler to + * return execution after the faulting instruction. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Get the program counter of the current exception. + * + * This function must be called within an exception handler. The behavior is + * undefined outside of an exception handler. + * + * @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); } + +/*! + * @brief Set the exception program counter + * + * This function must be called within an exception handler. The behavior + * is undefined outside of an exception handler. + * + * This function can be used to cause an exception handler to return execution + * to an address other than the one that caused the exception. + * + * @param cpu the CPU device handle + * @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); } + +#endif 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 new file mode 100644 index 000000000..2647c5981 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__FIXED_CLOCK_H +#define METAL__DRIVERS__FIXED_CLOCK_H + +struct __metal_driver_fixed_clock; + +#include +#include + +struct __metal_driver_vtable_fixed_clock { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_clock) + +struct __metal_driver_fixed_clock { + struct metal_clock clock; +}; + +#endif 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 new file mode 100644 index 000000000..936ce8d77 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__FIXED_FACTOR_CLOCK_H +#define METAL__DRIVERS__FIXED_FACTOR_CLOCK_H + +struct __metal_driver_fixed_factor_clock; + +#include +#include + +struct __metal_driver_vtable_fixed_factor_clock { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_factor_clock) + +struct __metal_driver_fixed_factor_clock { + struct metal_clock clock; +}; + +#endif 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 new file mode 100644 index 000000000..08d571e1c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h @@ -0,0 +1,24 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_CLINT0_H +#define METAL__DRIVERS__RISCV_CLINT0_H + +#include +#include + +struct __metal_driver_vtable_riscv_clint0 { + struct metal_interrupt_vtable clint_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_clint0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_riscv_clint0 { + struct metal_interrupt controller; + int init_done; +}; +#undef __METAL_MACHINE_MACROS + +#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 new file mode 100644 index 000000000..eb1e5b8ca --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h @@ -0,0 +1,203 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_CPU_H +#define METAL__DRIVERS__RISCV_CPU_H + +#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_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_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 +#if __riscv_xlen == 32 +#define METAL_MCAUSE_INTR 0x80000000UL +#define METAL_MCAUSE_CAUSE 0x000003FFUL +#else +#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_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 */ +/* 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 + +typedef enum { + 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_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_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_interrup_cmd_e; + +typedef struct __metal_interrupt_data { + long long pad : 64; + metal_interrupt_handler_t handler; + void *sub_int; + void *exint_data; +} __metal_interrupt_data; + +/* CPU interrupt controller */ + +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; +}; + + +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_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) + +struct __metal_driver_riscv_cpu_intc { + struct metal_interrupt controller; + int init_done; + uintptr_t metal_mtvec_table[METAL_MAX_MI]; + __metal_interrupt_data metal_int_table[METAL_MAX_MI]; + metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; +}; + +/* CPU driver*/ +struct __metal_driver_vtable_cpu { + struct metal_cpu_vtable cpu_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) + +struct __metal_driver_cpu { + struct metal_cpu 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 new file mode 100644 index 000000000..159ee6d69 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h @@ -0,0 +1,31 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_PLIC0_H +#define METAL__DRIVERS__RISCV_PLIC0_H + +#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 + +struct __metal_driver_vtable_riscv_plic0 { + struct metal_interrupt_vtable plic_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_plic0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_riscv_plic0 { + struct metal_interrupt controller; + int init_done; + metal_interrupt_handler_t metal_exint_table[__METAL_PLIC_SUBINTERRUPTS]; + __metal_interrupt_data metal_exdata_table[__METAL_PLIC_SUBINTERRUPTS]; +}; +#undef __METAL_MACHINE_MACROS + +#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 new file mode 100644 index 000000000..db9674625 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h @@ -0,0 +1,42 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_CLIC0_H +#define METAL__DRIVERS__SIFIVE_CLIC0_H + +#include +#include + +#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_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) + +struct __metal_driver_vtable_sifive_clic0 { + struct metal_interrupt_vtable clic_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_sifive_clic0 { + struct metal_interrupt controller; + int init_done; + metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; + __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; +}; +#undef __METAL_MACHINE_MACROS + +#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 new file mode 100644 index 000000000..d311f0cf2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H + +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) + +struct __metal_driver_sifive_fe310_g000_hfrosc { + 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_hfxosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h new file mode 100644 index 000000000..b86926fba --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h @@ -0,0 +1,20 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H + +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_hfxosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) + +struct __metal_driver_sifive_fe310_g000_hfxosc { + 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_pll.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h new file mode 100644 index 000000000..67f818f7b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h @@ -0,0 +1,26 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H + +struct __metal_driver_sifive_fe310_g000_pll; + +#include +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_pll { + void (*init)(struct __metal_driver_sifive_fe310_g000_pll *pll); + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) + +struct __metal_driver_sifive_fe310_g000_pll { + 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 new file mode 100644 index 000000000..87c9ca985 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h @@ -0,0 +1,23 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H + +#include +#include + +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); +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) + +struct __metal_driver_sifive_fe310_g000_prci { +}; + +#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 new file mode 100644 index 000000000..8c3cf907e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h @@ -0,0 +1,23 @@ +/* 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_global-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h new file mode 100644 index 000000000..9e6f2faf6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H +#define METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H + +#include +#include + +struct __metal_driver_vtable_sifive_global_external_interrupts0 { + struct metal_interrupt_vtable global0_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) + +struct __metal_driver_sifive_global_external_interrupts0 { + struct metal_interrupt irc; + int init_done; +}; + +#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 new file mode 100644 index 000000000..a0caeaba8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H +#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_button { + struct metal_button_vtable button_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) + +struct __metal_driver_sifive_gpio_button { + struct metal_button button; +}; + +#endif 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 new file mode 100644 index 000000000..a8dacf116 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H +#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_led { + struct metal_led_vtable led_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) + +struct __metal_driver_sifive_gpio_led { + struct metal_led led; +}; + +#endif 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 new file mode 100644 index 000000000..c9c7839e9 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H +#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_switch { + struct metal_switch_vtable switch_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) + +struct __metal_driver_sifive_gpio_switch { + struct metal_switch flip; +}; + +#endif 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 new file mode 100644 index 000000000..cc56dc722 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO0_H +#define METAL__DRIVERS__SIFIVE_GPIO0_H + +#include +#include + +struct __metal_driver_vtable_sifive_gpio0 { + const struct __metal_gpio_vtable gpio; +}; + +//struct __metal_driver_sifive_gpio0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) + +struct __metal_driver_sifive_gpio0 { + struct metal_gpio gpio; +}; + +#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 new file mode 100644 index 000000000..aa8d63078 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H +#define METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H + +#include +#include + +struct __metal_driver_vtable_sifive_local_external_interrupts0 { + struct metal_interrupt_vtable local0_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) + +struct __metal_driver_sifive_local_external_interrupts0 { + struct metal_interrupt irc; + int init_done; +}; + + +#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 new file mode 100644 index 000000000..90d4c831e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h @@ -0,0 +1,24 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_SPI0_H +#define METAL__DRIVERS__SIFIVE_SPI0_H + +#include +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_spi0 { + const struct metal_spi_vtable spi; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0) + +struct __metal_driver_sifive_spi0 { + struct metal_spi spi; + unsigned long baud_rate; +}; + +#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 new file mode 100644 index 000000000..e87db2c83 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_TEST0_H +#define METAL__DRIVERS__SIFIVE_TEST0_H + +#include +#include + +struct __metal_driver_vtable_sifive_test0 { + const struct __metal_shutdown_vtable shutdown; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_test0) + +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_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h new file mode 100644 index 000000000..11d954002 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h @@ -0,0 +1,28 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_UART0_H +#define METAL__DRIVERS__SIFIVE_UART0_H + +#include +#include +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_uart0 { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_uart0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0) + +struct __metal_driver_sifive_uart0 { + struct metal_uart uart; + unsigned long baud_rate; +}; + + +#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 new file mode 100644 index 000000000..513687dd7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h @@ -0,0 +1,151 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__GPIO_H +#define METAL__GPIO_H + +#include + +/*! + * @file gpio.h + * @brief API for manipulating general-purpose input/output + */ + +struct metal_gpio; + +struct __metal_gpio_vtable { + int (*disable_input)(struct metal_gpio *, long pins); + long (*output)(struct metal_gpio *); + 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); +}; + +/*! + * @struct metal_gpio + * @brief The handle for a GPIO interface + */ +struct metal_gpio { + const struct __metal_gpio_vtable *vtable; +}; + +/*! + * @brief Get a GPIO device handle + * @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); + +/*! + * @brief Disable 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 disabled + */ +inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { + if(!gpio) { + return 1; + } + + return gpio->vtable->disable_input(gpio, (1 << pin)); +} + +/*! + * @brief Enable 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 enabled + */ +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 Set the output value of a GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The pin number indexed from 0 + * @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; + } + + if(value == 0) { + return gpio->vtable->output_clear(gpio, (1 << pin)); + } else { + return gpio->vtable->output_set(gpio, (1 << pin)); + } +} + +/*! + * @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_pin(struct metal_gpio *gpio, int pin) { + if(!gpio) { + return 0; + } + + long value = gpio->vtable->output(gpio); + + if(value & (1 << pin)) { + return 1; + } else { + return 0; + } +} + +/*! + * @brief Clears the value of the GPIO pin + * @param gpio The handle for the GPIO interface + * @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; + } + + return gpio->vtable->output_clear(gpio, (1 << pin)); +} + +/*! + * @brief Toggles the value of the GPIO pin + * @param gpio The handle for the GPIO interface + * @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; + } + + return gpio->vtable->output_toggle(gpio, (1 << pin)); +} + +/*! + * @brief Enables and sets the pinmux for a GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to enable pinmux on + * @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; + } + + return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin)); +} + +#endif 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 new file mode 100644 index 000000000..43f587aca --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h @@ -0,0 +1,134 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__INTERRUPT_H +#define METAL__INTERRUPT_H + +/*! @file interrupt.h + * @brief API for registering and manipulating interrupts + */ + +#include + +/*! + * @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_vector_mode; + +/*! + * @brief Function signature for interrupt callback handlers + */ +typedef void (*metal_interrupt_handler_t) (int, void *); + +struct metal_interrupt; + +struct metal_interrupt_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 (*interrupt_vector_enable)(struct metal_interrupt *controller, + int id, metal_vector_mode mode); + 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); +}; + +/*! + * @brief A handle for an interrupt + */ +struct metal_interrupt { + const struct metal_interrupt_vtable *vtable; +}; + +/*! + * @brief Initialize a given interrupt controller + * + * Initialize a given interrupt controller. This function must be called + * before any interrupts are registered or enabled with the handler. It + * is invalid to initialize an interrupt controller more than once. + * + * @param controller The handle for the interrupt controller + */ +inline void metal_interrupt_init(struct metal_interrupt *controller) +{ + return controller->vtable->interrupt_init(controller); +} + + +/*! + * @brief Register an interrupt handler + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to register + * @param handler The interrupt handler callback + * @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); +} + +/*! + * @brief Enable an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return 0 upon success + */ +inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) +{ + return controller->vtable->interrupt_enable(controller, id); +} + +/*! + * @brief Disable an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to disable + * @return 0 upon success + */ +inline int metal_interrupt_disable(struct metal_interrupt *controller, int id) +{ + return controller->vtable->interrupt_disable(controller, id); +} + +/*! + * @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); +} + +/*! + * @brief Disable an interrupt vector + * @param controller The handle for the 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) +{ + 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) +{ + return controller->vtable->command_request(controller, cmd, data); +} + +#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 new file mode 100644 index 000000000..450054142 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__IO_H +#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)) + +/* Allows users to specify arbitrary fences. */ +#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 short __metal_io_u16; +typedef unsigned int __metal_io_u32; +#if __riscv_xlen >= 64 +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 new file mode 100644 index 000000000..1a2a05b8b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__ITIM_H +#define METAL__ITIM_H + +/*! @file itim.h + * + * 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"))) + +#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 new file mode 100644 index 000000000..a430b84c2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h @@ -0,0 +1,68 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LED_H +#define METAL__LED_H + +/*! + * @file led.h + * @brief API for manipulating LEDs + */ + +struct metal_led; + +struct metal_led_vtable { + int (*led_exist)(struct metal_led *led, char *label); + void (*led_enable)(struct metal_led *led); + void (*led_on)(struct metal_led *led); + void (*led_off)(struct metal_led *led); + void (*led_toggle)(struct metal_led *led); +}; + +/*! + * @brief A handle for an LED + */ +struct metal_led { + const struct metal_led_vtable *vtable; +}; + +/*! + * @brief Get a handle for an 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); + +/*! + * @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 + */ +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); } + +/*! + * @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); } + +/*! + * @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); } + +/*! + * @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); } + +#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 new file mode 100644 index 000000000..d863aa96e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h @@ -0,0 +1,127 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LOCK_H +#define METAL__LOCK_H + +#include +#include + +/*! + * @file lock.h + * @brief An API for creating and using a software lock/mutex + */ + +/* TODO: How can we make the exception code platform-independant? */ +#define _METAL_STORE_AMO_ACCESS_FAULT 7 + +/*! + * @def METAL_LOCK_DECLARE + * @brief Declare a lock + * + * 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 + +/*! + * @brief A handle for a lock + */ +struct metal_lock { + 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. + * + * 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) { +#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) { + return 1; + } + + /* If the memory doesn't support atomics, report an error */ + if(!metal_memory_supports_atomics(lock_mem)) { + return 2; + } + + lock->_state = 0; + + return 0; +#else + return 3; +#endif +} + +/*! + * @brief Take a lock + * @param lock The handle for a lock + * @return 0 if the lock is successfully taken + * + * 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) { +#ifdef __riscv_atomic + int old = 1; + int new = 1; + + while(old != 0) { + __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])" + : [old] "=r" (old) + : [new] "r" (new), [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))); + + /* Trigger a Store/AMO access fault */ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); + + /* If execution returns, indicate failure */ + return 1; +#endif +} + +/*! + * @brief Give back a held lock + * @param lock The handle for a lock + * @return 0 if the lock is successfully given + * + * 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) { +#ifdef __riscv_atomic + __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))); + + /* Trigger a Store/AMO access fault */ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); + + /* If execution returns, indicate failure */ + return 1; +#endif +} + +#endif /* METAL__LOCK_H */ 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 new file mode 100644 index 000000000..f76dbd632 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h @@ -0,0 +1,872 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#include + +#ifdef __METAL_MACHINE_MACROS + +#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#define MACROS_IF_SIFIVE_HIFIVE1_REVB____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_NUM_PARENTS 1 + +#ifndef __METAL_PLIC_SUBINTERRUPTS +#define __METAL_PLIC_SUBINTERRUPTS 0 +#endif +#ifndef __METAL_PLIC_NUM_PARENTS +#define __METAL_PLIC_NUM_PARENTS 0 +#endif +#ifndef __METAL_CLIC_SUBINTERRUPTS +#define __METAL_CLIC_SUBINTERRUPTS 0 +#endif + +#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ + +#else /* ! __METAL_MACHINE_MACROS */ + +#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H + +#define __METAL_CLINT_2000000_INTERRUPTS 2 + +#define METAL_MAX_CLINT_INTERRUPTS 2 + +#define __METAL_CLINT_NUM_PARENTS 2 + +#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 + +#define __METAL_PLIC_SUBINTERRUPTS 27 + +#define METAL_MAX_PLIC_INTERRUPTS 1 + +#define __METAL_PLIC_NUM_PARENTS 1 + +#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_GLOBAL_EXT_INTERRUPTS 0 + +#define __METAL_GPIO_10012000_INTERRUPTS 16 + +#define METAL_MAX_GPIO_INTERRUPTS 16 + +#define __METAL_SERIAL_10013000_INTERRUPTS 1 + +#define METAL_MAX_UART_INTERRUPTS 1 + + +#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; + +/* From clock@2 */ +struct __metal_driver_fixed_clock __metal_dt_clock_2; + +/* From clock@5 */ +struct __metal_driver_fixed_clock __metal_dt_clock_5; + +struct metal_memory __metal_dt_mem_dtim_80000000; + +struct metal_memory __metal_dt_mem_spi_10014000; + +/* From clint@2000000 */ +struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; + +/* From cpu@0 */ +struct __metal_driver_cpu __metal_dt_cpu_0; + +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; + +struct metal_pmp __metal_dt_pmp; + +/* From local_external_interrupts_0 */ +struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; + +/* From gpio@10012000 */ +struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; + +/* From led@0red */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; + +/* From led@0green */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; + +/* From spi@10014000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From serial@10013000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From clock@3 */ +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; + +/* From clock@4 */ +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; + + + +/* --------------------- fixed_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; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) { + return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { + return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; + } + else { + return 0; + } +} + + + +/* --------------------- fixed_factor_clock ------------ */ + + +/* --------------------- sifive_clint0 ------------ */ +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else if (idx == 1) { + return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; + } + else { + return NULL; + } +} + +static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +{ + if (idx == 0) { + return 3; + } + else if (idx == 1) { + return 7; + } + else { + return 0; + } +} + + + +/* --------------------- cpu ------------ */ +static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return 0; + } + else { + return -1; + } +} + +static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return 1000000; + } + else { + return 0; + } +} + +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; + } + else { + return NULL; + } +} + +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; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_plic0 ------------ */ +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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) +{ + if (idx == 0) { + return 11; + } + else if (idx == 0) { + return 11; + } + else { + return 0; + } +} + + + +/* --------------------- 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) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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))) { + return 9; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + return 10; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + return 11; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + return 12; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + return 13; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + return 14; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { + return 15; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { + return 16; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { + return 17; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { + return 18; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { + return 19; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { + return 20; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { + return 21; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + return 22; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_gpio_button ------------ */ + + +/* --------------------- sifive_gpio_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) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return 22; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return 19; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return 21; + } + else { + return 0; + } +} + +static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return "LD0red"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return "LD0green"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return "LD0blue"; + } + else { + return ""; + } +} + + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_spi0 ------------ */ +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 { + return 0; + } +} + +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 { + return 0; + } +} + +static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +{ + return (struct metal_clock *)&__metal_dt_clock_4.clock; +} + +static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +{ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; +} + +static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +{ + return 60; +} + +static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +{ + return 60; +} + + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- sifive_uart0 ------------ */ +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 { + return 0; + } +} + +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 { + return 0; + } +} + +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 { + return 0; + } +} + +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 { + return NULL; + } +} + +static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +{ + return 5; +} + +static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +{ + return (struct metal_clock *)&__metal_dt_clock_4.clock; +} + +static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +{ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; +} + +static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +{ + return 196608; +} + +static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +{ + return 196608; +} + + + +/* --------------------- sifive_fe310_g000_hfrosc ------------ */ +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) +{ + 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) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + +static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_hfxosc ------------ */ +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) +{ + 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) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_pll ------------ */ +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) +{ + 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) +{ + 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) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; +} + +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( ) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; +} + +static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) +{ + return 16000000; +} + + + +/* --------------------- sifive_fe310_g000_prci ------------ */ +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( ) +{ + 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( ) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + + + +/* --------------------- sifive_fu540_c000_l2 ------------ */ + + +#define __METAL_DT_MAX_MEMORIES 2 + +asm (".weak __metal_memory_table"); +struct metal_memory *__metal_memory_table[] = { + &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_spi_10014000}; + +/* From serial@10013000 */ +#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_STDOUT_UART_BAUD 115200 + +/* From clint@2000000 */ +#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller) + +#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller) + +#define __METAL_DT_MAX_HARTS 1 + +asm (".weak __metal_cpu_table"); +struct __metal_driver_cpu *__metal_cpu_table[] = { + &__metal_dt_cpu_0}; + +/* From interrupt_controller@c000000 */ +#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) + +#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) + +#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"); +struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { + &__metal_dt_gpio_10012000}; + +#define __METAL_DT_MAX_BUTTONS 0 + +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"); +struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { + &__metal_dt_led_0red, + &__metal_dt_led_0green, + &__metal_dt_led_0blue}; + +#define __METAL_DT_MAX_SWITCHES 0 + +asm (".weak __metal_switch_table"); +struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { + NULL }; +#define __METAL_DT_MAX_SPIS 1 + +asm (".weak __metal_spi_table"); +struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { + &__metal_dt_spi_10014000}; + +/* 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 /* ! __METAL_MACHINE_MACROS */ + +#endif /* ! ASSEMBLY */ 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 new file mode 100644 index 000000000..8c0cd048b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h @@ -0,0 +1,249 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H + +#include + + +/* --------------------- fixed_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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- 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); + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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( ); + + +/* --------------------- 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 ------------ */ + + +/* From clock@0 */ +struct __metal_driver_fixed_clock __metal_dt_clock_0 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@2 */ +struct __metal_driver_fixed_clock __metal_dt_clock_2 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@5 */ +struct __metal_driver_fixed_clock __metal_dt_clock_5 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +struct metal_memory __metal_dt_mem_dtim_80000000 = { + ._base_address = 2147483648UL, + ._size = 16384UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10014000 = { + ._base_address = 536870912UL, + ._size = 500000UL, + ._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, + .init_done = 0, +}; + +/* From cpu@0 */ +struct __metal_driver_cpu __metal_dt_cpu_0 = { + .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, +}; + +/* From interrupt_controller */ +struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = { + .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable, + .init_done = 0, +}; + +/* From interrupt_controller@c000000 */ +struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { + .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable, + .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, +}; + +/* 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 = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0green */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From spi@10014000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { + .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 clock@3 */ +struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, +}; + +/* From clock@1 */ +struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.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, +}; + +/* From prci@10008000 */ +struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { +}; + + +#endif /* SIFIVE_HIFIVE1_REVB____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 new file mode 100644 index 000000000..4ecd3e336 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h @@ -0,0 +1,237 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H + +/* From clock@0 */ +#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL + +/* From clock@2 */ +#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL + +/* From clock@5 */ +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL + +#define METAL_FIXED_CLOCK + +/* From clint@2000000 */ +#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL +#define METAL_RISCV_CLINT0_0_SIZE 65536UL + +#define METAL_RISCV_CLINT0 +#define METAL_RISCV_CLINT0_MSIP_BASE 0UL +#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL +#define METAL_RISCV_CLINT0_MTIME 49144UL + +/* From interrupt_controller@c000000 */ +#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592UL +#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL +#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL +#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 +#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 + +/* 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_AON0 +#define METAL_SIFIVE_AON0_WDOGCFG 0UL +#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL +#define METAL_SIFIVE_AON0_WDOGS 16UL +#define METAL_SIFIVE_AON0_WDOGFEED 24UL +#define METAL_SIFIVE_AON0_WDOGKEY 28UL +#define METAL_SIFIVE_AON0_WDOGCMP 32UL +#define METAL_SIFIVE_AON0_RTCCFG 64UL +#define METAL_SIFIVE_AON0_RTCLO 72UL +#define METAL_SIFIVE_AON0_RTCHI 72UL +#define METAL_SIFIVE_AON0_RTCS 80UL +#define METAL_SIFIVE_AON0_RTCCMP 96UL +#define METAL_SIFIVE_AON0_LFROSCCFG 112UL +#define METAL_SIFIVE_AON0_BACKUP0 128UL +#define METAL_SIFIVE_AON0_BACKUP1 132UL +#define METAL_SIFIVE_AON0_BACKUP2 136UL +#define METAL_SIFIVE_AON0_BACKUP3 140UL +#define METAL_SIFIVE_AON0_BACKUP4 144UL +#define METAL_SIFIVE_AON0_BACKUP5 148UL +#define METAL_SIFIVE_AON0_BACKUP6 152UL +#define METAL_SIFIVE_AON0_BACKUP7 152UL +#define METAL_SIFIVE_AON0_BACKUP8 160UL +#define METAL_SIFIVE_AON0_BACKUP9 164UL +#define METAL_SIFIVE_AON0_BACKUP10 168UL +#define METAL_SIFIVE_AON0_BACKUP11 172UL +#define METAL_SIFIVE_AON0_BACKUP12 176UL +#define METAL_SIFIVE_AON0_BACKUP13 180UL +#define METAL_SIFIVE_AON0_BACKUP14 184UL +#define METAL_SIFIVE_AON0_BACKUP15 188UL +#define METAL_SIFIVE_AON0_BACKUP16 192UL +#define METAL_SIFIVE_AON0_BACKUP17 196UL +#define METAL_SIFIVE_AON0_BACKUP18 200UL +#define METAL_SIFIVE_AON0_BACKUP19 204UL +#define METAL_SIFIVE_AON0_BACKUP20 208UL +#define METAL_SIFIVE_AON0_BACKUP21 212UL +#define METAL_SIFIVE_AON0_BACKUP22 216UL +#define METAL_SIFIVE_AON0_BACKUP23 220UL +#define METAL_SIFIVE_AON0_BACKUP24 224UL +#define METAL_SIFIVE_AON0_BACKUP25 228UL +#define METAL_SIFIVE_AON0_BACKUP26 232UL +#define METAL_SIFIVE_AON0_BACKUP27 236UL +#define METAL_SIFIVE_AON0_BACKUP28 240UL +#define METAL_SIFIVE_AON0_BACKUP29 244UL +#define METAL_SIFIVE_AON0_BACKUP30 248UL +#define METAL_SIFIVE_AON0_BACKUP31 252UL +#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL +#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL +#define METAL_SIFIVE_AON0_PMUIE 320UL +#define METAL_SIFIVE_AON0_PMUCAUSE 324UL +#define METAL_SIFIVE_AON0_PMUSLEEP 328UL +#define METAL_SIFIVE_AON0_PMUKEY 332UL + +/* From clock@3 */ + +#define METAL_SIFIVE_FE310_G000_HFROSC + +/* From clock@1 */ + +#define METAL_SIFIVE_FE310_G000_HFXOSC + +/* From prci@10008000 */ +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL + +#define METAL_SIFIVE_FE310_G000_PRCI +#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL +#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL + +/* From clock@4 */ +#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL + +#define METAL_SIFIVE_FE310_G000_PLL + +/* From gpio@10012000 */ +#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL +#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL + +#define METAL_SIFIVE_GPIO0 +#define METAL_SIFIVE_GPIO0_VALUE 0UL +#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL +#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL +#define METAL_SIFIVE_GPIO0_PORT 12UL +#define METAL_SIFIVE_GPIO0_PUE 16UL +#define METAL_SIFIVE_GPIO0_DS 20UL +#define METAL_SIFIVE_GPIO0_RISE_IE 24UL +#define METAL_SIFIVE_GPIO0_RISE_IP 28UL +#define METAL_SIFIVE_GPIO0_FALL_IE 32UL +#define METAL_SIFIVE_GPIO0_FALL_IP 36UL +#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL +#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL +#define METAL_SIFIVE_GPIO0_LOW_IE 48UL +#define METAL_SIFIVE_GPIO0_LOW_IP 52UL +#define METAL_SIFIVE_GPIO0_IOF_EN 56UL +#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL +#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL + +/* From led@0red */ + +/* From led@0green */ + +/* From led@0blue */ + +#define METAL_SIFIVE_GPIO_LEDS + +/* From i2c@10016000 */ +#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL +#define METAL_SIFIVE_I2C0_0_SIZE 4096UL + +#define METAL_SIFIVE_I2C0 +#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL +#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL +#define METAL_SIFIVE_I2C0_CONTROL 8UL +#define METAL_SIFIVE_I2C0_TRANSMIT 12UL +#define METAL_SIFIVE_I2C0_RECEIVE 12UL +#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 + +#define METAL_SIFIVE_PWM0 +#define METAL_SIFIVE_PWM0_PWMCFG 0UL +#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL +#define METAL_SIFIVE_PWM0_PWMS 16UL +#define METAL_SIFIVE_PWM0_PWMCMP0 32UL +#define METAL_SIFIVE_PWM0_PWMCMP1 36UL +#define METAL_SIFIVE_PWM0_PWMCMP2 40UL +#define METAL_SIFIVE_PWM0_PWMCMP3 44UL + +/* 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 + +#define METAL_SIFIVE_SPI0 +#define METAL_SIFIVE_SPI0_SCKDIV 0UL +#define METAL_SIFIVE_SPI0_SCKMODE 4UL +#define METAL_SIFIVE_SPI0_CSID 16UL +#define METAL_SIFIVE_SPI0_CSDEF 20UL +#define METAL_SIFIVE_SPI0_CSMODE 24UL +#define METAL_SIFIVE_SPI0_DELAY0 40UL +#define METAL_SIFIVE_SPI0_DELAY1 44UL +#define METAL_SIFIVE_SPI0_FMT 64UL +#define METAL_SIFIVE_SPI0_TXDATA 72UL +#define METAL_SIFIVE_SPI0_RXDATA 76UL +#define METAL_SIFIVE_SPI0_TXMARK 80UL +#define METAL_SIFIVE_SPI0_RXMARK 84UL +#define METAL_SIFIVE_SPI0_FCTRL 96UL +#define METAL_SIFIVE_SPI0_FFMT 100UL +#define METAL_SIFIVE_SPI0_IE 112UL +#define METAL_SIFIVE_SPI0_IP 116UL + +/* From serial@10013000 */ +#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL +#define METAL_SIFIVE_UART0_0_SIZE 4096UL + +#define METAL_SIFIVE_UART0 +#define METAL_SIFIVE_UART0_TXDATA 0UL +#define METAL_SIFIVE_UART0_RXDATA 4UL +#define METAL_SIFIVE_UART0_TXCTRL 8UL +#define METAL_SIFIVE_UART0_RXCTRL 12UL +#define METAL_SIFIVE_UART0_IE 16UL +#define METAL_SIFIVE_UART0_IP 20UL +#define METAL_SIFIVE_UART0_DIV 24UL + +#endif /* SIFIVE_HIFIVE1_REVB____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 new file mode 100644 index 000000000..b62d8b25a --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h @@ -0,0 +1,81 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__MEMORY_H +#define METAL__MEMORY_H + +#include +#include + +/*! + * @file memory.h + * + * @brief API for enumerating memory blocks + */ + +struct _metal_memory_attributes { + int R : 1; + int W : 1; + int X : 1; + int C : 1; + 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; +}; + +/*! + * @brief Get the memory block which services the given address + * + * Given a physical memory address, get a handle for the memory block to which + * 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 + */ +struct metal_memory *metal_get_memory_from_address(const uintptr_t address); + +/*! + * @brief Get the base address for a memory block + * @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; +} + +/*! + * @brief Get the size of a memory block + * @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; +} + +/*! + * @brief Query if a memory block supports atomic operations + * @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; +} + +/*! + * @brief Query if a memory block is cacheable + * @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; +} + +#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 new file mode 100644 index 000000000..9121b10a1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h @@ -0,0 +1,204 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PMP_H +#define METAL__PMP_H + +/*! + * @file metal/pmp.h + * + * @brief API for Configuring Physical Memory Protection on RISC-V Cores + * + * 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. + * + * Additional information about the use and configuration rules for PMPs + * can be found by reading the RISC-V Privileged Architecture Specification. + */ + +#include +#include + +struct metal_pmp; + +/*! + * @brief Set of available PMP addressing modes + */ +enum metal_pmp_address_mode { + /*! @brief Disable the PMP region */ + METAL_PMP_OFF = 0, + /*! @brief Use Top-of-Range mode */ + METAL_PMP_TOR = 1, + /*! @brief Use naturally-aligned 4-byte region mode */ + METAL_PMP_NA4 = 2, + /*! @brief Use naturally-aligned power-of-two mode */ + METAL_PMP_NAPOT = 3 +}; + +/*! + * @brief Configuration for a PMP region + */ +struct metal_pmp_config { + /*! @brief Sets whether reads to the PMP region succeed */ + int R : 1; + /*! @brief Sets whether writes to the PMP region succeed */ + int W : 1; + /*! @brief Sets whether the PMP region is executable */ + int X : 1; + + /*! @brief Sets the addressing mode of the PMP region */ + enum metal_pmp_address_mode A : 2; + + int _pad : 2; + + /*! @brief Sets whether the PMP region is locked */ + enum metal_pmp_locked { + METAL_PMP_UNLOCKED = 0, + METAL_PMP_LOCKED = 1 + } L : 1; +}; + +/*! + * @brief A handle for the PMP device + */ +struct metal_pmp { + /* The minimum granularity of the PMP region. Set by metal_pmp_init */ + uintptr_t _granularity[METAL_MAX_CORES]; +}; + +/*! + * @brief Get the PMP device handle + */ +struct metal_pmp *metal_pmp_get_device(void); + +/*! + * @brief Initialize the PMP + * @param pmp The PMP device handle to be initialized + * + * The PMP initialization routine is optional and may be called as many times + * as is desired. The effect of the initialization routine is to attempt to set + * all regions to unlocked and disabled, as well as to clear the X, W, and R + * bits. Only the pmp configuration of the hart which executes the routine will + * be affected. + * + * If any regions are fused to preset values by the implementation or locked, + * those PMP regions will silently remain uninitialized. + */ +void metal_pmp_init(struct metal_pmp *pmp); + +/*! + * @brief Configure a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to configure + * @param config The desired configuration of the PMP region + * @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); + +/*! + * @brief Get the configuration for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @param config Variable to store the PMP region configuration + * @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); + +/*! + * @brief Lock a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to lock + * @return 0 if the region is successfully locked + */ +int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the address for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @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); + +/*! + * @brief Get the address of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return The address of the PMP region, or 0 if the region could not be read + */ +size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the addressing mode of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @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); + +/*! + * @brief Get the addressing mode of a PMP region + * @param pmp The PMP device handle + * @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); + +/*! + * @brief Set the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param X The desired value of the executable bit + * @return 0 if the executable bit is successfully set + */ +int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X); + +/*! + * @brief Get the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the executable bit + */ +int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param W The desired value of the writable bit + * @return 0 if the writable bit is successfully set + */ +int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W); + +/*! + * @brief Get the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the writable bit + */ +int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param R The desired value of the readable bit + * @return 0 if the readable bit is successfully set + */ +int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the readable bit + */ +int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region); + +#endif 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 new file mode 100644 index 000000000..c5212e5d1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h @@ -0,0 +1,122 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PRIVILEGE_H +#define METAL__PRIVILEGE_H + +/*! + * @file metal/privilege.h + * + * @brief API for manipulating the privilege mode of a RISC-V system + * + * Additional information about privilege modes on RISC-V systems can be found + * by reading the RISC-V Privileged Architecture Specification v1.10. + */ + +#include + +enum metal_privilege_mode { + METAL_PRIVILEGE_USER = 0, + METAL_PRIVILEGE_SUPERVISOR = 1, + METAL_PRIVELEGE_MACHINE = 3, +}; + +#if __riscv_xlen == 32 +typedef uint32_t metal_xreg_t; +#elif __riscv_xlen == 64 +typedef uint64_t metal_xreg_t; +#endif + +#if __riscv_flen == 32 +typedef uint32_t metal_freg_t; +#elif __riscv_flen == 64 +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 t0; + metal_xreg_t t1; + metal_xreg_t t2; + + 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; +#ifndef __riscv_32e + 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 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 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 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; +#endif /* __riscv_flen */ +}; + +typedef void (*metal_privilege_entry_point_t)(); + +void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, + 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/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h new file mode 100644 index 000000000..3bebfa742 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h @@ -0,0 +1,36 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SHUTDOWN_H +#define METAL__SHUTDOWN_H + +/*! + * @file shutdown.h + * @brief API for shutting down a machine + */ + +struct __metal_shutdown; + +struct __metal_shutdown_vtable { + 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); } + +/*! + * @brief The public METAL shutdown interface + * + * Shuts down the machine, if the machine enables an interface for + * shutting down. When no interface is provided, will cause the machine + * to spin indefinitely. + * + * @param code The return code to set. 0 indicates program success. + */ +void metal_shutdown(int code) __attribute__((noreturn)); + +#endif 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 new file mode 100644 index 000000000..b011fe3ce --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h @@ -0,0 +1,78 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SPI_H +#define METAL__SPI_H + +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; + + /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ + unsigned int polarity : 1; + /*! @brief The phase of the SPI transfer, equivalent to CPHA */ + unsigned int phase : 1; + /*! @brief The endianness of the SPI transfer */ + unsigned int little_endian : 1; + /*! @brief The active state of the chip select line */ + unsigned int cs_active_high : 1; + /*! @brief The chip select ID to activate for the SPI transfer */ + unsigned int csid; +}; + +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 (*get_baud_rate)(struct metal_spi *spi); + int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); +}; + +/*! @brief A handle for a SPI device */ +struct metal_spi { + const struct metal_spi_vtable *vtable; +}; + +/*! @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); + +/*! @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); } + +/*! @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. + * @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) { + return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); +} + +/*! @brief Get the current baud rate of the SPI device + * @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); } + +/*! @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); } + +#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 new file mode 100644 index 000000000..d1c35bc93 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h @@ -0,0 +1,51 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SWITCH_H +#define METAL__SWITCH_H + +/*! + * @file switch.h + * @brief API for reading toggle switches + */ + +#include + +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); + int (*get_interrupt_id)(struct metal_switch *sw); +}; + +/*! + * @brief A handle for a switch + */ +struct metal_switch { + const struct metal_switch_vtable *vtable; +}; + +/*! + * @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 + */ +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); } + +/*! + * @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); } + +#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 new file mode 100644 index 000000000..eeae1f60b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h @@ -0,0 +1,36 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TIMER_H +#define METAL__TIMER_H + +/*! + * @file timer.h + * @brief API for reading and manipulating the machine timer + */ + +/*! + * @brief Read the machine cycle count + * @param hartid The hart ID to read the cycle count of + * @param cyclecount The variable to hold the value + * @return 0 upon success + */ +int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); + +/*! + * @brief Get the machine timebase frequency + * @param hartid The hart ID to read the timebase of + * @param timebase The variable to hold the value + * @return 0 upon success + */ +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 + * @return 0 upon success + */ +int metal_timer_set_tick(int hartid, int second); + +#endif 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 new file mode 100644 index 000000000..d2583e3be --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h @@ -0,0 +1,23 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TTY_H +#define METAL__TTY_H + +/*! + * @file tty.h + * @brief API for emulated serial teriminals + */ + +/*! + * @brief Write a character to the default output device + * + * 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); + +#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 new file mode 100644 index 000000000..611792a6c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h @@ -0,0 +1,94 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__UART_H +#define METAL__UART_H + +/*! + * @file uart.h + * @brief API for UART serial ports + */ + +#include + +struct metal_uart; + +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 (*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); + int (*get_interrupt_id)(struct metal_uart *uart); +}; + +/*! + * @brief Handle for a UART serial device + */ +struct metal_uart { + const struct metal_uart_vtable *vtable; +}; + +/*! + * @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. + * + * @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); } + +/*! + * @brief Output a character over the UART + * @param uart The UART device handle + * @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); } + +/*! + * @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 + */ +inline int metal_uart_getc(struct metal_uart *uart, unsigned char *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); } + +/*! + * @brief Set the baud rate of the UART peripheral + * @param uart The UART device handle + * @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); } + +/*! + * @brief Get the interrupt controller of the UART peripheral + * + * Get the interrupt controller for the UART peripheral. The interrupt + * controller must be initialized before any interrupts can be registered + * or enabled with it. + * + * @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); } + +/*! + * @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); } + +#endif 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 new file mode 100644 index 000000000..8c0cd048b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h @@ -0,0 +1,249 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H + +#include + + +/* --------------------- fixed_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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- 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); + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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); + + +/* --------------------- 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( ); + + +/* --------------------- 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 ------------ */ + + +/* From clock@0 */ +struct __metal_driver_fixed_clock __metal_dt_clock_0 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@2 */ +struct __metal_driver_fixed_clock __metal_dt_clock_2 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@5 */ +struct __metal_driver_fixed_clock __metal_dt_clock_5 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +struct metal_memory __metal_dt_mem_dtim_80000000 = { + ._base_address = 2147483648UL, + ._size = 16384UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10014000 = { + ._base_address = 536870912UL, + ._size = 500000UL, + ._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, + .init_done = 0, +}; + +/* From cpu@0 */ +struct __metal_driver_cpu __metal_dt_cpu_0 = { + .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, +}; + +/* From interrupt_controller */ +struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = { + .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable, + .init_done = 0, +}; + +/* From interrupt_controller@c000000 */ +struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { + .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable, + .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, +}; + +/* 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 = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0green */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From spi@10014000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { + .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 clock@3 */ +struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, +}; + +/* From clock@1 */ +struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.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, +}; + +/* From prci@10008000 */ +struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { +}; + + +#endif /* SIFIVE_HIFIVE1_REVB____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 new file mode 100644 index 000000000..4ecd3e336 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h @@ -0,0 +1,237 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H + +/* From clock@0 */ +#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL + +/* From clock@2 */ +#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL + +/* From clock@5 */ +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL + +#define METAL_FIXED_CLOCK + +/* From clint@2000000 */ +#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL +#define METAL_RISCV_CLINT0_0_SIZE 65536UL + +#define METAL_RISCV_CLINT0 +#define METAL_RISCV_CLINT0_MSIP_BASE 0UL +#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL +#define METAL_RISCV_CLINT0_MTIME 49144UL + +/* From interrupt_controller@c000000 */ +#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592UL +#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL +#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL +#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 +#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 + +/* 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_AON0 +#define METAL_SIFIVE_AON0_WDOGCFG 0UL +#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL +#define METAL_SIFIVE_AON0_WDOGS 16UL +#define METAL_SIFIVE_AON0_WDOGFEED 24UL +#define METAL_SIFIVE_AON0_WDOGKEY 28UL +#define METAL_SIFIVE_AON0_WDOGCMP 32UL +#define METAL_SIFIVE_AON0_RTCCFG 64UL +#define METAL_SIFIVE_AON0_RTCLO 72UL +#define METAL_SIFIVE_AON0_RTCHI 72UL +#define METAL_SIFIVE_AON0_RTCS 80UL +#define METAL_SIFIVE_AON0_RTCCMP 96UL +#define METAL_SIFIVE_AON0_LFROSCCFG 112UL +#define METAL_SIFIVE_AON0_BACKUP0 128UL +#define METAL_SIFIVE_AON0_BACKUP1 132UL +#define METAL_SIFIVE_AON0_BACKUP2 136UL +#define METAL_SIFIVE_AON0_BACKUP3 140UL +#define METAL_SIFIVE_AON0_BACKUP4 144UL +#define METAL_SIFIVE_AON0_BACKUP5 148UL +#define METAL_SIFIVE_AON0_BACKUP6 152UL +#define METAL_SIFIVE_AON0_BACKUP7 152UL +#define METAL_SIFIVE_AON0_BACKUP8 160UL +#define METAL_SIFIVE_AON0_BACKUP9 164UL +#define METAL_SIFIVE_AON0_BACKUP10 168UL +#define METAL_SIFIVE_AON0_BACKUP11 172UL +#define METAL_SIFIVE_AON0_BACKUP12 176UL +#define METAL_SIFIVE_AON0_BACKUP13 180UL +#define METAL_SIFIVE_AON0_BACKUP14 184UL +#define METAL_SIFIVE_AON0_BACKUP15 188UL +#define METAL_SIFIVE_AON0_BACKUP16 192UL +#define METAL_SIFIVE_AON0_BACKUP17 196UL +#define METAL_SIFIVE_AON0_BACKUP18 200UL +#define METAL_SIFIVE_AON0_BACKUP19 204UL +#define METAL_SIFIVE_AON0_BACKUP20 208UL +#define METAL_SIFIVE_AON0_BACKUP21 212UL +#define METAL_SIFIVE_AON0_BACKUP22 216UL +#define METAL_SIFIVE_AON0_BACKUP23 220UL +#define METAL_SIFIVE_AON0_BACKUP24 224UL +#define METAL_SIFIVE_AON0_BACKUP25 228UL +#define METAL_SIFIVE_AON0_BACKUP26 232UL +#define METAL_SIFIVE_AON0_BACKUP27 236UL +#define METAL_SIFIVE_AON0_BACKUP28 240UL +#define METAL_SIFIVE_AON0_BACKUP29 244UL +#define METAL_SIFIVE_AON0_BACKUP30 248UL +#define METAL_SIFIVE_AON0_BACKUP31 252UL +#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL +#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL +#define METAL_SIFIVE_AON0_PMUIE 320UL +#define METAL_SIFIVE_AON0_PMUCAUSE 324UL +#define METAL_SIFIVE_AON0_PMUSLEEP 328UL +#define METAL_SIFIVE_AON0_PMUKEY 332UL + +/* From clock@3 */ + +#define METAL_SIFIVE_FE310_G000_HFROSC + +/* From clock@1 */ + +#define METAL_SIFIVE_FE310_G000_HFXOSC + +/* From prci@10008000 */ +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL + +#define METAL_SIFIVE_FE310_G000_PRCI +#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL +#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL + +/* From clock@4 */ +#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL + +#define METAL_SIFIVE_FE310_G000_PLL + +/* From gpio@10012000 */ +#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL +#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL + +#define METAL_SIFIVE_GPIO0 +#define METAL_SIFIVE_GPIO0_VALUE 0UL +#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL +#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL +#define METAL_SIFIVE_GPIO0_PORT 12UL +#define METAL_SIFIVE_GPIO0_PUE 16UL +#define METAL_SIFIVE_GPIO0_DS 20UL +#define METAL_SIFIVE_GPIO0_RISE_IE 24UL +#define METAL_SIFIVE_GPIO0_RISE_IP 28UL +#define METAL_SIFIVE_GPIO0_FALL_IE 32UL +#define METAL_SIFIVE_GPIO0_FALL_IP 36UL +#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL +#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL +#define METAL_SIFIVE_GPIO0_LOW_IE 48UL +#define METAL_SIFIVE_GPIO0_LOW_IP 52UL +#define METAL_SIFIVE_GPIO0_IOF_EN 56UL +#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL +#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL + +/* From led@0red */ + +/* From led@0green */ + +/* From led@0blue */ + +#define METAL_SIFIVE_GPIO_LEDS + +/* From i2c@10016000 */ +#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL +#define METAL_SIFIVE_I2C0_0_SIZE 4096UL + +#define METAL_SIFIVE_I2C0 +#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL +#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL +#define METAL_SIFIVE_I2C0_CONTROL 8UL +#define METAL_SIFIVE_I2C0_TRANSMIT 12UL +#define METAL_SIFIVE_I2C0_RECEIVE 12UL +#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 + +#define METAL_SIFIVE_PWM0 +#define METAL_SIFIVE_PWM0_PWMCFG 0UL +#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL +#define METAL_SIFIVE_PWM0_PWMS 16UL +#define METAL_SIFIVE_PWM0_PWMCMP0 32UL +#define METAL_SIFIVE_PWM0_PWMCMP1 36UL +#define METAL_SIFIVE_PWM0_PWMCMP2 40UL +#define METAL_SIFIVE_PWM0_PWMCMP3 44UL + +/* 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 + +#define METAL_SIFIVE_SPI0 +#define METAL_SIFIVE_SPI0_SCKDIV 0UL +#define METAL_SIFIVE_SPI0_SCKMODE 4UL +#define METAL_SIFIVE_SPI0_CSID 16UL +#define METAL_SIFIVE_SPI0_CSDEF 20UL +#define METAL_SIFIVE_SPI0_CSMODE 24UL +#define METAL_SIFIVE_SPI0_DELAY0 40UL +#define METAL_SIFIVE_SPI0_DELAY1 44UL +#define METAL_SIFIVE_SPI0_FMT 64UL +#define METAL_SIFIVE_SPI0_TXDATA 72UL +#define METAL_SIFIVE_SPI0_RXDATA 76UL +#define METAL_SIFIVE_SPI0_TXMARK 80UL +#define METAL_SIFIVE_SPI0_RXMARK 84UL +#define METAL_SIFIVE_SPI0_FCTRL 96UL +#define METAL_SIFIVE_SPI0_FFMT 100UL +#define METAL_SIFIVE_SPI0_IE 112UL +#define METAL_SIFIVE_SPI0_IP 116UL + +/* From serial@10013000 */ +#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL +#define METAL_SIFIVE_UART0_0_SIZE 4096UL + +#define METAL_SIFIVE_UART0 +#define METAL_SIFIVE_UART0_TXDATA 0UL +#define METAL_SIFIVE_UART0_RXDATA 4UL +#define METAL_SIFIVE_UART0_TXCTRL 8UL +#define METAL_SIFIVE_UART0_RXCTRL 12UL +#define METAL_SIFIVE_UART0_IE 16UL +#define METAL_SIFIVE_UART0_IP 20UL +#define METAL_SIFIVE_UART0_DIV 24UL + +#endif /* SIFIVE_HIFIVE1_REVB____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 new file mode 100644 index 000000000..7070af7e8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds @@ -0,0 +1,236 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +OUTPUT_ARCH("riscv") + +ENTRY(_enter) + +MEMORY +{ + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 + flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + itim_init PT_LOAD; + ram PT_NULL; + itim PT_NULL; +} + +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); + + + .init : + { + KEEP (*(.text.metal.init.enter)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >flash AT>flash :flash + + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.itim .itim.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >flash AT>flash :flash + + + . = ALIGN(4); + + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + + .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 + + + .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 + + + .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 + + + .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 + + + .litimalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_itim_source_start = . ); + } >flash AT>flash :flash + + + .ditimalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_itim_target_start = . ); + } >ram AT>flash :ram_init + + + .itim : + { + *(.itim .itim.*) + } >flash AT>flash :flash + + + . = ALIGN(8); + PROVIDE( metal_segment_itim_target_end = . ); + + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + PROVIDE( metal_segment_data_source_start = . ); + } >flash AT>flash :flash + + + .dalign : + { + . = ALIGN(4); + PROVIDE( metal_segment_data_target_start = . ); + } >ram AT>flash :ram_init + + + .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 + + +} + 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 new file mode 100644 index 000000000..f76dbd632 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h @@ -0,0 +1,872 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#include + +#ifdef __METAL_MACHINE_MACROS + +#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#define MACROS_IF_SIFIVE_HIFIVE1_REVB____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_NUM_PARENTS 1 + +#ifndef __METAL_PLIC_SUBINTERRUPTS +#define __METAL_PLIC_SUBINTERRUPTS 0 +#endif +#ifndef __METAL_PLIC_NUM_PARENTS +#define __METAL_PLIC_NUM_PARENTS 0 +#endif +#ifndef __METAL_CLIC_SUBINTERRUPTS +#define __METAL_CLIC_SUBINTERRUPTS 0 +#endif + +#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ + +#else /* ! __METAL_MACHINE_MACROS */ + +#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H + +#define __METAL_CLINT_2000000_INTERRUPTS 2 + +#define METAL_MAX_CLINT_INTERRUPTS 2 + +#define __METAL_CLINT_NUM_PARENTS 2 + +#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 + +#define __METAL_PLIC_SUBINTERRUPTS 27 + +#define METAL_MAX_PLIC_INTERRUPTS 1 + +#define __METAL_PLIC_NUM_PARENTS 1 + +#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_GLOBAL_EXT_INTERRUPTS 0 + +#define __METAL_GPIO_10012000_INTERRUPTS 16 + +#define METAL_MAX_GPIO_INTERRUPTS 16 + +#define __METAL_SERIAL_10013000_INTERRUPTS 1 + +#define METAL_MAX_UART_INTERRUPTS 1 + + +#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; + +/* From clock@2 */ +struct __metal_driver_fixed_clock __metal_dt_clock_2; + +/* From clock@5 */ +struct __metal_driver_fixed_clock __metal_dt_clock_5; + +struct metal_memory __metal_dt_mem_dtim_80000000; + +struct metal_memory __metal_dt_mem_spi_10014000; + +/* From clint@2000000 */ +struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; + +/* From cpu@0 */ +struct __metal_driver_cpu __metal_dt_cpu_0; + +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; + +struct metal_pmp __metal_dt_pmp; + +/* From local_external_interrupts_0 */ +struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; + +/* From gpio@10012000 */ +struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; + +/* From led@0red */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; + +/* From led@0green */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; + +/* From led@0blue */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; + +/* From spi@10014000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From serial@10013000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From clock@3 */ +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; + +/* From clock@4 */ +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; + + + +/* --------------------- fixed_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; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) { + return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { + return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; + } + else { + return 0; + } +} + + + +/* --------------------- fixed_factor_clock ------------ */ + + +/* --------------------- sifive_clint0 ------------ */ +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else if (idx == 1) { + return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; + } + else { + return NULL; + } +} + +static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +{ + if (idx == 0) { + return 3; + } + else if (idx == 1) { + return 7; + } + else { + return 0; + } +} + + + +/* --------------------- cpu ------------ */ +static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return 0; + } + else { + return -1; + } +} + +static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return 1000000; + } + else { + return 0; + } +} + +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; + } + else { + return NULL; + } +} + +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; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_plic0 ------------ */ +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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) +{ + if (idx == 0) { + return 11; + } + else if (idx == 0) { + return 11; + } + else { + return 0; + } +} + + + +/* --------------------- 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) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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; + } + else { + return 0; + } +} + +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))) { + return 9; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + return 10; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + return 11; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + return 12; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + return 13; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + return 14; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { + return 15; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { + return 16; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { + return 17; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { + return 18; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { + return 19; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { + return 20; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { + return 21; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + return 22; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_gpio_button ------------ */ + + +/* --------------------- sifive_gpio_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) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return 22; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return 19; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return 21; + } + else { + return 0; + } +} + +static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { + return "LD0red"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { + return "LD0green"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { + return "LD0blue"; + } + else { + return ""; + } +} + + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_spi0 ------------ */ +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 { + return 0; + } +} + +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 { + return 0; + } +} + +static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +{ + return (struct metal_clock *)&__metal_dt_clock_4.clock; +} + +static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +{ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; +} + +static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +{ + return 60; +} + +static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +{ + return 60; +} + + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- sifive_uart0 ------------ */ +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 { + return 0; + } +} + +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 { + return 0; + } +} + +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 { + return 0; + } +} + +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 { + return NULL; + } +} + +static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +{ + return 5; +} + +static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +{ + return (struct metal_clock *)&__metal_dt_clock_4.clock; +} + +static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +{ + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; +} + +static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +{ + return 196608; +} + +static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +{ + return 196608; +} + + + +/* --------------------- sifive_fe310_g000_hfrosc ------------ */ +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) +{ + 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) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + +static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_hfxosc ------------ */ +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) +{ + 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) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_pll ------------ */ +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) +{ + 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) +{ + 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) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; +} + +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( ) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; +} + +static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) +{ + return 16000000; +} + + + +/* --------------------- sifive_fe310_g000_prci ------------ */ +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( ) +{ + 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( ) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + + + +/* --------------------- sifive_fu540_c000_l2 ------------ */ + + +#define __METAL_DT_MAX_MEMORIES 2 + +asm (".weak __metal_memory_table"); +struct metal_memory *__metal_memory_table[] = { + &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_spi_10014000}; + +/* From serial@10013000 */ +#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_STDOUT_UART_BAUD 115200 + +/* From clint@2000000 */ +#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller) + +#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller) + +#define __METAL_DT_MAX_HARTS 1 + +asm (".weak __metal_cpu_table"); +struct __metal_driver_cpu *__metal_cpu_table[] = { + &__metal_dt_cpu_0}; + +/* From interrupt_controller@c000000 */ +#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) + +#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) + +#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"); +struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { + &__metal_dt_gpio_10012000}; + +#define __METAL_DT_MAX_BUTTONS 0 + +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"); +struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { + &__metal_dt_led_0red, + &__metal_dt_led_0green, + &__metal_dt_led_0blue}; + +#define __METAL_DT_MAX_SWITCHES 0 + +asm (".weak __metal_switch_table"); +struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { + NULL }; +#define __METAL_DT_MAX_SPIS 1 + +asm (".weak __metal_spi_table"); +struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { + &__metal_dt_spi_10014000}; + +/* 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 /* ! __METAL_MACHINE_MACROS */ + +#endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url new file mode 100644 index 000000000..f59b1cedd --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,11 +[InternetShortcut] +IDList= +URL=https://github.com/sifive/freedom-metal-docs diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S new file mode 100644 index 000000000..920ee4b9f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S @@ -0,0 +1,246 @@ +/* Copyright (c) 2017-2018 SiFive Inc. All rights reserved. + + This copyrighted material is made available to anyone wishing to use, + modify, copy, or redistribute it subject to the terms and conditions + of the FreeBSD License. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + including the implied warranties of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. A copy of this license is available at + http://www.opensource.org/licenses. +*/ + +/* crt0.S: Entry point for RISC-V METAL programs. */ + +.section .text.libgloss.start +.global _start +.type _start, @function + + /* _start is defined by the METAL to have been called with the following + * arguments: + * a0: the hart ID of the currently executing hart. Harts can start at + * any arbitrary point, it's the C library's job to ensure the code is + * safe. + * a1: a pointer to a description of the machine on which this code is + * currently executing. This is probably 0 on an embedded system + * because they tend to not be dynamically portable. As such, newlib + * ignores this argument. + * a2: a pointer to a function that must be run after the envirnoment has + * been initialized, but before user code can be expected to be run. + * If this is 0 then there is no function to be run. */ +_start: +.cfi_startproc +.cfi_undefined ra + + /* This is a bit funky: it's not usually sane for _start to return, but in + * this case we actually want to in order to signal an error to the METAL. */ + mv s0, ra + + /* Before doing anything we must initialize the global pointer, as we cannot + * safely perform any access that may be relaxed without GP being set. This + * is done with relaxation disabled to avoid relaxing the address calculation + * to just "addi gp, gp, 0". */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* The METAL is designed for a bare-metal environment and therefor is expected + * to define its own stack pointer. We also align the stack pointer here + * because the only RISC-V ABI that's currently defined mandates 16-byte + * stack alignment. */ + la sp, _sp + + /* Increment by hartid number of stack sizes */ + li t0, 0 + la t1, __stack_size +1: + beq t0, a0, 1f + add sp, sp, t1 + addi t0, t0, 1 + j 1b +1: + andi sp, sp, -16 + + /* If we're not hart 0, skip the initialization work */ + la t0, __metal_boot_hart + bne a0, t0, _skip_init + + /* Embedded systems frequently require relocating the data segment before C + * code can be run -- for example, the data segment may exist in flash upon + * boot and then need to get relocated into a non-persistant writable memory + * before C code can execute. If this is the case we do so here. This step + * is optional: if the METAL provides an environment in which this relocation + * is not necessary then it must simply set metal_segment_data_source_start to + * be equal to metal_segment_data_target_start. */ + la t0, metal_segment_data_source_start + la t1, metal_segment_data_target_start + la t2, metal_segment_data_target_end + + beq t0, t1, 2f + bge t1, t2, 2f + +1: +#if __riscv_xlen == 32 + lw a0, 0(t0) + addi t0, t0, 4 + sw a0, 0(t1) + addi t1, t1, 4 + blt t1, t2, 1b +#else + ld a0, 0(t0) + addi t0, t0, 8 + sd a0, 0(t1) + addi t1, t1, 8 + blt t1, t2, 1b +#endif +2: + + /* Copy the ITIM section */ + la t0, metal_segment_itim_source_start + la t1, metal_segment_itim_target_start + la t2, metal_segment_itim_target_end + + beq t0, t1, 2f + bge t1, t2, 2f + +1: +#if __riscv_xlen == 32 + lw a0, 0(t0) + addi t0, t0, 4 + sw a0, 0(t1) + addi t1, t1, 4 + blt t1, t2, 1b +#else + ld a0, 0(t0) + addi t0, t0, 8 + sd a0, 0(t1) + addi t1, t1, 8 + blt t1, t2, 1b +#endif +2: + + /* Fence all subsequent instruction fetches until after the ITIM writes + complete */ + fence.i + + /* Zero the BSS segment. */ + la t1, metal_segment_bss_target_start + la t2, metal_segment_bss_target_end + + bge t1, t2, 2f + +1: +#if __riscv_xlen == 32 + sw x0, 0(t1) + addi t1, t1, 4 + blt t1, t2, 1b +#else + sd x0, 0(t1) + addi t1, t1, 8 + blt t1, t2, 1b +#endif +2: + + /* At this point we're in an environment that can execute C code. The first + * thing to do is to make the callback to the parent environment if it's been + * requested to do so. */ + beqz a2, 1f + jalr a2 +1: + + /* The RISC-V port only uses new-style constructors and destructors. */ + la a0, __libc_fini_array + call atexit + call __libc_init_array + +_skip_init: + + /* Synchronize harts so that secondary harts wait until hart 0 finishes + initializing */ + call __metal_synchronize_harts + + /* Check RISC-V isa and enable FS bits if Floating Point architecture. */ + csrr a5, misa + li a4, 0x10028 + and a5, a5, a4 + beqz a5, 1f + csrr a5, mstatus + lui a4, 0x2 + or a5, a5, a4 + csrw mstatus, a5 + csrwi fcsr, 0 +1: + + /* This is a C runtime, so main() is defined to have some arguments. Since + * there's nothing sane the METAL can pass we don't bother with that but + * instead just setup as close to a NOP as we can. */ + li a0, 1 /* argc=1 */ + la a1, argv /* argv = {"libgloss", NULL} */ + la a2, envp /* envp = {NULL} */ + call secondary_main + + /* Call exit to handle libc's cleanup routines. Under normal contains this + * shouldn't even get called, but I'm still not using a tail call here + * because returning to the METAL is the right thing to do in pathological + * situations. */ + call exit + + /* And here's where we return. Again, it's a bit odd but the METAL defines + * this as a bad idea (ie, as opposed to leaving it undefined) and at this + * point it's really the only thing left to do. */ + mv ra, s0 + ret + +.cfi_endproc + +/* RISC-V systems always use __libc_{init,fini}_array, but for compatibility we + * define _{init,fini} to do nothing. */ +.global _init +.type _init, @function +.global _fini +.type _fini, @function +_init: +_fini: + ret +.size _init, .-_init +.size _fini, .-_fini + +/* By default, secondary_main will cause secondary harts to spin forever. + * Users can redefine secondary_main themselves to run code on secondary harts */ +.weak secondary_main +.global secondary_main +.type secondary_main, @function + +secondary_main: + addi sp, sp, -16 +#if __riscv_xlen == 32 + sw ra, 4(sp) +#else + sd ra, 8(sp) +#endif + csrr t0, mhartid + la t1, __metal_boot_hart + beq t0, t1, 2f +1: + wfi + j 1b +2: + call main +#if __riscv_xlen == 32 + lw ra, 4(sp) +#else + ld ra, 8(sp) +#endif + addi sp, sp, 16 + ret + +/* This shim allows main() to be passed a set of arguments that can satisfy the + * requirements of the C API. */ +.section .rodata.libgloss.start +argv: +.dc.a name +envp: +.dc.a 0 +name: +.asciz "libgloss" + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c new file mode 100644 index 000000000..8be22104e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c @@ -0,0 +1,9 @@ +#include +#include + +int +nanosleep(const struct timespec *rqtp, struct timespec *rmtp) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c new file mode 100644 index 000000000..3e857d1df --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c @@ -0,0 +1,59 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) +#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) +#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) + +/* + * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for + * hart 0 to finish copying the datat section, zeroing the BSS, and running + * the libc contstructors. + */ +void _synchronize_harts() { +#if __METAL_DT_MAX_HARTS > 1 + + int hart = metal_cpu_get_current_hartid(); + uintptr_t msip_base = 0; + + /* Get the base address of the MSIP registers */ +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); + msip_base += METAL_RISCV_CLINT0_MSIP_BASE; +#elif __METAL_DT_RISCV_CLIC0_HANDLE + msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); + msip_base += METAL_RISCV_CLIC0_MSIP_BASE; +#else +#warning No handle for CLINT or CLIC found, harts may be unsynchronized after init! +#endif + + /* Disable machine interrupts as a precaution */ + __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); + + if (hart == 0) { + /* Hart 0 waits for all harts to set their MSIP bit */ + for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { + while (METAL_MSIP(msip_base, i) == 0) ; + } + + /* Hart 0 clears everyone's MSIP bit */ + for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { + METAL_MSIP(msip_base, i) = 0; + } + } else { + /* Other harts set their MSIP bit to indicate they're ready */ + METAL_MSIP(msip_base, hart) = 1; + __asm__ volatile ("fence w,rw"); + + /* Wait for hart 0 to clear the MSIP bit */ + while (METAL_MSIP(msip_base, hart) == 1) ; + } + +#endif /* __METAL_DT_MAX_HARTS > 1 */ +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c new file mode 100644 index 000000000..c0bc1534d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c @@ -0,0 +1,8 @@ +#include + +int +_access(const char *file, int mode) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c new file mode 100644 index 000000000..f33d26a44 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c @@ -0,0 +1,8 @@ +#include + +int +_chdir(const char *path) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c new file mode 100644 index 000000000..67412bf7d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c @@ -0,0 +1,9 @@ +#include +#include + +int +_chmod(const char *path, mode_t mode) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c new file mode 100644 index 000000000..302952eb1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c @@ -0,0 +1,9 @@ +#include +#include + +int +_chown(const char *path, uid_t owner, gid_t group) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c new file mode 100644 index 000000000..26dd6a59e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c @@ -0,0 +1,8 @@ +#include + +int +_close(int file) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c new file mode 100644 index 000000000..9ae9f7e50 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c @@ -0,0 +1,8 @@ +#include + +int +_execve(const char *name, char *const argv[], char *const env[]) +{ + errno = ENOMEM; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c new file mode 100644 index 000000000..35f5f1a16 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c @@ -0,0 +1,8 @@ +#include + +void +_exit(int exit_status) +{ + metal_shutdown(exit_status); + while (1); +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c new file mode 100644 index 000000000..873d52c2e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c @@ -0,0 +1,8 @@ +#include + +int +_faccessat(int dirfd, const char *file, int mode, int flags) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c new file mode 100644 index 000000000..64e67569f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c @@ -0,0 +1,8 @@ +#include + +int +_fork() +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c new file mode 100644 index 000000000..fedc28977 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c @@ -0,0 +1,9 @@ +#include +#include + +int +_fstat(int file, struct stat *st) +{ + errno = -ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c new file mode 100644 index 000000000..f2f43bd9e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c @@ -0,0 +1,9 @@ +#include +#include + +int +_fstatat(int dirfd, const char *file, struct stat *st, int flags) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c new file mode 100644 index 000000000..65c156398 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c @@ -0,0 +1,9 @@ +#include +#include + +int +_ftime(struct timeb *tp) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c new file mode 100644 index 000000000..82e8404ee --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c @@ -0,0 +1,8 @@ +#include + +char * +_getcwd(char *buf, size_t size) +{ + errno = -ENOSYS; + return NULL; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c new file mode 100644 index 000000000..589ad117c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c @@ -0,0 +1,7 @@ +#include + +int +_getpid() +{ + return 1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c new file mode 100644 index 000000000..409b2ce2f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c @@ -0,0 +1,21 @@ +#include +#include +#include + +int +_gettimeofday(struct timeval *tp, void *tzp) +{ + int rv; + unsigned long long mcc, timebase; + rv = metal_timer_get_cyclecount(0, &mcc); + if (rv != 0) { + return -1; + } + rv = metal_timer_get_timebase_frequency(0, &timebase); + if (rv != 0) { + return -1; + } + tp->tv_sec = mcc / timebase; + tp->tv_usec = mcc % timebase * 1000000 / timebase; + return 0; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c new file mode 100644 index 000000000..dd4f1461b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c @@ -0,0 +1,7 @@ +#include + +int +_isatty(int file) +{ + return (file == STDOUT_FILENO); +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c new file mode 100644 index 000000000..9003f266f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c @@ -0,0 +1,8 @@ +#include + +int +_kill(int pid, int sig) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c new file mode 100644 index 000000000..40d5912bc --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c @@ -0,0 +1,7 @@ +#include + +int _link(const char *old_name, const char *new_name) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c new file mode 100644 index 000000000..d28a781f8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c @@ -0,0 +1,9 @@ +#include +#include + +off_t +_lseek(int file, off_t ptr, int dir) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c new file mode 100644 index 000000000..97a45855f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c @@ -0,0 +1,8 @@ +#include +#include + +int _lstat(const char *file, struct stat *st) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c new file mode 100644 index 000000000..a59f627f0 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c @@ -0,0 +1,8 @@ +#include + +int +_open(const char *name, int flags, int mode) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c new file mode 100644 index 000000000..206de3bde --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c @@ -0,0 +1,8 @@ +#include + +int +_openat(int dirfd, const char *name, int flags, int mode) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c new file mode 100644 index 000000000..15833cabb --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c @@ -0,0 +1,9 @@ +#include +#include + +ssize_t +_read(int file, void *ptr, size_t len) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c new file mode 100644 index 000000000..cc01c8ffb --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c @@ -0,0 +1,39 @@ +#include + +/* brk is handled entirely within the C library. This limits METAL programs that + * use the C library to be disallowed from dynamically allocating memory + * without talking to the C library, but that sounds like a sane way to go + * about it. Note that there is no error checking anywhere in this file, users + * will simply get the relevant error when actually trying to use the memory + * that's been allocated. */ +extern char metal_segment_heap_target_start; +extern char metal_segment_heap_target_end; +static char *brk = &metal_segment_heap_target_start; + +int +_brk(void *addr) +{ + brk = addr; + return 0; +} + +char * +_sbrk(ptrdiff_t incr) +{ + char *old = brk; + + /* If __heap_size == 0, we can't allocate memory on the heap */ + if(&metal_segment_heap_target_start == &metal_segment_heap_target_end) { + return (void *)-1; + } + + /* Don't move the break past the end of the heap */ + if ((brk + incr) < &metal_segment_heap_target_end) { + brk += incr; + } else { + brk = &metal_segment_heap_target_end; + return (void *)-1; + } + + return old; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c new file mode 100644 index 000000000..3c2e41910 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c @@ -0,0 +1,9 @@ +#include +#include + +int +_stat(const char *file, struct stat *st) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c new file mode 100644 index 000000000..452a252ae --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c @@ -0,0 +1,16 @@ +#include +#include + +/* Get configurable system variables. */ + +long +_sysconf(int name) +{ + switch (name) + { + case _SC_CLK_TCK: + return CLOCKS_PER_SEC; + } + + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c new file mode 100644 index 000000000..6beedcb30 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +extern int _gettimeofday(struct timeval *, void *); + +/* Timing information for current process. From + newlib/libc/include/sys/times.h the tms struct fields are as follows: + + - clock_t tms_utime : user clock ticks + - clock_t tms_stime : system clock ticks + - clock_t tms_cutime : children's user clock ticks + - clock_t tms_cstime : children's system clock ticks + + Since maven does not currently support processes we set both of the + children's times to zero. Eventually we might want to separately + account for user vs system time, but for now we just return the total + number of cycles since starting the program. */ +clock_t +_times(struct tms *buf) +{ + int rv; + // when called for the first time, initialize t0 + static struct timeval t0; + if (t0.tv_sec == 0 && t0.tv_usec == 0) + _gettimeofday (&t0, 0); + + struct timeval t; + _gettimeofday (&t, 0); + + unsigned long long timebase; + rv = metal_timer_get_timebase_frequency(0, &timebase); + if (rv != 0) { + return -1; + } + + long long utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); + buf->tms_utime = utime * timebase / 1000000; + buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0; + return 0; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c new file mode 100644 index 000000000..b369d2017 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c @@ -0,0 +1,8 @@ +#include + +int +_unlink(const char *name) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c new file mode 100644 index 000000000..33d557aa7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c @@ -0,0 +1,9 @@ +#include +struct utimbuf; + +int +_utime(const char *path, const struct utimbuf *times) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c new file mode 100644 index 000000000..9d459f14c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c @@ -0,0 +1,7 @@ +#include + +int _wait(int *status) +{ + errno = ENOSYS; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c new file mode 100644 index 000000000..bfcf0cb2b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +/* Write to a file. */ +ssize_t +_write(int file, const void *ptr, size_t len) +{ + if (file != STDOUT_FILENO) { + errno = ENOSYS; + return -1; + } + + const char *bptr = ptr; + for (size_t i = 0; i < len; ++i) + metal_tty_putc(bptr[i]); + return 0; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h new file mode 100644 index 000000000..3ae1c143e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h @@ -0,0 +1,59 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__BUTTON_H +#define METAL__BUTTON_H + +/*! + * @file button.h + * API for interfacing with physical buttons + */ + +#include + +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); + int (*get_interrupt_id)(struct metal_button *button); +}; + +/*! + * @brief A button device handle + * + * A `struct metal_button` is an implementation-defined object which represents + * a button on a development board. + */ +struct metal_button { + const struct metal_button_vtable *vtable; +}; + +/*! + * @brief Get a reference to a button + * + * @param label The DeviceTree label for the button + * @return A handle for the button + */ +struct metal_button* metal_button_get(char *label); + + +/*! + * @brief Get the interrupt controller for a button + * + * @param button The handle for the button + * @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); } + +/*! + * @brief Get the interrupt id for a button + * + * @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h new file mode 100644 index 000000000..bad026480 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h @@ -0,0 +1,96 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__CACHE_H +#define METAL__CACHE_H + +/*! + * @file cache.h + * + * @brief API for configuring caches + */ +#include + +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); +}; + +/*! + * @brief a handle for a cache + */ +struct metal_cache { + const struct __metal_cache_vtable *vtable; +}; + +/*! + * @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. + */ +__inline__ void metal_cache_init(struct metal_cache *cache, int ways) { + cache->vtable->init(cache, ways); +} + +/*! + * @brief Get the current number of enabled cache ways + * @param cache The handle for the cache + * @return The current number of enabled cache ways + */ +__inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { + return cache->vtable->get_enabled_ways(cache); +} + +/*! + * @brief Enable the requested number of cache ways + * @param cache The handle for the cache + * @param ways The number of ways to enabled + * @return 0 if the ways are successfully enabled + */ +__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { + return cache->vtable->set_enabled_ways(cache, 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); + +/*! + * @brief Flush icache for L1 on the requested core + * @param hartid The core to flush + * @return None + */ +void metal_icache_l1_flush(int hartid); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h new file mode 100644 index 000000000..622fc9470 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h @@ -0,0 +1,154 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#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. + */ + +struct metal_clock; + +#include + +/* The generic interface to all clocks. */ +struct __metal_clock_vtable { + long (*get_rate_hz)(const struct metal_clock *clk); + long (*set_rate_hz)(struct metal_clock *clk, long hz); +}; + +/*! + * @brief Function signature of clock rate change callbacks + */ +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 Type for the linked list of callbacks for clock rate changes + */ +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. + * + * 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 linked list */ + metal_clock_callback *_pre_rate_change_callback; + + /* Post-rate change callback linked list */ + metal_clock_callback *_post_rate_change_callback; +}; + +/*! + * @brief Returns the current rate of the given 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); } + +/*! + * @brief Set the current rate of a clock + * + * @param clk The handle for the clock + * @param hz The desired rate in Hz + * @return The new rate of the clock in Hz. + * + * Attempts to set the current rate of the given clock to as close as possible + * 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. + */ +__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); + + _metal_clock_call_all_callbacks(clk->_post_rate_change_callback); + + return out; +} + +/*! + * @brief Register a callback that must be called before a rate change + * + * @param clk The handle for the clock + * @param cb The callback to be registered + */ +__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); +} + +/*! + * @brief Registers a callback that must be called after a rate change + * + * @param clk The handle for the clock + * @param cb The callback to be registered + */ +__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/freedom-metal/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h new file mode 100644 index 000000000..62c0ea975 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__COMPILER_H +#define METAL__COMPILER_H + +#define __METAL_DECLARE_VTABLE(type) \ + extern const struct type type; + +#define __METAL_DEFINE_VTABLE(type) \ + const struct type type + +#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))) + +void _metal_trap(int ecode); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h new file mode 100644 index 000000000..dbd3dbfb5 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h @@ -0,0 +1,271 @@ +/* Copyright 2018 SiFive, Inc */ + +/* SPDX-License-Identifier: Apache-2.0 */ + +/*! @file cpu.h + * @brief API for accessing CPU capabilities. + */ + +#ifndef METAL__CPU_H +#define METAL__CPU_H + +#include +#include + +struct metal_cpu; + +/*! + * @brief Function signature for exception handlers + */ +typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode); + +struct metal_cpu_vtable { + 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); + int (*get_tmr_interrupt_id)(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); + 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); +}; + +/*! @brief A device handle for a CPU hart + */ +struct metal_cpu { + const struct metal_cpu_vtable *vtable; +}; + +/*! @brief Get a reference to a CPU hart + * + * @param hartid The ID of the desired CPU hart + * @return A pointer to the CPU device handle + */ +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(void); + +/*! @brief Get the number of CPU harts + * + * @return The number of CPU harts */ +int metal_cpu_get_num_harts(void); + +/*! @brief Get the CPU cycle count timer value + * + * Get the value of the cycle count timer for a given CPU + * + * @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->mcycle_get(cpu); } + +/*! @brief Get the timebase of the CPU + * + * Get the value of the timebase of the cycle count timer + * + * @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); } + +/*! @brief Get the value of the mtime RTC + * + * Get the value of the mtime real-time clock. The CPU interrupt controller + * must be initialized before this function is called or the return value + * will be 0. + * + * @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); } + +/*! @brief Set the value of the RTC mtimecmp RTC + * + * Set the value of the mtime real-time clock compare register. The CPU + * interrupt controller must be initialized before this function is called + * or the return value will be -1; + * + * @param cpu The CPU device handle + * @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); } + +/*! @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. + * + * @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); } + +/*! @brief Get the RTC timer interrupt id + * + * Get the interrupt ID of the real-time clock interrupt + * + * @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); } + +/*! @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. + * + * @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); } + +/*! @brief Get the software interrupt id + * + * Get the interrupt ID for the software/inter-process interrupt + * + * @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); } + +/*! + * @brief Set the inter-process interrupt for a hart + * + * Trigger a software/inter-process interrupt for a hart. The CPU interrupt + * controller for the CPU handle passed to this function must be initialized + * before this function is called. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Clear the inter-process interrupt for a hart + * + * Clear the software/inter-process interrupt for a hart. The CPU interrupt + * controller for the CPU handle passed to this function must be initialized + * before this function is called. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Get the value of MSIP for the given hart + * + * Get the value of the machine software interrupt pending bit for + * the given hart. The CPU interrupt controller for the CPU handle passed + * as argument to this function must be initialized before this function + * is called. + * + * @param cpu the CPU device handle + * @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); } + +/*! + * @brief Get the interrupt controller for the CPU + * + * Get the CPU interrupt controller. The controller returned by this + * function must be initialized before any interrupts are registered + * or enabled and before any exception handlers are registered with + * this CPU. + * + * @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); } + +/*! + * @brief Register an exception handler + * + * 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); } + +/*! + * @brief Get the length of an instruction in bytes + * + * Get the length of an instruction in bytes. + * + * On RISC-V platforms, this is useful for detecting whether an instruction is + * compressed (2 bytes long) or uncompressed (4 bytes long). + * + * This function is useful in conjuction with `metal_cpu_get_exception_pc()` + * and `metal_cpu_set_exception_pc()` in order to cause the exception handler to + * return execution after the faulting instruction. + * + * @param cpu The CPU device handle + * @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); } + +/*! + * @brief Get the program counter of the current exception. + * + * This function must be called within an exception handler. The behavior is + * undefined outside of an exception handler. + * + * @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); } + +/*! + * @brief Set the exception program counter + * + * This function must be called within an exception handler. The behavior + * is undefined outside of an exception handler. + * + * This function can be used to cause an exception handler to return execution + * to an address other than the one that caused the exception. + * + * @param cpu the CPU device handle + * @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h new file mode 100644 index 000000000..2647c5981 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__FIXED_CLOCK_H +#define METAL__DRIVERS__FIXED_CLOCK_H + +struct __metal_driver_fixed_clock; + +#include +#include + +struct __metal_driver_vtable_fixed_clock { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_clock) + +struct __metal_driver_fixed_clock { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h new file mode 100644 index 000000000..936ce8d77 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__FIXED_FACTOR_CLOCK_H +#define METAL__DRIVERS__FIXED_FACTOR_CLOCK_H + +struct __metal_driver_fixed_factor_clock; + +#include +#include + +struct __metal_driver_vtable_fixed_factor_clock { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_factor_clock) + +struct __metal_driver_fixed_factor_clock { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h new file mode 100644 index 000000000..08d571e1c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h @@ -0,0 +1,24 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_CLINT0_H +#define METAL__DRIVERS__RISCV_CLINT0_H + +#include +#include + +struct __metal_driver_vtable_riscv_clint0 { + struct metal_interrupt_vtable clint_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_clint0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_riscv_clint0 { + struct metal_interrupt controller; + int init_done; +}; +#undef __METAL_MACHINE_MACROS + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h new file mode 100644 index 000000000..ca91e0a95 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h @@ -0,0 +1,192 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_CPU_H +#define METAL__DRIVERS__RISCV_CPU_H + +#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_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_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 +#if __riscv_xlen == 32 +#define METAL_MCAUSE_INTR 0x80000000UL +#define METAL_MCAUSE_CAUSE 0x000003FFUL +#else +#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_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 */ +/* 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_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_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_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_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_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_interrup_cmd_e; + +typedef struct __metal_interrupt_data { + long long pad : 64; + metal_interrupt_handler_t handler; + void *sub_int; + void *exint_data; +} __metal_interrupt_data; + +/* CPU interrupt controller */ + +uintptr_t __metal_myhart_id(void); + +struct __metal_driver_vtable_riscv_cpu_intc { + struct metal_interrupt_vtable controller_vtable; +}; + + +void __metal_interrupt_global_enable(void); +void __metal_interrupt_global_disable(void); +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) + +struct __metal_driver_riscv_cpu_intc { + struct metal_interrupt controller; + int init_done; + uintptr_t metal_mtvec_table[METAL_MAX_MI]; + __metal_interrupt_data metal_int_table[METAL_MAX_MI]; + metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; +}; + +/* CPU driver*/ +struct __metal_driver_vtable_cpu { + struct metal_cpu_vtable cpu_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) + +struct __metal_driver_cpu { + struct metal_cpu cpu; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h new file mode 100644 index 000000000..159ee6d69 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h @@ -0,0 +1,31 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__RISCV_PLIC0_H +#define METAL__DRIVERS__RISCV_PLIC0_H + +#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 + +struct __metal_driver_vtable_riscv_plic0 { + struct metal_interrupt_vtable plic_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_plic0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_riscv_plic0 { + struct metal_interrupt controller; + int init_done; + metal_interrupt_handler_t metal_exint_table[__METAL_PLIC_SUBINTERRUPTS]; + __metal_interrupt_data metal_exdata_table[__METAL_PLIC_SUBINTERRUPTS]; +}; +#undef __METAL_MACHINE_MACROS + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h new file mode 100644 index 000000000..2153cf384 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h @@ -0,0 +1,23 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H +#define METAL__DRIVERS__SIFIVE_CCACHE0_H + +#include +#include + +struct __metal_driver_vtable_sifive_ccache0 { + struct __metal_cache_vtable cache; +}; + +struct __metal_driver_sifive_ccache0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_ccache0) + +struct __metal_driver_sifive_ccache0 { + struct metal_cache cache; +}; + +#endif + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h new file mode 100644 index 000000000..7fef38d19 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h @@ -0,0 +1,43 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_CLIC0_H +#define METAL__DRIVERS__SIFIVE_CLIC0_H + +#include +#include + +#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_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) + +struct __metal_driver_vtable_sifive_clic0 { + struct metal_interrupt_vtable clic_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) + +#define __METAL_MACHINE_MACROS +#include +struct __metal_driver_sifive_clic0 { + struct metal_interrupt controller; + int init_done; + int pad[14]; + metal_interrupt_vector_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; + __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; +}; +#undef __METAL_MACHINE_MACROS + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h new file mode 100644 index 000000000..d311f0cf2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H + +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) + +struct __metal_driver_sifive_fe310_g000_hfrosc { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h new file mode 100644 index 000000000..b86926fba --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h @@ -0,0 +1,20 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H + +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_hfxosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) + +struct __metal_driver_sifive_fe310_g000_hfxosc { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h new file mode 100644 index 000000000..64985c6bb --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/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/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h new file mode 100644 index 000000000..67f818f7b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h @@ -0,0 +1,26 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H + +struct __metal_driver_sifive_fe310_g000_pll; + +#include +#include +#include + +struct __metal_driver_vtable_sifive_fe310_g000_pll { + void (*init)(struct __metal_driver_sifive_fe310_g000_pll *pll); + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) + +struct __metal_driver_sifive_fe310_g000_pll { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h new file mode 100644 index 000000000..387130be5 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h @@ -0,0 +1,24 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H + +#include +#include + +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); +}; + +__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/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h new file mode 100644 index 000000000..bb98f169e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h @@ -0,0 +1,23 @@ +/* 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 + +#include +#include + +struct __metal_driver_vtable_sifive_fu540_c000_l2 { + struct __metal_cache_vtable cache; +}; + +struct __metal_driver_sifive_fu540_c000_l2; + +__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/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h new file mode 100644 index 000000000..9e6f2faf6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H +#define METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H + +#include +#include + +struct __metal_driver_vtable_sifive_global_external_interrupts0 { + struct metal_interrupt_vtable global0_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) + +struct __metal_driver_sifive_global_external_interrupts0 { + struct metal_interrupt irc; + int init_done; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h new file mode 100644 index 000000000..a0caeaba8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H +#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_button { + struct metal_button_vtable button_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) + +struct __metal_driver_sifive_gpio_button { + struct metal_button button; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h new file mode 100644 index 000000000..a8dacf116 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H +#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_led { + struct metal_led_vtable led_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) + +struct __metal_driver_sifive_gpio_led { + struct metal_led led; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h new file mode 100644 index 000000000..c9c7839e9 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H +#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H + +#include +#include +#include + +struct __metal_driver_vtable_sifive_switch { + struct metal_switch_vtable switch_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) + +struct __metal_driver_sifive_gpio_switch { + struct metal_switch flip; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h new file mode 100644 index 000000000..cc56dc722 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_GPIO0_H +#define METAL__DRIVERS__SIFIVE_GPIO0_H + +#include +#include + +struct __metal_driver_vtable_sifive_gpio0 { + const struct __metal_gpio_vtable gpio; +}; + +//struct __metal_driver_sifive_gpio0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) + +struct __metal_driver_sifive_gpio0 { + struct metal_gpio gpio; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h new file mode 100644 index 000000000..aa8d63078 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H +#define METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H + +#include +#include + +struct __metal_driver_vtable_sifive_local_external_interrupts0 { + struct metal_interrupt_vtable local0_vtable; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) + +struct __metal_driver_sifive_local_external_interrupts0 { + struct metal_interrupt irc; + int init_done; +}; + + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h new file mode 100644 index 000000000..b0ed143bf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h @@ -0,0 +1,27 @@ +/* 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/freedom-metal/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h new file mode 100644 index 000000000..c4a6848e7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h @@ -0,0 +1,26 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_SPI0_H +#define METAL__DRIVERS__SIFIVE_SPI0_H + +#include +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_spi0 { + const struct metal_spi_vtable spi; +}; + +__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/freedom-metal/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h new file mode 100644 index 000000000..e87db2c83 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_TEST0_H +#define METAL__DRIVERS__SIFIVE_TEST0_H + +#include +#include + +struct __metal_driver_vtable_sifive_test0 { + const struct __metal_shutdown_vtable shutdown; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_test0) + +struct __metal_driver_sifive_test0 { + struct __metal_shutdown shutdown; +}; + + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_trace.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_trace.h new file mode 100644 index 000000000..3c67522f4 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/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/freedom-metal/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h new file mode 100644 index 000000000..5d585e783 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h @@ -0,0 +1,30 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_UART0_H +#define METAL__DRIVERS__SIFIVE_UART0_H + +#include +#include +#include +#include +#include +#include + +struct __metal_driver_vtable_sifive_uart0 { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_uart0; + +__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/freedom-metal/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h new file mode 100644 index 000000000..12b143d58 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/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/freedom-metal/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h new file mode 100644 index 000000000..7645494ff --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h @@ -0,0 +1,284 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__GPIO_H +#define METAL__GPIO_H + +#include +#include + +/*! + * @file gpio.h + * @brief API for manipulating general-purpose input/output + */ + +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; +}; + +/*! + * @brief Get a GPIO device handle + * @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(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 + * @param gpio The handle for the GPIO interface + * @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; + } + + return gpio->vtable->disable_input(gpio, (1 << pin)); +} + +/*! + * @brief Enable 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 enabled + */ +__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 + * @param pin The pin number indexed from 0 + * @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; + } + + if(value == 0) { + return gpio->vtable->output_clear(gpio, (1 << pin)); + } else { + return gpio->vtable->output_set(gpio, (1 << pin)); + } +} + +/*! + * @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_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; + } else { + return 0; + } +} + +/*! + * @brief Clears the value of the GPIO pin + * @param gpio The handle for the GPIO interface + * @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; + } + + return gpio->vtable->output_clear(gpio, (1 << pin)); +} + +/*! + * @brief Toggles the value of the GPIO pin + * @param gpio The handle for the GPIO interface + * @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; + } + + return gpio->vtable->output_toggle(gpio, (1 << pin)); +} + +/*! + * @brief Enables and sets the pinmux for a GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to enable pinmux on + * @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; + } + + 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/freedom-metal/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h new file mode 100644 index 000000000..4f59bd36b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h @@ -0,0 +1,461 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__INTERRUPT_H +#define METAL__INTERRUPT_H + +/*! @file interrupt.h + * @brief API for registering and manipulating interrupts + */ + +#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_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 Function signature for interrupt callback handlers + */ +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); + 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); + int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id); + 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); + int (*command_request)(struct metal_interrupt *controller, int cmd, void *data); + int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time); +}; + +/*! + * @brief A handle for an interrupt + */ +struct metal_interrupt { + const struct metal_interrupt_vtable *vtable; +}; + +/*! + * @brief Initialize a given interrupt controller + * + * Initialize a given interrupt controller. This function must be called + * before any interrupts are registered or enabled with the handler. It + * is invalid to initialize an interrupt controller more than once. + * + * @param controller The handle for the interrupt 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 + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to register + * @param handler The interrupt handler callback + * @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); +} + +/*! + * @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); +} + +/*! + * @brief Enable an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return 0 upon success + */ +__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id) +{ + return controller->vtable->interrupt_enable(controller, id); +} + +/*! + * @brief Disable an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to disable + * @return 0 upon success + */ +__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 Enable an interrupt vector + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return 0 upon success + */ +__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id) +{ + return controller->vtable->interrupt_vector_enable(controller, id); +} + +/*! + * @brief Disable an interrupt vector + * @param controller The handle for the 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) +{ + return controller->vtable->interrupt_vector_disable(controller, id); +} + +/*! + * @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); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h new file mode 100644 index 000000000..d55b4520a --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__IO_H +#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)) + +/* Allows users to specify arbitrary fences. */ +#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 short __metal_io_u16; +typedef unsigned int __metal_io_u32; +#if __riscv_xlen >= 64 +typedef unsigned long __metal_io_u64; +#endif + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h new file mode 100644 index 000000000..1a2a05b8b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__ITIM_H +#define METAL__ITIM_H + +/*! @file itim.h + * + * 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"))) + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h new file mode 100644 index 000000000..f2aa39ceb --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h @@ -0,0 +1,68 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LED_H +#define METAL__LED_H + +/*! + * @file led.h + * @brief API for manipulating LEDs + */ + +struct metal_led; + +struct metal_led_vtable { + int (*led_exist)(struct metal_led *led, char *label); + void (*led_enable)(struct metal_led *led); + void (*led_on)(struct metal_led *led); + void (*led_off)(struct metal_led *led); + void (*led_toggle)(struct metal_led *led); +}; + +/*! + * @brief A handle for an LED + */ +struct metal_led { + const struct metal_led_vtable *vtable; +}; + +/*! + * @brief Get a handle for an 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); + +/*! + * @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 + */ +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); } + +/*! + * @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); } + +/*! + * @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); } + +/*! + * @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h new file mode 100644 index 000000000..0702cbf16 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h @@ -0,0 +1,146 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LOCK_H +#define METAL__LOCK_H + +#include +#include +#include + +/*! + * @file lock.h + * @brief An API for creating and using a software lock/mutex + */ + +/* 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 + * + * 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 + +/*! + * @brief A handle for a lock + */ +struct metal_lock { + 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. + * + * 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) { +#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) { + return 1; + } + + /* If the memory doesn't support atomics, report an error */ + if(!metal_memory_supports_atomics(lock_mem)) { + return 2; + } + + lock->_state = 0; + + return 0; +#else + return 3; +#endif +} + +/*! + * @brief Take a lock + * @param lock The handle for a lock + * @return 0 if the lock is successfully taken + * + * 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) { +#ifdef __riscv_atomic + int old = 1; + int new = 1; + + 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)) + : "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))); + + /* Trigger a Store/AMO access fault */ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); + + /* If execution returns, indicate failure */ + return 1; +#endif +} + +/*! + * @brief Give back a held lock + * @param lock The handle for a lock + * @return 0 if the lock is successfully given + * + * 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) { +#ifdef __riscv_atomic + __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))); + + /* Trigger a Store/AMO access fault */ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); + + /* If execution returns, indicate failure */ + return 1; +#endif +} + +#endif /* METAL__LOCK_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h new file mode 100644 index 000000000..9de7d6162 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h @@ -0,0 +1,81 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__MEMORY_H +#define METAL__MEMORY_H + +#include +#include + +/*! + * @file memory.h + * + * @brief API for enumerating memory blocks + */ + +struct _metal_memory_attributes { + 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; +}; + +/*! + * @brief Get the memory block which services the given address + * + * Given a physical memory address, get a handle for the memory block to which + * 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 + */ +struct metal_memory *metal_get_memory_from_address(const uintptr_t address); + +/*! + * @brief Get the base address for a memory block + * @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; +} + +/*! + * @brief Get the size of a memory block + * @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; +} + +/*! + * @brief Query if a memory block supports atomic operations + * @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; +} + +/*! + * @brief Query if a memory block is cacheable + * @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; +} + +#endif /* METAL__MEMORY_H */ + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h new file mode 100644 index 000000000..d948656c8 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h @@ -0,0 +1,209 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PMP_H +#define METAL__PMP_H + +/*! + * @file metal/pmp.h + * + * @brief API for Configuring Physical Memory Protection on RISC-V Cores + * + * 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. + * + * Additional information about the use and configuration rules for PMPs + * can be found by reading the RISC-V Privileged Architecture Specification. + */ + +#include +#include + +struct metal_pmp; + +/*! + * @brief Set of available PMP addressing modes + */ +enum metal_pmp_address_mode { + /*! @brief Disable the PMP region */ + METAL_PMP_OFF = 0, + /*! @brief Use Top-of-Range mode */ + METAL_PMP_TOR = 1, + /*! @brief Use naturally-aligned 4-byte region mode */ + METAL_PMP_NA4 = 2, + /*! @brief Use naturally-aligned power-of-two mode */ + METAL_PMP_NAPOT = 3 +}; + +/*! + * @brief Configuration for a PMP region + */ +struct metal_pmp_config { + /*! @brief Sets whether reads to the PMP region succeed */ + unsigned int R : 1; + /*! @brief Sets whether writes to the PMP region succeed */ + unsigned int W : 1; + /*! @brief Sets whether the PMP region is executable */ + unsigned int X : 1; + + /*! @brief Sets the addressing mode of the PMP region */ + enum metal_pmp_address_mode A : 2; + + int _pad : 2; + + /*! @brief Sets whether the PMP region is locked */ + enum metal_pmp_locked { + METAL_PMP_UNLOCKED = 0, + METAL_PMP_LOCKED = 1 + } L : 1; +}; + +/*! + * @brief A handle for the PMP device + */ +struct metal_pmp { + /* The minimum granularity of the PMP region. Set by metal_pmp_init */ + uintptr_t _granularity[METAL_MAX_CORES]; +}; + +/*! + * @brief Get the PMP device handle + */ +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 + * + * The PMP initialization routine is optional and may be called as many times + * as is desired. The effect of the initialization routine is to attempt to set + * all regions to unlocked and disabled, as well as to clear the X, W, and R + * bits. Only the pmp configuration of the hart which executes the routine will + * be affected. + * + * If any regions are fused to preset values by the implementation or locked, + * those PMP regions will silently remain uninitialized. + */ +void metal_pmp_init(struct metal_pmp *pmp); + +/*! + * @brief Configure a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to configure + * @param config The desired configuration of the PMP region + * @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); + +/*! + * @brief Get the configuration for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @param config Variable to store the PMP region configuration + * @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); + +/*! + * @brief Lock a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to lock + * @return 0 if the region is successfully locked + */ +int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the address for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @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); + +/*! + * @brief Get the address of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return The address of the PMP region, or 0 if the region could not be read + */ +size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the addressing mode of a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @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); + +/*! + * @brief Get the addressing mode of a PMP region + * @param pmp The PMP device handle + * @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); + +/*! + * @brief Set the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param X The desired value of the executable bit + * @return 0 if the executable bit is successfully set + */ +int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X); + +/*! + * @brief Get the executable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the executable bit + */ +int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param W The desired value of the writable bit + * @return 0 if the writable bit is successfully set + */ +int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W); + +/*! + * @brief Get the writable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the writable bit + */ +int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to set + * @param R The desired value of the readable bit + * @return 0 if the readable bit is successfully set + */ +int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R); + +/*! + * @brief Set the readable bit for a PMP region + * @param pmp The PMP device handle + * @param region The PMP region to read + * @return the value of the readable bit + */ +int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h new file mode 100644 index 000000000..928a936b1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h @@ -0,0 +1,122 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PRIVILEGE_H +#define METAL__PRIVILEGE_H + +/*! + * @file metal/privilege.h + * + * @brief API for manipulating the privilege mode of a RISC-V system + * + * Additional information about privilege modes on RISC-V systems can be found + * by reading the RISC-V Privileged Architecture Specification v1.10. + */ + +#include + +enum metal_privilege_mode { + METAL_PRIVILEGE_USER = 0, + METAL_PRIVILEGE_SUPERVISOR = 1, + METAL_PRIVILEGE_MACHINE = 3, +}; + +#if __riscv_xlen == 32 +typedef uint32_t metal_xreg_t; +#elif __riscv_xlen == 64 +typedef uint64_t metal_xreg_t; +#endif + +#if __riscv_flen == 32 +typedef uint32_t metal_freg_t; +#elif __riscv_flen == 64 +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 t0; + metal_xreg_t t1; + metal_xreg_t t2; + + 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; +#ifndef __riscv_32e + 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 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 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 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; +#endif /* __riscv_flen */ +}; + +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); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h new file mode 100644 index 000000000..2e742ea38 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h @@ -0,0 +1,127 @@ +/* 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/freedom-metal/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h new file mode 100644 index 000000000..8d4020b5c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h @@ -0,0 +1,36 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SHUTDOWN_H +#define METAL__SHUTDOWN_H + +/*! + * @file shutdown.h + * @brief API for shutting down a machine + */ + +struct __metal_shutdown; + +struct __metal_shutdown_vtable { + 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); } + +/*! + * @brief The public METAL shutdown interface + * + * Shuts down the machine, if the machine enables an interface for + * shutting down. When no interface is provided, will cause the machine + * to spin indefinitely. + * + * @param code The return code to set. 0 indicates program success. + */ +void metal_shutdown(int code) __attribute__((noreturn)); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h new file mode 100644 index 000000000..635e3c151 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h @@ -0,0 +1,90 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SPI_H +#define METAL__SPI_H + +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; + + /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ + unsigned int polarity : 1; + /*! @brief The phase of the SPI transfer, equivalent to CPHA */ + unsigned int phase : 1; + /*! @brief The endianness of the SPI transfer */ + unsigned int little_endian : 1; + /*! @brief The active state of the chip select line */ + 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 (*get_baud_rate)(struct metal_spi *spi); + int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); +}; + +/*! @brief A handle for a SPI device */ +struct metal_spi { + const struct metal_spi_vtable *vtable; +}; + +/*! @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(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); } + +/*! @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. + * @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) { + return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); +} + +/*! @brief Get the current baud rate of the SPI device + * @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); } + +/*! @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h new file mode 100644 index 000000000..61f0efe56 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h @@ -0,0 +1,51 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SWITCH_H +#define METAL__SWITCH_H + +/*! + * @file switch.h + * @brief API for reading toggle switches + */ + +#include + +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); + int (*get_interrupt_id)(struct metal_switch *sw); +}; + +/*! + * @brief A handle for a switch + */ +struct metal_switch { + const struct metal_switch_vtable *vtable; +}; + +/*! + * @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 + */ +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); } + +/*! + * @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h new file mode 100644 index 000000000..5c33b6f1b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h @@ -0,0 +1,18 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TIME_H +#define METAL__TIME_H + +#include + +/*! + * @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/freedom-metal/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h new file mode 100644 index 000000000..eeae1f60b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h @@ -0,0 +1,36 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TIMER_H +#define METAL__TIMER_H + +/*! + * @file timer.h + * @brief API for reading and manipulating the machine timer + */ + +/*! + * @brief Read the machine cycle count + * @param hartid The hart ID to read the cycle count of + * @param cyclecount The variable to hold the value + * @return 0 upon success + */ +int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); + +/*! + * @brief Get the machine timebase frequency + * @param hartid The hart ID to read the timebase of + * @param timebase The variable to hold the value + * @return 0 upon success + */ +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 + * @return 0 upon success + */ +int metal_timer_set_tick(int hartid, int second); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h new file mode 100644 index 000000000..fe4c000db --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h @@ -0,0 +1,52 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TTY_H +#define METAL__TTY_H + +/*! + * @file tty.h + * @brief API for emulated serial teriminals + */ + +/*! + * @brief Write a character to the default output device + * + * Write a character to the default output device, which for most + * targets is the UART serial port. + * + * putc() does CR/LF mapping. + * putc_raw() does not. + * + * @param c The character to write to the terminal + * @return 0 on success, or -1 on failure. + */ +int metal_tty_putc(int c); + +/*! + * @brief Write a raw character to the default output device + * + * Write a character to the default output device, which for most + * targets is the UART serial port. + * + * putc() does CR/LF mapping. + * putc_raw() does not. + * + * @param c The character to write to the terminal + * @return 0 on success, or -1 on failure. + */ +int metal_tty_putc_raw(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/freedom-metal/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h new file mode 100644 index 000000000..e9e4d0436 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h @@ -0,0 +1,106 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__UART_H +#define METAL__UART_H + +/*! + * @file uart.h + * @brief API for UART serial ports + */ + +#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, 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); + int (*get_interrupt_id)(struct metal_uart *uart); +}; + +/*! + * @brief Handle for a UART serial device + */ +struct metal_uart { + const struct metal_uart_vtable *vtable; +}; + +/*! + * @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. + * + * @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) { uart->vtable->init(uart, baud_rate); } + +/*! + * @brief Output a character over the UART + * @param uart The UART device handle + * @param c The character to send over the UART + * @return 0 upon success + */ +__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, 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); } + +/*! + * @brief Set the baud rate of the UART peripheral + * @param uart The UART device handle + * @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); } + +/*! + * @brief Get the interrupt controller of the UART peripheral + * + * Get the interrupt controller for the UART peripheral. The interrupt + * controller must be initialized before any interrupts can be registered + * or enabled with it. + * + * @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); } + +/*! + * @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); } + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h new file mode 100644 index 000000000..b5ff48697 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h @@ -0,0 +1,163 @@ +/* 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/freedom-metal/src/button.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c new file mode 100644 index 000000000..efd645334 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c @@ -0,0 +1,27 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +struct metal_button* metal_button_get (char *label) +{ + int i; + struct metal_button *button; + + if ((__METAL_DT_MAX_BUTTONS == 0) || (label == NULL)) { + return NULL; + } + + for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { + button = (struct metal_button*)__metal_button_table[i]; + if (button->vtable->button_exist(button, label)) { + return button; + } + } + return NULL; +} + +extern __inline__ struct metal_interrupt* + metal_button_interrupt_controller(struct metal_button *button); +extern __inline__ int metal_button_get_interrupt_id(struct metal_button *button); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c new file mode 100644 index 000000000..024ba52ad --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c @@ -0,0 +1,187 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +extern __inline__ void metal_cache_init(struct metal_cache *cache, int ways); +extern __inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache); +extern __inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways); + +int metal_dcache_l1_available(int hartid) { + switch (hartid) { + case 0: +#ifdef __METAL_CPU_0_DCACHE_HANDLE + return __METAL_CPU_0_DCACHE_HANDLE; +#endif + break; + case 1: +#ifdef __METAL_CPU_1_DCACHE_HANDLE + return __METAL_CPU_1_DCACHE_HANDLE; +#endif + break; + case 2: +#ifdef __METAL_CPU_2_DCACHE_HANDLE + return __METAL_CPU_2_DCACHE_HANDLE; +#endif + break; + case 3: +#ifdef __METAL_CPU_3_DCACHE_HANDLE + return __METAL_CPU_3_DCACHE_HANDLE; +#endif + break; + case 4: +#ifdef __METAL_CPU_4_DCACHE_HANDLE + return __METAL_CPU_4_DCACHE_HANDLE; +#endif + break; + case 5: +#ifdef __METAL_CPU_5_DCACHE_HANDLE + return __METAL_CPU_5_DCACHE_HANDLE; +#endif + break; + case 6: +#ifdef __METAL_CPU_6_DCACHE_HANDLE + return __METAL_CPU_6_DCACHE_HANDLE; +#endif + break; + case 7: +#ifdef __METAL_CPU_7_DCACHE_HANDLE + return __METAL_CPU_7_DCACHE_HANDLE; +#endif + break; + case 8: +#ifdef __METAL_CPU_8_DCACHE_HANDLE + return __METAL_CPU_8_DCACHE_HANDLE; +#endif + break; + } + return 0; +} + +int metal_icache_l1_available(int hartid) { + switch (hartid) { + case 0: +#ifdef __METAL_CPU_0_ICACHE_HANDLE + return __METAL_CPU_0_ICACHE_HANDLE; +#endif + break; + case 1: +#ifdef __METAL_CPU_1_ICACHE_HANDLE + return __METAL_CPU_1_ICACHE_HANDLE; +#endif + break; + case 2: +#ifdef __METAL_CPU_2_ICACHE_HANDLE + return __METAL_CPU_2_ICACHE_HANDLE; +#endif + break; + case 3: +#ifdef __METAL_CPU_3_ICACHE_HANDLE + return __METAL_CPU_3_ICACHE_HANDLE; +#endif + break; + case 4: +#ifdef __METAL_CPU_4_ICACHE_HANDLE + return __METAL_CPU_4_ICACHE_HANDLE; +#endif + break; + case 5: +#ifdef __METAL_CPU_5_ICACHE_HANDLE + return __METAL_CPU_5_ICACHE_HANDLE; +#endif + break; + case 6: +#ifdef __METAL_CPU_6_ICACHE_HANDLE + return __METAL_CPU_6_ICACHE_HANDLE; +#endif + break; + case 7: +#ifdef __METAL_CPU_7_ICACHE_HANDLE + return __METAL_CPU_7_ICACHE_HANDLE; +#endif + break; + case 8: +#ifdef __METAL_CPU_8_ICACHE_HANDLE + return __METAL_CPU_8_ICACHE_HANDLE; +#endif + break; + } + return 0; +} + +/*! + * @brief CFlush.D.L1 instruction is a custom instruction implemented as a + * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) + * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) + * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 + * |--------|--------|--------|--------|--------|--------|--------|--------| + * +-------------+------------+----------+------+--------+-----------------+ + * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | + * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| + * +--------------------------+----------+------+--------+-----------------+ + * 31 -0x40 20 15 0 12 x0 7 0x73 0 + * +--------+--------+--------+----------+------+--------+--------+--------+ + * where, + * rs1 = 0x0, CFLUSH.D.L1 writes back and invalidates all lines in the L1 D$ + * rs1 != x0, CFLUSH.D.L1 writes back and invalidates the L1 D$ line containing + * the virtual address in integer register rs1. + */ +void metal_dcache_l1_flush(int hartid, uintptr_t address) +{ + if (metal_dcache_l1_available(hartid)) { + // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' + __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x40" : : "r" (address)); + __asm__ __volatile__ ("fence.i"); // FENCE + } +} + +/*! + * @brief CDiscard.D.L1 instruction is a custom instruction implemented as a + * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) + * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) + * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 + * |--------|--------|--------|--------|--------|--------|--------|--------| + * +-------------+------------+----------+------+--------+-----------------+ + * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | + * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| + * +--------------------------+----------+------+--------+-----------------+ + * 31 -0x3E 20 15 0 12 x0 7 0x73 0 + * +--------+--------+--------+----------+------+--------+--------+--------+ + * where, + * rs1 = 0x0, CDISCARD.D.L1 invalidates all lines in the L1 D$ with no writes back. + * rs1 != x0, CDISCARD.D.L1 invalidates the L1 D$ line containing the virtual address + * in integer register rs1, with no writes back. + */ +void metal_dcache_l1_discard(int hartid, uintptr_t address) +{ + if (metal_dcache_l1_available(hartid)) { + // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' + __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x3E" : : "r" (address)); + __asm__ __volatile__ ("fence.i"); // FENCE + } +} + +/*! + * @brief CFlush.I.L1 instruction is a custom instruction implemented as a state + * machine in L1 Instruction Cache (I$) with funct3=0, (for core with data caches) + * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) + * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 + * |--------|--------|--------|--------|--------|--------|--------|--------| + * +-------------+------------+----------+------+--------+-----------------+ + * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | + * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-0-0-0-0-0|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| + * +--------------------------+----------+------+--------+-----------------+ + * 31 -0x3F 20 15 0 12 x0 7 0x73 0 + * +--------+--------+--------+----------+------+--------+--------+--------+ + * CFLUSH.I.L1 invalidates all lines in the L1 I$. + */ +void metal_icache_l1_flush(int hartid) +{ + if (metal_icache_l1_available(hartid)) { + // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' + __asm__ __volatile__ (".insn i 0x73, 0, x0, x0, -0x3F" : : ); + __asm__ __volatile__ ("fence.i"); // FENCE + } +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c new file mode 100644 index 000000000..cc3f4dcf3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c @@ -0,0 +1,12 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +extern __inline__ void _metal_clock_call_all_callbacks(const metal_clock_callback *const list); +extern __inline__ metal_clock_callback *_metal_clock_append_to_callbacks(metal_clock_callback *list, metal_clock_callback *const cb); + +extern __inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk); +extern __inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz); +extern __inline__ void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); +extern __inline__ void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c new file mode 100644 index 000000000..25fda5de7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c @@ -0,0 +1,59 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +struct metal_cpu* metal_cpu_get(unsigned int hartid) +{ + if (hartid < __METAL_DT_MAX_HARTS) { + return (struct metal_cpu *)__metal_cpu_table[hartid]; + } + return NULL; +} + +int metal_cpu_get_current_hartid() +{ +#ifdef __riscv + int mhartid; + __asm__ volatile("csrr %0, mhartid" : "=r" (mhartid)); + return mhartid; +#endif +} + +int metal_cpu_get_num_harts() +{ + return __METAL_DT_MAX_HARTS; +} + +extern __inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu); + +extern __inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu); + +extern __inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time); + +extern __inline__ struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu); + +extern __inline__ struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid); + +extern __inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid); + +extern __inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid); + +extern __inline__ struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler); + +extern __inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc); + +extern __inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu); + +extern __inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c new file mode 100644 index 000000000..92c61d023 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c @@ -0,0 +1,29 @@ +/* Copyright 2018 SiFive, Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_FIXED_CLOCK + +#include +#include +#include + +long __metal_driver_fixed_clock_get_rate_hz(const struct metal_clock *gclk) +{ + return __metal_driver_fixed_clock_rate(gclk); +} + +long __metal_driver_fixed_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) +{ + return __metal_driver_fixed_clock_get_rate_hz(gclk); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_fixed_clock) = { + .clock.get_rate_hz = __metal_driver_fixed_clock_get_rate_hz, + .clock.set_rate_hz = __metal_driver_fixed_clock_set_rate_hz, +}; + +#endif /* METAL_FIXED_CLOCK */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c new file mode 100644 index 000000000..57d83af87 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c @@ -0,0 +1,34 @@ +/* Copyright 2018 SiFive, Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_FIXED_FACTOR_CLOCK + +#include +#include +#include + +long __metal_driver_fixed_factor_clock_get_rate_hz(const struct metal_clock *gclk) +{ + struct metal_clock *parent = __metal_driver_fixed_factor_clock_parent(gclk); + long parent_rate = 1; + if(parent) { + parent_rate = parent->vtable->get_rate_hz(parent); + } + + return __metal_driver_fixed_factor_clock_mult(gclk) * parent_rate / __metal_driver_fixed_factor_clock_div(gclk); +} + +long __metal_driver_fixed_factor_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) +{ + return __metal_driver_fixed_factor_clock_get_rate_hz(gclk); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_fixed_factor_clock) = { + .clock.get_rate_hz = __metal_driver_fixed_factor_clock_get_rate_hz, + .clock.set_rate_hz = __metal_driver_fixed_factor_clock_set_rate_hz, +}; +#endif /* METAL_FIXED_FACTOR_CLOCK */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c new file mode 100644 index 000000000..50c0c5c21 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c @@ -0,0 +1,5 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c new file mode 100644 index 000000000..d0488b317 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c @@ -0,0 +1,283 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_RISCV_CLINT0 + +#include +#include +#include +#include + +unsigned long long __metal_clint0_mtime_get (struct __metal_driver_riscv_clint0 *clint) +{ + __metal_io_u32 lo, hi; + unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); + + /* Guard against rollover when reading */ + do { + hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)); + lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME)); + } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)) != hi); + + return (((unsigned long long)hi) << 32) | lo; +} + +int __metal_driver_riscv_clint0_mtimecmp_set(struct metal_interrupt *controller, + int hartid, + unsigned long long time) +{ + struct __metal_driver_riscv_clint0 *clint = + (struct __metal_driver_riscv_clint0 *)(controller); + unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); + /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, + * and are NOT internally latched for multiword transfers. + * Need to be careful about sequencing to avoid triggering + * spurious interrupts: For that set the high word to a max + * value first. + */ + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE)) = (__metal_io_u32)time; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); + return 0; +} + +static struct metal_interrupt *_get_cpu_intc() +{ + int hartid = 0; + __asm__ volatile("csrr %[hartid], mhartid" + : [hartid] "=r" (hartid) :: "memory"); + + struct metal_cpu *cpu = metal_cpu_get(hartid); + + return metal_cpu_interrupt_controller(cpu); +} + +void __metal_driver_riscv_clint0_init (struct metal_interrupt *controller) +{ + int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + struct __metal_driver_riscv_clint0 *clint = + (struct __metal_driver_riscv_clint0 *)(controller); + + if ( !clint->init_done ) { + /* Register its interrupts with with parent controller, aka sw and timerto its default isr */ + for (int i = 0; i < num_interrupts; i++) { + struct metal_interrupt *intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); + int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc->vtable->interrupt_register(intc, line, NULL, controller); + } + clint->init_done = 1; + } +} + +int __metal_driver_riscv_clint0_register (struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = -1; + metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); + struct metal_interrupt *intc = NULL; + struct metal_interrupt *cpu_intc = _get_cpu_intc(); + int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + + if ( (mode != METAL_VECTOR_MODE) && (mode != METAL_DIRECT_MODE) ) { + return rc; + } + + for(int i = 0; i < num_interrupts; i++) { + int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); + if (cpu_intc == intc && id == line) { + break; + } + intc = NULL; + } + + /* Register its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_register(intc, id, isr, priv); + } + return rc; +} + +int __metal_driver_riscv_clint0_vector_register (struct metal_interrupt *controller, + int id, metal_interrupt_vector_handler_t isr, + void *priv) +{ + /* Not supported. User can override the 'weak' handler with their own */ + int rc = -1; + return rc; +} + +metal_vector_mode __metal_driver_riscv_clint0_get_vector_mode (struct metal_interrupt *controller) +{ + return __metal_controller_interrupt_vector_mode(); +} + +int __metal_driver_riscv_clint0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) +{ + int rc = -1; + struct metal_interrupt *intc = _get_cpu_intc(); + + if (intc) { + /* Valid vector modes are VECTOR and DIRECT, anything else is invalid (-1) */ + switch (mode) { + case METAL_VECTOR_MODE: + case METAL_DIRECT_MODE: + rc = intc->vtable->interrupt_set_vector_mode(intc, mode); + break; + case METAL_HARDWARE_VECTOR_MODE: + case METAL_SELECTIVE_NONVECTOR_MODE: + case METAL_SELECTIVE_VECTOR_MODE: + break; + } + } + return rc; +} + +int __metal_driver_riscv_clint0_enable (struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if ( id ) { + struct metal_interrupt *intc = NULL; + struct metal_interrupt *cpu_intc = _get_cpu_intc(); + int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + + for(int i = 0; i < num_interrupts; i++) { + int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); + if(cpu_intc == intc && id == line) { + break; + } + intc = NULL; + } + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_enable(intc, id); + } + } + + return rc; +} + +int __metal_driver_riscv_clint0_disable (struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if ( id ) { + struct metal_interrupt *intc = NULL; + struct metal_interrupt *cpu_intc = _get_cpu_intc(); + int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + + for(int i = 0; i < num_interrupts; i++) { + int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); + if(cpu_intc == intc && id == line) { + break; + } + intc = NULL; + } + + /* Disable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_disable(intc, id); + } + } + + return rc; +} + +int __metal_driver_riscv_clint0_command_request (struct metal_interrupt *controller, + int command, void *data) +{ + int hartid; + int rc = -1; + struct __metal_driver_riscv_clint0 *clint = + (struct __metal_driver_riscv_clint0 *)(controller); + unsigned long control_base = __metal_driver_sifive_clint0_control_base(controller); + + switch (command) { + case METAL_TIMER_MTIME_GET: + if (data) { + *(unsigned long long *)data = __metal_clint0_mtime_get(clint); + rc = 0; + } + break; + case METAL_SOFTWARE_IPI_CLEAR: + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))) = METAL_DISABLE; + rc = 0; + } + break; + case METAL_SOFTWARE_IPI_SET: + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))) = METAL_ENABLE; + /* Callers of this function assume it's blocking, in the sense that + * the IPI is guarnteed to have been delivered before the function + * returns. We can't really guarnteed it's delivered, but we can + * read back the control register after writing it in at least an + * attempt to provide some semblence of ordering here. The fence + * ensures the read is order after the write -- it wouldn't be + * necessary under RVWMO because this is the same address, but we + * don't have an IO memory model so I'm being a bit overkill here. + */ + __METAL_IO_FENCE(o,i); + rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))); + rc = 0; + } + break; + case METAL_SOFTWARE_MSIP_GET: + rc = 0; + if (data) { + hartid = *(int *)data; + rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))); + } + break; + default: + break; + } + + return rc; +} + +int __metal_driver_riscv_clint0_clear_interrupt (struct metal_interrupt *controller, int id) +{ + int hartid = metal_cpu_get_current_hartid(); + return __metal_driver_riscv_clint0_command_request(controller, + METAL_SOFTWARE_IPI_CLEAR, &hartid); +} + +int __metal_driver_riscv_clint0_set_interrupt (struct metal_interrupt *controller, int id) +{ + int hartid = metal_cpu_get_current_hartid(); + return __metal_driver_riscv_clint0_command_request(controller, + METAL_SOFTWARE_IPI_SET, &hartid); +} + + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_clint0) = { + .clint_vtable.interrupt_init = __metal_driver_riscv_clint0_init, + .clint_vtable.interrupt_register = __metal_driver_riscv_clint0_register, + .clint_vtable.interrupt_vector_register = __metal_driver_riscv_clint0_vector_register, + .clint_vtable.interrupt_enable = __metal_driver_riscv_clint0_enable, + .clint_vtable.interrupt_disable = __metal_driver_riscv_clint0_disable, + .clint_vtable.interrupt_get_vector_mode = __metal_driver_riscv_clint0_get_vector_mode, + .clint_vtable.interrupt_set_vector_mode = __metal_driver_riscv_clint0_set_vector_mode, + .clint_vtable.interrupt_clear = __metal_driver_riscv_clint0_clear_interrupt, + .clint_vtable.interrupt_set = __metal_driver_riscv_clint0_set_interrupt, + .clint_vtable.command_request = __metal_driver_riscv_clint0_command_request, + .clint_vtable.mtimecmp_set = __metal_driver_riscv_clint0_mtimecmp_set, +}; + +#endif /* METAL_RISCV_CLINT0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c new file mode 100644 index 000000000..b693f312a --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c @@ -0,0 +1,999 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +extern void __metal_vector_table(); +unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu); +int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, unsigned long long time); + +struct metal_cpu *__metal_driver_cpu_get(int hartid) +{ + if (hartid < __METAL_DT_MAX_HARTS) { + return &(__metal_cpu_table[hartid]->cpu); + } + return (struct metal_cpu *)NULL; +} + +uintptr_t __metal_myhart_id (void) +{ + uintptr_t myhart; + __asm__ volatile ("csrr %0, mhartid" : "=r"(myhart)); + return myhart; +} + +void __metal_zero_memory (unsigned char *base, unsigned int size) +{ + volatile unsigned char *ptr; + for (ptr = base; ptr < (base + size); ptr++){ + *ptr = 0; + } +} + +void __metal_interrupt_global_enable (void) { + uintptr_t m; + __asm__ volatile ("csrrs %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); +} + +void __metal_interrupt_global_disable (void) { + uintptr_t m; + __asm__ volatile ("csrrc %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); +} + +void __metal_interrupt_software_enable (void) { + uintptr_t m; + __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); +} + +void __metal_interrupt_software_disable (void) { + uintptr_t m; + __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); +} + +void __metal_interrupt_timer_enable (void) { + uintptr_t m; + __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); +} + +void __metal_interrupt_timer_disable (void) { + uintptr_t m; + __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); +} + +void __metal_interrupt_external_enable (void) { + uintptr_t m; + __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); +} + +void __metal_interrupt_external_disable (void) { + unsigned long m; + __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); +} + +void __metal_interrupt_local_enable (int id) { + uintptr_t b = 1 << id; + uintptr_t m; + __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(b)); +} + +void __metal_interrupt_local_disable (int id) { + uintptr_t b = 1 << id; + uintptr_t m; + __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(b)); +} + +void __metal_default_exception_handler (struct metal_cpu *cpu, int ecode) { + metal_shutdown(100); +} + +void __metal_default_interrupt_handler (int id, void *priv) { + metal_shutdown(200); +} + +/* The metal_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_interrupt_vector_handler (void) { + metal_shutdown(300); +} + +/* The metal_software_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_SW].handler(METAL_INTERRUPT_ID_SW, priv); + } +} + +void __metal_default_sw_handler (int id, void *priv) { + uintptr_t mcause; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE]((struct metal_cpu *)cpu, id); + } +} + +/* The metal_timer_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_TMR].handler(METAL_INTERRUPT_ID_TMR, priv); + } +} + +void __metal_default_timer_handler (int id, void *priv) { + struct metal_cpu *cpu = __metal_driver_cpu_get(__metal_myhart_id()); + unsigned long long time = __metal_driver_cpu_mtime_get(cpu); + + /* Set a 10 cycle timer */ + __metal_driver_cpu_mtimecmp_set(cpu, time + 10); +} + +/* The metal_external_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_EXT].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_EXT].handler(METAL_INTERRUPT_ID_EXT, priv); + } +} + +void __metal_exception_handler(void) __attribute__((interrupt, aligned(128))); +void __metal_exception_handler (void) { + int id; + void *priv; + uintptr_t mcause, mepc, mtval, mtvec; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); + __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); + __asm__ volatile ("csrr %0, mtval" : "=r"(mtval)); + __asm__ volatile ("csrr %0, mtvec" : "=r"(mtvec)); + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + id = mcause & METAL_MCAUSE_CAUSE; + if (mcause & METAL_MCAUSE_INTR) { + if ((id < METAL_INTERRUPT_ID_CSW) || + ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) { + priv = intc->metal_int_table[id].exint_data; + intc->metal_int_table[id].handler(id, priv); + return; + } + if ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_CLIC) { + uintptr_t mtvt; + metal_interrupt_handler_t mtvt_handler; + + __asm__ volatile ("csrr %0, 0x307" : "=r"(mtvt)); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; + mtvt_handler = (metal_interrupt_handler_t)*(uintptr_t *)mtvt; + mtvt_handler(id, priv); + return; + } + } else { + intc->metal_exception_table[id]((struct metal_cpu *)cpu, id); + } + } +} + +/* The metal_lc0_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC0].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC0].handler(METAL_INTERRUPT_ID_LC0, priv); + } +} + +/* The metal_lc1_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC1].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC1].handler(METAL_INTERRUPT_ID_LC1, priv); + } +} + +/* The metal_lc2_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC2].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC2].handler(METAL_INTERRUPT_ID_LC2, priv); + } +} + +/* The metal_lc3_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC3].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC3].handler(METAL_INTERRUPT_ID_LC3, priv); + } +} + +/* The metal_lc4_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC4].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC4].handler(METAL_INTERRUPT_ID_LC4, priv); + } +} + +/* The metal_lc5_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC5].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC5].handler(METAL_INTERRUPT_ID_LC5, priv); + } +} + +/* The metal_lc6_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC6].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC6].handler(METAL_INTERRUPT_ID_LC6, priv); + } +} + +/* The metal_lc7_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC7].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC7].handler(METAL_INTERRUPT_ID_LC7, priv); + } +} + +/* The metal_lc8_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC8].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC8].handler(METAL_INTERRUPT_ID_LC8, priv); + } +} + +/* The metal_lc9_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC9].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC9].handler(METAL_INTERRUPT_ID_LC9, priv); + } +} + +/* The metal_lc10_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC10].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC10].handler(METAL_INTERRUPT_ID_LC10, priv); + } +} + +/* The metal_lc11_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC11].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC11].handler(METAL_INTERRUPT_ID_LC11, priv); + } +} + +/* The metal_lc12_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC12].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC12].handler(METAL_INTERRUPT_ID_LC12, priv); + } +} + +/* The metal_lc13_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC13].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC13].handler(METAL_INTERRUPT_ID_LC13, priv); + } +} + +/* The metal_lc14_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC14].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC14].handler(METAL_INTERRUPT_ID_LC14, priv); + } +} + +/* The metal_lc15_interrupt_vector_handler() function can be redefined. */ +void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler (void) { + void *priv; + struct __metal_driver_riscv_cpu_intc *intc; + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; + + if ( cpu ) { + intc = (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC15].exint_data; + intc->metal_int_table[METAL_INTERRUPT_ID_LC15].handler(METAL_INTERRUPT_ID_LC15, priv); + } +} + +metal_vector_mode __metal_controller_interrupt_vector_mode (void) +{ + uintptr_t val; + + asm volatile ("csrr %0, mtvec" : "=r"(val)); + val &= METAL_MTVEC_MASK; + + switch (val) { + case METAL_MTVEC_CLIC: + return METAL_SELECTIVE_VECTOR_MODE; + case METAL_MTVEC_CLIC_VECTORED: + return METAL_HARDWARE_VECTOR_MODE; + case METAL_MTVEC_VECTORED: + return METAL_VECTOR_MODE; + } + return METAL_DIRECT_MODE; +} + +void __metal_controller_interrupt_vector (metal_vector_mode mode, void *vec_table) +{ + uintptr_t trap_entry, val; + + __asm__ volatile ("csrr %0, mtvec" : "=r"(val)); + val &= ~(METAL_MTVEC_CLIC_VECTORED | METAL_MTVEC_CLIC_RESERVED); + trap_entry = (uintptr_t)vec_table; + + switch (mode) { + case METAL_SELECTIVE_NONVECTOR_MODE: + case METAL_SELECTIVE_VECTOR_MODE: + __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); + __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC)); + break; + case METAL_HARDWARE_VECTOR_MODE: + __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); + __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC_VECTORED)); + break; + case METAL_VECTOR_MODE: + __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry | METAL_MTVEC_VECTORED)); + break; + case METAL_DIRECT_MODE: + __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED)); + break; + } +} + +int __metal_valid_interrupt_id (int id) +{ + switch (id) { + case METAL_INTERRUPT_ID_SW: + case METAL_INTERRUPT_ID_TMR: + case METAL_INTERRUPT_ID_EXT: + case METAL_INTERRUPT_ID_LC0: + case METAL_INTERRUPT_ID_LC1: + case METAL_INTERRUPT_ID_LC2: + case METAL_INTERRUPT_ID_LC3: + case METAL_INTERRUPT_ID_LC4: + case METAL_INTERRUPT_ID_LC5: + case METAL_INTERRUPT_ID_LC6: + case METAL_INTERRUPT_ID_LC7: + case METAL_INTERRUPT_ID_LC8: + case METAL_INTERRUPT_ID_LC9: + case METAL_INTERRUPT_ID_LC10: + case METAL_INTERRUPT_ID_LC11: + case METAL_INTERRUPT_ID_LC12: + case METAL_INTERRUPT_ID_LC13: + case METAL_INTERRUPT_ID_LC14: + case METAL_INTERRUPT_ID_LC15: + return 1; + default: + break; + } + + return 0; +} + + +int __metal_local_interrupt_enable (struct metal_interrupt *controller, + metal_interrupt_id_e id, int enable) +{ + int rc = 0; + + if ( !controller) { + return -1; + } + + switch (id) { + case METAL_INTERRUPT_ID_BASE: + if (enable) { + __metal_interrupt_global_enable(); + } else { + __metal_interrupt_global_disable(); + } + break; + case METAL_INTERRUPT_ID_SW: + if (enable) { + __metal_interrupt_software_enable(); + } else { + __metal_interrupt_software_disable(); + } + break; + case METAL_INTERRUPT_ID_TMR: + if (enable) { + __metal_interrupt_timer_enable(); + } else { + __metal_interrupt_timer_disable(); + } + break; + case METAL_INTERRUPT_ID_EXT: + if (enable) { + __metal_interrupt_external_enable(); + } else { + __metal_interrupt_external_disable(); + } + break; + case METAL_INTERRUPT_ID_LC0: + case METAL_INTERRUPT_ID_LC1: + case METAL_INTERRUPT_ID_LC2: + case METAL_INTERRUPT_ID_LC3: + case METAL_INTERRUPT_ID_LC4: + case METAL_INTERRUPT_ID_LC5: + case METAL_INTERRUPT_ID_LC6: + case METAL_INTERRUPT_ID_LC7: + case METAL_INTERRUPT_ID_LC8: + case METAL_INTERRUPT_ID_LC9: + case METAL_INTERRUPT_ID_LC10: + case METAL_INTERRUPT_ID_LC11: + case METAL_INTERRUPT_ID_LC12: + case METAL_INTERRUPT_ID_LC13: + case METAL_INTERRUPT_ID_LC14: + case METAL_INTERRUPT_ID_LC15: + if (enable) { + __metal_interrupt_local_enable(id); + } else { + __metal_interrupt_local_disable(id); + } + break; + default: + rc = -1; + } + return rc; +} + +int __metal_exception_register (struct metal_interrupt *controller, + int ecode, metal_exception_handler_t isr) +{ + struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); + + if ((ecode < METAL_MAX_EXCEPTION_CODE) && isr) { + intc->metal_exception_table[ecode] = isr; + return 0; + } + return -1; +} + +void __metal_driver_riscv_cpu_controller_interrupt_init (struct metal_interrupt *controller) +{ + struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); + uintptr_t val; + + if ( !intc->init_done ) { + /* Disable and clear all interrupt sources */ + __asm__ volatile ("csrc mie, %0" :: "r"(-1)); + __asm__ volatile ("csrc mip, %0" :: "r"(-1)); + + /* Read the misa CSR to determine if the delegation registers exist */ + uintptr_t misa; + __asm__ volatile ("csrr %0, misa" : "=r" (misa)); + + /* The delegation CSRs exist if user mode interrupts (N extension) or + * supervisor mode (S extension) are supported */ + if((misa & METAL_ISA_N_EXTENSIONS) || (misa & METAL_ISA_S_EXTENSIONS)) { + /* Disable interrupt and exception delegation */ + __asm__ volatile ("csrc mideleg, %0" :: "r"(-1)); + __asm__ volatile ("csrc medeleg, %0" :: "r"(-1)); + } + + /* The satp CSR exists if supervisor mode (S extension) is supported */ + if(misa & METAL_ISA_S_EXTENSIONS) { + /* Clear the entire CSR to make sure that satp.MODE = 0 */ + __asm__ volatile ("csrc satp, %0" :: "r"(-1)); + } + + /* Default to use direct interrupt, setup sw cb table*/ + for (int i = 0; i < METAL_MAX_MI; i++) { + intc->metal_int_table[i].handler = NULL; + intc->metal_int_table[i].sub_int = NULL; + intc->metal_int_table[i].exint_data = NULL; + } + for (int i = 0; i < METAL_MAX_ME; i++) { + intc->metal_exception_table[i] = __metal_default_exception_handler; + } + __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); + __asm__ volatile ("csrr %0, misa" : "=r"(val)); + if (val & (METAL_ISA_D_EXTENSIONS | METAL_ISA_F_EXTENSIONS | METAL_ISA_Q_EXTENSIONS)) { + /* Floating point architecture, so turn on FP register saving*/ + __asm__ volatile ("csrr %0, mstatus" : "=r"(val)); + __asm__ volatile ("csrw mstatus, %0" :: "r"(val | METAL_MSTATUS_FS_INIT)); + } + intc->init_done = 1; + } +} + +int __metal_driver_riscv_cpu_controller_interrupt_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = 0; + struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); + + if ( !__metal_valid_interrupt_id(id) ) { + return -11; + } + + if (isr) { + intc->metal_int_table[id].handler = isr; + intc->metal_int_table[id].exint_data = priv; + } else { + switch (id) { + case METAL_INTERRUPT_ID_SW: + intc->metal_int_table[id].handler = __metal_default_sw_handler; + intc->metal_int_table[id].sub_int = priv; + break; + case METAL_INTERRUPT_ID_TMR: + intc->metal_int_table[id].handler = __metal_default_timer_handler; + intc->metal_int_table[id].sub_int = priv; + break; + case METAL_INTERRUPT_ID_EXT: + case METAL_INTERRUPT_ID_LC0: + case METAL_INTERRUPT_ID_LC1: + case METAL_INTERRUPT_ID_LC2: + case METAL_INTERRUPT_ID_LC3: + case METAL_INTERRUPT_ID_LC4: + case METAL_INTERRUPT_ID_LC5: + case METAL_INTERRUPT_ID_LC6: + case METAL_INTERRUPT_ID_LC7: + case METAL_INTERRUPT_ID_LC8: + case METAL_INTERRUPT_ID_LC9: + case METAL_INTERRUPT_ID_LC10: + case METAL_INTERRUPT_ID_LC11: + case METAL_INTERRUPT_ID_LC12: + case METAL_INTERRUPT_ID_LC13: + case METAL_INTERRUPT_ID_LC14: + case METAL_INTERRUPT_ID_LC15: + intc->metal_int_table[id].handler = __metal_default_interrupt_handler; + intc->metal_int_table[id].sub_int = priv; + break; + default: + rc = -12; + } + } + return rc; +} + +int __metal_driver_riscv_cpu_controller_interrupt_enable (struct metal_interrupt *controller, + int id) +{ + return __metal_local_interrupt_enable(controller, id, METAL_ENABLE); +} + +int __metal_driver_riscv_cpu_controller_interrupt_disable (struct metal_interrupt *controller, + int id) +{ + return __metal_local_interrupt_enable(controller, id, METAL_DISABLE); +} + +int __metal_driver_riscv_cpu_controller_interrupt_enable_vector(struct metal_interrupt *controller, + int id, metal_vector_mode mode) +{ + struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); + + if (id == METAL_INTERRUPT_ID_BASE) { + if (mode == METAL_DIRECT_MODE) { + __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); + return 0; + } + if (mode == METAL_VECTOR_MODE) { + __metal_controller_interrupt_vector(mode, (void *)&intc->metal_mtvec_table); + return 0; + } + } + return -1; +} + +int __metal_driver_riscv_cpu_controller_interrupt_disable_vector(struct metal_interrupt *controller, + int id) +{ + if (id == METAL_INTERRUPT_ID_BASE) { + __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); + return 0; + } + return -1; +} + +metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode (struct metal_interrupt *controller) +{ + return __metal_controller_interrupt_vector_mode(); +} + +int __metal_driver_riscv_cpu_controller_set_vector_mode (struct metal_interrupt *controller, + metal_vector_mode mode) +{ + struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); + ( void ) intc; + + if (mode == METAL_DIRECT_MODE) { + __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); + return 0; + } + if (mode == METAL_VECTOR_MODE) { + __metal_controller_interrupt_vector(mode, (void *)__metal_vector_table); + return 0; + } + return -1; +} + +int __metal_driver_riscv_cpu_controller_command_request (struct metal_interrupt *controller, + int cmd, void *data) +{ + /* NOP for now, unless local interrupt lines the like of clic, clint, plic */ + return 0; +} + +/* CPU driver !!! */ + +unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu) +{ + unsigned long long val = 0; + +#if __riscv_xlen == 32 + unsigned long hi, hi1, lo; + + __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi)); + __asm__ volatile ("csrr %0, mcycle" : "=r"(lo)); + __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi1)); + if (hi == hi1) { + val = ((unsigned long long)hi << 32) | lo; + } +#else + __asm__ volatile ("csrr %0, mcycle" : "=r"(val)); +#endif + + return val; +} + +unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) +{ + int timebase; + if (!cpu) { + return 0; + } + + timebase = __metal_driver_cpu_timebase((struct metal_cpu *)cpu); + return timebase; +} + +unsigned long long __metal_driver_cpu_mtime_get (struct metal_cpu *cpu) +{ + unsigned long long time = 0; + struct metal_interrupt *tmr_intc; + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; + if (tmr_intc) { + tmr_intc->vtable->command_request(tmr_intc, + METAL_TIMER_MTIME_GET, &time); + } + } + return time; +} + +int __metal_driver_cpu_mtimecmp_set (struct metal_cpu *cpu, unsigned long long time) +{ + int rc = -1; + struct metal_interrupt *tmr_intc; + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; + if (tmr_intc) { + rc = tmr_intc->vtable->mtimecmp_set(tmr_intc, + __metal_driver_cpu_hartid(cpu), + time); + } + } + return rc; +} + +struct metal_interrupt * +__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) +{ +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + return __METAL_DT_RISCV_CLINT0_HANDLE; +#else +#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE + return __METAL_DT_SIFIVE_CLIC0_HANDLE; +#else +#pragma message("There is no interrupt controller for Timer interrupt") + return NULL; +#endif +#endif +} + +int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu) +{ + return METAL_INTERRUPT_ID_TMR; +} + +struct metal_interrupt * +__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) +{ +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + return __METAL_DT_RISCV_CLINT0_HANDLE; +#else +#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE + return __METAL_DT_SIFIVE_CLIC0_HANDLE; +#else +#pragma message("There is no interrupt controller for Software interrupt") + return NULL; +#endif +#endif +} + +int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu) +{ + return METAL_INTERRUPT_ID_SW; +} + +int __metal_driver_cpu_set_sw_ipi (struct metal_cpu *cpu, int hartid) +{ + int rc = -1; + struct metal_interrupt *sw_intc; + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; + if (sw_intc) { + rc = sw_intc->vtable->command_request(sw_intc, + METAL_SOFTWARE_IPI_SET, &hartid); + } + } + return rc; +} + +int __metal_driver_cpu_clear_sw_ipi (struct metal_cpu *cpu, int hartid) +{ + int rc = -1; + struct metal_interrupt *sw_intc; + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; + if (sw_intc) { + rc = sw_intc->vtable->command_request(sw_intc, + METAL_SOFTWARE_IPI_CLEAR, &hartid); + } + } + return rc; +} + +int __metal_driver_cpu_get_msip (struct metal_cpu *cpu, int hartid) +{ + int rc = 0; + struct metal_interrupt *sw_intc; + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; + if (sw_intc) { + rc = sw_intc->vtable->command_request(sw_intc, + METAL_SOFTWARE_MSIP_GET, &hartid); + } + } + return rc; +} + +struct metal_interrupt * +__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu) +{ + return __metal_driver_cpu_interrupt_controller(cpu); +} + +int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv) +{ + if ( __metal_driver_cpu_interrupt_controller(cpu) ) { + /* Only support machine mode for now */ + __metal_interrupt_global_enable(); + return 0; + } + return -1; +} + +int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv) +{ + if ( __metal_driver_cpu_interrupt_controller(cpu) ) { + /* Only support machine mode for now */ + __metal_interrupt_global_disable(); + return 0; + } + return -1; +} + +int __metal_driver_cpu_exception_register(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t isr) +{ + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + + if (intc) { + return __metal_exception_register((struct metal_interrupt *)intc, ecode, isr); + } + return -1; +} + +int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc) +{ + /** + * Per ISA compressed instruction has last two bits of opcode set. + * The encoding '00' '01' '10' are used for compressed instruction. + * Only enconding '11' isn't regarded as compressed instruction (>16b). + */ + return ((*(unsigned short*)epc & METAL_INSN_LENGTH_MASK) + == METAL_INSN_NOT_COMPRESSED) ? 4 : 2; +} + +uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu) +{ + uintptr_t mepc; + __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); + return mepc; +} + +int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc) +{ + __asm__ volatile ("csrw mepc, %0" :: "r"(mepc)); + return 0; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) = { + .controller_vtable.interrupt_init = __metal_driver_riscv_cpu_controller_interrupt_init, + .controller_vtable.interrupt_register = __metal_driver_riscv_cpu_controller_interrupt_register, + .controller_vtable.interrupt_enable = __metal_driver_riscv_cpu_controller_interrupt_enable, + .controller_vtable.interrupt_disable = __metal_driver_riscv_cpu_controller_interrupt_disable, + .controller_vtable.interrupt_get_vector_mode = __metal_driver_riscv_cpu_controller_get_vector_mode, + .controller_vtable.interrupt_set_vector_mode = __metal_driver_riscv_cpu_controller_set_vector_mode, + .controller_vtable.command_request = __metal_driver_riscv_cpu_controller_command_request, +}; + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = { + .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get, + .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get, + .cpu_vtable.mtime_get = __metal_driver_cpu_mtime_get, + .cpu_vtable.mtimecmp_set = __metal_driver_cpu_mtimecmp_set, + .cpu_vtable.tmr_controller_interrupt = __metal_driver_cpu_timer_controller_interrupt, + .cpu_vtable.get_tmr_interrupt_id = __metal_driver_cpu_get_timer_interrupt_id, + .cpu_vtable.sw_controller_interrupt = __metal_driver_cpu_sw_controller_interrupt, + .cpu_vtable.get_sw_interrupt_id = __metal_driver_cpu_get_sw_interrupt_id, + .cpu_vtable.set_sw_ipi = __metal_driver_cpu_set_sw_ipi, + .cpu_vtable.clear_sw_ipi = __metal_driver_cpu_clear_sw_ipi, + .cpu_vtable.get_msip = __metal_driver_cpu_get_msip, + .cpu_vtable.controller_interrupt = __metal_driver_cpu_controller_interrupt, + .cpu_vtable.exception_register = __metal_driver_cpu_exception_register, + .cpu_vtable.get_ilen = __metal_driver_cpu_get_instruction_length, + .cpu_vtable.get_epc = __metal_driver_cpu_get_exception_pc, + .cpu_vtable.set_epc = __metal_driver_cpu_set_exception_pc, +}; + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c new file mode 100644 index 000000000..3272f1c66 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c @@ -0,0 +1,195 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_RISCV_PLIC0 + +#include +#include +#include +#include + +unsigned int __metal_plic0_claim_interrupt (struct __metal_driver_riscv_plic0 *plic) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_CLAIM)); +} + +void __metal_plic0_complete_interrupt(struct __metal_driver_riscv_plic0 *plic, + unsigned int id) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_CLAIM)) = id; +} + +int __metal_plic0_set_threshold(struct metal_interrupt *controller, unsigned int threshold) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_THRESHOLD)) = threshold; + return 0; +} + +unsigned int __metal_plic0_get_threshold(struct metal_interrupt *controller) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); + + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_THRESHOLD)); +} + +int __metal_plic0_set_priority(struct metal_interrupt *controller, int id, unsigned int priority) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)controller); + unsigned int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)controller); + if ( (max_priority) && (priority < max_priority) ) { + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_PRIORITY_BASE + + (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = priority; + return 0; + } + return -1; +} + +unsigned int __metal_plic0_get_priority(struct metal_interrupt *controller, int id) +{ + unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); + + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_PRIORITY_BASE + + (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))); +} + +void __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, int id, int enable) +{ + unsigned int current; + unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); + + current = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_ENABLE_BASE + + (id >> METAL_PLIC_SOURCE_SHIFT) * 4)); + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_PLIC0_ENABLE_BASE + + ((id >> METAL_PLIC_SOURCE_SHIFT) * 4))) = + enable ? (current | (1 << (id & METAL_PLIC_SOURCE_MASK))) + : (current & ~(1 << (id & METAL_PLIC_SOURCE_MASK))); +} + +void __metal_plic0_default_handler (int id, void *priv) { + metal_shutdown(300); +} + +void __metal_plic0_handler (int id, void *priv) +{ + struct __metal_driver_riscv_plic0 *plic = priv; + unsigned int idx = __metal_plic0_claim_interrupt(plic); + unsigned int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic); + + if ( (idx < num_interrupts) && (plic->metal_exint_table[idx]) ) { + plic->metal_exint_table[idx](idx, + plic->metal_exdata_table[idx].exint_data); + } + + __metal_plic0_complete_interrupt(plic, idx); +} + +void __metal_driver_riscv_plic0_init (struct metal_interrupt *controller) +{ + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if ( !plic->init_done ) { + int num_interrupts, line; + struct metal_interrupt *intc; + + for(int parent = 0; parent < __METAL_PLIC_NUM_PARENTS; parent++) { + num_interrupts = __metal_driver_sifive_plic0_num_interrupts(controller); + intc = __metal_driver_sifive_plic0_interrupt_parents(controller, parent); + line = __metal_driver_sifive_plic0_interrupt_lines(controller, parent); + + /* Initialize ist parent controller, aka cpu_intc. */ + intc->vtable->interrupt_init(intc); + + for (int i = 0; i < num_interrupts; i++) { + __metal_plic0_enable(plic, i, METAL_DISABLE); + __metal_plic0_set_priority(controller, i, 0); + plic->metal_exint_table[i] = NULL; + plic->metal_exdata_table[i].sub_int = NULL; + plic->metal_exdata_table[i].exint_data = NULL; + } + + __metal_plic0_set_threshold(controller, 0); + + /* Register plic (ext) interrupt with with parent controller */ + intc->vtable->interrupt_register(intc, line, NULL, plic); + /* Register plic handler for dispatching its device interrupts */ + intc->vtable->interrupt_register(intc, line, __metal_plic0_handler, plic); + /* Enable plic (ext) interrupt with with parent controller */ + intc->vtable->interrupt_enable(intc, line); + } + plic->init_done = 1; + } +} + +int __metal_driver_riscv_plic0_register (struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { + return -1; + } + + if (isr) { + __metal_plic0_set_priority(controller, id, 2); + plic->metal_exint_table[id] = isr; + plic->metal_exdata_table[id].exint_data = priv; + } else { + __metal_plic0_set_priority(controller, id, 1); + plic->metal_exint_table[id] = __metal_plic0_default_handler; + plic->metal_exdata_table[id].sub_int = priv; + } + + return 0; +} + +int __metal_driver_riscv_plic0_enable (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { + return -1; + } + + __metal_plic0_enable(plic, id, METAL_ENABLE); + return 0; +} + +int __metal_driver_riscv_plic0_disable (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { + return -1; + } + __metal_plic0_enable(plic, id, METAL_DISABLE); + return 0; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_plic0) = { + .plic_vtable.interrupt_init = __metal_driver_riscv_plic0_init, + .plic_vtable.interrupt_register = __metal_driver_riscv_plic0_register, + .plic_vtable.interrupt_enable = __metal_driver_riscv_plic0_enable, + .plic_vtable.interrupt_disable = __metal_driver_riscv_plic0_disable, + .plic_vtable.interrupt_get_threshold = __metal_plic0_get_threshold, + .plic_vtable.interrupt_set_threshold = __metal_plic0_set_threshold, + .plic_vtable.interrupt_get_priority = __metal_plic0_get_priority, + .plic_vtable.interrupt_set_priority = __metal_plic0_set_priority, +}; + +#endif /* METAL_RISCV_PLIC0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c new file mode 100644 index 000000000..6f8723735 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c @@ -0,0 +1,84 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_CCACHE0 + +#include +#include +#include +#include + +#define L2_CONFIG_WAYS_SHIFT 8 +#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) + +void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways); + +static void metal_driver_sifive_ccache0_init(void) __attribute__((constructor)); +static void metal_driver_sifive_ccache0_init(void) +{ +#ifdef __METAL_DT_SIFIVE_CCACHE0_HANDLE + /* Get the handle for the L2 cache controller */ + struct metal_cache *l2 = __METAL_DT_SIFIVE_CCACHE0_HANDLE; + if(!l2) { + return; + } + + /* Get the number of available ways per bank */ + unsigned long control_base = __metal_driver_sifive_ccache0_control_base(l2); + uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_CONFIG)); + ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); + + /* Enable all the ways */ + __metal_driver_sifive_ccache0_init(l2, ways); +#endif +} + +void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways) +{ + metal_cache_set_enabled_ways(l2, ways); +} + +int __metal_driver_sifive_ccache0_get_enabled_ways(struct metal_cache *cache) +{ + unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); + + uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)); + + /* The stored number is the index, so add one */ + return (0xFF & way_enable) + 1; +} + +int __metal_driver_sifive_ccache0_set_enabled_ways(struct metal_cache *cache, int ways) +{ + unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); + + /* We can't decrease the number of enabled ways */ + if(metal_cache_get_enabled_ways(cache) > ways) { + return -2; + } + + /* The stored value is the index, so subtract one */ + uint32_t value = 0xFF & (ways - 1); + + /* Set the number of enabled ways */ + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)) = value; + + /* Make sure the number of ways was set correctly */ + if(metal_cache_get_enabled_ways(cache) != ways) { + return -3; + } + + return 0; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_ccache0) = { + .cache.init = __metal_driver_sifive_ccache0_init, + .cache.get_enabled_ways = __metal_driver_sifive_ccache0_get_enabled_ways, + .cache.set_enabled_ways = __metal_driver_sifive_ccache0_set_enabled_ways, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c new file mode 100644 index 000000000..12c3dac06 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c @@ -0,0 +1,736 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_CLIC0 + +#include +#include +#include +#include +#include + +typedef enum metal_clic_vector_{ + METAL_CLIC_NONVECTOR = 0, + METAL_CLIC_VECTORED = 1 +} metal_clic_vector; + +struct __metal_clic_cfg { + unsigned char : 1, + nmbits : 2, + nlbits : 4, + nvbit : 1; +}; + +const struct __metal_clic_cfg __metal_clic_defaultcfg = { + .nmbits = METAL_INTR_PRIV_M_MODE, + .nlbits = 0, + .nvbit = METAL_CLIC_NONVECTOR + }; + +void __metal_clic0_handler(int id, void *priv) __attribute__((aligned(64))); + +void __metal_clic0_default_vector_handler (void) __attribute__((interrupt, aligned(64))); + +struct __metal_clic_cfg __metal_clic0_configuration (struct __metal_driver_sifive_clic0 *clic, + struct __metal_clic_cfg *cfg) +{ + volatile unsigned char val; + struct __metal_clic_cfg cliccfg; + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + + if ( cfg ) { + val = cfg->nmbits << 5 | cfg->nlbits << 1 | cfg->nvbit; + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICCFG)) = val; + } + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICCFG)); + cliccfg.nmbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK) >> 5; + cliccfg.nlbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK) >> 1; + cliccfg.nvbit = val & METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK; + return cliccfg; +} + +int __metal_clic0_interrupt_set_mode (struct __metal_driver_sifive_clic0 *clic, int id, int mode) +{ + uint8_t mask, val; + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + + if (mode >= (cfg.nmbits << 1)) { + /* Do nothing, mode request same or exceed what configured in CLIC */ + return 0; + } + + /* Mask out nmbits and retain other values */ + mask = ((uint8_t)(-1)) >> cfg.nmbits; + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) & mask; + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = val | (mode << (8 - cfg.nmbits)); + return 0; +} + +int __metal_clic0_interrupt_set_level (struct __metal_driver_sifive_clic0 *clic, int id, unsigned int level) +{ + uint8_t mask, nmmask, nlmask, val; + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + + /* Drop the LSBs that don't fit in nlbits */ + level = level >> (METAL_CLIC_MAX_NLBITS - cfg.nlbits); + + nmmask = ~( ((uint8_t)(-1)) >> (cfg.nmbits) ); + nlmask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits); + mask = ~(nlmask | nmmask); + + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, level); + return 0; +} + +unsigned int __metal_clic0_interrupt_get_level (struct __metal_driver_sifive_clic0 *clic, int id) +{ + int level; + uint8_t mask, val, freebits, nlbits; + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + + if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { + nlbits = num_intbits - cfg.nmbits; + } else { + nlbits = cfg.nlbits; + } + + mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); + freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; + + if (mask == 0) { + level = (1 << METAL_CLIC_MAX_NLBITS) - 1; + } else { + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + val = __METAL_GET_FIELD(val, mask); + level = (val << (METAL_CLIC_MAX_NLBITS - nlbits)) | freebits; + } + + return level; +} + +int __metal_clic0_interrupt_set_priority (struct __metal_driver_sifive_clic0 *clic, int id, int priority) +{ + uint8_t mask, npmask, val, npbits; + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + + if ((cfg.nmbits + cfg.nlbits) < num_intbits) { + npbits = num_intbits - (cfg.nmbits + cfg.nlbits); + priority = priority >> (8 - npbits); + + mask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits + npbits); + npmask = ~(((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits)); + mask = ~(mask | npmask); + + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, priority); + } + return 0; +} + +int __metal_clic0_interrupt_get_priority (struct __metal_driver_sifive_clic0 *clic, int id) +{ + int priority; + uint8_t mask, val, freebits, nlbits; + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + + if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { + nlbits = num_intbits - cfg.nmbits; + } else { + nlbits = cfg.nlbits; + } + + mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); + freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; + + if (mask == 0) { + priority = (1 << METAL_CLIC_MAX_NLBITS) - 1; + } else { + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + priority = __METAL_GET_FIELD(val, freebits); + } + return priority; +} + +int __metal_clic0_interrupt_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, int id, int enable) +{ + uint8_t mask, val; + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + + mask = 1 << (8 - num_intbits); + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + /* Ensure its value is 1 bit wide */ + enable &= 0x1; + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, enable); + return 0; +} + +int __metal_clic0_interrupt_is_vectored (struct __metal_driver_sifive_clic0 *clic, int id) +{ + uint8_t mask, val; + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + + mask = 1 << (8 - num_intbits); + val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + return __METAL_GET_FIELD(val, mask); +} + +int __metal_clic0_interrupt_enable (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id >= num_subinterrupts) { + return -1; + } + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_ENABLE; + return 0; +} + +int __metal_clic0_interrupt_disable (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id >= num_subinterrupts) { + return -1; + } + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_DISABLE; + return 0; +} + +int __metal_clic0_interrupt_is_enabled (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id >= num_subinterrupts) { + return 0; + } + return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)); +} + +int __metal_clic0_interrupt_is_pending (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id >= num_subinterrupts) { + return 0; + } + return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)); +} + +int __metal_clic0_interrupt_set (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id < num_subinterrupts) { + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_ENABLE; + return 0; + } + return -1; +} + +int __metal_clic0_interrupt_clear (struct __metal_driver_sifive_clic0 *clic, int id) +{ + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if (id < num_subinterrupts) { + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_DISABLE; + return 0; + } + return -1; +} + +int __metal_clic0_configure_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, metal_vector_mode mode) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + + switch (mode) { + case METAL_SELECTIVE_NONVECTOR_MODE: + cfg.nvbit = METAL_CLIC_NONVECTOR; + __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); + break; + case METAL_SELECTIVE_VECTOR_MODE: + cfg.nvbit = METAL_CLIC_VECTORED; + __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); + break; + case METAL_HARDWARE_VECTOR_MODE: + cfg.nvbit = METAL_CLIC_VECTORED; + __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); + break; + default: + return -1; + } + __metal_clic0_configuration(clic, &cfg); + return 0; +} + +metal_vector_mode __metal_clic0_configure_get_vector_mode (struct __metal_driver_sifive_clic0 *clic) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); + + if (mode == METAL_SELECTIVE_VECTOR_MODE) { + if (cfg.nvbit) { + return METAL_SELECTIVE_VECTOR_MODE; + } else { + return METAL_SELECTIVE_NONVECTOR_MODE; + } + } else { + return mode; + } +} + +int __metal_clic0_configure_set_privilege (struct __metal_driver_sifive_clic0 *clic, metal_intr_priv_mode priv) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + + cfg.nmbits = priv; + __metal_clic0_configuration(clic, &cfg); + return 0; +} + +metal_intr_priv_mode __metal_clic0_configure_get_privilege (struct __metal_driver_sifive_clic0 *clic) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + + return cfg.nmbits; +} + +int __metal_clic0_configure_set_level (struct __metal_driver_sifive_clic0 *clic, int level) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + + cfg.nlbits = level & 0xF; + __metal_clic0_configuration(clic, &cfg); + return 0; +} + +int __metal_clic0_configure_get_level (struct __metal_driver_sifive_clic0 *clic) +{ + struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); + + return cfg.nlbits; +} + +unsigned long long __metal_clic0_mtime_get (struct __metal_driver_sifive_clic0 *clic) +{ + __metal_io_u32 lo, hi; + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + + /* Guard against rollover when reading */ + do { + hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)); + lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME)); + } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)) != hi); + + return (((unsigned long long)hi) << 32) | lo; +} + +int __metal_driver_sifive_clic0_mtimecmp_set(struct metal_interrupt *controller, + int hartid, + unsigned long long time) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + + unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, + * and are NOT internally latched for multiword transfers. + * Need to be careful about sequencing to avoid triggering + * spurious interrupts: For that set the high word to a max + * value first. + */ + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE)) = (__metal_io_u32)time; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); + return 0; +} + +void __metal_clic0_handler (int id, void *priv) +{ + struct __metal_driver_sifive_clic0 *clic = priv; + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + + if ( (id < num_subinterrupts) && (clic->metal_exint_table[id].handler) ) { + clic->metal_exint_table[id].handler(id, clic->metal_exint_table[id].exint_data); + } +} + +void __metal_clic0_default_handler (int id, void *priv) { + metal_shutdown(300); +} + +void __metal_clic0_default_vector_handler (void) { + metal_shutdown(400); +} + +void __metal_driver_sifive_clic0_init (struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + + if ( !clic->init_done ) { + int level, max_levels, line, num_interrupts, num_subinterrupts; + struct __metal_clic_cfg cfg = __metal_clic_defaultcfg; + struct metal_interrupt *intc = + __metal_driver_sifive_clic0_interrupt_parent(controller); + + /* Initialize ist parent controller, aka cpu_intc. */ + intc->vtable->interrupt_init(intc); + __metal_controller_interrupt_vector(METAL_SELECTIVE_NONVECTOR_MODE, + &clic->metal_mtvt_table); + + /* + * Register its interrupts with with parent controller, + * aka sw, timer and ext to its default isr + */ + num_interrupts = __metal_driver_sifive_clic0_num_interrupts(controller); + for (int i = 0; i < num_interrupts; i++) { + line = __metal_driver_sifive_clic0_interrupt_lines(controller, i); + intc->vtable->interrupt_register(intc, line, NULL, clic); + } + + /* Default CLIC mode to per dts */ + max_levels = __metal_driver_sifive_clic0_max_levels(controller); + cfg.nlbits = (max_levels > METAL_CLIC_MAX_NLBITS) ? + METAL_CLIC_MAX_NLBITS : max_levels; + __metal_clic0_configuration(clic, &cfg); + + level = (1 << cfg.nlbits) - 1; + num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + clic->metal_mtvt_table[0] = &__metal_clic0_handler; + for (int i = 1; i < num_subinterrupts; i++) { + clic->metal_mtvt_table[i] = NULL; + clic->metal_exint_table[i].handler = NULL; + clic->metal_exint_table[i].sub_int = NULL; + clic->metal_exint_table[i].exint_data = NULL; + __metal_clic0_interrupt_disable(clic, i); + __metal_clic0_interrupt_set_level(clic, i, level); + } + clic->init_done = 1; + } +} + +int __metal_driver_sifive_clic0_register (struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = -1; + int num_subinterrupts; + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + struct metal_interrupt *intc = + __metal_driver_sifive_clic0_interrupt_parent(controller); + metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); + + if ( ( (mode == METAL_SELECTIVE_VECTOR_MODE) && + (__metal_clic0_interrupt_is_vectored(clic, id)) ) || + (mode == METAL_HARDWARE_VECTOR_MODE) || + (mode == METAL_VECTOR_MODE) || + (mode == METAL_DIRECT_MODE) ) { + return rc; + } + + /* Register its interrupts with parent controller */ + if (id < METAL_INTERRUPT_ID_CSW) { + return intc->vtable->interrupt_register(intc, id, isr, priv); + } + + /* + * CLIC (sub-interrupts) devices interrupts start at 16 but offset from 0 + * Reset the IDs to reflects this. + */ + num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + if (id < num_subinterrupts) { + if ( isr) { + clic->metal_exint_table[id].handler = isr; + clic->metal_exint_table[id].exint_data = priv; + } else { + clic->metal_exint_table[id].handler = __metal_clic0_default_handler; + clic->metal_exint_table[id].sub_int = priv; + } + rc = 0; + } + return rc; +} + +int __metal_driver_sifive_clic0_vector_register (struct metal_interrupt *controller, + int id, metal_interrupt_vector_handler_t isr, + void *priv) +{ + int rc = -1; + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + struct metal_interrupt *intc = + __metal_driver_sifive_clic0_interrupt_parent(controller); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); + + if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { + return rc; + } + if ((mode == METAL_SELECTIVE_VECTOR_MODE) && + (__metal_clic0_interrupt_is_vectored(clic, id) == 0) ) { + return rc; + } + if (id < num_subinterrupts) { + if ( isr) { + clic->metal_mtvt_table[id] = isr; + clic->metal_exint_table[id].exint_data = priv; + } else { + clic->metal_mtvt_table[id] = __metal_clic0_default_vector_handler; + clic->metal_exint_table[id].sub_int = priv; + } + rc = 0; + } + return rc; +} + +int __metal_driver_sifive_clic0_enable (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_enable(clic, id); +} + +int __metal_driver_sifive_clic0_disable (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_disable(clic, id); +} + +int __metal_driver_sifive_clic0_enable_interrupt_vector(struct metal_interrupt *controller, int id) +{ + int rc = -1; + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); + + if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { + return rc; + } + if (id < num_subinterrupts) { + __metal_clic0_interrupt_set_vector_mode(clic, id, METAL_ENABLE); + return 0; + } + return -1; +} + +int __metal_driver_sifive_clic0_disable_interrupt_vector(struct metal_interrupt *controller, int id) +{ + int num_subinterrupts; + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + + num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + if (id < num_subinterrupts) { + __metal_clic0_interrupt_set_vector_mode(clic, id, METAL_DISABLE); + return 0; + } + return -1; +} + +metal_vector_mode __metal_driver_sifive_clic0_get_vector_mode (struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_get_vector_mode(clic); +} + +int __metal_driver_sifive_clic0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_set_vector_mode(clic, mode); +} + +metal_intr_priv_mode __metal_driver_sifive_clic0_get_privilege (struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_get_privilege(clic); +} + +int __metal_driver_sifive_clic0_set_privilege (struct metal_interrupt *controller, metal_intr_priv_mode priv) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_set_privilege(clic, priv); +} + +unsigned int __metal_driver_sifive_clic0_get_threshold (struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_get_level(clic); +} + +int __metal_driver_sifive_clic0_set_threshold (struct metal_interrupt *controller, unsigned int level) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_configure_set_level(clic, level); +} + +unsigned int __metal_driver_sifive_clic0_get_priority (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_get_priority(clic, id); +} + +int __metal_driver_sifive_clic0_set_priority (struct metal_interrupt *controller, int id, unsigned int priority) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_set_priority(clic, id, priority); +} + +int __metal_driver_sifive_clic0_clear_interrupt (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_clear(clic, id); +} + +int __metal_driver_sifive_clic0_set_interrupt (struct metal_interrupt *controller, int id) +{ + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_set(clic, id); +} + +int __metal_driver_sifive_clic0_command_request (struct metal_interrupt *controller, + int command, void *data) +{ + int hartid; + int rc = -1; + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + unsigned long control_base = __metal_driver_sifive_clic0_control_base(controller); + + switch (command) { + case METAL_TIMER_MTIME_GET: + if (data) { + *(unsigned long long *)data = __metal_clic0_mtime_get(clic); + rc = 0; + } + break; + case METAL_SOFTWARE_IPI_CLEAR: + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))) = METAL_DISABLE; + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_DISABLE; + rc = 0; + } + break; + case METAL_SOFTWARE_IPI_SET: + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))) = METAL_ENABLE; + __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_ENABLE; + rc = 0; + } + break; + case METAL_SOFTWARE_MSIP_GET: + rc = 0; + if (data) { + hartid = *(int *)data; + rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + (hartid * 4))); + } + break; + default: + break; + } + + return rc; +} +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_clic0) = { + .clic_vtable.interrupt_init = __metal_driver_sifive_clic0_init, + .clic_vtable.interrupt_register = __metal_driver_sifive_clic0_register, + .clic_vtable.interrupt_vector_register = __metal_driver_sifive_clic0_vector_register, + .clic_vtable.interrupt_enable = __metal_driver_sifive_clic0_enable, + .clic_vtable.interrupt_disable = __metal_driver_sifive_clic0_disable, + .clic_vtable.interrupt_vector_enable = __metal_driver_sifive_clic0_enable_interrupt_vector, + .clic_vtable.interrupt_vector_disable = __metal_driver_sifive_clic0_disable_interrupt_vector, + .clic_vtable.interrupt_get_vector_mode = __metal_driver_sifive_clic0_get_vector_mode, + .clic_vtable.interrupt_set_vector_mode = __metal_driver_sifive_clic0_set_vector_mode, + .clic_vtable.interrupt_get_privilege = __metal_driver_sifive_clic0_get_privilege, + .clic_vtable.interrupt_set_privilege = __metal_driver_sifive_clic0_set_privilege, + .clic_vtable.interrupt_get_threshold = __metal_driver_sifive_clic0_get_threshold, + .clic_vtable.interrupt_set_threshold = __metal_driver_sifive_clic0_set_threshold, + .clic_vtable.interrupt_get_priority = __metal_driver_sifive_clic0_get_priority, + .clic_vtable.interrupt_set_priority = __metal_driver_sifive_clic0_set_priority, + .clic_vtable.interrupt_clear = __metal_driver_sifive_clic0_clear_interrupt, + .clic_vtable.interrupt_set = __metal_driver_sifive_clic0_set_interrupt, + .clic_vtable.command_request = __metal_driver_sifive_clic0_command_request, + .clic_vtable.mtimecmp_set = __metal_driver_sifive_clic0_mtimecmp_set, +}; + +#endif /* METAL_SIFIVE_CLIC0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c new file mode 100644 index 000000000..61af8d314 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c @@ -0,0 +1,44 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FE310_G000_HFROSC + +#include +#include + +#define CONFIG_DIVIDER 0x0000003FUL +#define CONFIG_TRIM 0x001F0000UL +#define CONFIG_ENABLE 0x40000000UL +#define CONFIG_READY 0x80000000UL + +long __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(const struct metal_clock *clock) +{ + struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfrosc_ref(clock); + long config_offset = __metal_driver_sifive_fe310_g000_hfrosc_config_offset(clock); + struct __metal_driver_sifive_fe310_g000_prci *config_base = + __metal_driver_sifive_fe310_g000_hfrosc_config_base(clock); + const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = + __metal_driver_sifive_fe310_g000_prci_vtable(); + long cfg = vtable->get_reg(config_base, config_offset); + + if ((cfg & CONFIG_ENABLE) == 0) + return -1; + if ((cfg & CONFIG_READY) == 0) + return -1; + return metal_clock_get_rate_hz(ref) / ((cfg & CONFIG_DIVIDER) + 1); +} + +long __metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz(struct metal_clock *clock, long rate) +{ + return __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(clock); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) = { + .clock.get_rate_hz = &__metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz, + .clock.set_rate_hz = &__metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz, +}; +#endif /* METAL_SIFIVE_FE310_G000_HFROSC */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c new file mode 100644 index 000000000..9ed7a0bf3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c @@ -0,0 +1,43 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FE310_G000_HFXOSC + +#include +#include + +#define CONFIG_ENABLE 0x40000000UL +#define CONFIG_READY 0x80000000UL + +long __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(const struct metal_clock *clock) +{ + struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfxosc_ref(clock); + long config_offset = __metal_driver_sifive_fe310_g000_hfxosc_config_offset(clock); + struct __metal_driver_sifive_fe310_g000_prci *config_base = + __metal_driver_sifive_fe310_g000_hfxosc_config_base(clock); + const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = + __metal_driver_sifive_fe310_g000_prci_vtable(); + long cfg = vtable->get_reg(config_base, config_offset); + + if ((cfg & CONFIG_ENABLE) == 0) + return -1; + if ((cfg & CONFIG_READY) == 0) + return -1; + return metal_clock_get_rate_hz(ref); +} + +long __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz(struct metal_clock *clock, long rate) +{ + return __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(clock); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) = { + .clock.get_rate_hz = __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz, + .clock.set_rate_hz = __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz, +}; + +#endif /* METAL_SIFIVE_FE310_G000_HFXOSC */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c new file mode 100644 index 000000000..324382b9d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c @@ -0,0 +1,53 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FE310_G000_LFROSC + +#include +#include + +/* LFROSCCFG */ +#define METAL_LFROSCCFG_DIV_MASK 0x3F +#define METAL_LFROSCCFG_TRIM_SHIFT 16 +#define METAL_LFROSCCFG_TRIM_MASK (0x1F << METAL_LFROSCCFG_TRIM_SHIFT) +#define METAL_LFROSCCFG_EN (1 << 30) +#define METAL_LFROSCCFG_RDY (1 << 31) + +/* LFCLKMUX */ +#define METAL_LFCLKMUX_SEL 1 +#define METAL_LFCLKMUX_EXT_MUX_STATUS (1 << 31) + +#define LFROSC_REGW(addr) (__METAL_ACCESS_ONCE((__metal_io_u32 *)addr)) + +long __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(const struct metal_clock *clock) +{ + struct metal_clock *internal_ref = __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(clock); + struct metal_clock *external_ref = __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(clock); + + unsigned long int cfg_reg = __metal_driver_sifive_fe310_g000_lfrosc_config_reg(clock); + unsigned long int mux_reg = __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(clock); + + if(LFROSC_REGW(mux_reg) & METAL_LFCLKMUX_EXT_MUX_STATUS) { + return metal_clock_get_rate_hz(external_ref); + } + + const unsigned long int div = (LFROSC_REGW(cfg_reg) & METAL_LFROSCCFG_DIV_MASK) + 1; + + return metal_clock_get_rate_hz(internal_ref) / div; +} + +long __metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz(struct metal_clock *clock, long rate) +{ + return __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(clock); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc) = { + .clock.get_rate_hz = &__metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz, + .clock.set_rate_hz = &__metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz, +}; +#endif /* METAL_SIFIVE_FE310_G000_LFROSC */ + +typedef int no_empty_translation_units; + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c new file mode 100644 index 000000000..2ca468f43 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c @@ -0,0 +1,360 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FE310_G000_PLL + +#include +#include + +#include +#include +#include + +#define PLL_R 0x00000007UL +#define PLL_F 0x000003F0UL +#define PLL_Q 0x00000C00UL +#define PLL_SEL 0x00010000UL +#define PLL_REFSEL 0x00020000UL +#define PLL_BYPASS 0x00040000UL +#define PLL_LOCK 0x80000000UL + +#define DIV_DIV 0x0000003FUL +#define DIV_1 0x00000100UL + +#define PLL_R_SHIFT(r) ((r << 0) & PLL_R) +#define PLL_F_SHIFT(f) ((f << 4) & PLL_F) +#define PLL_Q_SHIFT(q) ((q << 10) & PLL_Q) +#define PLL_DIV_SHIFT(d) ((d << 0) & DIV_DIV) + +struct pll_config_t { + unsigned long multiplier; + unsigned long divisor; + unsigned long min_input_rate; + unsigned long max_input_rate; + unsigned long r; + unsigned long f; + unsigned long q; + long d; /* < 0 if disabled */ +}; + +static const struct pll_config_t pll_configs[] = { + /* + * multiplier + * ^ divisor + * | ^ min_input_rate + * | | ^ max_input_rate + * | | | ^ r + * | | | | ^ f + * | | | | | ^ q + * | | | | | | ^ d + * | | | | | | | ^ + * | | | | | | | | */ + { 1, 32, 12000000, 24000000, 1, 31, 3, 63}, + { 1, 32, 24000000, 48000000, 3, 31, 2, 63}, + { 1, 16, 6000000, 12000000, 0, 31, 3, 63}, + { 1, 16, 12000000, 24000000, 1, 31, 2, 63}, + { 1, 16, 24000000, 48000000, 3, 31, 2, 31}, + { 1, 8, 6000000, 12000000, 0, 31, 3, 31}, + { 1, 8, 12000000, 24000000, 1, 31, 2, 31}, + { 1, 8, 24000000, 48000000, 3, 31, 2, 15}, + { 1, 4, 6000000, 12000000, 0, 31, 3, 15}, + { 1, 4, 12000000, 24000000, 1, 31, 2, 15}, + { 1, 4, 24000000, 48000000, 3, 31, 2, 7}, + { 1, 2, 6000000, 12000000, 0, 31, 2, 15}, + { 1, 2, 12000000, 24000000, 1, 31, 1, 15}, + { 1, 2, 24000000, 48000000, 3, 31, 1, 7}, + { 2, 1, 6000000, 12000000, 0, 31, 1, 7}, + { 2, 1, 12000000, 24000000, 1, 31, 1, 3}, + { 2, 1, 24000000, 48000000, 3, 31, 3, -1}, + { 4, 1, 6000000, 12000000, 0, 31, 3, 0}, + { 4, 1, 12000000, 24000000, 1, 31, 3, -1}, + { 4, 1, 24000000, 48000000, 3, 31, 2, -1}, + { 6, 1, 6000000, 10666666, 0, 35, 1, 2}, + { 6, 1, 10666666, 12000000, 0, 23, 3, -1}, + { 6, 1, 12000000, 16000000, 1, 47, 3, -1}, + { 6, 1, 16000000, 18000000, 1, 23, 2, -1}, + { 6, 1, 18000000, 21333333, 2, 35, 2, -1}, + { 8, 1, 6000000, 12000000, 0, 31, 3, -1}, + { 8, 1, 12000000, 24000000, 1, 31, 2, -1}, + { 8, 1, 24000000, 48000000, 3, 31, 1, -1}, + {10, 1, 6000000, 9600000, 0, 39, 3, -1}, + {10, 1, 9600000, 12000000, 0, 19, 2, -1}, + {10, 1, 12000000, 19200000, 1, 39, 2, -1}, + {10, 1, 19200000, 24000000, 1, 19, 1, -1}, + {10, 1, 24000000, 38400000, 3, 39, 1, -1}, + {12, 1, 6000000, 8000000, 0, 47, 3, -1}, + {12, 1, 8000000, 12000000, 0, 23, 2, -1}, + {12, 1, 12000000, 16000000, 1, 47, 2, -1}, + {12, 1, 16000000, 24000000, 1, 23, 1, -1}, + {12, 1, 24000000, 30000000, 3, 47, 1, -1}, + {12, 1, 30000000, 32000000, 3, 47, 1, -1}, + {14, 1, 6000000, 6857142, 0, 55, 3, -1}, + {14, 1, 6857143, 12000000, 0, 27, 2, -1}, + {14, 1, 12000000, 13714285, 1, 55, 2, -1}, + {14, 1, 13714286, 24000000, 1, 27, 1, -1}, + {14, 1, 24000000, 27428571, 3, 55, 1, -1}, + {16, 1, 6000000, 12000000, 0, 31, 2, -1}, + {16, 1, 12000000, 24000000, 1, 31, 1, -1}, + {18, 1, 6000000, 10666666, 0, 35, 2, -1}, + {18, 1, 10666667, 12000000, 0, 17, 1, -1}, + {18, 1, 12000000, 21333333, 1, 35, 1, -1}, + {20, 1, 6000000, 9600000, 0, 39, 2, -1}, + {20, 1, 9600000, 12000000, 0, 19, 1, -1}, + {20, 1, 12000000, 19200000, 1, 39, 1, -1}, + {22, 1, 6000000, 8727272, 0, 43, 2, -1}, + {22, 1, 8727273, 12000000, 0, 21, 1, -1}, + {22, 1, 12000000, 17454545, 1, 43, 1, -1}, + {24, 1, 6000000, 8000000, 0, 47, 2, -1}, + {24, 1, 8000000, 12000000, 0, 23, 1, -1}, + {24, 1, 12000000, 16000000, 1, 47, 1, -1}, + {26, 1, 6000000, 7384615, 0, 51, 2, -1}, + {26, 1, 7384616, 12000000, 0, 25, 1, -1}, + {26, 1, 12000000, 14768230, 1, 51, 1, -1}, + {28, 1, 6000000, 6857142, 0, 55, 2, -1}, + {28, 1, 6857143, 12000000, 0, 27, 1, -1}, + {28, 1, 12000000, 13714285, 1, 55, 1, -1}, + {30, 1, 6000000, 6400000, 0, 59, 2, -1}, + {30, 1, 6400000, 12000000, 0, 29, 1, -1}, + {30, 1, 12000000, 12800000, 1, 59, 1, -1}, + {32, 1, 6000000, 12000000, 0, 31, 1, -1} +}; + +#define PLL_CONFIG_NOT_VALID -1 + +void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll); + +/* Given the rate of the PLL input frequency and a PLL configuration, what + * will the resulting PLL output frequency be? + * Arguments: + * - pll_input_rate the PLL input frequency in hertz + * - config the PLL configuration + * Returns: + * - PLL_CONFIG_NOT_VALID if the configuration is not valid for the input frequency + * - the output frequency, in hertz */ +static long get_pll_config_freq(unsigned long pll_input_rate, const struct pll_config_t *config) +{ + if(pll_input_rate < config->min_input_rate || pll_input_rate > config->max_input_rate) + return PLL_CONFIG_NOT_VALID; + + return pll_input_rate * config->multiplier / config->divisor; +} + +#ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE + +static void metal_sifive_fe310_g000_pll_init(void) __attribute__((constructor)); +static void metal_sifive_fe310_g000_pll_init(void) { + long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); + /* If the PLL init_rate is zero, don't initialize the PLL */ + if(init_rate != 0) + __metal_driver_sifive_fe310_g000_pll_init(__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE); +} + +#endif /* __METAL_DT_SIFIVE_FE310_G000__PLL_HANDLE */ + +void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll) { + struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(&(pll->clock)); + long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); + long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(); + long base = __metal_driver_sifive_fe310_g000_prci_base(); + + __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); + + /* If the PLL clock has had a _pre_rate_change_callback configured, call it */ + _metal_clock_call_all_callbacks(pll->clock._pre_rate_change_callback); + + /* If we're running off of the PLL, switch off before we start configuring it*/ + if((__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) == 0) + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_SEL); + + /* Make sure we're running off of the external oscillator for stability */ + if(pllref != NULL) + __METAL_ACCESS_ONCE(pllcfg) |= PLL_REFSEL; + + /* Configure the PLL to run at the requested init frequency. + * Using the vtable instead of the user API because we want to control + * when the callbacks occur. */ + pll->clock.vtable->set_rate_hz(&(pll->clock), init_rate); + + /* If the PLL clock has had a rate_change_callback configured, call it */ + _metal_clock_call_all_callbacks(pll->clock._post_rate_change_callback); +} + +long __metal_driver_sifive_fe310_g000_pll_get_rate_hz(const struct metal_clock *clock) +{ + struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); + struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); + long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); + struct __metal_driver_sifive_fe310_g000_prci *config_base = + __metal_driver_sifive_fe310_g000_pll_config_base(clock); + long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); + struct __metal_driver_sifive_fe310_g000_prci *divider_base = + __metal_driver_sifive_fe310_g000_pll_divider_base(clock); + const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = + __metal_driver_sifive_fe310_g000_prci_vtable(); + + long cfg = vtable->get_reg(config_base, config_offset); + long div = vtable->get_reg(divider_base, divider_offset); + + /* At the end of the PLL there's one big mux: it either selects the HFROSC + * (bypassing the PLL entirely) or uses the PLL. */ + if (__METAL_GET_FIELD(cfg, PLL_SEL) == 0) + return metal_clock_get_rate_hz(pllsel0); + + /* There's a clock mux before the PLL that selects between the HFROSC adn + * the HFXOSC as the PLL's input clock. */ + long ref_hz = metal_clock_get_rate_hz(__METAL_GET_FIELD(cfg, PLL_REFSEL) ? pllref : pllsel0); + + /* It's possible to bypass the PLL, which is an internal bpyass. This + * still obays the PLL's input clock mu. */ + if (__METAL_GET_FIELD(cfg, PLL_BYPASS)) + return ref_hz; + + /* Logically the PLL is a three stage div-mul-div. */ + long div_r = __METAL_GET_FIELD(cfg, PLL_R) + 1; + long mul_f = 2 * (__METAL_GET_FIELD(cfg, PLL_F) + 1); + if (__METAL_GET_FIELD(cfg, PLL_Q) == 0) + return -1; + long div_q = 1 << __METAL_GET_FIELD(cfg, PLL_Q); + + /* In addition to the dividers inherent in the PLL, there's an additional + * clock divider that lives after the PLL and lets us pick a more + * interesting range of frequencies. */ + long pllout = (((ref_hz / div_r) * mul_f) / div_q); + if (__METAL_GET_FIELD(div, DIV_1)) + return pllout; + + return pllout / (2 * (__METAL_GET_FIELD(div, DIV_DIV) + 1)); +} + +/* Find a valid configuration for the PLL which is closest to the desired + * output frequency. + * Arguments: + * - ref_hz PLL input frequency + * - rate desired PLL output frequency + * Returns: + * -1 if no valid configuration is available + * the index into pll_configs of a valid configuration */ +static int find_closest_config(long ref_hz, long rate) +{ + int closest_index = -1; + long closest_diff = LONG_MAX; + + /* We're probably trying for a fast output frequency, so start from + * the high end of the configs. */ + for(int i = (sizeof(pll_configs) / sizeof(pll_configs[0])) - 1; i >= 0; i--) + { + long config_freq = get_pll_config_freq(ref_hz, &(pll_configs[i])); + if(config_freq != PLL_CONFIG_NOT_VALID) + { + long freq_diff = abs(config_freq - rate); + if(freq_diff < closest_diff) + { + closest_index = i; + closest_diff = freq_diff; + } + } + } + + return closest_index; +} + +/* Configure the PLL and wait for it to lock */ +static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, const struct pll_config_t *config) +{ + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_R); + __METAL_ACCESS_ONCE(pllcfg) |= PLL_R_SHIFT(config->r); + + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_F); + __METAL_ACCESS_ONCE(pllcfg) |= PLL_F_SHIFT(config->f); + + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_Q); + __METAL_ACCESS_ONCE(pllcfg) |= PLL_Q_SHIFT(config->q); + + if(config->d < 0) + { + /* disable final divider */ + __METAL_ACCESS_ONCE(plloutdiv) |= DIV_1; + + __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); + __METAL_ACCESS_ONCE(plloutdiv) |= PLL_DIV_SHIFT(1); + } + else + { + __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_1); + + __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); + __METAL_ACCESS_ONCE(plloutdiv) |= PLL_DIV_SHIFT(config->d); + } + + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_BYPASS); + + /* Wait for PLL to lock */ + while((__METAL_ACCESS_ONCE(pllcfg) & PLL_LOCK) == 0) ; +} + +long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, long rate) +{ + struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); + struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); + long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); + long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); + long base = __metal_driver_sifive_fe310_g000_prci_base(); + + __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); + __metal_io_u32 *plloutdiv = (__metal_io_u32 *) (base + divider_offset); + + /* We can't modify the PLL if coreclk is driven by it, so switch it off */ + if (__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) + __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_SEL); + + /* There's a clock mux before the PLL that selects between the HFROSC and + * the HFXOSC as the PLL's input clock. */ + long ref_hz = metal_clock_get_rate_hz(__METAL_ACCESS_ONCE(pllcfg) & PLL_REFSEL ? pllref : pllsel0); + + /* if the desired rate is within 75%-125% of the input clock, bypass the PLL */ + if((ref_hz * 3 / 4) <= rate && (ref_hz * 5 / 4) >= rate) + { + __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; + } + else + { + int config_index = find_closest_config(ref_hz, rate); + if(config_index != -1) + { + configure_pll(pllcfg, plloutdiv, &(pll_configs[config_index])); + } + else + { + /* unable to find a valid configuration */ + __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; + } + } + + /* Enable the PLL */ + __METAL_ACCESS_ONCE(pllcfg) |= PLL_SEL; + + return __metal_driver_sifive_fe310_g000_pll_get_rate_hz(clock); +} + +#ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE +static void use_hfxosc(void) __attribute__((constructor)); +static void use_hfxosc(void) +{ + long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); + metal_clock_set_rate_hz( + &__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE->clock, init_rate + ); +} +#endif + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) = { + .init = __metal_driver_sifive_fe310_g000_pll_init, + .clock.get_rate_hz = __metal_driver_sifive_fe310_g000_pll_get_rate_hz, + .clock.set_rate_hz = __metal_driver_sifive_fe310_g000_pll_set_rate_hz, +}; + +#endif /* METAL_SIFIVE_FE310_G000_PLL */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c new file mode 100644 index 000000000..1236eca3b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c @@ -0,0 +1,28 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FE310_G000_PRCI + +#include +#include + +long __metal_driver_sifive_fe310_g000_prci_get_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset) { + unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)); +} + +long __metal_driver_sifive_fe310_g000_prci_set_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset, long value) { + unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)) = value; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) = { + .get_reg = __metal_driver_sifive_fe310_g000_prci_get_reg, + .set_reg = __metal_driver_sifive_fe310_g000_prci_set_reg, +}; + +#endif /* METAL_SIFIVE_FE310_G000_PRCI */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c new file mode 100644 index 000000000..aafc6e5e3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c @@ -0,0 +1,84 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_FU540_C000_L2 + +#include +#include +#include +#include + +#define L2_CONFIG_WAYS_SHIFT 8 +#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) + +void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways); + +static void metal_driver_sifive_fu540_c000_l2_init(void) __attribute__((constructor)); +static void metal_driver_sifive_fu540_c000_l2_init(void) +{ +#ifdef __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE + /* Get the handle for the L2 cache controller */ + struct metal_cache *l2 = __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE; + if(!l2) { + return; + } + + /* Get the number of available ways per bank */ + unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(l2); + uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_CONFIG)); + ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); + + /* Enable all the ways */ + __metal_driver_sifive_fu540_c000_l2_init(l2, ways); +#endif +} + +void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways) +{ + metal_cache_set_enabled_ways(l2, ways); +} + +int __metal_driver_sifive_fu540_c000_l2_get_enabled_ways(struct metal_cache *cache) +{ + unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); + + uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)); + + /* The stored number is the index, so add one */ + return (0xFF & way_enable) + 1; +} + +int __metal_driver_sifive_fu540_c000_l2_set_enabled_ways(struct metal_cache *cache, int ways) +{ + unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); + + /* We can't decrease the number of enabled ways */ + if(metal_cache_get_enabled_ways(cache) > ways) { + return -2; + } + + /* The stored value is the index, so subtract one */ + uint32_t value = 0xFF & (ways - 1); + + /* Set the number of enabled ways */ + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)) = value; + + /* Make sure the number of ways was set correctly */ + if(metal_cache_get_enabled_ways(cache) != ways) { + return -3; + } + + return 0; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) = { + .cache.init = __metal_driver_sifive_fu540_c000_l2_init, + .cache.get_enabled_ways = __metal_driver_sifive_fu540_c000_l2_get_enabled_ways, + .cache.set_enabled_ways = __metal_driver_sifive_fu540_c000_l2_set_enabled_ways, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c new file mode 100644 index 000000000..0d56bafef --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c @@ -0,0 +1,169 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0 + +#include +#include +#include +#include + +void __metal_driver_sifive_global_external_interrupt_init(struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_global_external_interrupts0 *global0; + + global0 = (struct __metal_driver_sifive_global_external_interrupts0 *)(controller); + if ( !global0->init_done ) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + intc->vtable->interrupt_init(intc); + /* Register its interrupts with with parent controller */ + for (int i = 0; + i < __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); + i++) { + intc->vtable->interrupt_register(intc, + __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, i), + NULL, controller); + } + global0->init_done = 1; + } + } +} + +int __metal_driver_sifive_global_external_interrupt_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_register(intc, id, isr, priv); + } + } + return rc; +} + +int __metal_driver_sifive_global_external_interrupt_enable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_enable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_global_external_interrupt_disable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_disable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_global_external_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int threshold) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + if (intc) { + return intc->vtable->interrupt_set_threshold(intc, threshold); + } + return -1; +} + +unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struct metal_interrupt *controller) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + return intc->vtable->interrupt_get_threshold(intc); + } + return 0; +} + +int __metal_driver_sifive_global_external_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + if (intc) { + return intc->vtable->interrupt_set_priority(intc, id, priority); + } + return -1; +} + +unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct metal_interrupt *controller, int id) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + return intc->vtable->interrupt_get_priority(intc, id); + } + return 0; +} + +int __metal_driver_sifive_global_external_command_request (struct metal_interrupt *controller, + int command, void *data) +{ + int idx; + int rc = -1; + + switch (command) { + case METAL_MAX_INTERRUPT_GET: + rc = __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); + break; + case METAL_INDEX_INTERRUPT_GET: + rc = 0; + if (data) { + idx = *(int *)data; + rc = __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, idx); + } + break; + default: + break; + } + + return rc; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) = { + .global0_vtable.interrupt_init = __metal_driver_sifive_global_external_interrupt_init, + .global0_vtable.interrupt_register = __metal_driver_sifive_global_external_interrupt_register, + .global0_vtable.interrupt_enable = __metal_driver_sifive_global_external_interrupt_enable, + .global0_vtable.interrupt_disable = __metal_driver_sifive_global_external_interrupt_disable, + .global0_vtable.interrupt_get_threshold = __metal_driver_sifive_global_external_interrupt_get_threshold, + .global0_vtable.interrupt_set_threshold = __metal_driver_sifive_global_external_interrupt_set_threshold, + .global0_vtable.interrupt_get_priority = __metal_driver_sifive_global_external_interrupt_get_priority, + .global0_vtable.interrupt_set_priority = __metal_driver_sifive_global_external_interrupt_set_priority, + .global0_vtable.command_request = __metal_driver_sifive_global_external_command_request, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c new file mode 100644 index 000000000..923fe2711 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c @@ -0,0 +1,57 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GPIO_BUTTONS + +#include +#include +#include +#include + +int __metal_driver_button_exist (struct metal_button *button, char *label) +{ + if (strcmp(__metal_driver_sifive_gpio_button_label(button), label) == 0) { + return 1; + } + return 0; +} + +struct metal_interrupt * +__metal_driver_button_interrupt_controller(struct metal_button *button) +{ + return __metal_driver_sifive_gpio_button_interrupt_controller(button); +} + +int __metal_driver_button_get_interrupt_id(struct metal_button *button) +{ + int irq, max_irq; + struct metal_interrupt *irc; + + irq = __metal_driver_sifive_gpio_button_interrupt_line(button); + irc = __metal_driver_sifive_gpio_button_interrupt_controller(button); + + if (irc != NULL) { + max_irq = _metal_interrupt_command_request(irc, + METAL_MAX_INTERRUPT_GET, + NULL); + + if (irq < max_irq) { + return _metal_interrupt_command_request(irc, + METAL_INDEX_INTERRUPT_GET, + (void *)&irq); + } + } + return METAL_INTERRUPT_ID_LCMX; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_button) = { + .button_vtable.button_exist = __metal_driver_button_exist, + .button_vtable.interrupt_controller = __metal_driver_button_interrupt_controller, + .button_vtable.get_interrupt_id = __metal_driver_button_get_interrupt_id, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c new file mode 100644 index 000000000..a6b627458 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c @@ -0,0 +1,85 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GPIO_LEDS + +#include +#include +#include +#include + +int __metal_driver_led_exist (struct metal_led *led, char *label) +{ + if (strcmp(__metal_driver_sifive_gpio_led_label(led), label) == 0) { + return 1; + } + return 0; +} + +void __metal_driver_led_enable (struct metal_led *led) +{ + int pin; + struct metal_gpio *gpio; + + pin = __metal_driver_sifive_gpio_led_pin(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); + + if (gpio != NULL) { + /* Configure LED as output */ + metal_gpio_disable_input((struct metal_gpio *) gpio, pin); + metal_gpio_enable_output((struct metal_gpio *) gpio, pin); + } +} + +void __metal_driver_led_on (struct metal_led *led) +{ + int pin; + struct metal_gpio *gpio; + + pin = __metal_driver_sifive_gpio_led_pin(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); + + if (gpio != NULL) { + metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 1); + } +} + +void __metal_driver_led_off (struct metal_led *led) +{ + int pin; + struct metal_gpio *gpio; + + pin = __metal_driver_sifive_gpio_led_pin(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); + + if (gpio != NULL) { + metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 0); + } +} + +void __metal_driver_led_toggle (struct metal_led *led) +{ + int pin; + struct metal_gpio *gpio; + + pin = __metal_driver_sifive_gpio_led_pin(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); + + if (gpio != NULL) { + metal_gpio_toggle_pin((struct metal_gpio *) gpio, pin); + } +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_led) = { + .led_vtable.led_exist = __metal_driver_led_exist, + .led_vtable.led_enable = __metal_driver_led_enable, + .led_vtable.led_on = __metal_driver_led_on, + .led_vtable.led_off = __metal_driver_led_off, + .led_vtable.led_toggle = __metal_driver_led_toggle, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c new file mode 100644 index 000000000..fa0a819f1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c @@ -0,0 +1,56 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GPIO_SWITCHES + +#include +#include +#include +#include + +int __metal_driver_switch_exist (struct metal_switch *flip, char *label) +{ + if (strcmp(__metal_driver_sifive_gpio_switch_label(flip), label) == 0) { + return 1; + } + return 0; +} + +struct metal_interrupt * +__metal_driver_switch_interrupt_controller(struct metal_switch *flip) +{ + return __metal_driver_sifive_gpio_switch_interrupt_controller(flip); +} + +int __metal_driver_switch_get_interrupt_id(struct metal_switch *flip) +{ + int irq, max_irq; + struct metal_interrupt *irc; + + irq = __metal_driver_sifive_gpio_switch_interrupt_line(flip); + irc = __metal_driver_sifive_gpio_switch_interrupt_controller(flip); + if (irc != NULL) { + max_irq = _metal_interrupt_command_request(irc, + METAL_MAX_INTERRUPT_GET, + NULL); + + if (irq < max_irq) { + return _metal_interrupt_command_request(irc, + METAL_INDEX_INTERRUPT_GET, + (void *)&irq); + } + } + return METAL_INTERRUPT_ID_LCMX; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_switch) = { + .switch_vtable.switch_exist = __metal_driver_switch_exist, + .switch_vtable.interrupt_controller = __metal_driver_switch_interrupt_controller, + .switch_vtable.get_interrupt_id = __metal_driver_switch_get_interrupt_id, +}; + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c new file mode 100644 index 000000000..9ebbea03c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c @@ -0,0 +1,221 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GPIO0 + +#include +#include +#include + +int __metal_driver_sifive_gpio0_enable_input(struct metal_gpio *ggpio, long source) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) |= source; + + return 0; +} + +int __metal_driver_sifive_gpio0_disable_input(struct metal_gpio *ggpio, long source) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) &= ~source; + + return 0; +} + +long __metal_driver_sifive_gpio0_input(struct metal_gpio *ggpio) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_VALUE)); +} + +long __metal_driver_sifive_gpio0_output(struct metal_gpio *ggpio) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)); +} + + +int __metal_driver_sifive_gpio0_disable_output(struct metal_gpio *ggpio, long source) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) &= ~source; + + return 0; +} + +int __metal_driver_sifive_gpio0_enable_output(struct metal_gpio *ggpio, long source) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) |= source; + + return 0; +} + +int __metal_driver_sifive_gpio0_output_set(struct metal_gpio *ggpio, long value) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) |= value; + + return 0; +} + +int __metal_driver_sifive_gpio0_output_clear(struct metal_gpio *ggpio, long value) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) &= ~value; + + return 0; +} + +int __metal_driver_sifive_gpio0_output_toggle(struct metal_gpio *ggpio, long value) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) = + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) ^ value; + + return 0; +} + +int __metal_driver_sifive_gpio0_enable_io(struct metal_gpio *ggpio, long source, long dest) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_SEL)) &= ~source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) |= dest; + + return 0; +} + +int __metal_driver_sifive_gpio0_disable_io(struct metal_gpio *ggpio, long source) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) &= ~source; + + return 0; +} + +int __metal_driver_sifive_gpio0_config_int(struct metal_gpio *ggpio, long source, int intr_type) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + switch (intr_type) + { + case METAL_GPIO_INT_DISABLE: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) &= ~source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) &= ~source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) &= ~source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) &= ~source; + break; + case METAL_GPIO_INT_RISING: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + break; + case METAL_GPIO_INT_FALLING: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + break; + case METAL_GPIO_INT_BOTH_EDGE: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + break; + case METAL_GPIO_INT_HIGH: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + break; + case METAL_GPIO_INT_LOW: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; + case METAL_GPIO_INT_BOTH_LEVEL: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; + case METAL_GPIO_INT_MAX: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; + } + return 0; +} + +int __metal_driver_sifive_gpio0_clear_int(struct metal_gpio *ggpio, long source, int intr_type) +{ + long base = __metal_driver_sifive_gpio0_base(ggpio); + + switch (intr_type) + { + case METAL_GPIO_INT_RISING: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + break; + case METAL_GPIO_INT_FALLING: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + break; + case METAL_GPIO_INT_BOTH_EDGE: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + break; + case METAL_GPIO_INT_HIGH: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + break; + case METAL_GPIO_INT_LOW: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; + case METAL_GPIO_INT_BOTH_LEVEL: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; + case METAL_GPIO_INT_MAX: + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; + } + return 0; +} + +struct metal_interrupt * +__metal_driver_gpio_interrupt_controller(struct metal_gpio *gpio) +{ + return __metal_driver_sifive_gpio0_interrupt_parent(gpio); +} + +int __metal_driver_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) +{ + int irq; + irq = __metal_driver_sifive_gpio0_interrupt_lines(gpio, pin); + return irq; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_gpio0) = { + .gpio.disable_input = __metal_driver_sifive_gpio0_disable_input, + .gpio.enable_input = __metal_driver_sifive_gpio0_enable_input, + .gpio.input = __metal_driver_sifive_gpio0_input, + .gpio.output = __metal_driver_sifive_gpio0_output, + .gpio.disable_output = __metal_driver_sifive_gpio0_disable_output, + .gpio.enable_output = __metal_driver_sifive_gpio0_enable_output, + .gpio.output_set = __metal_driver_sifive_gpio0_output_set, + .gpio.output_clear = __metal_driver_sifive_gpio0_output_clear, + .gpio.output_toggle = __metal_driver_sifive_gpio0_output_toggle, + .gpio.enable_io = __metal_driver_sifive_gpio0_enable_io, + .gpio.disable_io = __metal_driver_sifive_gpio0_disable_io, + .gpio.config_int = __metal_driver_sifive_gpio0_config_int, + .gpio.clear_int = __metal_driver_sifive_gpio0_clear_int, + .gpio.interrupt_controller = __metal_driver_gpio_interrupt_controller, + .gpio.get_interrupt_id = __metal_driver_gpio_get_interrupt_id, +}; + +#endif /* METAL_SIFIVE_GPIO0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c new file mode 100644 index 000000000..1c34ca447 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c @@ -0,0 +1,151 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 + +#include +#include +#include + +void __metal_driver_sifive_local_external_interrupt_init(struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_local_external_interrupts0 *local0; + + local0 = (struct __metal_driver_sifive_local_external_interrupts0 *)(controller); + if ( !local0->init_done ) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + if (intc) { + /* Register its interruptswith with parent controller, aka all external to default isr */ + for (int i = 0; + i < __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); + i++) { + intc->vtable->interrupt_register(intc, + __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, i), + NULL, controller); + } + local0->init_done = 1; + } + } +} + +int __metal_driver_sifive_local_external_interrupt_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_register(intc, id, isr, priv); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_enable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_disable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int threshold) +{ + /* Core controller does not support threshold configuration */ + return -1; +} + +unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold(struct metal_interrupt *controller) +{ + /* Core controller does not support threshold configuration */ + return 0; +} + + +int __metal_driver_sifive_local_external_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) +{ + /* Core controller does not support priority configuration */ + return -1; +} + +unsigned int __metal_driver_sifive_local_external_interrupt_get_priority(struct metal_interrupt *controller, int id) +{ + /* Core controller does not support priority configuration */ + return 0; +} + +int __metal_driver_sifive_local_external_command_request (struct metal_interrupt *controller, + int command, void *data) +{ + int idx; + int rc = -1; + + switch (command) { + case METAL_MAX_INTERRUPT_GET: + rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); + break; + case METAL_INDEX_INTERRUPT_GET: + rc = 0; + if (data) { + idx = *(int *)data; + rc = __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, idx); + } + break; + default: + break; + } + + return rc; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) = { + .local0_vtable.interrupt_init = __metal_driver_sifive_local_external_interrupt_init, + .local0_vtable.interrupt_register = __metal_driver_sifive_local_external_interrupt_register, + .local0_vtable.interrupt_enable = __metal_driver_sifive_local_external_interrupt_enable, + .local0_vtable.interrupt_disable = __metal_driver_sifive_local_external_interrupt_disable, + .local0_vtable.interrupt_get_threshold = __metal_driver_sifive_local_external_interrupt_get_threshold, + .local0_vtable.interrupt_set_threshold = __metal_driver_sifive_local_external_interrupt_set_threshold, + .local0_vtable.interrupt_get_priority = __metal_driver_sifive_local_external_interrupt_get_priority, + .local0_vtable.interrupt_set_priority = __metal_driver_sifive_local_external_interrupt_set_priority, + .local0_vtable.command_request = __metal_driver_sifive_local_external_command_request, +}; + +#endif + +typedef int no_empty_translation_units; + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c new file mode 100644 index 000000000..79b81e7bf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c @@ -0,0 +1,121 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_RTC0 + +#include +#include + +#include + +/* RTCCFG */ +#define METAL_RTCCFG_RTCSCALE_MASK 0xF +#define METAL_RTCCFG_ENALWAYS (1 << 12) +#define METAL_RTCCFG_IP0 (1 << 28) + +/* RTCCMP0 */ +#define METAL_RTCCMP0_MAX UINT32_MAX + +#define RTC_REG(base, offset) (((unsigned long)base + offset)) +#define RTC_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)RTC_REG(base, offset))) + +uint64_t __metal_driver_sifive_rtc0_get_rate(const struct metal_rtc *const rtc) { + const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); + return metal_clock_get_rate_hz(clock); +} + +uint64_t __metal_driver_sifive_rtc0_set_rate(const struct metal_rtc *const rtc, const uint64_t rate) { + const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); + return metal_clock_get_rate_hz(clock); +} + +uint64_t __metal_driver_sifive_rtc0_get_compare(const struct metal_rtc *const rtc) { + const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); + + const uint32_t shift = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) & METAL_RTCCFG_RTCSCALE_MASK; + + return ((uint64_t)RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) << shift); +} + +uint64_t __metal_driver_sifive_rtc0_set_compare(const struct metal_rtc *const rtc, const uint64_t compare) { + const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); + + /* Determine the bit shift and shifted value to store in rtccmp0/rtccfg.scale */ + uint32_t shift = 0; + uint64_t comp_shifted = compare; + while (comp_shifted > METAL_RTCCMP0_MAX) { + shift += 1; + comp_shifted = comp_shifted >> shift; + } + + /* Set the value of rtccfg.scale */ + uint32_t cfg = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG); + cfg &= ~(METAL_RTCCFG_RTCSCALE_MASK); + cfg |= (METAL_RTCCFG_RTCSCALE_MASK & shift); + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) = cfg; + + /* Set the value of rtccmp0 */ + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) = (uint32_t) comp_shifted; + + return __metal_driver_sifive_rtc0_get_compare(rtc); +} + +uint64_t __metal_driver_sifive_rtc0_get_count(const struct metal_rtc *const rtc) { + const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); + + uint64_t count = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI); + count <<= 32; + count |= RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTLO); + + return count; +} + +uint64_t __metal_driver_sifive_rtc0_set_count(const struct metal_rtc *const rtc, const uint64_t count) { + const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); + + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI) = (UINT_MAX & (count >> 32)); + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTLO) = (UINT_MAX & count); + + return __metal_driver_sifive_rtc0_get_count(rtc); +} + +int __metal_driver_sifive_rtc0_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option) { + const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); + + switch (option) { + default: + case METAL_RTC_STOP: + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) &= ~(METAL_RTCCFG_ENALWAYS); + break; + case METAL_RTC_RUN: + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) |= METAL_RTCCFG_ENALWAYS; + break; + } + + return 0; +} + +struct metal_interrupt *__metal_driver_sifive_rtc0_get_interrupt(const struct metal_rtc *const rtc) { + return __metal_driver_sifive_rtc0_interrupt_parent(rtc); +} + +int __metal_driver_sifive_rtc0_get_interrupt_id(const struct metal_rtc *const rtc) { + return __metal_driver_sifive_rtc0_interrupt_line(rtc); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_rtc0) = { + .rtc.get_rate = __metal_driver_sifive_rtc0_get_rate, + .rtc.set_rate = __metal_driver_sifive_rtc0_set_rate, + .rtc.get_compare = __metal_driver_sifive_rtc0_get_compare, + .rtc.set_compare = __metal_driver_sifive_rtc0_set_compare, + .rtc.get_count = __metal_driver_sifive_rtc0_get_count, + .rtc.set_count = __metal_driver_sifive_rtc0_set_count, + .rtc.run = __metal_driver_sifive_rtc0_run, + .rtc.get_interrupt = __metal_driver_sifive_rtc0_get_interrupt, + .rtc.get_interrupt_id = __metal_driver_sifive_rtc0_get_interrupt_id, +}; + +#endif + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c new file mode 100644 index 000000000..2a346354f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c @@ -0,0 +1,405 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_SPI0 +#include +#include +#include +#include +#include + +/* Register fields */ +#define METAL_SPI_SCKDIV_MASK 0xFFF + +#define METAL_SPI_SCKMODE_PHA_SHIFT 0 +#define METAL_SPI_SCKMODE_POL_SHIFT 1 + +#define METAL_SPI_CSMODE_MASK 3 +#define METAL_SPI_CSMODE_AUTO 0 +#define METAL_SPI_CSMODE_HOLD 2 +#define METAL_SPI_CSMODE_OFF 3 + +#define METAL_SPI_PROTO_MASK 3 +#define METAL_SPI_PROTO_SINGLE 0 +#define METAL_SPI_PROTO_DUAL 1 +#define METAL_SPI_PROTO_QUAD 2 + +#define METAL_SPI_ENDIAN_LSB 4 + +#define METAL_SPI_DISABLE_RX 8 + +#define METAL_SPI_FRAME_LEN_SHIFT 16 +#define METAL_SPI_FRAME_LEN_MASK (0xF << METAL_SPI_FRAME_LEN_SHIFT) + +#define METAL_SPI_TXDATA_FULL (1 << 31) +#define METAL_SPI_RXDATA_EMPTY (1 << 31) +#define METAL_SPI_TXMARK_MASK 7 +#define METAL_SPI_TXWM 1 +#define METAL_SPI_TXRXDATA_MASK (0xFF) + +#define METAL_SPI_INTERVAL_SHIFT 16 + +#define METAL_SPI_CONTROL_IO 0 +#define METAL_SPI_CONTROL_MAPPED 1 + +#define METAL_SPI_REG(offset) (((unsigned long)control_base + offset)) +#define METAL_SPI_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)METAL_SPI_REG(offset))) +#define METAL_SPI_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_SPI_REG(offset))) + +#define METAL_SPI_RXDATA_TIMEOUT 1 + +static int configure_spi(struct __metal_driver_sifive_spi0 *spi, struct metal_spi_config *config) +{ + long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); + /* Set protocol */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_PROTO_MASK); + switch (config->protocol) { + case METAL_SPI_SINGLE: + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; + break; + case METAL_SPI_DUAL: + if (config->multi_wire == MULTI_WIRE_ALL) + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_DUAL; + else + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; + break; + case METAL_SPI_QUAD: + if (config->multi_wire == MULTI_WIRE_ALL) + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_QUAD; + else + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; + break; + default: + /* Unsupported value */ + return -1; + } + + /* Set Polarity */ + if(config->polarity) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_PHA_SHIFT); + } else { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_PHA_SHIFT); + } + + /* Set Phase */ + if(config->phase) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_POL_SHIFT); + } else { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_POL_SHIFT); + } + + /* Set Endianness */ + if(config->little_endian) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_ENDIAN_LSB; + } else { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_ENDIAN_LSB); + } + + /* Always populate receive FIFO */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_DISABLE_RX); + + /* Set CS Active */ + if(config->cs_active_high) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 0; + } else { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 1; + } + + /* Set frame length */ + if((METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) & METAL_SPI_FRAME_LEN_MASK) != (8 << METAL_SPI_FRAME_LEN_SHIFT)) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_FRAME_LEN_MASK); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= (8 << METAL_SPI_FRAME_LEN_SHIFT); + } + + /* Set CS line */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSID) = 1 << (config->csid); + + /* Toggle off memory-mapped SPI flash mode, toggle on programmable IO mode + * It seems that with this line uncommented, the debugger cannot have access + * to the chip at all because it assumes the chip is in memory-mapped mode. + * I have to compile the code with this line commented and launch gdb, + * reset cores, reset $pc, set *((int *) 0x20004060) = 0, (set the flash + * interface control register to programmable I/O mode) and then continue + * Alternative, comment out the "flash" line in openocd.cfg */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FCTRL) = METAL_SPI_CONTROL_IO; + + return 0; +} + +static void spi_mode_switch(struct __metal_driver_sifive_spi0 *spi, + struct metal_spi_config *config, + unsigned int trans_stage) { + long control_base = + __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); + + if (config->multi_wire == trans_stage) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_PROTO_MASK); + switch (config->protocol) { + case METAL_SPI_DUAL: + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_DUAL; + break; + case METAL_SPI_QUAD: + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_QUAD; + break; + default: + /* Unsupported value */ + return; + } + } +} + +int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, + struct metal_spi_config *config, + size_t len, + char *tx_buf, + char *rx_buf) +{ + struct __metal_driver_sifive_spi0 *spi = (void *)gspi; + long control_base = __metal_driver_sifive_spi0_control_base(gspi); + int rc = 0; + size_t i = 0; + + rc = configure_spi(spi, config); + if(rc != 0) { + return rc; + } + + /* Hold the chip select line for all len transferred */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) |= METAL_SPI_CSMODE_HOLD; + + unsigned long rxdata; + + /* Declare time_t variables to break out of infinite while loop */ + time_t endwait; + + for (i = 0; i < config->cmd_num; i++) { + + while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) + ; + + if (tx_buf) { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; + } else { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; + } + + endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; + + while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & + METAL_SPI_RXDATA_EMPTY) { + if (metal_time() > endwait) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= + ~(METAL_SPI_CSMODE_MASK); + + return 1; + } + } + + if (rx_buf) { + rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); + } + } + + /* switch to Dual/Quad mode */ + spi_mode_switch(spi, config, MULTI_WIRE_ADDR_DATA); + + /* Send Addr data */ + for (; i < (config->cmd_num + config->addr_num); i++) { + + while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) + ; + + if (tx_buf) { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; + } else { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; + } + + endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; + + while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & + METAL_SPI_RXDATA_EMPTY) { + if (metal_time() > endwait) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= + ~(METAL_SPI_CSMODE_MASK); + + return 1; + } + } + + if (rx_buf) { + rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); + } + } + + /* Send Dummy data */ + for (; i < (config->cmd_num + config->addr_num + config->dummy_num); i++) { + + while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) + ; + + if (tx_buf) { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; + } else { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; + } + + endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; + + while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & + METAL_SPI_RXDATA_EMPTY) { + if (metal_time() > endwait) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= + ~(METAL_SPI_CSMODE_MASK); + return 1; + } + } + if (rx_buf) { + rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); + } + } + + /* switch to Dual/Quad mode */ + spi_mode_switch(spi, config, MULTI_WIRE_DATA_ONLY); + + for (; i < len; i++) { + /* Master send bytes to the slave */ + + /* Wait for TXFIFO to not be full */ + while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL); + + /* Transfer byte by modifying the least significant byte in the TXDATA register */ + if (tx_buf) { + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; + } else { + /* Transfer a 0 byte if the sending buffer is NULL */ + METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; + } + + /* Master receives bytes from the RX FIFO */ + + /* Wait for RXFIFO to not be empty, but break the nested loops if timeout + * this timeout method needs refining, preferably taking into account + * the device specs */ + endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; + + while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & METAL_SPI_RXDATA_EMPTY) { + if (metal_time() > endwait) { + /* If timeout, deassert the CS */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); + + /* If timeout, return error code 1 immediately */ + return 1; + } + } + + /* Only store the dequeued byte if the receive_buffer is not NULL */ + if (rx_buf) { + rx_buf[i] = (char) (rxdata & METAL_SPI_TXRXDATA_MASK); + } + } + + /* On the last byte, set CSMODE to auto so that the chip select transitions back to high + * The reason that CS pin is not deasserted after transmitting out the byte buffer is timing. + * The code on the host side likely executes faster than the ability of FIFO to send out bytes. + * After the host iterates through the array, fifo is likely not cleared yet. If host deasserts + * the CS pin immediately, the following bytes in the output FIFO will not be sent consecutively. + * There needs to be a better way to handle this. */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); + + return 0; +} + +int __metal_driver_sifive_spi0_get_baud_rate(struct metal_spi *gspi) +{ + struct __metal_driver_sifive_spi0 *spi = (void *)gspi; + return spi->baud_rate; +} + +int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, int baud_rate) +{ + long control_base = __metal_driver_sifive_spi0_control_base(gspi); + struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); + struct __metal_driver_sifive_spi0 *spi = (void *)gspi; + + spi->baud_rate = baud_rate; + + if (clock != NULL) { + long clock_rate = clock->vtable->get_rate_hz(clock); + + /* Calculate divider */ + long div = (clock_rate / (2 * baud_rate)) - 1; + + if(div > METAL_SPI_SCKDIV_MASK) { + /* The requested baud rate is lower than we can support at + * the current clock rate */ + return -1; + } + + /* Set divider */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) &= ~METAL_SPI_SCKDIV_MASK; + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) |= (div & METAL_SPI_SCKDIV_MASK); + } + + return 0; +} + +static void pre_rate_change_callback_func(void *priv) +{ + long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)priv); + + /* Detect when the TXDATA is empty by setting the transmit watermark count + * to one and waiting until an interrupt is pending (indicating an empty TXFIFO) */ + METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) &= ~(METAL_SPI_TXMARK_MASK); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) |= (METAL_SPI_TXMARK_MASK & 1); + + while((METAL_SPI_REGW(METAL_SIFIVE_SPI0_IP) & METAL_SPI_TXWM) == 0) ; +} + +static void post_rate_change_callback_func(void *priv) +{ + struct __metal_driver_sifive_spi0 *spi = priv; + metal_spi_set_baud_rate(&spi->spi, spi->baud_rate); +} + +void __metal_driver_sifive_spi0_init(struct metal_spi *gspi, int baud_rate) +{ + struct __metal_driver_sifive_spi0 *spi = (void *)(gspi); + struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); + struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_spi0_pinmux(gspi); + + if(clock != NULL) { + spi->pre_rate_change_callback.callback = &pre_rate_change_callback_func; + spi->pre_rate_change_callback.priv = spi; + metal_clock_register_pre_rate_change_callback(clock, &(spi->pre_rate_change_callback)); + + spi->post_rate_change_callback.callback = &post_rate_change_callback_func; + spi->post_rate_change_callback.priv = spi; + metal_clock_register_post_rate_change_callback(clock, &(spi->post_rate_change_callback)); + } + + metal_spi_set_baud_rate(&(spi->spi), baud_rate); + + if (pinmux != NULL) { + long pinmux_output_selector = __metal_driver_sifive_spi0_pinmux_output_selector(gspi); + long pinmux_source_selector = __metal_driver_sifive_spi0_pinmux_source_selector(gspi); + pinmux->gpio.vtable->enable_io( + (struct metal_gpio *) pinmux, + pinmux_output_selector, + pinmux_source_selector + ); + } +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_spi0) = { + .spi.init = __metal_driver_sifive_spi0_init, + .spi.transfer = __metal_driver_sifive_spi0_transfer, + .spi.get_baud_rate = __metal_driver_sifive_spi0_get_baud_rate, + .spi.set_baud_rate = __metal_driver_sifive_spi0_set_baud_rate, +}; +#endif /* METAL_SIFIVE_SPI0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c new file mode 100644 index 000000000..79deebbf5 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c @@ -0,0 +1,30 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_TEST0 + +#include + +#include + +#include +#include + +void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); +void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) +{ + long base = __metal_driver_sifive_test0_base(sd); + uint32_t out = (code << 16) + (code == 0 ? 0x5555 : 0x3333); + while (1) { + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_TEST0_FINISHER_OFFSET)) = out; + } +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_test0) = { + .shutdown.exit = &__metal_driver_sifive_test0_exit, +}; +#endif /* METAL_SIFIVE_TEST0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c new file mode 100644 index 000000000..8b63fbd28 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c @@ -0,0 +1,95 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_TRACE + +#include +#include + +#define TRACE_REG(offset) (((unsigned long)base + (offset))) +#define TRACE_REG8(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)TRACE_REG(offset))) +#define TRACE_REG16(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u16 *)TRACE_REG(offset))) +#define TRACE_REG32(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)TRACE_REG(offset))) + +static void write_itc_uint32(struct metal_uart *trace, uint32_t data) { + long base = __metal_driver_sifive_trace_base(trace); + + TRACE_REG32(METAL_SIFIVE_TRACE_ITCSTIMULUS) = data; +} + +static void write_itc_uint16(struct metal_uart *trace, uint16_t data) { + long base = __metal_driver_sifive_trace_base(trace); + + TRACE_REG16(METAL_SIFIVE_TRACE_ITCSTIMULUS + 2) = data; +} + +static void write_itc_uint8(struct metal_uart *trace, uint8_t data) { + long base = __metal_driver_sifive_trace_base(trace); + + TRACE_REG8(METAL_SIFIVE_TRACE_ITCSTIMULUS + 3) = data; +} + +int __metal_driver_sifive_trace_putc(struct metal_uart *trace, + unsigned char c) { + static uint32_t buffer = 0; + static int bytes_in_buffer = 0; + + buffer |= (((uint32_t)c) << (bytes_in_buffer * 8)); + + bytes_in_buffer += 1; + + if (bytes_in_buffer >= 4) { + write_itc_uint32(trace, buffer); + + buffer = 0; + bytes_in_buffer = 0; + } else if ((c == '\n') || (c == '\r')) { // partial write + switch (bytes_in_buffer) { + case 3: // do a full word write + write_itc_uint16(trace, (uint16_t)(buffer)); + write_itc_uint8(trace, (uint8_t)(buffer >> 16)); + break; + case 2: // do a 16 bit write + write_itc_uint16(trace, (uint16_t)buffer); + break; + case 1: // do a 1 byte write + write_itc_uint8(trace, (uint8_t)buffer); + break; + } + + buffer = 0; + bytes_in_buffer = 0; + } + + return (int)c; +} + +void __metal_driver_sifive_trace_init(struct metal_uart *trace, int baud_rate) { + // The only init we do here is to make sure ITC 0 is enabled. It is up to + // Freedom Studio or other mechanisms to make sure tracing is enabled. If we + // try to enable tracing here, it will likely conflict with Freedom Studio, + // and they will just fight with each other. + + long base = __metal_driver_sifive_trace_base(trace); + + TRACE_REG32(METAL_SIFIVE_TRACE_ITCTRACEENABLE) |= 0x00000001; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_trace) = { + .uart.init = __metal_driver_sifive_trace_init, + .uart.putc = __metal_driver_sifive_trace_putc, + .uart.getc = NULL, + + .uart.get_baud_rate = NULL, + .uart.set_baud_rate = NULL, + + .uart.controller_interrupt = NULL, + .uart.get_interrupt_id = NULL, +}; + +#endif /* METAL_SIFIVE_TRACE */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c new file mode 100644 index 000000000..2e8098aa7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c @@ -0,0 +1,173 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_UART0 + +#include +#include + +/* TXDATA Fields */ +#define UART_TXEN (1 << 0) +#define UART_TXFULL (1 << 31) + +/* RXDATA Fields */ +#define UART_RXEN (1 << 0) +#define UART_RXEMPTY (1 << 31) + +/* TXCTRL Fields */ +#define UART_NSTOP (1 << 1) +#define UART_TXCNT(count) ((0x7 & count) << 16) + +/* IP Fields */ +#define UART_TXWM (1 << 0) + +#define UART_REG(offset) (((unsigned long)control_base + offset)) +#define UART_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)UART_REG(offset))) +#define UART_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset))) + +struct metal_interrupt * +__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart) +{ + return __metal_driver_sifive_uart0_interrupt_parent(uart); +} + +int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart) +{ + return (__metal_driver_sifive_uart0_interrupt_line(uart) + METAL_INTERRUPT_ID_GL0); +} + + +int __metal_driver_sifive_uart0_txready(struct metal_uart *uart) +{ + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + return !((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL)); +} + + +int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, int c) +{ + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + while (!__metal_driver_sifive_uart0_txready(uart)) { + /* wait */ + } + UART_REGW(METAL_SIFIVE_UART0_TXDATA) = c; + return 0; +} + + +int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, int *c) +{ + uint32_t ch; + long control_base = __metal_driver_sifive_uart0_control_base(uart); + /* No seperate status register, we get status and the byte at same time */ + ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA);; + if( ch & UART_RXEMPTY ){ + *c = -1; /* aka: EOF in most of the world */ + } else { + *c = ch & 0x0ff; + } + return 0; +} + + +int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart) +{ + struct __metal_driver_sifive_uart0 *uart = (void *)guart; + return uart->baud_rate; +} + +int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud_rate) +{ + struct __metal_driver_sifive_uart0 *uart = (void *)guart; + long control_base = __metal_driver_sifive_uart0_control_base(guart); + struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); + + uart->baud_rate = baud_rate; + + if (clock != NULL) { + long clock_rate = clock->vtable->get_rate_hz(clock); + UART_REGW(METAL_SIFIVE_UART0_DIV) = clock_rate / baud_rate - 1; + UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXEN; + UART_REGW(METAL_SIFIVE_UART0_RXCTRL) |= UART_RXEN; + } + return 0; +} + +static void pre_rate_change_callback_func(void *priv) +{ + struct __metal_driver_sifive_uart0 *uart = priv; + long control_base = __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv); + struct metal_clock *clock = __metal_driver_sifive_uart0_clock((struct metal_uart *)priv); + + /* Detect when the TXDATA is empty by setting the transmit watermark count + * to one and waiting until an interrupt is pending */ + + UART_REGW(METAL_SIFIVE_UART0_TXCTRL) &= ~(UART_TXCNT(0x7)); + UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(1); + + while((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) ; + + /* When the TXDATA clears, the UART is still shifting out the last byte. + * Calculate the time we must drain to finish transmitting and then wait + * that long. */ + + long bits_per_symbol = (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10; + long clk_freq = clock->vtable->get_rate_hz(clock); + long cycles_to_wait = bits_per_symbol * clk_freq / uart->baud_rate; + + for(volatile long x = 0; x < cycles_to_wait; x++) + __asm__("nop"); +} + +static void post_rate_change_callback_func(void *priv) +{ + struct __metal_driver_sifive_uart0 *uart = priv; + metal_uart_set_baud_rate(&uart->uart, uart->baud_rate); +} + +void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate) +{ + struct __metal_driver_sifive_uart0 *uart = (void *)(guart); + struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); + struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_uart0_pinmux(guart); + + if(clock != NULL) { + uart->pre_rate_change_callback.callback = &pre_rate_change_callback_func; + uart->pre_rate_change_callback.priv = guart; + metal_clock_register_pre_rate_change_callback(clock, &(uart->pre_rate_change_callback)); + + uart->post_rate_change_callback.callback = &post_rate_change_callback_func; + uart->post_rate_change_callback.priv = guart; + metal_clock_register_post_rate_change_callback(clock, &(uart->post_rate_change_callback)); + } + + metal_uart_set_baud_rate(&(uart->uart), baud_rate); + + if (pinmux != NULL) { + long pinmux_output_selector = __metal_driver_sifive_uart0_pinmux_output_selector(guart); + long pinmux_source_selector = __metal_driver_sifive_uart0_pinmux_source_selector(guart); + pinmux->gpio.vtable->enable_io( + (struct metal_gpio *) pinmux, + pinmux_output_selector, + pinmux_source_selector + ); + } +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_uart0) = { + .uart.init = __metal_driver_sifive_uart0_init, + .uart.putc = __metal_driver_sifive_uart0_putc, + .uart.getc = __metal_driver_sifive_uart0_getc, + .uart.get_baud_rate = __metal_driver_sifive_uart0_get_baud_rate, + .uart.set_baud_rate = __metal_driver_sifive_uart0_set_baud_rate, + .uart.controller_interrupt = __metal_driver_sifive_uart0_interrupt_controller, + .uart.get_interrupt_id = __metal_driver_sifive_uart0_get_interrupt_id, +}; + +#endif /* METAL_SIFIVE_UART0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c new file mode 100644 index 000000000..1a6cf362e --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c @@ -0,0 +1,213 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_WDOG0 + +#include +#include + +#include + +/* WDOGCFG */ +#define METAL_WDOGCFG_SCALE_MASK 7 +#define METAL_WDOGCFG_RSTEN (1 << 8) +#define METAL_WDOGCFG_ZEROCMP (1 << 9) +#define METAL_WDOGCFG_ENALWAYS (1 << 12) +#define METAL_WDOGCFG_COREAWAKE (1 << 13) +#define METAL_WDOGCFG_IP (1 << 28) + +/* WDOGCMP */ +#define METAL_WDOGCMP_MASK 0xFFFF + +#define WDOG_REG(base, offset) (((unsigned long)base + offset)) +#define WDOG_REGB(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)WDOG_REG(base, offset))) +#define WDOG_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)WDOG_REG(base, offset))) + +/* All writes to watchdog registers must be precedded by a write of + * a magic number to WDOGKEY */ +#define WDOG_UNLOCK(base) (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGKEY) = METAL_SIFIVE_WDOG0_MAGIC_KEY) + +/* Unlock the watchdog and then perform a register access */ +#define WDOG_UNLOCK_REGW(base, offset) \ + WDOG_UNLOCK(base);\ + WDOG_REGW(base, offset) + +int __metal_driver_sifive_wdog0_feed(const struct metal_watchdog *const wdog) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGFEED) = METAL_SIFIVE_WDOG0_MAGIC_FOOD; + + return 0; +} + +long int __metal_driver_sifive_wdog0_get_rate(const struct metal_watchdog *const wdog) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); + + const long int clock_rate = metal_clock_get_rate_hz(clock); + + if (clock_rate == 0) + return -1; + + const unsigned int scale = (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) & METAL_WDOGCFG_SCALE_MASK); + + return clock_rate / (1 << scale); +} + +long int __metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const wdog, const long int rate) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); + + const long int clock_rate = metal_clock_get_rate_hz(clock); + + if (rate >= clock_rate) { + /* We can't scale the rate above the driving clock. Clear the scale + * field and return the driving clock rate */ + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); + return clock_rate; + } + + /* Look for the closest scale value */ + long min_diff = LONG_MAX; + unsigned int min_scale = 0; + for (int i = 0; i < METAL_WDOGCFG_SCALE_MASK; i++) { + const long int new_rate = clock_rate / (1 << i); + + long int diff = rate - new_rate; + if (diff < 0) + diff *= -1; + + if (diff < min_diff) { + min_diff = diff; + min_scale = i; + } + } + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= (METAL_WDOGCFG_SCALE_MASK & min_scale); + + return clock_rate / (1 << min_scale); +} + +long int __metal_driver_sifive_wdog0_get_timeout(const struct metal_watchdog *const wdog) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + return (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) & METAL_WDOGCMP_MASK); +} + +long int __metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *const wdog, const long int timeout) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + /* Cap the timeout at the max value */ + const long int set_timeout = timeout > METAL_WDOGCMP_MASK ? METAL_WDOGCMP_MASK : timeout; + + /* If we edit the timeout value in-place by masking the compare value to 0 and + * then writing it, we cause a spurious interrupt because the compare value + * is temporarily 0. Instead, read the value into a local variable, modify it + * there, and then write the whole register back */ + uint32_t wdogcmp = WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP); + + wdogcmp &= ~(METAL_WDOGCMP_MASK); + wdogcmp |= set_timeout; + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) = wdogcmp; + + return set_timeout; +} + +int __metal_driver_sifive_wdog0_set_result(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + /* Turn off reset enable and counter reset */ + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_RSTEN | METAL_WDOGCFG_ZEROCMP); + + switch (result) { + default: + case METAL_WATCHDOG_NO_RESULT: + break; + case METAL_WATCHDOG_INTERRUPT: + /* Reset counter to zero after match */ + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ZEROCMP; + break; + case METAL_WATCHDOG_FULL_RESET: + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_RSTEN; + break; + } + + return 0; +} + +int __metal_driver_sifive_wdog0_run(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_ENALWAYS | METAL_WDOGCFG_COREAWAKE); + + switch (option) { + default: + case METAL_WATCHDOG_STOP: + break; + case METAL_WATCHDOG_RUN_ALWAYS: + /* Feed the watchdog before starting to reset counter */ + __metal_driver_sifive_wdog0_feed(wdog); + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ENALWAYS; + break; + case METAL_WATCHDOG_RUN_AWAKE: + /* Feed the watchdog before starting to reset counter */ + __metal_driver_sifive_wdog0_feed(wdog); + + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_COREAWAKE; + break; + } + + return 0; +} + +struct metal_interrupt *__metal_driver_sifive_wdog0_get_interrupt(const struct metal_watchdog *const wdog) +{ + return __metal_driver_sifive_wdog0_interrupt_parent(wdog); +} + +int __metal_driver_sifive_wdog0_get_interrupt_id(const struct metal_watchdog *const wdog) +{ + return __metal_driver_sifive_wdog0_interrupt_line(wdog); +} + +int __metal_driver_sifive_wdog0_clear_interrupt(const struct metal_watchdog *const wdog) +{ + const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + + /* Clear the interrupt pending bit */ + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_IP); + + return 0; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_wdog0) = { + .watchdog.feed = __metal_driver_sifive_wdog0_feed, + .watchdog.get_rate = __metal_driver_sifive_wdog0_get_rate, + .watchdog.set_rate = __metal_driver_sifive_wdog0_set_rate, + .watchdog.get_timeout = __metal_driver_sifive_wdog0_get_timeout, + .watchdog.set_timeout = __metal_driver_sifive_wdog0_set_timeout, + .watchdog.set_result = __metal_driver_sifive_wdog0_set_result, + .watchdog.run = __metal_driver_sifive_wdog0_run, + .watchdog.get_interrupt = __metal_driver_sifive_wdog0_get_interrupt, + .watchdog.get_interrupt_id = __metal_driver_sifive_wdog0_get_interrupt_id, + .watchdog.clear_interrupt = __metal_driver_sifive_wdog0_clear_interrupt, +}; + +#endif /* METAL_SIFIVE_WDOG0 */ + +typedef int no_empty_translation_units; + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S new file mode 100644 index 000000000..97da3fd33 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S @@ -0,0 +1,106 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* This code executes before _start, which is contained inside the C library. + * In embedded systems we want to ensure that _enter, which contains the first + * code to be executed, can be loaded at a specific address. To enable this + * feature we provide the '.text.metal.init.enter' section, which is + * defined to have the first address being where execution should start. */ +.section .text.metal.init.enter +.global _enter +_enter: + .cfi_startproc + + /* Inform the debugger that there is nowhere to backtrace past _enter. */ + .cfi_undefined ra + + /* The absolute first thing that must happen is configuring the global + * pointer register, which must be done with relaxation disabled because + * it's not valid to obtain the address of any symbol without GP + * configured. The C environment might go ahead and do this again, but + * that's safe as it's a fixed register. */ +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + /* Set up a simple trap vector to catch anything that goes wrong early in + * the boot process. */ + la t0, early_trap_vector + csrw mtvec, t0 + /* enable chicken bit if core is bullet series*/ + la t0, __metal_chicken_bit + beqz t0, 1f + csrwi 0x7C1, 0 +1: + + /* There may be pre-initialization routines inside the MBI code that run in + * C, so here we set up a C environment. First we set up a stack pointer, + * which is left as a weak reference in order to allow initialization + * routines that do not need a stack to be set up to transparently be + * called. */ + .weak __metal_stack_pointer + la sp, __metal_stack_pointer + + /* Check for an initialization routine and call it if one exists, otherwise + * just skip over the call entirely. Note that __metal_initialize isn't + * actually a full C function, as it doesn't end up with the .bss or .data + * segments having been initialized. This is done to avoid putting a + * burden on systems that can be initialized without having a C environment + * set up. */ + .weak __metal_before_start + la ra, __metal_before_start + beqz ra, 1f + jalr ra +1: + + /* At this point we can enter the C runtime's startup file. The arguments + * to this function are designed to match those provided to the SEE, just + * so we don't have to write another ABI. */ + csrr a0, mhartid + li a1, 0 + li a2, 0 + call _start + + /* If we've made it back here then there's probably something wrong. We + * allow the METAL to register a handler here. */ + .weak __metal_after_main + la ra, __metal_after_main + beqz ra, 1f + jalr ra +1: + + /* If that handler returns then there's not a whole lot we can do. Just + * try to make some noise. */ + la t0, 1f + csrw mtvec, t0 +1: + lw t1, 0(x0) + j 1b + + .cfi_endproc + +/* For sanity's sake we set up an early trap vector that just does nothing. If + * you end up here then there's a bug in the early boot code somewhere. */ +.section .text.metal.init.trapvec +.align 2 +early_trap_vector: + .cfi_startproc + csrr t0, mcause + csrr t1, mepc + csrr t2, mtval + j early_trap_vector + .cfi_endproc + +/* The GCC port might not emit a __register_frame_info symbol, which eventually + * results in a weak undefined reference that eventually causes crash when it + * is dereference early in boot. We really shouldn't need to put this here, + * but to deal with what I think is probably a bug in the linker script I'm + * going to leave this in for now. At least it's fairly cheap :) */ +.weak __register_frame_info +.global __register_frame_info +.section .text.metal.init.__register_frame_info +__register_frame_info: + .cfi_startproc + ret + .cfi_endproc diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c new file mode 100644 index 000000000..504526eb3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c @@ -0,0 +1,30 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +extern __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_set_pin(struct metal_gpio *, int pin, int value); +extern __inline__ int metal_gpio_clear_pin(struct metal_gpio *, int pin); +extern __inline__ int metal_gpio_toggle_pin(struct metal_gpio *, int pin); +extern __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *, int pin, int io_function); +extern __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *, int pin); +extern __inline__ struct metal_interrupt* metal_gpio_interrupt_controller(struct metal_gpio *gpio); +extern __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type); +extern __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type); + +struct metal_gpio *metal_gpio_get_device(unsigned int device_num) +{ + if(device_num > __MEE_DT_MAX_GPIOS) { + return NULL; + } + + return (struct metal_gpio *) __metal_gpio_table[device_num]; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c new file mode 100644 index 000000000..eeb88b26f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c @@ -0,0 +1,82 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include + +struct metal_interrupt* metal_interrupt_get_controller (metal_intr_cntrl_type cntrl, + int id) +{ + switch (cntrl) { + case METAL_CPU_CONTROLLER: + break; + case METAL_CLINT_CONTROLLER: +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + return __METAL_DT_RISCV_CLINT0_HANDLE; +#endif + break; + case METAL_CLIC_CONTROLLER: +#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE + return __METAL_DT_SIFIVE_CLIC0_HANDLE; +#endif + break; + case METAL_PLIC_CONTROLLER: +#ifdef __METAL_DT_RISCV_PLIC0_HANDLE + return __METAL_DT_RISCV_PLIC0_HANDLE; +#endif + break; + } + return NULL; +} + +extern __inline__ void metal_interrupt_init(struct metal_interrupt *controller); + +extern __inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller, + metal_vector_mode mode); +extern __inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller); + +extern __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, + metal_intr_priv_mode mode); +extern __inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller); + +extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int level); +extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); + +extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); + +extern __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller, + int id, + metal_interrupt_handler_t handler, + void *priv); + +extern __inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller, + int id, + metal_interrupt_vector_handler_t handler, + void *priv_data); + +extern __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id); + +extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); + +extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int threshold); + +extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); + +extern __inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id); + +extern __inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id); + +extern __inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller, + int cmd, void *data); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c new file mode 100644 index 000000000..91b74dbde --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c @@ -0,0 +1,38 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include + +struct metal_led* metal_led_get_rgb (char *label, char *color) +{ + int i; + struct metal_led *led; + char led_label[100]; + + if ((__METAL_DT_MAX_LEDS == 0) || + (label == NULL) || (color == NULL)) { + return NULL; + } + + strcpy(led_label, label); + strcat(led_label, color); + for (i = 0; i < __METAL_DT_MAX_LEDS; i++) { + led = (struct metal_led*)__metal_led_table[i]; + if (led->vtable->led_exist(led, led_label)) { + return led; + } + } + return NULL; +} + +struct metal_led* metal_led_get (char *label) +{ + return metal_led_get_rgb(label, ""); +} + +extern __inline__ void metal_led_enable(struct metal_led *led); +extern __inline__ void metal_led_on(struct metal_led *led); +extern __inline__ void metal_led_off(struct metal_led *led); +extern __inline__ void metal_led_toggle(struct metal_led *led); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/lock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/lock.c new file mode 100644 index 000000000..9e04230a3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/lock.c @@ -0,0 +1,8 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +extern __inline__ int metal_lock_init(struct metal_lock *lock); +extern __inline__ int metal_lock_take(struct metal_lock *lock); +extern __inline__ int metal_lock_give(struct metal_lock *lock); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c new file mode 100644 index 000000000..05ab7ead2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c @@ -0,0 +1,26 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +struct metal_memory *metal_get_memory_from_address(const uintptr_t address) { + for(int i = 0; i < __METAL_DT_MAX_MEMORIES; i++) { + struct metal_memory *mem = __metal_memory_table[i]; + + uintptr_t lower_bound = metal_memory_get_base_address(mem); + uintptr_t upper_bound = lower_bound + metal_memory_get_size(mem); + + if((address >= lower_bound) && (address < upper_bound)) { + return mem; + } + } + + return NULL; +} + +extern __inline__ uintptr_t metal_memory_get_base_address(const struct metal_memory *memory); +extern __inline__ size_t metal_memory_get_size(const struct metal_memory *memory); +extern __inline__ int metal_memory_supports_atomics(const struct metal_memory *memory); +extern __inline__ int metal_memory_is_cachable(const struct metal_memory *memory); + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c new file mode 100644 index 000000000..5c2f68ada --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c @@ -0,0 +1,586 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include + +#define CONFIG_TO_INT(_config) (*((char *) &(_config))) +#define INT_TO_CONFIG(_int) (*((struct metal_pmp_config *)(char *) &(_int))) + +struct metal_pmp *metal_pmp_get_device(void) +{ +#ifdef __METAL_DT_PMP_HANDLE + return __METAL_DT_PMP_HANDLE; +#else + return NULL; +#endif +} + +/* This function calculates the minimum granularity from the address + * that pmpaddr takes on after writing all ones to pmpaddr when pmpcfg = 0. + * + * Detect the address granularity based on the position of the + * least-significant 1 set in the address. + * + * For example, if the value read from pmpaddr is 0x3ffffc00, the + * least-significant set bit is in bit 10 (counting from 0), resulting + * in a detected granularity of 2^(10 + 2) = 4096. + */ +static uintptr_t _get_detected_granularity(uintptr_t address) { + if(address == 0) { + return (uintptr_t) -1; + } + + /* Get the index of the least significant set bit */ + int index = 0; + while(((address >> index) & 0x1) == 0) { + index += 1; + } + + /* The granularity is equal to 2^(index + 2) bytes */ + return (1 << (index + 2)); +} + +/* This function calculates the granularity requested by the user's provided + * value for pmpaddr. + * + * Calculate the requested granularity based on the position of the + * least-significant unset bit. + * + * For example, if the requested address is 0x20009ff, the least-significant + * unset bit is at index 9 (counting from 0), resulting in a requested + * granularity of 2^(9 + 3) = 4096. + */ +static uintptr_t _get_pmpaddr_granularity(uintptr_t address) { + /* Get the index of the least significant unset bit */ + int index = 0; + while(((address >> index) & 0x1) == 1) { + index += 1; + } + + /* The granularity is equal to 2^(index + 3) bytes */ + return (1 << (index + 3)); +} + +/* Get the number of pmp regions for the given hart */ +int metal_pmp_num_regions(int hartid) +{ + struct metal_cpu *cpu = metal_cpu_get(hartid); + + return __metal_driver_cpu_num_pmp_regions(cpu); +} + +/* Get the number of pmp regions for the current hart */ +static unsigned int _pmp_regions() { + return metal_pmp_num_regions(metal_cpu_get_current_hartid()); +} + +void metal_pmp_init(struct metal_pmp *pmp) { + if(!pmp) { + return; + } + + struct metal_pmp_config init_config = { + .L = METAL_PMP_UNLOCKED, + .A = METAL_PMP_OFF, + .X = 0, + .W = 0, + .R = 0, + }; + + for(unsigned int i = 0; i < _pmp_regions(); i++) { + metal_pmp_set_region(pmp, i, init_config, 0); + } + + /* Detect the region granularity by writing all 1s to pmpaddr0 while + * pmpcfg0 = 0. */ + if(metal_pmp_set_address(pmp, 0, -1) != 0) { + /* Failed to detect granularity */ + return; + } + + /* Calculate the granularity based on the value that pmpaddr0 takes on */ + pmp->_granularity[metal_cpu_get_current_hartid()] = _get_detected_granularity(metal_pmp_get_address(pmp, 0)); + + /* Clear pmpaddr0 */ + metal_pmp_set_address(pmp, 0, 0); +} + +int metal_pmp_set_region(struct metal_pmp *pmp, + unsigned int region, + struct metal_pmp_config config, + size_t address) +{ + struct metal_pmp_config old_config; + size_t old_address; + size_t cfgmask; + size_t pmpcfg; + int rc = 0; + + if(!pmp) { + /* Device handle cannot be NULL */ + return 1; + } + + if(region > _pmp_regions()) { + /* Region outside of supported range */ + return 2; + } + + if(config.A == METAL_PMP_NA4 && pmp->_granularity[metal_cpu_get_current_hartid()] > 4) { + /* The requested granularity is too small */ + return 3; + } + + if(config.A == METAL_PMP_NAPOT && + pmp->_granularity[metal_cpu_get_current_hartid()] > _get_pmpaddr_granularity(address)) + { + /* The requested granularity is too small */ + return 3; + } + + rc = metal_pmp_get_region(pmp, region, &old_config, &old_address); + if(rc) { + /* Error reading region */ + return rc; + } + + if(old_config.L == METAL_PMP_LOCKED) { + /* Cannot modify locked region */ + return 4; + } + + /* Update the address first, because if the region is being locked we won't + * be able to modify it after we set the config */ + if(old_address != address) { + switch(region) { + case 0: + __asm__("csrw pmpaddr0, %[addr]" + :: [addr] "r" (address) :); + break; + case 1: + __asm__("csrw pmpaddr1, %[addr]" + :: [addr] "r" (address) :); + break; + case 2: + __asm__("csrw pmpaddr2, %[addr]" + :: [addr] "r" (address) :); + break; + case 3: + __asm__("csrw pmpaddr3, %[addr]" + :: [addr] "r" (address) :); + break; + case 4: + __asm__("csrw pmpaddr4, %[addr]" + :: [addr] "r" (address) :); + break; + case 5: + __asm__("csrw pmpaddr5, %[addr]" + :: [addr] "r" (address) :); + break; + case 6: + __asm__("csrw pmpaddr6, %[addr]" + :: [addr] "r" (address) :); + break; + case 7: + __asm__("csrw pmpaddr7, %[addr]" + :: [addr] "r" (address) :); + break; + case 8: + __asm__("csrw pmpaddr8, %[addr]" + :: [addr] "r" (address) :); + break; + case 9: + __asm__("csrw pmpaddr9, %[addr]" + :: [addr] "r" (address) :); + break; + case 10: + __asm__("csrw pmpaddr10, %[addr]" + :: [addr] "r" (address) :); + break; + case 11: + __asm__("csrw pmpaddr11, %[addr]" + :: [addr] "r" (address) :); + break; + case 12: + __asm__("csrw pmpaddr12, %[addr]" + :: [addr] "r" (address) :); + break; + case 13: + __asm__("csrw pmpaddr13, %[addr]" + :: [addr] "r" (address) :); + break; + case 14: + __asm__("csrw pmpaddr14, %[addr]" + :: [addr] "r" (address) :); + break; + case 15: + __asm__("csrw pmpaddr15, %[addr]" + :: [addr] "r" (address) :); + break; + } + } + +#if __riscv_xlen==32 + if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { + /* Mask to clear old pmpcfg */ + cfgmask = (0xFF << (8 * (region % 4)) ); + pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 4)) ); + + switch(region / 4) { + case 0: + __asm__("csrc pmpcfg0, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg0, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + case 1: + __asm__("csrc pmpcfg1, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg1, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + case 2: + __asm__("csrc pmpcfg2, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg2, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + case 3: + __asm__("csrc pmpcfg3, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg3, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + } + } +#elif __riscv_xlen==64 + if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { + /* Mask to clear old pmpcfg */ + cfgmask = (0xFF << (8 * (region % 8)) ); + pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 8)) ); + + switch(region / 8) { + case 0: + __asm__("csrc pmpcfg0, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg0, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + case 1: + __asm__("csrc pmpcfg2, %[mask]" + :: [mask] "r" (cfgmask) :); + + __asm__("csrs pmpcfg2, %[cfg]" + :: [cfg] "r" (pmpcfg) :); + break; + } + } +#else +#error XLEN is not set to supported value for PMP driver +#endif + + return 0; +} + +int metal_pmp_get_region(struct metal_pmp *pmp, + unsigned int region, + struct metal_pmp_config *config, + size_t *address) +{ + size_t pmpcfg = 0; + char *pmpcfg_convert = (char *)&pmpcfg; + + if(!pmp || !config || !address) { + /* NULL pointers are invalid arguments */ + return 1; + } + + if(region > _pmp_regions()) { + /* Region outside of supported range */ + return 2; + } + +#if __riscv_xlen==32 + switch(region / 4) { + case 0: + __asm__("csrr %[cfg], pmpcfg0" + : [cfg] "=r" (pmpcfg) ::); + break; + case 1: + __asm__("csrr %[cfg], pmpcfg1" + : [cfg] "=r" (pmpcfg) ::); + break; + case 2: + __asm__("csrr %[cfg], pmpcfg2" + : [cfg] "=r" (pmpcfg) ::); + break; + case 3: + __asm__("csrr %[cfg], pmpcfg3" + : [cfg] "=r" (pmpcfg) ::); + break; + } + + pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 4)) ) ); + +#elif __riscv_xlen==64 + switch(region / 8) { + case 0: + __asm__("csrr %[cfg], pmpcfg0" + : [cfg] "=r" (pmpcfg) ::); + break; + case 1: + __asm__("csrr %[cfg], pmpcfg2" + : [cfg] "=r" (pmpcfg) ::); + break; + } + + pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 8)) ) ); + +#else +#error XLEN is not set to supported value for PMP driver +#endif + + *config = INT_TO_CONFIG(*pmpcfg_convert); + + switch(region) { + case 0: + __asm__("csrr %[addr], pmpaddr0" + : [addr] "=r" (*address) ::); + break; + case 1: + __asm__("csrr %[addr], pmpaddr1" + : [addr] "=r" (*address) ::); + break; + case 2: + __asm__("csrr %[addr], pmpaddr2" + : [addr] "=r" (*address) ::); + break; + case 3: + __asm__("csrr %[addr], pmpaddr3" + : [addr] "=r" (*address) ::); + break; + case 4: + __asm__("csrr %[addr], pmpaddr4" + : [addr] "=r" (*address) ::); + break; + case 5: + __asm__("csrr %[addr], pmpaddr5" + : [addr] "=r" (*address) ::); + break; + case 6: + __asm__("csrr %[addr], pmpaddr6" + : [addr] "=r" (*address) ::); + break; + case 7: + __asm__("csrr %[addr], pmpaddr7" + : [addr] "=r" (*address) ::); + break; + case 8: + __asm__("csrr %[addr], pmpaddr8" + : [addr] "=r" (*address) ::); + break; + case 9: + __asm__("csrr %[addr], pmpaddr9" + : [addr] "=r" (*address) ::); + break; + case 10: + __asm__("csrr %[addr], pmpaddr10" + : [addr] "=r" (*address) ::); + break; + case 11: + __asm__("csrr %[addr], pmpaddr11" + : [addr] "=r" (*address) ::); + break; + case 12: + __asm__("csrr %[addr], pmpaddr12" + : [addr] "=r" (*address) ::); + break; + case 13: + __asm__("csrr %[addr], pmpaddr13" + : [addr] "=r" (*address) ::); + break; + case 14: + __asm__("csrr %[addr], pmpaddr14" + : [addr] "=r" (*address) ::); + break; + case 15: + __asm__("csrr %[addr], pmpaddr15" + : [addr] "=r" (*address) ::); + break; + } + + return 0; +} + +int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &address); + if(rc) { + return rc; + } + + if(config.L == METAL_PMP_LOCKED) { + return 0; + } + + config.L = METAL_PMP_LOCKED; + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + + +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address) +{ + struct metal_pmp_config config; + size_t old_address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &old_address); + if(rc) { + return rc; + } + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + +size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address = 0; + + metal_pmp_get_region(pmp, region, &config, &address); + + return address; +} + + +int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode) +{ + struct metal_pmp_config config; + size_t address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &address); + if(rc) { + return rc; + } + + config.A = mode; + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + +enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address = 0; + + metal_pmp_get_region(pmp, region, &config, &address); + + return config.A; +} + + +int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X) +{ + struct metal_pmp_config config; + size_t address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &address); + if(rc) { + return rc; + } + + config.X = X; + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + +int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address = 0; + + metal_pmp_get_region(pmp, region, &config, &address); + + return config.X; +} + + +int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W) +{ + struct metal_pmp_config config; + size_t address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &address); + if(rc) { + return rc; + } + + config.W = W; + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + +int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address = 0; + + metal_pmp_get_region(pmp, region, &config, &address); + + return config.W; +} + + +int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R) +{ + struct metal_pmp_config config; + size_t address; + int rc = 0; + + rc = metal_pmp_get_region(pmp, region, &config, &address); + if(rc) { + return rc; + } + + config.R = R; + + rc = metal_pmp_set_region(pmp, region, config, address); + + return rc; +} + +int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region) +{ + struct metal_pmp_config config; + size_t address = 0; + + metal_pmp_get_region(pmp, region, &config, &address); + + return config.R; +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c new file mode 100644 index 000000000..54bfcfc2c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c @@ -0,0 +1,57 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#include + +#define METAL_MSTATUS_MIE_OFFSET 3 +#define METAL_MSTATUS_MPIE_OFFSET 7 +#define METAL_MSTATUS_SIE_OFFSET 1 +#define METAL_MSTATUS_SPIE_OFFSET 5 +#define METAL_MSTATUS_UIE_OFFSET 0 +#define METAL_MSTATUS_UPIE_OFFSET 4 + +#define METAL_MSTATUS_MPP_OFFSET 11 +#define METAL_MSTATUS_MPP_MASK 3 + +void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, + struct metal_register_file regfile, + metal_privilege_entry_point_t entry_point) +{ + uintptr_t mstatus; + __asm__ volatile("csrr %0, mstatus" : "=r" (mstatus)); + + /* Set xPIE bits based on current xIE bits */ + if(mstatus && (1 << METAL_MSTATUS_MIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_MPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_MPIE_OFFSET); + } + if(mstatus && (1 << METAL_MSTATUS_SIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_SPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_SPIE_OFFSET); + } + if(mstatus && (1 << METAL_MSTATUS_UIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_UPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_UPIE_OFFSET); + } + + /* Set MPP to the requested privilege mode */ + mstatus &= ~(METAL_MSTATUS_MPP_MASK << METAL_MSTATUS_MPP_OFFSET); + mstatus |= (mode << METAL_MSTATUS_MPP_OFFSET); + + __asm__ volatile("csrw mstatus, %0" :: "r" (mstatus)); + + /* Set the entry point in MEPC */ + __asm__ volatile("csrw mepc, %0" :: "r" (entry_point)); + + /* Set the register file */ + __asm__ volatile("mv ra, %0" :: "r" (regfile.ra)); + __asm__ volatile("mv sp, %0" :: "r" (regfile.sp)); + + __asm__ volatile("mret"); +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c new file mode 100644 index 000000000..8b79892df --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c @@ -0,0 +1,27 @@ +/* Copyright 2019 SiFive, Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +#include + +extern inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc); +extern inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, const uint64_t rate); +extern inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc); +extern inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, const uint64_t compare); +extern inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc); +extern inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, const uint64_t count); +extern inline int metal_rtc_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option); +extern inline struct metal_interrupt *metal_rtc_get_interrupt(const struct metal_rtc *const rtc); +extern inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc); + +struct metal_rtc *metal_rtc_get_device(int index) { +#ifdef __METAL_DT_MAX_RTCS + if (index < __METAL_DT_MAX_RTCS) { + return (struct metal_rtc *) __metal_rtc_table[index]; + } +#endif + return NULL; +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c new file mode 100644 index 000000000..c3b5255a7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c @@ -0,0 +1,22 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +extern __inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code); + +#if defined(__METAL_DT_SHUTDOWN_HANDLE) +void metal_shutdown(int code) +{ + __metal_shutdown_exit(__METAL_DT_SHUTDOWN_HANDLE, code); +} +#else +#pragma message("There is no defined shutdown mechanism, metal_shutdown() will spin.") +void metal_shutdown(int code) +{ + while (1) { + __asm__ volatile ("nop"); + } +} +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c new file mode 100644 index 000000000..de8cda737 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c @@ -0,0 +1,21 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +extern __inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate); +extern __inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf); +extern __inline__ int metal_spi_get_baud_rate(struct metal_spi *spi); +extern __inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate); + +struct metal_spi *metal_spi_get_device(unsigned int device_num) +{ +#if __METAL_DT_MAX_SPIS > 0 + if (device_num < __METAL_DT_MAX_SPIS) { + return (struct metal_spi *) __metal_spi_table[device_num]; + } +#endif + + return NULL; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c new file mode 100644 index 000000000..4f17229c7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c @@ -0,0 +1,27 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +struct metal_switch* metal_switch_get (char *label) +{ + int i; + struct metal_switch *flip; + + if ((__METAL_DT_MAX_BUTTONS == 0) || (label == NULL)) { + return NULL; + } + + for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { + flip = (struct metal_switch*)__metal_switch_table[i]; + if (flip->vtable->switch_exist(flip, label)) { + return flip; + } + } + return NULL; +} + +extern __inline__ struct metal_interrupt* + metal_switch_interrupt_controller(struct metal_switch *flip); +extern __inline__ int metal_switch_get_interrupt_id(struct metal_switch *flip); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c new file mode 100644 index 000000000..a5338e942 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c @@ -0,0 +1,62 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) +#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) +#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) + +/* + * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for + * hart 0 to finish copying the datat section, zeroing the BSS, and running + * the libc contstructors. + */ +__attribute__((section(".init"))) +void __metal_synchronize_harts() { +#if __METAL_DT_MAX_HARTS > 1 + + int hart; + __asm__ volatile("csrr %0, mhartid" : "=r" (hart) ::); + + uintptr_t msip_base = 0; + + /* Get the base address of the MSIP registers */ +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); + msip_base += METAL_RISCV_CLINT0_MSIP_BASE; +#elif __METAL_DT_RISCV_CLIC0_HANDLE + msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); + msip_base += METAL_RISCV_CLIC0_MSIP_BASE; +#else +#pragma message(No handle for CLINT or CLIC found, harts may be unsynchronized after init!) +#endif + + /* Disable machine interrupts as a precaution */ + __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); + + if (hart == 0) { + /* Hart 0 waits for all harts to set their MSIP bit */ + for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { + while (METAL_MSIP(msip_base, i) == 0) ; + } + + /* Hart 0 clears everyone's MSIP bit */ + for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { + METAL_MSIP(msip_base, i) = 0; + } + } else { + /* Other harts set their MSIP bit to indicate they're ready */ + METAL_MSIP(msip_base, hart) = 1; + __asm__ volatile ("fence w,rw"); + + /* Wait for hart 0 to clear the MSIP bit */ + while (METAL_MSIP(msip_base, hart) == 1) ; + } + +#endif /* __METAL_DT_MAX_HARTS > 1 */ +} + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c new file mode 100644 index 000000000..529f8bd56 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c @@ -0,0 +1,30 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include + +int metal_gettimeofday(struct timeval *tp, void *tzp) +{ + int rv; + unsigned long long mcc, timebase; + if ((rv = metal_timer_get_cyclecount(0, &mcc))) { + return -1; + } + if ((rv = metal_timer_get_timebase_frequency(0, &timebase))) { + return -1; + } + tp->tv_sec = mcc / timebase; + tp->tv_usec = mcc % timebase * 1000000 / timebase; + return 0; +} + +time_t metal_time (void) +{ + struct timeval now; + + if (metal_gettimeofday(&now, NULL) < 0) + now.tv_sec = (time_t) -1; + + return now.tv_sec; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c new file mode 100644 index 000000000..f58413321 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c @@ -0,0 +1,80 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include +#include + +#if defined(__METAL_DT_MAX_HARTS) +/* This implementation serves as a small shim that interfaces with the first + * timer on a system. */ +int metal_timer_get_cyclecount(int hartid, unsigned long long *mcc) +{ + struct metal_cpu *cpu = metal_cpu_get(hartid); + + if ( cpu ) { + *mcc = metal_cpu_get_timer(cpu); + return 0; + } + return -1; +} + +int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase) +{ + struct metal_cpu *cpu = metal_cpu_get(hartid); + + if ( cpu ) { + *timebase = metal_cpu_get_timebase(cpu); + return 0; + } + return -1; +} + +int metal_timer_get_machine_time(int hartid) +{ + struct metal_cpu *cpu = metal_cpu_get(hartid); + + if ( cpu ) { + return metal_cpu_get_mtime(cpu); + } + return 0; +} + +int metal_timer_set_machine_time(int hartid, unsigned long long time) +{ + struct metal_cpu *cpu = metal_cpu_get(hartid); + + if ( cpu ) { + return metal_cpu_set_mtimecmp(cpu, time); + } + return -1; +} + +#else + +/* This implementation of gettimeofday doesn't actually do anything, it's just there to + * provide a shim and return 0 so we can ensure that everything can link to _gettimeofday. + */ +int nop_cyclecount(int id, unsigned long long *c) __attribute__((section(".text.metal.nop.cyclecount"))); +int nop_cyclecount(int id, unsigned long long *c) { return -1; } +int nop_timebase(unsigned long long *t) __attribute__((section(".text.metal.nop.timebase"))); +int nop_timebase(unsigned long long *t) { return -1; } +int nop_tick(int second) __attribute__((section(".text.metal.nop.tick"))); +int nop_tick(int second) { return -1; } +int metal_timer_get_cyclecount(int hartid, unsigned long long *c) __attribute__((weak, alias("nop_cyclecount"))) +{ +#pragma message("There is no default timer device, metal_timer_get_cyclecount() will always return cyclecount -1.") +} +int metal_timer_get_timebase_frequency(unsigned long long *t) __attribute__((weak, alias("nop_timebase"))) +{ +#pragma message("There is no default timer device, metal_timer_get_timebase_frequency() will always return timebase -1.") +} +int metal_timer_set_tick(int second) __attribute__((weak, alias("nop_tick"))) +{ +#pragma message("There is no default timer device, metal_timer_set_tick) will always return -1.") +} + +#endif + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S new file mode 100644 index 000000000..b55b6656a --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S @@ -0,0 +1,53 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#define METAL_MSTATUS_MIE_SHIFT 8 +#define METAL_MSTATUS_MPP_M 3 +#define METAL_MSTATUS_MPP_SHIFT 11 + +#define METAL_MTVEC_MODE_MASK 3 + +/* void _metal_trap(int ecode) + * + * Trigger a machine-mode trap with exception code ecode + */ +.global _metal_trap +.type _metal_trap, @function + +_metal_trap: + + /* Store the instruction which called _metal_trap in mepc */ + addi t0, ra, -1 + csrw mepc, t0 + + /* Set mcause to the desired exception code */ + csrw mcause, a0 + + /* Read mstatus */ + csrr t0, mstatus + + /* Set MIE=0 */ + li t1, -1 + xori t1, t1, METAL_MSTATUS_MIE_SHIFT + and t0, t0, t1 + + /* Set MPP=M */ + li t1, METAL_MSTATUS_MPP_M + slli t1, t1, METAL_MSTATUS_MPP_SHIFT + or t0, t0, t1 + + /* Write mstatus */ + csrw mstatus, t0 + + /* Read mtvec */ + csrr t0, mtvec + + /* + * Mask the mtvec MODE bits + * Exceptions always jump to mtvec.BASE regradless of the vectoring mode. + */ + andi t0, t0, METAL_MTVEC_MODE_MASK + + /* Jump to mtvec */ + jr t0 + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c new file mode 100644 index 000000000..306192451 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c @@ -0,0 +1,51 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include + +#if defined(__METAL_DT_STDOUT_UART_HANDLE) +/* This implementation serves as a small shim that interfaces with the first + * UART on a system. */ +int metal_tty_putc(int c) +{ + if (c == '\n') { + metal_tty_putc_raw( '\r' ); + } + return metal_tty_putc_raw( c ); +} + +int metal_tty_putc_raw(int c) +{ + return metal_uart_putc(__METAL_DT_STDOUT_UART_HANDLE, c); +} + +int metal_tty_getc(int *c) +{ + do { + metal_uart_getc( __METAL_DT_STDOUT_UART_HANDLE, c ); + /* -1 means no key pressed, getc waits */ + } while( -1 == *c ) + ; + return 0; +} + +#ifndef __METAL_DT_STDOUT_UART_BAUD +#define __METAL_DT_STDOUT_UART_BAUD 115200 +#endif + +static void metal_tty_init(void) __attribute__((constructor)); +static void metal_tty_init(void) +{ + metal_uart_init(__METAL_DT_STDOUT_UART_HANDLE, __METAL_DT_STDOUT_UART_BAUD); +} +#else +/* This implementation of putc doesn't actually do anything, it's just there to + * provide a shim that eats all the characters so we can ensure that everything + * can link to metal_tty_putc. */ +int nop_putc(int c) __attribute__((section(".text.metal.nop.putc"))); +int nop_putc(int c) { return -1; } +int metal_tty_putc(int c) __attribute__((weak, alias("nop_putc"))); +#pragma message("There is no default output device, metal_tty_putc() will throw away all input.") +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c new file mode 100644 index 000000000..8981eb8d3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c @@ -0,0 +1,11 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +extern __inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate); +extern __inline__ int metal_uart_putc(struct metal_uart *uart, int c); +extern __inline__ int metal_uart_txready(struct metal_uart *uart); +extern __inline__ int metal_uart_getc(struct metal_uart *uart, int *c); +extern __inline__ int metal_uart_get_baud_rate(struct metal_uart *uart); +extern __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/vector.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/vector.S new file mode 100644 index 000000000..1da52d2df --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/vector.S @@ -0,0 +1,160 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Jump table for CLINT vectored mode + */ +.weak metal_interrupt_vector_handler +.balign 4, 0 +.global metal_interrupt_vector_handler + +.weak metal_software_interrupt_vector_handler +.balign 4, 0 +.global metal_software_interrupt_vector_handler + +.weak metal_timer_interrupt_vector_handler +.balign 4, 0 +.global metal_timer_interrupt_vector_handler + +.weak metal_external_interrupt_vector_handler +.balign 4, 0 +.global metal_external_interrupt_vector_handler + +.weak metal_lc0_interrupt_vector_handler +.balign 4, 0 +.global metal_lc0_interrupt_vector_handler + +.weak metal_lc1_interrupt_vector_handler +.balign 4, 0 +.global metal_lc1_interrupt_vector_handler + +.weak metal_lc2_interrupt_vector_handler +.balign 4, 0 +.global metal_lc2_interrupt_vector_handler + +.weak metal_lc3_interrupt_vector_handler +.balign 4, 0 +.global metal_lc3_interrupt_vector_handler + +.weak metal_lc4_interrupt_vector_handler +.balign 4, 0 +.global metal_lc4_interrupt_vector_handler + +.weak metal_lc5_interrupt_vector_handler +.balign 4, 0 +.global metal_lc5_interrupt_vector_handler + +.weak metal_lc6_interrupt_vector_handler +.balign 4, 0 +.global metal_lc6_interrupt_vector_handler + +.weak metal_lc7_interrupt_vector_handler +.balign 4, 0 +.global metal_lc7_interrupt_vector_handler + +.weak metal_lc8_interrupt_vector_handler +.balign 4, 0 +.global metal_lc8_interrupt_vector_handler + +.weak metal_lc9_interrupt_vector_handler +.balign 4, 0 +.global metal_lc9_interrupt_vector_handler + +.weak metal_lc10_interrupt_vector_handler +.balign 4, 0 +.global metal_lc10_interrupt_vector_handler + +.weak metal_lc11_interrupt_vector_handler +.balign 4, 0 +.global metal_lc11_interrupt_vector_handler + +.weak metal_lc12_interrupt_vector_handler +.balign 4, 0 +.global metal_lc12_interrupt_vector_handler + +.weak metal_lc13_interrupt_vector_handler +.balign 4, 0 +.global metal_lc13_interrupt_vector_handler + +.weak metal_lc14_interrupt_vector_handler +.balign 4, 0 +.global metal_lc14_interrupt_vector_handler + +.weak metal_lc15_interrupt_vector_handler +.balign 4, 0 +.global metal_lc15_interrupt_vector_handler + +#if __riscv_xlen == 32 +.balign 128, 0 +#else +.balign 256, 0 +#endif +.option norvc +.global __metal_vector_table +__metal_vector_table: +IRQ_0: + j metal_interrupt_vector_handler +IRQ_1: + j metal_interrupt_vector_handler +IRQ_2: + j metal_interrupt_vector_handler +IRQ_3: + j metal_software_interrupt_vector_handler +IRQ_4: + j metal_interrupt_vector_handler +IRQ_5: + j metal_interrupt_vector_handler +IRQ_6: + j metal_interrupt_vector_handler +IRQ_7: + j metal_timer_interrupt_vector_handler +IRQ_8: + j metal_interrupt_vector_handler +IRQ_9: + j metal_interrupt_vector_handler +IRQ_10: + j metal_interrupt_vector_handler +IRQ_11: + j metal_interrupt_vector_handler +IRQ_12: + j metal_interrupt_vector_handler +IRQ_13: + j metal_interrupt_vector_handler +IRQ_14: + j metal_interrupt_vector_handler +IRQ_15: + j metal_interrupt_vector_handler +IRQ_LC0: + j metal_lc0_interrupt_vector_handler +IRQ_LC1: + j metal_lc1_interrupt_vector_handler +IRQ_LC2: + j metal_lc2_interrupt_vector_handler +IRQ_LC3: + j metal_lc3_interrupt_vector_handler +IRQ_LC4: + j metal_lc4_interrupt_vector_handler +IRQ_LC5: + j metal_lc5_interrupt_vector_handler +IRQ_LC6: + j metal_lc6_interrupt_vector_handler +IRQ_LC7: + j metal_lc7_interrupt_vector_handler +IRQ_LC8: + j metal_lc8_interrupt_vector_handler +IRQ_LC9: + j metal_lc9_interrupt_vector_handler +IRQ_LC10: + j metal_lc10_interrupt_vector_handler +IRQ_LC11: + j metal_lc11_interrupt_vector_handler +IRQ_LC12: + j metal_lc12_interrupt_vector_handler +IRQ_LC13: + j metal_lc13_interrupt_vector_handler +IRQ_LC14: + j metal_lc14_interrupt_vector_handler +IRQ_LC15: + j metal_lc15_interrupt_vector_handler + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S new file mode 100644 index 000000000..f2602c430 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S @@ -0,0 +1,266 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 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! + */ + + .extern ulRegTest1LoopCounter + .extern ulRegTest2LoopCounter + + .global vRegTest1Implementation + .global vRegTest2Implementation + +/*-----------------------------------------------------------*/ + +/* + * The register check tasks are described in the comments at the top of + * main_full.c. + */ + +.align( 4 ) +vRegTest1Implementation: + + /* Fill the core registers with known values. */ + li x5, 0x5 + li x6, 0x6 + li x7, 0x7 + li x8, 0x8 + li x9, 0x9 + li x10, 0xa + li x11, 0xb + li x12, 0xc + li x13, 0xd + li x14, 0xe + li x15, 0xf + li x16, 0x10 + li x17, 0x11 + li x18, 0x12 + li x19, 0x13 + li x20, 0x14 + li x21, 0x15 + li x22, 0x16 + li x23, 0x17 + li x24, 0x18 + li x25, 0x19 + li x26, 0x1a + li x27, 0x1b + li x28, 0x1c + li x29, 0x1d + li x30, 0x1e + +reg1_loop: + + /* Check each register still contains the expected known value. + vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation + uses x5 as the temporary. */ + li x31, 0x5 + bne x31, x5, reg1_error_loop + li x31, 0x6 + bne x31, x6, reg1_error_loop + li x31, 0x7 + bne x31, x7, reg1_error_loop + li x31, 0x8 + bne x31, x8, reg1_error_loop + li x31, 0x9 + bne x31, x9, reg1_error_loop + li x31, 0xa + bne x31, x10, reg1_error_loop + li x31, 0xb + bne x31, x11, reg1_error_loop + li x31, 0xc + bne x31, x12, reg1_error_loop + li x31, 0xd + bne x31, x13, reg1_error_loop + li x31, 0xe + bne x31, x14, reg1_error_loop + li x31, 0xf + bne x31, x15, reg1_error_loop + li x31, 0x10 + bne x31, x16, reg1_error_loop + li x31, 0x11 + bne x31, x17, reg1_error_loop + li x31, 0x12 + bne x31, x18, reg1_error_loop + li x31, 0x13 + bne x31, x19, reg1_error_loop + li x31, 0x14 + bne x31, x20, reg1_error_loop + li x31, 0x15 + bne x31, x21, reg1_error_loop + li x31, 0x16 + bne x31, x22, reg1_error_loop + li x31, 0x17 + bne x31, x23, reg1_error_loop + li x31, 0x18 + bne x31, x24, reg1_error_loop + li x31, 0x19 + bne x31, x25, reg1_error_loop + li x31, 0x1a + bne x31, x26, reg1_error_loop + li x31, 0x1b + bne x31, x27, reg1_error_loop + li x31, 0x1c + bne x31, x28, reg1_error_loop + li x31, 0x1d + bne x31, x29, reg1_error_loop + li x31, 0x1e + bne x31, x30, reg1_error_loop + + /* Everything passed, increment the loop counter. */ + lw x31, ulRegTest1LoopCounterConst + lw x30, 0(x31) + addi x30, x30, 1 + sw x30, 0(x31) + + /* Restore clobbered register reading for next loop. */ + li x30, 0x1e + + /* Yield to increase code coverage. */ + ecall + + /* Start again. */ + jal reg1_loop + +reg1_error_loop: + /* Jump here if a register contains an uxpected value. This stops the loop + counter being incremented so the check task knows an error was found. */ + ebreak + jal reg1_error_loop + +.align( 4 ) +ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter + +/*-----------------------------------------------------------*/ + +.align( 4 ) +vRegTest2Implementation: + + /* Fill the core registers with known values. */ + li x6, 0x61 + li x7, 0x71 + li x8, 0x81 + li x9, 0x91 + li x10, 0xa1 + li x11, 0xb1 + li x12, 0xc1 + li x13, 0xd1 + li x14, 0xe1 + li x15, 0xf1 + li x16, 0x20 + li x17, 0x21 + li x18, 0x22 + li x19, 0x23 + li x20, 0x24 + li x21, 0x25 + li x22, 0x26 + li x23, 0x27 + li x24, 0x28 + li x25, 0x29 + li x26, 0x2a + li x27, 0x2b + li x28, 0x2c + li x29, 0x2d + li x30, 0x2e + li x31, 0x2f + +Reg2_loop: + + /* Check each register still contains the expected known value. + vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation + uses x31 as the temporary. */ + li x5, 0x61 + bne x5, x6, reg2_error_loop + li x5, 0x71 + bne x5, x7, reg2_error_loop + li x5, 0x81 + bne x5, x8, reg2_error_loop + li x5, 0x91 + bne x5, x9, reg2_error_loop + li x5, 0xa1 + bne x5, x10, reg2_error_loop + li x5, 0xb1 + bne x5, x11, reg2_error_loop + li x5, 0xc1 + bne x5, x12, reg2_error_loop + li x5, 0xd1 + bne x5, x13, reg2_error_loop + li x5, 0xe1 + bne x5, x14, reg2_error_loop + li x5, 0xf1 + bne x5, x15, reg2_error_loop + li x5, 0x20 + bne x5, x16, reg2_error_loop + li x5, 0x21 + bne x5, x17, reg2_error_loop + li x5, 0x22 + bne x5, x18, reg2_error_loop + li x5, 0x23 + bne x5, x19, reg2_error_loop + li x5, 0x24 + bne x5, x20, reg2_error_loop + li x5, 0x25 + bne x5, x21, reg2_error_loop + li x5, 0x26 + bne x5, x22, reg2_error_loop + li x5, 0x27 + bne x5, x23, reg2_error_loop + li x5, 0x28 + bne x5, x24, reg2_error_loop + li x5, 0x29 + bne x5, x25, reg2_error_loop + li x5, 0x2a + bne x5, x26, reg2_error_loop + li x5, 0x2b + bne x5, x27, reg2_error_loop + li x5, 0x2c + bne x5, x28, reg2_error_loop + li x5, 0x2d + bne x5, x29, reg2_error_loop + li x5, 0x2e + bne x5, x30, reg2_error_loop + li x5, 0x2f + bne x5, x31, reg2_error_loop + + /* Everything passed, increment the loop counter. */ + lw x5, ulRegTest2LoopCounterConst + lw x6, 0(x5) + addi x6, x6, 1 + sw x6, 0(x5) + + /* Restore clobbered register reading for next loop. */ + li x6, 0x61 + + /* Start again. */ + jal Reg2_loop + +reg2_error_loop: + /* Jump here if a register contains an uxpected value. This stops the loop + counter being incremented so the check task knows an error was found. */ + ebreak + jal reg2_error_loop + +.align( 4 ) +ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c new file mode 100644 index 000000000..1f25b0174 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c @@ -0,0 +1,306 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 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 comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + * + ****************************************************************************** + * + * main_full() creates all the demo application tasks and software timers, then + * starts the scheduler. The web documentation provides more details of the + * standard demo application tasks, which provide no particular functionality, + * but do provide a good example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill both the core registers with known values, then + * check that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + * + * "Check" task - The check executes every three seconds. It checks that all + * the standard demo tasks, and the register check tasks, are not only still + * executing, but are executing without reporting any errors. The check task + * toggles the LED every three seconds if all the standard demo tasks are + * executing as expected, or every 500ms if a potential error is discovered in + * any task. + */ + +/* Standard includes. */ +#include +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "semphr.h" + +/* Standard demo application includes. */ +#include "dynamic.h" +#include "blocktim.h" +#include "TimerDemo.h" +#include "TaskNotify.h" + +/* Priorities for the demo application tasks. */ +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) + +/* The period of the check task, in ms, converted to ticks using the +pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have +been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */ +#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL ) +#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL ) + +/* Parameters that are passed into the register check tasks solely for the +purpose of ensuring parameters are passed into tasks correctly. */ +#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) +#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) + +/* The base period used by the timer test tasks. */ +#define mainTIMER_TEST_PERIOD ( 50 ) + +/* The size of the stack allocated to the check task (as described in the +comments at the top of this file. */ +#define mainCHECK_TASK_STACK_SIZE_WORDS 160 + +/* Size of the stacks to allocated for the register check tasks. */ +#define mainREG_TEST_STACK_SIZE_WORDS 90 + +/*-----------------------------------------------------------*/ + +/* + * Called by main() to run the full demo (as opposed to the blinky demo) when + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +void main_full( void ); + +/* + * The check task, as described at the top of this file. + */ +static void prvCheckTask( void *pvParameters ); + +/* + * Register check tasks as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly file, but the + * entry points are kept in the C file for the convenience of checking the task + * parameter. + */ +static void prvRegTestTaskEntry1( void *pvParameters ); +extern void vRegTest1Implementation( void ); +static void prvRegTestTaskEntry2( void *pvParameters ); +extern void vRegTest2Implementation( void ); + +/* + * Tick hook used by the full demo, which includes code that interacts with + * some of the tests. + */ +void vFullDemoTickHook( void ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check task. If the variables keep incrementing, +then the register check tasks have not discovered any errors. If a variable +stops incrementing, then an error has been found. */ +uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; +volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter; +volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter; +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ + /* Start all the other standard demo/test tasks. They have no particular + functionality, but do demonstrate how to use the FreeRTOS API and test the + kernel port. */ + vCreateBlockTimeTasks(); + vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); + vStartDynamicPriorityTasks(); + vStartTaskNotifyTask(); + + /* Create the register check tasks, as described at the top of this file. + Use xTaskCreateStatic() to create a task using only statically allocated + memory. */ + xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */ + "Reg1", /* The name of the task. */ + mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */ + mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */ + tskIDLE_PRIORITY, /* Priority of the task. */ + NULL ); /* Can be used to pass out a handle to the created task. */ + xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); + + /* Create the task that performs the 'check' functionality, as described at + the top of this file. */ + xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL ); + + /* Start the scheduler. */ + 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 prvCheckTask( void *pvParameters ) +{ +TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; +TickType_t xLastExecutionTime; +uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +char * const pcPassMessage = "."; +char * pcStatusMessage = pcPassMessage; +extern void vToggleLED( void ); + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() + works correctly. */ + xLastExecutionTime = xTaskGetTickCount(); + + /* Cycle for ever, delaying then checking all the other tasks are still + operating without error. The onboard LED is toggled on each iteration. + If an error is detected then the delay period is decreased from + mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the + effect of increasing the rate at which the onboard LED toggles, and in so + doing gives visual feedback of the system status. */ + for( ;; ) + { + /* Delay until it is time to execute again. */ + vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); + + /* Check all the demo tasks (other than the flash tasks) to ensure + that they are all still running, and that none have detected an error. */ + if( xAreDynamicPriorityTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "ERROR: Dynamic priority demo/tests.\r\n"; + } + + if( xAreBlockTimeTestTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "ERROR: Block time demo/tests.\r\n"; + } + + if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE ) + { + pcStatusMessage = "ERROR: Timer demo/tests.\r\n"; + } + + if( xAreTaskNotificationTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "ERROR: Task notification demo/tests.\r\n"; + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + pcStatusMessage = "ERROR: Register test 1.\r\n"; + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + pcStatusMessage = "ERROR: Register test 2.\r\n"; + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + /* Write the status message to the UART and toggle the LED to show the + system status if the UART is not connected. */ + vToggleLED(); + + /* If an error has been found then increase the LED toggle rate by + increasing the cycle frequency. */ + if( pcStatusMessage != pcPassMessage ) + { + xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry1( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) + { + /* Start the part of the test that is written in assembler. */ + vRegTest1Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check task will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry2( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) + { + /* Start the part of the test that is written in assembler. */ + vRegTest2Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check task will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +void vFullDemoTickHook( void ) +{ + /* Called from vApplicationTickHook() when the project is configured to + build the full test/demo applications. */ + + /* Use task notifications from an interrupt. */ + xNotifyTaskFromISR(); +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c new file mode 100644 index 000000000..de03b623b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c @@ -0,0 +1,275 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 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! + */ + +/****************************************************************************** + * 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 (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and standard FreeRTOS hook functions. + * + * When running on the HiFive Rev B hardware: + * When executing correctly the blue LED will toggle every three seconds. If + * the blue LED toggles every 500ms then one of the self-monitoring test tasks + * discovered a potential issue. If the red led toggles rapidly then a hardware + * exception occurred. + * + * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON + * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO + * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT! + * + */ + +/* FreeRTOS kernel includes. */ +#include +#include + +/* Freedom metal driver includes. */ +#include +#include + +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 + +/* Index to first HART (there is only one). */ +#define mainHART_0 0 + +/* Registers used to initialise the PLIC. */ +#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) ) +#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) ) +#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) ) +#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) ) + +/*-----------------------------------------------------------*/ + +/* + * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 + extern void main_blinky( void ); +#else + extern void main_full( void ); +#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ + +/* + * Prototypes for the standard FreeRTOS callback/hook functions implemented + * within this file. See https://www.freertos.org/a00016.html + */ +void vApplicationMallocFailedHook( void ); +void vApplicationIdleHook( void ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationTickHook( void ); + +/* + * Setup the hardware to run this demo. + */ +static void prvSetupHardware( void ); + +/* + * Used by the Freedom Metal drivers. + */ +static struct metal_led *pxBlueLED = NULL; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + prvSetupHardware(); + + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + { + main_blinky(); + } + #else + { + main_full(); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ +struct metal_cpu *pxCPU; +struct metal_interrupt *pxInterruptController; + + /* Initialise the blue LED. */ + pxBlueLED = metal_led_get_rgb( "LD0", "blue" ); + configASSERT( pxBlueLED ); + metal_led_enable( pxBlueLED ); + metal_led_off( pxBlueLED ); + + /* Initialise the interrupt controller. */ + pxCPU = metal_cpu_get( mainHART_0 ); + configASSERT( pxCPU ); + pxInterruptController = metal_cpu_interrupt_controller( pxCPU ); + configASSERT( pxInterruptController ); + metal_interrupt_init( pxInterruptController ); + + /* Set all interrupt enable bits to 0. */ + mainPLIC_ENABLE_0 = 0UL; + mainPLIC_ENABLE_1 = 0UL; + + /* Clear all pending interrupts. */ + mainPLIC_PENDING_0 = 0UL; + mainPLIC_PENDING_1 = 0UL; +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c or heap_2.c are used, then the size of the + heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in + FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used + to query the size of free heap space that remains (although it does not + provide information on how the remaining heap might be fragmented). */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* The tests in the full demo expect some interaction with interrupts. */ + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 ) + { + extern void vFullDemoTickHook( void ); + vFullDemoTickHook(); + } + #endif +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( void ) +{ +static struct metal_led *pxRedLED = NULL; +volatile uint32_t ul; +const uint32_t ulNullLoopDelay = 0x1ffffUL; + + taskDISABLE_INTERRUPTS(); + + /* Initialise the red LED. */ + pxRedLED = metal_led_get_rgb( "LD0", "red" ); + configASSERT( pxRedLED ); + metal_led_enable( pxRedLED ); + metal_led_off( pxRedLED ); + + /* Flash the red LED to indicate that assert was hit - interrupts are off + here to prevent any further tick interrupts or context switches, so the + delay is implemented as a crude loop instead of a peripheral timer. */ + for( ;; ) + { + for( ul = 0; ul < ulNullLoopDelay; ul++ ) + { + __asm volatile( "nop" ); + } + metal_led_toggle( pxRedLED ); + } +} +/*-----------------------------------------------------------*/ + +void handle_trap( void ) +{ +volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPLICPending0Register = 0UL, ulPLICPending1Register = 0UL; + + /* Store a few register values that might be useful when determining why this + function was called. */ + __asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) ); + __asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) ); + ulPLICPending0Register = mainPLIC_PENDING_0; + ulPLICPending1Register = mainPLIC_PENDING_1; + + /* Prevent compiler warnings about unused variables. */ + ( void ) ulPLICPending0Register; + ( void ) ulPLICPending1Register; + + /* Force an assert as this function has not been implemented as the demo + does not use external interrupts. */ + configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); +} +/*-----------------------------------------------------------*/ + +void vToggleLED( void ) +{ + metal_led_toggle( pxBlueLED ); +} +/*-----------------------------------------------------------*/ + +void *malloc( size_t xSize ) +{ + /* The linker script does not define a heap so artificially force an assert() + if something unexpectedly uses the C library heap. See + https://www.freertos.org/a00111.html for more information. */ + configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); + + /* Remove warnings about unused parameter. */ + ( void ) xSize; + return NULL; +} +/*-----------------------------------------------------------*/ + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.cproject b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.cproject deleted file mode 100644 index 8efeeeefd..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.cproject +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.project b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.project deleted file mode 100644 index f22f74077..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.project +++ /dev/null @@ -1,303 +0,0 @@ - - - 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_FreedomStudio/.settings/language.settings.xml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.settings/language.settings.xml deleted file mode 100644 index b0d04ea76..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/.settings/language.settings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/FreeRTOSConfig.h deleted file mode 100644 index a7a0c1180..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/FreeRTOSConfig.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 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 configCLINT_BASE_ADDRESS CLINT_CTRL_ADDR -#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 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/blinky_demo/main_blinky.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/blinky_demo/main_blinky.c deleted file mode 100644 index 30aeb1baa..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/blinky_demo/main_blinky.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 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_FreedomStudio/bsp/design.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/design.dts deleted file mode 100644 index 970d3be72..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/design.dts +++ /dev/null @@ -1,209 +0,0 @@ -/dts-v1/; - -/ { - #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"; - }; - }; -}; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/design.reglist b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/design.reglist deleted file mode 100644 index 921dd83ac..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/design.reglist +++ /dev/null @@ -1,54 +0,0 @@ -zero -ra -sp -gp -tp -t0 -t1 -t2 -fp -s1 -a0 -a1 -a2 -a3 -a4 -a5 -a6 -a7 -s2 -s3 -s4 -s5 -s6 -s7 -s8 -s9 -s10 -s11 -t3 -t4 -t5 -t6 -pc -mstatus -misa -mie -mtvec -mscratch -mepc -mcause -mtval -mip -mvendorid -marchid -mimpid -mhartid -tselect -tdata1 -tdata2 -tdata3 -dcsr -dpc -dscratch -priv diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/button.h deleted file mode 100644 index 0c26f435a..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/button.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__BUTTON_H -#define METAL__BUTTON_H - -/*! - * @file button.h - * API for interfacing with physical buttons - */ - -#include - -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); - int (*get_interrupt_id)(struct metal_button *button); -}; - -/*! - * @brief A button device handle - * - * A `struct metal_button` is an implementation-defined object which represents - * a button on a development board. - */ -struct metal_button { - const struct metal_button_vtable *vtable; -}; - -/*! - * @brief Get a reference to a button - * - * @param label The DeviceTree label for the button - * @return A handle for the button - */ -struct metal_button* metal_button_get(char *label); - - -/*! - * @brief Get the interrupt controller for a button - * - * @param button The handle for the button - * @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); } - -/*! - * @brief Get the interrupt id for a button - * - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cache.h deleted file mode 100644 index a8a60ada6..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cache.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__CACHE_H -#define METAL__CACHE_H - -/*! - * @file cache.h - * - * @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); -}; - -/*! - * @brief a handle for a cache - */ -struct metal_cache { - const struct __metal_cache_vtable *vtable; -}; - -/*! - * @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. - */ -inline void metal_cache_init(struct metal_cache *cache, int ways) { - return cache->vtable->init(cache, ways); -} - -/*! - * @brief Get the current number of enabled cache ways - * @param cache The handle for the cache - * @return The current number of enabled cache ways - */ -inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { - return cache->vtable->get_enabled_ways(cache); -} - -/*! - * @brief Enable the requested number of cache ways - * @param cache The handle for the cache - * @param ways The number of ways to enabled - * @return 0 if the ways are successfully enabled - */ -inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { - return cache->vtable->set_enabled_ways(cache, ways); -} - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/clock.h deleted file mode 100644 index 277841e01..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/clock.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#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. - */ - -struct metal_clock; - -#include - -/* The generic interface to all clocks. */ -struct __metal_clock_vtable { - long (*get_rate_hz)(const struct metal_clock *clk); - long (*set_rate_hz)(struct metal_clock *clk, long hz); -}; - -/*! - * @brief Function signature of clock pre-rate change callbacks - */ -typedef void (*metal_clock_pre_rate_change_callback)(void *priv); - -/*! - * @brief Function signature of clock post-rate change callbacks - */ -typedef void (*metal_clock_post_rate_change_callback)(void *priv); - -/*! - * @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. - * - * 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; - - /* Post-rate change callback */ - metal_clock_post_rate_change_callback _post_rate_change_callback; - void *_post_rate_change_callback_priv; -}; - -/*! - * @brief Returns the current rate of the given 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); } - -/*! - * @brief Set the current rate of a clock - * - * @param clk The handle for the clock - * @param hz The desired rate in Hz - * @return The new rate of the clock in Hz. - * - * Attempts to set the current rate of the given clock to as close as possible - * 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. - */ -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); - - 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); - - return out; -} - -/*! - * @brief Register a callback that must be called before a rate change - * - * @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; -} - -/*! - * @brief Registers a callback that must be called after a rate change - * - * @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; -} - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/compiler.h deleted file mode 100644 index 62c0ea975..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/compiler.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__COMPILER_H -#define METAL__COMPILER_H - -#define __METAL_DECLARE_VTABLE(type) \ - extern const struct type type; - -#define __METAL_DEFINE_VTABLE(type) \ - const struct type type - -#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))) - -void _metal_trap(int ecode); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cpu.h deleted file mode 100644 index 453bd12de..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/cpu.h +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ - -/* SPDX-License-Identifier: Apache-2.0 */ - -/*! @file cpu.h - * @brief API for accessing CPU capabilities. - */ - -#ifndef METAL__CPU_H -#define METAL__CPU_H - -#include -#include - -struct metal_cpu; - -/*! - * @brief Function signature for exception handlers - */ -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 (*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); - int (*get_tmr_interrupt_id)(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); - 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); -}; - -/*! @brief A device handle for a CPU hart - */ -struct metal_cpu { - const struct metal_cpu_vtable *vtable; -}; - -/*! @brief Get a reference to a CPU hart - * - * @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); - -/*! @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(); - -/*! @brief Get the number of CPU harts - * - * @return The number of CPU harts */ -int metal_cpu_get_num_harts(); - -/*! @brief Get the CPU cycle count timer value - * - * Get the value of the cycle count timer for a given CPU - * - * @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); } - -/*! @brief Get the timebase of the CPU - * - * Get the value of the timebase of the cycle count timer - * - * @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); } - -/*! @brief Get the value of the mtime RTC - * - * Get the value of the mtime real-time clock. The CPU interrupt controller - * must be initialized before this function is called or the return value - * will be 0. - * - * @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); } - -/*! @brief Set the value of the RTC mtimecmp RTC - * - * Set the value of the mtime real-time clock compare register. The CPU - * interrupt controller must be initialized before this function is called - * or the return value will be -1; - * - * @param cpu The CPU device handle - * @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); } - -/*! @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. - * - * @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); } - -/*! @brief Get the RTC timer interrupt id - * - * Get the interrupt ID of the real-time clock interrupt - * - * @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); } - -/*! @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. - * - * @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); } - -/*! @brief Get the software interrupt id - * - * Get the interrupt ID for the software/inter-process interrupt - * - * @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); } - -/*! - * @brief Set the inter-process interrupt for a hart - * - * Trigger a software/inter-process interrupt for a hart. The CPU interrupt - * controller for the CPU handle passed to this function must be initialized - * before this function is called. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Clear the inter-process interrupt for a hart - * - * Clear the software/inter-process interrupt for a hart. The CPU interrupt - * controller for the CPU handle passed to this function must be initialized - * before this function is called. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Get the value of MSIP for the given hart - * - * Get the value of the machine software interrupt pending bit for - * the given hart. The CPU interrupt controller for the CPU handle passed - * as argument to this function must be initialized before this function - * is called. - * - * @param cpu the CPU device handle - * @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); } - -/*! - * @brief Get the interrupt controller for the CPU - * - * Get the CPU interrupt controller. The controller returned by this - * function must be initialized before any interrupts are registered - * or enabled and before any exception handlers are registered with - * this CPU. - * - * @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); } - -/*! - * @brief Register an exception handler - * - * 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); } - -/*! - * @brief Get the length of an instruction in bytes - * - * Get the length of an instruction in bytes. - * - * On RISC-V platforms, this is useful for detecting whether an instruction is - * compressed (2 bytes long) or uncompressed (4 bytes long). - * - * This function is useful in conjuction with `metal_cpu_get_exception_pc()` - * and `metal_cpu_set_exception_pc()` in order to cause the exception handler to - * return execution after the faulting instruction. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Get the program counter of the current exception. - * - * This function must be called within an exception handler. The behavior is - * undefined outside of an exception handler. - * - * @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); } - -/*! - * @brief Set the exception program counter - * - * This function must be called within an exception handler. The behavior - * is undefined outside of an exception handler. - * - * This function can be used to cause an exception handler to return execution - * to an address other than the one that caused the exception. - * - * @param cpu the CPU device handle - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h deleted file mode 100644 index 2647c5981..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__FIXED_CLOCK_H -#define METAL__DRIVERS__FIXED_CLOCK_H - -struct __metal_driver_fixed_clock; - -#include -#include - -struct __metal_driver_vtable_fixed_clock { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_clock) - -struct __metal_driver_fixed_clock { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h deleted file mode 100644 index 936ce8d77..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__FIXED_FACTOR_CLOCK_H -#define METAL__DRIVERS__FIXED_FACTOR_CLOCK_H - -struct __metal_driver_fixed_factor_clock; - -#include -#include - -struct __metal_driver_vtable_fixed_factor_clock { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_factor_clock) - -struct __metal_driver_fixed_factor_clock { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h deleted file mode 100644 index 08d571e1c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_CLINT0_H -#define METAL__DRIVERS__RISCV_CLINT0_H - -#include -#include - -struct __metal_driver_vtable_riscv_clint0 { - struct metal_interrupt_vtable clint_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_clint0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_riscv_clint0 { - struct metal_interrupt controller; - int init_done; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h deleted file mode 100644 index eb1e5b8ca..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_CPU_H -#define METAL__DRIVERS__RISCV_CPU_H - -#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_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_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 -#if __riscv_xlen == 32 -#define METAL_MCAUSE_INTR 0x80000000UL -#define METAL_MCAUSE_CAUSE 0x000003FFUL -#else -#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_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 */ -/* 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 - -typedef enum { - 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_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_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_interrup_cmd_e; - -typedef struct __metal_interrupt_data { - long long pad : 64; - metal_interrupt_handler_t handler; - void *sub_int; - void *exint_data; -} __metal_interrupt_data; - -/* CPU interrupt controller */ - -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; -}; - - -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_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) - -struct __metal_driver_riscv_cpu_intc { - struct metal_interrupt controller; - int init_done; - uintptr_t metal_mtvec_table[METAL_MAX_MI]; - __metal_interrupt_data metal_int_table[METAL_MAX_MI]; - metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; -}; - -/* CPU driver*/ -struct __metal_driver_vtable_cpu { - struct metal_cpu_vtable cpu_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) - -struct __metal_driver_cpu { - struct metal_cpu cpu; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h deleted file mode 100644 index 159ee6d69..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_PLIC0_H -#define METAL__DRIVERS__RISCV_PLIC0_H - -#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 - -struct __metal_driver_vtable_riscv_plic0 { - struct metal_interrupt_vtable plic_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_plic0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_riscv_plic0 { - struct metal_interrupt controller; - int init_done; - metal_interrupt_handler_t metal_exint_table[__METAL_PLIC_SUBINTERRUPTS]; - __metal_interrupt_data metal_exdata_table[__METAL_PLIC_SUBINTERRUPTS]; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h deleted file mode 100644 index db9674625..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_CLIC0_H -#define METAL__DRIVERS__SIFIVE_CLIC0_H - -#include -#include - -#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_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) - -struct __metal_driver_vtable_sifive_clic0 { - struct metal_interrupt_vtable clic_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_sifive_clic0 { - struct metal_interrupt controller; - int init_done; - metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; - __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h deleted file mode 100644 index d311f0cf2..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H - -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) - -struct __metal_driver_sifive_fe310_g000_hfrosc { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h deleted file mode 100644 index b86926fba..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfxosc.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H - -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_hfxosc { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) - -struct __metal_driver_sifive_fe310_g000_hfxosc { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h deleted file mode 100644 index 67f818f7b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_pll.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H - -struct __metal_driver_sifive_fe310_g000_pll; - -#include -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_pll { - void (*init)(struct __metal_driver_sifive_fe310_g000_pll *pll); - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) - -struct __metal_driver_sifive_fe310_g000_pll { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h deleted file mode 100644 index 87c9ca985..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H - -#include -#include - -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); -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) - -struct __metal_driver_sifive_fe310_g000_prci { -}; - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_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_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_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h deleted file mode 100644 index 9e6f2faf6..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_global-external-interrupts0.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H -#define METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H - -#include -#include - -struct __metal_driver_vtable_sifive_global_external_interrupts0 { - struct metal_interrupt_vtable global0_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) - -struct __metal_driver_sifive_global_external_interrupts0 { - struct metal_interrupt irc; - int init_done; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h deleted file mode 100644 index a0caeaba8..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H -#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_button { - struct metal_button_vtable button_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) - -struct __metal_driver_sifive_gpio_button { - struct metal_button button; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h deleted file mode 100644 index a8dacf116..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H -#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_led { - struct metal_led_vtable led_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) - -struct __metal_driver_sifive_gpio_led { - struct metal_led led; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h deleted file mode 100644 index c9c7839e9..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H -#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_switch { - struct metal_switch_vtable switch_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) - -struct __metal_driver_sifive_gpio_switch { - struct metal_switch flip; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h deleted file mode 100644 index cc56dc722..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO0_H -#define METAL__DRIVERS__SIFIVE_GPIO0_H - -#include -#include - -struct __metal_driver_vtable_sifive_gpio0 { - const struct __metal_gpio_vtable gpio; -}; - -//struct __metal_driver_sifive_gpio0; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) - -struct __metal_driver_sifive_gpio0 { - struct metal_gpio gpio; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h deleted file mode 100644 index aa8d63078..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H -#define METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H - -#include -#include - -struct __metal_driver_vtable_sifive_local_external_interrupts0 { - struct metal_interrupt_vtable local0_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) - -struct __metal_driver_sifive_local_external_interrupts0 { - struct metal_interrupt irc; - int init_done; -}; - - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h deleted file mode 100644 index 90d4c831e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_SPI0_H -#define METAL__DRIVERS__SIFIVE_SPI0_H - -#include -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_spi0 { - const struct metal_spi_vtable spi; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0) - -struct __metal_driver_sifive_spi0 { - struct metal_spi spi; - unsigned long baud_rate; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h deleted file mode 100644 index e87db2c83..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_TEST0_H -#define METAL__DRIVERS__SIFIVE_TEST0_H - -#include -#include - -struct __metal_driver_vtable_sifive_test0 { - const struct __metal_shutdown_vtable shutdown; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_test0) - -struct __metal_driver_sifive_test0 { - struct __metal_shutdown shutdown; -}; - - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h deleted file mode 100644 index 11d954002..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_UART0_H -#define METAL__DRIVERS__SIFIVE_UART0_H - -#include -#include -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_uart0 { - const struct metal_uart_vtable uart; -}; - -struct __metal_driver_sifive_uart0; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0) - -struct __metal_driver_sifive_uart0 { - struct metal_uart uart; - unsigned long baud_rate; -}; - - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/gpio.h deleted file mode 100644 index 513687dd7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/gpio.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__GPIO_H -#define METAL__GPIO_H - -#include - -/*! - * @file gpio.h - * @brief API for manipulating general-purpose input/output - */ - -struct metal_gpio; - -struct __metal_gpio_vtable { - int (*disable_input)(struct metal_gpio *, long pins); - long (*output)(struct metal_gpio *); - 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); -}; - -/*! - * @struct metal_gpio - * @brief The handle for a GPIO interface - */ -struct metal_gpio { - const struct __metal_gpio_vtable *vtable; -}; - -/*! - * @brief Get a GPIO device handle - * @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); - -/*! - * @brief Disable 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 disabled - */ -inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; - } - - return gpio->vtable->disable_input(gpio, (1 << pin)); -} - -/*! - * @brief Enable 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 enabled - */ -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 Set the output value of a GPIO pin - * @param gpio The handle for the GPIO interface - * @param pin The pin number indexed from 0 - * @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; - } - - if(value == 0) { - return gpio->vtable->output_clear(gpio, (1 << pin)); - } else { - return gpio->vtable->output_set(gpio, (1 << pin)); - } -} - -/*! - * @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_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 0; - } - - long value = gpio->vtable->output(gpio); - - if(value & (1 << pin)) { - return 1; - } else { - return 0; - } -} - -/*! - * @brief Clears the value of the GPIO pin - * @param gpio The handle for the GPIO interface - * @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; - } - - return gpio->vtable->output_clear(gpio, (1 << pin)); -} - -/*! - * @brief Toggles the value of the GPIO pin - * @param gpio The handle for the GPIO interface - * @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; - } - - return gpio->vtable->output_toggle(gpio, (1 << pin)); -} - -/*! - * @brief Enables and sets the pinmux for a GPIO pin - * @param gpio The handle for the GPIO interface - * @param pin The bitmask for the pin to enable pinmux on - * @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; - } - - return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin)); -} - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/interrupt.h deleted file mode 100644 index 43f587aca..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/interrupt.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__INTERRUPT_H -#define METAL__INTERRUPT_H - -/*! @file interrupt.h - * @brief API for registering and manipulating interrupts - */ - -#include - -/*! - * @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_vector_mode; - -/*! - * @brief Function signature for interrupt callback handlers - */ -typedef void (*metal_interrupt_handler_t) (int, void *); - -struct metal_interrupt; - -struct metal_interrupt_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 (*interrupt_vector_enable)(struct metal_interrupt *controller, - int id, metal_vector_mode mode); - 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); -}; - -/*! - * @brief A handle for an interrupt - */ -struct metal_interrupt { - const struct metal_interrupt_vtable *vtable; -}; - -/*! - * @brief Initialize a given interrupt controller - * - * Initialize a given interrupt controller. This function must be called - * before any interrupts are registered or enabled with the handler. It - * is invalid to initialize an interrupt controller more than once. - * - * @param controller The handle for the interrupt controller - */ -inline void metal_interrupt_init(struct metal_interrupt *controller) -{ - return controller->vtable->interrupt_init(controller); -} - - -/*! - * @brief Register an interrupt handler - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to register - * @param handler The interrupt handler callback - * @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); -} - -/*! - * @brief Enable an interrupt - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to enable - * @return 0 upon success - */ -inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) -{ - return controller->vtable->interrupt_enable(controller, id); -} - -/*! - * @brief Disable an interrupt - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to disable - * @return 0 upon success - */ -inline int metal_interrupt_disable(struct metal_interrupt *controller, int id) -{ - return controller->vtable->interrupt_disable(controller, id); -} - -/*! - * @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); -} - -/*! - * @brief Disable an interrupt vector - * @param controller The handle for the 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) -{ - 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) -{ - return controller->vtable->command_request(controller, cmd, data); -} - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/io.h deleted file mode 100644 index 450054142..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__IO_H -#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)) - -/* Allows users to specify arbitrary fences. */ -#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 short __metal_io_u16; -typedef unsigned int __metal_io_u32; -#if __riscv_xlen >= 64 -typedef unsigned long __metal_io_u64; -#endif - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/itim.h deleted file mode 100644 index 1a2a05b8b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/itim.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__ITIM_H -#define METAL__ITIM_H - -/*! @file itim.h - * - * 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"))) - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/led.h deleted file mode 100644 index a430b84c2..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/led.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__LED_H -#define METAL__LED_H - -/*! - * @file led.h - * @brief API for manipulating LEDs - */ - -struct metal_led; - -struct metal_led_vtable { - int (*led_exist)(struct metal_led *led, char *label); - void (*led_enable)(struct metal_led *led); - void (*led_on)(struct metal_led *led); - void (*led_off)(struct metal_led *led); - void (*led_toggle)(struct metal_led *led); -}; - -/*! - * @brief A handle for an LED - */ -struct metal_led { - const struct metal_led_vtable *vtable; -}; - -/*! - * @brief Get a handle for an 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); - -/*! - * @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 - */ -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); } - -/*! - * @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); } - -/*! - * @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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/lock.h deleted file mode 100644 index d863aa96e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/lock.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__LOCK_H -#define METAL__LOCK_H - -#include -#include - -/*! - * @file lock.h - * @brief An API for creating and using a software lock/mutex - */ - -/* TODO: How can we make the exception code platform-independant? */ -#define _METAL_STORE_AMO_ACCESS_FAULT 7 - -/*! - * @def METAL_LOCK_DECLARE - * @brief Declare a lock - * - * 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 - -/*! - * @brief A handle for a lock - */ -struct metal_lock { - 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. - * - * 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) { -#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) { - return 1; - } - - /* If the memory doesn't support atomics, report an error */ - if(!metal_memory_supports_atomics(lock_mem)) { - return 2; - } - - lock->_state = 0; - - return 0; -#else - return 3; -#endif -} - -/*! - * @brief Take a lock - * @param lock The handle for a lock - * @return 0 if the lock is successfully taken - * - * 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) { -#ifdef __riscv_atomic - int old = 1; - int new = 1; - - while(old != 0) { - __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])" - : [old] "=r" (old) - : [new] "r" (new), [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))); - - /* Trigger a Store/AMO access fault */ - _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); - - /* If execution returns, indicate failure */ - return 1; -#endif -} - -/*! - * @brief Give back a held lock - * @param lock The handle for a lock - * @return 0 if the lock is successfully given - * - * 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) { -#ifdef __riscv_atomic - __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))); - - /* Trigger a Store/AMO access fault */ - _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); - - /* If execution returns, indicate failure */ - return 1; -#endif -} - -#endif /* METAL__LOCK_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine.h deleted file mode 100644 index f76dbd632..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine.h +++ /dev/null @@ -1,872 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef ASSEMBLY - -#include - -#ifdef __METAL_MACHINE_MACROS - -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____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_NUM_PARENTS 1 - -#ifndef __METAL_PLIC_SUBINTERRUPTS -#define __METAL_PLIC_SUBINTERRUPTS 0 -#endif -#ifndef __METAL_PLIC_NUM_PARENTS -#define __METAL_PLIC_NUM_PARENTS 0 -#endif -#ifndef __METAL_CLIC_SUBINTERRUPTS -#define __METAL_CLIC_SUBINTERRUPTS 0 -#endif - -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ - -#else /* ! __METAL_MACHINE_MACROS */ - -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H - -#define __METAL_CLINT_2000000_INTERRUPTS 2 - -#define METAL_MAX_CLINT_INTERRUPTS 2 - -#define __METAL_CLINT_NUM_PARENTS 2 - -#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 - -#define __METAL_PLIC_SUBINTERRUPTS 27 - -#define METAL_MAX_PLIC_INTERRUPTS 1 - -#define __METAL_PLIC_NUM_PARENTS 1 - -#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_GLOBAL_EXT_INTERRUPTS 0 - -#define __METAL_GPIO_10012000_INTERRUPTS 16 - -#define METAL_MAX_GPIO_INTERRUPTS 16 - -#define __METAL_SERIAL_10013000_INTERRUPTS 1 - -#define METAL_MAX_UART_INTERRUPTS 1 - - -#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; - -/* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; - -/* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; - -struct metal_memory __metal_dt_mem_dtim_80000000; - -struct metal_memory __metal_dt_mem_spi_10014000; - -/* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; - -/* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; - -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; - -struct metal_pmp __metal_dt_pmp; - -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; - -/* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; - -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; - -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; - -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; - -/* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; - -/* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; - -/* From clock@3 */ -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; - -/* From clock@4 */ -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; - - - -/* --------------------- fixed_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; - } - else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) { - return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY; - } - else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { - return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; - } - else { - return 0; - } -} - - - -/* --------------------- fixed_factor_clock ------------ */ - - -/* --------------------- sifive_clint0 ------------ */ -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else if (idx == 1) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; - } - else { - return NULL; - } -} - -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) -{ - if (idx == 0) { - return 3; - } - else if (idx == 1) { - return 7; - } - else { - return 0; - } -} - - - -/* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) -{ - if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 0; - } - else { - return -1; - } -} - -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) -{ - if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; - } - else { - return 0; - } -} - -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; - } - else { - return NULL; - } -} - -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; - } - else { - return 0; - } -} - - - -/* --------------------- sifive_plic0 ------------ */ -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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) -{ - if (idx == 0) { - return 11; - } - else if (idx == 0) { - return 11; - } - else { - return 0; - } -} - - - -/* --------------------- 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) -{ - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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))) { - return 9; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { - return 10; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { - return 11; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { - return 12; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { - return 13; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { - return 14; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { - return 15; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { - return 16; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { - return 17; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { - return 18; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { - return 19; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { - return 20; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { - return 21; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { - return 22; - } - else { - return 0; - } -} - - - -/* --------------------- sifive_gpio_button ------------ */ - - -/* --------------------- sifive_gpio_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) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else { - return NULL; - } -} - -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) -{ - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return 22; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return 19; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return 21; - } - else { - return 0; - } -} - -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) -{ - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return "LD0red"; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return "LD0green"; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return "LD0blue"; - } - else { - return ""; - } -} - - - -/* --------------------- sifive_gpio_switch ------------ */ - - -/* --------------------- sifive_spi0 ------------ */ -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 { - return 0; - } -} - -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 { - return 0; - } -} - -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) -{ - return (struct metal_clock *)&__metal_dt_clock_4.clock; -} - -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) -{ - return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; -} - -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) -{ - return 60; -} - -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) -{ - return 60; -} - - - -/* --------------------- sifive_test0 ------------ */ - - -/* --------------------- sifive_uart0 ------------ */ -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 { - return 0; - } -} - -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 { - return 0; - } -} - -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 { - return 0; - } -} - -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 { - return NULL; - } -} - -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) -{ - return 5; -} - -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) -{ - return (struct metal_clock *)&__metal_dt_clock_4.clock; -} - -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) -{ - return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; -} - -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) -{ - return 196608; -} - -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) -{ - return 196608; -} - - - -/* --------------------- sifive_fe310_g000_hfrosc ------------ */ -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) -{ - 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) -{ - return &__metal_driver_vtable_sifive_fe310_g000_prci; -} - -static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) -{ - return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; -} - - - -/* --------------------- sifive_fe310_g000_hfxosc ------------ */ -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) -{ - 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) -{ - return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; -} - - - -/* --------------------- sifive_fe310_g000_pll ------------ */ -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) -{ - 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) -{ - 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) -{ - return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; -} - -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( ) -{ - return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; -} - -static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) -{ - return 16000000; -} - - - -/* --------------------- sifive_fe310_g000_prci ------------ */ -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( ) -{ - 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( ) -{ - return &__metal_driver_vtable_sifive_fe310_g000_prci; -} - - - -/* --------------------- sifive_fu540_c000_l2 ------------ */ - - -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); -struct metal_memory *__metal_memory_table[] = { - &__metal_dt_mem_dtim_80000000, - &__metal_dt_mem_spi_10014000}; - -/* From serial@10013000 */ -#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart) - -#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart) - -#define __METAL_DT_STDOUT_UART_BAUD 115200 - -/* From clint@2000000 */ -#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller) - -#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller) - -#define __METAL_DT_MAX_HARTS 1 - -asm (".weak __metal_cpu_table"); -struct __metal_driver_cpu *__metal_cpu_table[] = { - &__metal_dt_cpu_0}; - -/* From interrupt_controller@c000000 */ -#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) - -#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) - -#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"); -struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { - &__metal_dt_gpio_10012000}; - -#define __METAL_DT_MAX_BUTTONS 0 - -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"); -struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { - &__metal_dt_led_0red, - &__metal_dt_led_0green, - &__metal_dt_led_0blue}; - -#define __METAL_DT_MAX_SWITCHES 0 - -asm (".weak __metal_switch_table"); -struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { - NULL }; -#define __METAL_DT_MAX_SPIS 1 - -asm (".weak __metal_spi_table"); -struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; - -/* 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 /* ! __METAL_MACHINE_MACROS */ - -#endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/inline.h deleted file mode 100644 index 8c0cd048b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/inline.h +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef ASSEMBLY - -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H - -#include - - -/* --------------------- fixed_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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- sifive_gpio_switch ------------ */ - - -/* --------------------- 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); - - -/* --------------------- sifive_test0 ------------ */ - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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( ); - - -/* --------------------- 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 ------------ */ - - -/* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -/* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -/* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -struct metal_memory __metal_dt_mem_dtim_80000000 = { - ._base_address = 2147483648UL, - ._size = 16384UL, - ._attrs = { - .R = 1, - .W = 1, - .X = 1, - .C = 1, - .A = 1}, -}; - -struct metal_memory __metal_dt_mem_spi_10014000 = { - ._base_address = 536870912UL, - ._size = 500000UL, - ._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, - .init_done = 0, -}; - -/* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0 = { - .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, -}; - -/* From interrupt_controller */ -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = { - .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable, - .init_done = 0, -}; - -/* From interrupt_controller@c000000 */ -struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { - .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable, - .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, -}; - -/* 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 = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { - .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 clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { - .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, -}; - -/* From clock@1 */ -struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { - .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.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, -}; - -/* From prci@10008000 */ -struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { -}; - - -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ -#endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/platform.h deleted file mode 100644 index 4ecd3e336..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/machine/platform.h +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H - -/* From clock@0 */ -#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL - -/* From clock@2 */ -#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL - -/* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL - -#define METAL_FIXED_CLOCK - -/* From clint@2000000 */ -#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL -#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL -#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL -#define METAL_RISCV_CLINT0_0_SIZE 65536UL - -#define METAL_RISCV_CLINT0 -#define METAL_RISCV_CLINT0_MSIP_BASE 0UL -#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL -#define METAL_RISCV_CLINT0_MTIME 49144UL - -/* From interrupt_controller@c000000 */ -#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592UL -#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL -#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL -#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 -#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 - -/* 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_AON0 -#define METAL_SIFIVE_AON0_WDOGCFG 0UL -#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL -#define METAL_SIFIVE_AON0_WDOGS 16UL -#define METAL_SIFIVE_AON0_WDOGFEED 24UL -#define METAL_SIFIVE_AON0_WDOGKEY 28UL -#define METAL_SIFIVE_AON0_WDOGCMP 32UL -#define METAL_SIFIVE_AON0_RTCCFG 64UL -#define METAL_SIFIVE_AON0_RTCLO 72UL -#define METAL_SIFIVE_AON0_RTCHI 72UL -#define METAL_SIFIVE_AON0_RTCS 80UL -#define METAL_SIFIVE_AON0_RTCCMP 96UL -#define METAL_SIFIVE_AON0_LFROSCCFG 112UL -#define METAL_SIFIVE_AON0_BACKUP0 128UL -#define METAL_SIFIVE_AON0_BACKUP1 132UL -#define METAL_SIFIVE_AON0_BACKUP2 136UL -#define METAL_SIFIVE_AON0_BACKUP3 140UL -#define METAL_SIFIVE_AON0_BACKUP4 144UL -#define METAL_SIFIVE_AON0_BACKUP5 148UL -#define METAL_SIFIVE_AON0_BACKUP6 152UL -#define METAL_SIFIVE_AON0_BACKUP7 152UL -#define METAL_SIFIVE_AON0_BACKUP8 160UL -#define METAL_SIFIVE_AON0_BACKUP9 164UL -#define METAL_SIFIVE_AON0_BACKUP10 168UL -#define METAL_SIFIVE_AON0_BACKUP11 172UL -#define METAL_SIFIVE_AON0_BACKUP12 176UL -#define METAL_SIFIVE_AON0_BACKUP13 180UL -#define METAL_SIFIVE_AON0_BACKUP14 184UL -#define METAL_SIFIVE_AON0_BACKUP15 188UL -#define METAL_SIFIVE_AON0_BACKUP16 192UL -#define METAL_SIFIVE_AON0_BACKUP17 196UL -#define METAL_SIFIVE_AON0_BACKUP18 200UL -#define METAL_SIFIVE_AON0_BACKUP19 204UL -#define METAL_SIFIVE_AON0_BACKUP20 208UL -#define METAL_SIFIVE_AON0_BACKUP21 212UL -#define METAL_SIFIVE_AON0_BACKUP22 216UL -#define METAL_SIFIVE_AON0_BACKUP23 220UL -#define METAL_SIFIVE_AON0_BACKUP24 224UL -#define METAL_SIFIVE_AON0_BACKUP25 228UL -#define METAL_SIFIVE_AON0_BACKUP26 232UL -#define METAL_SIFIVE_AON0_BACKUP27 236UL -#define METAL_SIFIVE_AON0_BACKUP28 240UL -#define METAL_SIFIVE_AON0_BACKUP29 244UL -#define METAL_SIFIVE_AON0_BACKUP30 248UL -#define METAL_SIFIVE_AON0_BACKUP31 252UL -#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL -#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL -#define METAL_SIFIVE_AON0_PMUIE 320UL -#define METAL_SIFIVE_AON0_PMUCAUSE 324UL -#define METAL_SIFIVE_AON0_PMUSLEEP 328UL -#define METAL_SIFIVE_AON0_PMUKEY 332UL - -/* From clock@3 */ - -#define METAL_SIFIVE_FE310_G000_HFROSC - -/* From clock@1 */ - -#define METAL_SIFIVE_FE310_G000_HFXOSC - -/* From prci@10008000 */ -#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL -#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL -#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL -#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL - -#define METAL_SIFIVE_FE310_G000_PRCI -#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL -#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL -#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL -#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL - -/* From clock@4 */ -#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL - -#define METAL_SIFIVE_FE310_G000_PLL - -/* From gpio@10012000 */ -#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL -#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL -#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL -#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL - -#define METAL_SIFIVE_GPIO0 -#define METAL_SIFIVE_GPIO0_VALUE 0UL -#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL -#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL -#define METAL_SIFIVE_GPIO0_PORT 12UL -#define METAL_SIFIVE_GPIO0_PUE 16UL -#define METAL_SIFIVE_GPIO0_DS 20UL -#define METAL_SIFIVE_GPIO0_RISE_IE 24UL -#define METAL_SIFIVE_GPIO0_RISE_IP 28UL -#define METAL_SIFIVE_GPIO0_FALL_IE 32UL -#define METAL_SIFIVE_GPIO0_FALL_IP 36UL -#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL -#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL -#define METAL_SIFIVE_GPIO0_LOW_IE 48UL -#define METAL_SIFIVE_GPIO0_LOW_IP 52UL -#define METAL_SIFIVE_GPIO0_IOF_EN 56UL -#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL -#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL - -/* From led@0red */ - -/* From led@0green */ - -/* From led@0blue */ - -#define METAL_SIFIVE_GPIO_LEDS - -/* From i2c@10016000 */ -#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL -#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL -#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL -#define METAL_SIFIVE_I2C0_0_SIZE 4096UL - -#define METAL_SIFIVE_I2C0 -#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL -#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL -#define METAL_SIFIVE_I2C0_CONTROL 8UL -#define METAL_SIFIVE_I2C0_TRANSMIT 12UL -#define METAL_SIFIVE_I2C0_RECEIVE 12UL -#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 - -#define METAL_SIFIVE_PWM0 -#define METAL_SIFIVE_PWM0_PWMCFG 0UL -#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL -#define METAL_SIFIVE_PWM0_PWMS 16UL -#define METAL_SIFIVE_PWM0_PWMCMP0 32UL -#define METAL_SIFIVE_PWM0_PWMCMP1 36UL -#define METAL_SIFIVE_PWM0_PWMCMP2 40UL -#define METAL_SIFIVE_PWM0_PWMCMP3 44UL - -/* 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 - -#define METAL_SIFIVE_SPI0 -#define METAL_SIFIVE_SPI0_SCKDIV 0UL -#define METAL_SIFIVE_SPI0_SCKMODE 4UL -#define METAL_SIFIVE_SPI0_CSID 16UL -#define METAL_SIFIVE_SPI0_CSDEF 20UL -#define METAL_SIFIVE_SPI0_CSMODE 24UL -#define METAL_SIFIVE_SPI0_DELAY0 40UL -#define METAL_SIFIVE_SPI0_DELAY1 44UL -#define METAL_SIFIVE_SPI0_FMT 64UL -#define METAL_SIFIVE_SPI0_TXDATA 72UL -#define METAL_SIFIVE_SPI0_RXDATA 76UL -#define METAL_SIFIVE_SPI0_TXMARK 80UL -#define METAL_SIFIVE_SPI0_RXMARK 84UL -#define METAL_SIFIVE_SPI0_FCTRL 96UL -#define METAL_SIFIVE_SPI0_FFMT 100UL -#define METAL_SIFIVE_SPI0_IE 112UL -#define METAL_SIFIVE_SPI0_IP 116UL - -/* From serial@10013000 */ -#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL -#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL -#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL -#define METAL_SIFIVE_UART0_0_SIZE 4096UL - -#define METAL_SIFIVE_UART0 -#define METAL_SIFIVE_UART0_TXDATA 0UL -#define METAL_SIFIVE_UART0_RXDATA 4UL -#define METAL_SIFIVE_UART0_TXCTRL 8UL -#define METAL_SIFIVE_UART0_RXCTRL 12UL -#define METAL_SIFIVE_UART0_IE 16UL -#define METAL_SIFIVE_UART0_IP 20UL -#define METAL_SIFIVE_UART0_DIV 24UL - -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/memory.h deleted file mode 100644 index b62d8b25a..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/memory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__MEMORY_H -#define METAL__MEMORY_H - -#include -#include - -/*! - * @file memory.h - * - * @brief API for enumerating memory blocks - */ - -struct _metal_memory_attributes { - int R : 1; - int W : 1; - int X : 1; - int C : 1; - 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; -}; - -/*! - * @brief Get the memory block which services the given address - * - * Given a physical memory address, get a handle for the memory block to which - * 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 - */ -struct metal_memory *metal_get_memory_from_address(const uintptr_t address); - -/*! - * @brief Get the base address for a memory block - * @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; -} - -/*! - * @brief Get the size of a memory block - * @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; -} - -/*! - * @brief Query if a memory block supports atomic operations - * @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; -} - -/*! - * @brief Query if a memory block is cacheable - * @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; -} - -#endif /* METAL__MEMORY_H */ - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/pmp.h deleted file mode 100644 index 9121b10a1..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/pmp.h +++ /dev/null @@ -1,204 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__PMP_H -#define METAL__PMP_H - -/*! - * @file metal/pmp.h - * - * @brief API for Configuring Physical Memory Protection on RISC-V Cores - * - * 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. - * - * Additional information about the use and configuration rules for PMPs - * can be found by reading the RISC-V Privileged Architecture Specification. - */ - -#include -#include - -struct metal_pmp; - -/*! - * @brief Set of available PMP addressing modes - */ -enum metal_pmp_address_mode { - /*! @brief Disable the PMP region */ - METAL_PMP_OFF = 0, - /*! @brief Use Top-of-Range mode */ - METAL_PMP_TOR = 1, - /*! @brief Use naturally-aligned 4-byte region mode */ - METAL_PMP_NA4 = 2, - /*! @brief Use naturally-aligned power-of-two mode */ - METAL_PMP_NAPOT = 3 -}; - -/*! - * @brief Configuration for a PMP region - */ -struct metal_pmp_config { - /*! @brief Sets whether reads to the PMP region succeed */ - int R : 1; - /*! @brief Sets whether writes to the PMP region succeed */ - int W : 1; - /*! @brief Sets whether the PMP region is executable */ - int X : 1; - - /*! @brief Sets the addressing mode of the PMP region */ - enum metal_pmp_address_mode A : 2; - - int _pad : 2; - - /*! @brief Sets whether the PMP region is locked */ - enum metal_pmp_locked { - METAL_PMP_UNLOCKED = 0, - METAL_PMP_LOCKED = 1 - } L : 1; -}; - -/*! - * @brief A handle for the PMP device - */ -struct metal_pmp { - /* The minimum granularity of the PMP region. Set by metal_pmp_init */ - uintptr_t _granularity[METAL_MAX_CORES]; -}; - -/*! - * @brief Get the PMP device handle - */ -struct metal_pmp *metal_pmp_get_device(void); - -/*! - * @brief Initialize the PMP - * @param pmp The PMP device handle to be initialized - * - * The PMP initialization routine is optional and may be called as many times - * as is desired. The effect of the initialization routine is to attempt to set - * all regions to unlocked and disabled, as well as to clear the X, W, and R - * bits. Only the pmp configuration of the hart which executes the routine will - * be affected. - * - * If any regions are fused to preset values by the implementation or locked, - * those PMP regions will silently remain uninitialized. - */ -void metal_pmp_init(struct metal_pmp *pmp); - -/*! - * @brief Configure a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to configure - * @param config The desired configuration of the PMP region - * @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); - -/*! - * @brief Get the configuration for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @param config Variable to store the PMP region configuration - * @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); - -/*! - * @brief Lock a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to lock - * @return 0 if the region is successfully locked - */ -int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the address for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @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); - -/*! - * @brief Get the address of a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return The address of the PMP region, or 0 if the region could not be read - */ -size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the addressing mode of a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @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); - -/*! - * @brief Get the addressing mode of a PMP region - * @param pmp The PMP device handle - * @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); - -/*! - * @brief Set the executable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param X The desired value of the executable bit - * @return 0 if the executable bit is successfully set - */ -int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X); - -/*! - * @brief Get the executable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the executable bit - */ -int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the writable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param W The desired value of the writable bit - * @return 0 if the writable bit is successfully set - */ -int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W); - -/*! - * @brief Get the writable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the writable bit - */ -int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the readable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param R The desired value of the readable bit - * @return 0 if the readable bit is successfully set - */ -int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R); - -/*! - * @brief Set the readable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the readable bit - */ -int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/privilege.h deleted file mode 100644 index c5212e5d1..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/privilege.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__PRIVILEGE_H -#define METAL__PRIVILEGE_H - -/*! - * @file metal/privilege.h - * - * @brief API for manipulating the privilege mode of a RISC-V system - * - * Additional information about privilege modes on RISC-V systems can be found - * by reading the RISC-V Privileged Architecture Specification v1.10. - */ - -#include - -enum metal_privilege_mode { - METAL_PRIVILEGE_USER = 0, - METAL_PRIVILEGE_SUPERVISOR = 1, - METAL_PRIVELEGE_MACHINE = 3, -}; - -#if __riscv_xlen == 32 -typedef uint32_t metal_xreg_t; -#elif __riscv_xlen == 64 -typedef uint64_t metal_xreg_t; -#endif - -#if __riscv_flen == 32 -typedef uint32_t metal_freg_t; -#elif __riscv_flen == 64 -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 t0; - metal_xreg_t t1; - metal_xreg_t t2; - - 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; -#ifndef __riscv_32e - 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 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 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 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; -#endif /* __riscv_flen */ -}; - -typedef void (*metal_privilege_entry_point_t)(); - -void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/shutdown.h deleted file mode 100644 index 3bebfa742..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/shutdown.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SHUTDOWN_H -#define METAL__SHUTDOWN_H - -/*! - * @file shutdown.h - * @brief API for shutting down a machine - */ - -struct __metal_shutdown; - -struct __metal_shutdown_vtable { - 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); } - -/*! - * @brief The public METAL shutdown interface - * - * Shuts down the machine, if the machine enables an interface for - * shutting down. When no interface is provided, will cause the machine - * to spin indefinitely. - * - * @param code The return code to set. 0 indicates program success. - */ -void metal_shutdown(int code) __attribute__((noreturn)); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/spi.h deleted file mode 100644 index b011fe3ce..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/spi.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SPI_H -#define METAL__SPI_H - -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; - - /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ - unsigned int polarity : 1; - /*! @brief The phase of the SPI transfer, equivalent to CPHA */ - unsigned int phase : 1; - /*! @brief The endianness of the SPI transfer */ - unsigned int little_endian : 1; - /*! @brief The active state of the chip select line */ - unsigned int cs_active_high : 1; - /*! @brief The chip select ID to activate for the SPI transfer */ - unsigned int csid; -}; - -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 (*get_baud_rate)(struct metal_spi *spi); - int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); -}; - -/*! @brief A handle for a SPI device */ -struct metal_spi { - const struct metal_spi_vtable *vtable; -}; - -/*! @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); - -/*! @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); } - -/*! @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. - * @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) { - return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); -} - -/*! @brief Get the current baud rate of the SPI device - * @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); } - -/*! @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/switch.h deleted file mode 100644 index d1c35bc93..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/switch.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SWITCH_H -#define METAL__SWITCH_H - -/*! - * @file switch.h - * @brief API for reading toggle switches - */ - -#include - -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); - int (*get_interrupt_id)(struct metal_switch *sw); -}; - -/*! - * @brief A handle for a switch - */ -struct metal_switch { - const struct metal_switch_vtable *vtable; -}; - -/*! - * @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 - */ -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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/timer.h deleted file mode 100644 index eeae1f60b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/timer.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__TIMER_H -#define METAL__TIMER_H - -/*! - * @file timer.h - * @brief API for reading and manipulating the machine timer - */ - -/*! - * @brief Read the machine cycle count - * @param hartid The hart ID to read the cycle count of - * @param cyclecount The variable to hold the value - * @return 0 upon success - */ -int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); - -/*! - * @brief Get the machine timebase frequency - * @param hartid The hart ID to read the timebase of - * @param timebase The variable to hold the value - * @return 0 upon success - */ -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 - * @return 0 upon success - */ -int metal_timer_set_tick(int hartid, int second); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/tty.h deleted file mode 100644 index d2583e3be..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/tty.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__TTY_H -#define METAL__TTY_H - -/*! - * @file tty.h - * @brief API for emulated serial teriminals - */ - -/*! - * @brief Write a character to the default output device - * - * 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); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/uart.h deleted file mode 100644 index 611792a6c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/install/include/metal/uart.h +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__UART_H -#define METAL__UART_H - -/*! - * @file uart.h - * @brief API for UART serial ports - */ - -#include - -struct metal_uart; - -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 (*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); - int (*get_interrupt_id)(struct metal_uart *uart); -}; - -/*! - * @brief Handle for a UART serial device - */ -struct metal_uart { - const struct metal_uart_vtable *vtable; -}; - -/*! - * @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. - * - * @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); } - -/*! - * @brief Output a character over the UART - * @param uart The UART device handle - * @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); } - -/*! - * @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 - */ -inline int metal_uart_getc(struct metal_uart *uart, unsigned char *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); } - -/*! - * @brief Set the baud rate of the UART peripheral - * @param uart The UART device handle - * @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); } - -/*! - * @brief Get the interrupt controller of the UART peripheral - * - * Get the interrupt controller for the UART peripheral. The interrupt - * controller must be initialized before any interrupts can be registered - * or enabled with it. - * - * @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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-inline.h deleted file mode 100644 index 8c0cd048b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-inline.h +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef ASSEMBLY - -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H - -#include - - -/* --------------------- fixed_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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- sifive_gpio_switch ------------ */ - - -/* --------------------- 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); - - -/* --------------------- sifive_test0 ------------ */ - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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); - - -/* --------------------- 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( ); - - -/* --------------------- 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 ------------ */ - - -/* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -/* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -/* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5 = { - .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, -}; - -struct metal_memory __metal_dt_mem_dtim_80000000 = { - ._base_address = 2147483648UL, - ._size = 16384UL, - ._attrs = { - .R = 1, - .W = 1, - .X = 1, - .C = 1, - .A = 1}, -}; - -struct metal_memory __metal_dt_mem_spi_10014000 = { - ._base_address = 536870912UL, - ._size = 500000UL, - ._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, - .init_done = 0, -}; - -/* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0 = { - .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, -}; - -/* From interrupt_controller */ -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = { - .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable, - .init_done = 0, -}; - -/* From interrupt_controller@c000000 */ -struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { - .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable, - .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, -}; - -/* 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 = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { - .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, -}; - -/* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { - .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 clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { - .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, -}; - -/* From clock@1 */ -struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { - .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.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, -}; - -/* From prci@10008000 */ -struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { -}; - - -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ -#endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-platform.h deleted file mode 100644 index 4ecd3e336..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal-platform.h +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H - -/* From clock@0 */ -#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL - -/* From clock@2 */ -#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL - -/* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL - -#define METAL_FIXED_CLOCK - -/* From clint@2000000 */ -#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL -#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL -#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL -#define METAL_RISCV_CLINT0_0_SIZE 65536UL - -#define METAL_RISCV_CLINT0 -#define METAL_RISCV_CLINT0_MSIP_BASE 0UL -#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL -#define METAL_RISCV_CLINT0_MTIME 49144UL - -/* From interrupt_controller@c000000 */ -#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592UL -#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL -#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL -#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 -#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 - -/* 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_AON0 -#define METAL_SIFIVE_AON0_WDOGCFG 0UL -#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL -#define METAL_SIFIVE_AON0_WDOGS 16UL -#define METAL_SIFIVE_AON0_WDOGFEED 24UL -#define METAL_SIFIVE_AON0_WDOGKEY 28UL -#define METAL_SIFIVE_AON0_WDOGCMP 32UL -#define METAL_SIFIVE_AON0_RTCCFG 64UL -#define METAL_SIFIVE_AON0_RTCLO 72UL -#define METAL_SIFIVE_AON0_RTCHI 72UL -#define METAL_SIFIVE_AON0_RTCS 80UL -#define METAL_SIFIVE_AON0_RTCCMP 96UL -#define METAL_SIFIVE_AON0_LFROSCCFG 112UL -#define METAL_SIFIVE_AON0_BACKUP0 128UL -#define METAL_SIFIVE_AON0_BACKUP1 132UL -#define METAL_SIFIVE_AON0_BACKUP2 136UL -#define METAL_SIFIVE_AON0_BACKUP3 140UL -#define METAL_SIFIVE_AON0_BACKUP4 144UL -#define METAL_SIFIVE_AON0_BACKUP5 148UL -#define METAL_SIFIVE_AON0_BACKUP6 152UL -#define METAL_SIFIVE_AON0_BACKUP7 152UL -#define METAL_SIFIVE_AON0_BACKUP8 160UL -#define METAL_SIFIVE_AON0_BACKUP9 164UL -#define METAL_SIFIVE_AON0_BACKUP10 168UL -#define METAL_SIFIVE_AON0_BACKUP11 172UL -#define METAL_SIFIVE_AON0_BACKUP12 176UL -#define METAL_SIFIVE_AON0_BACKUP13 180UL -#define METAL_SIFIVE_AON0_BACKUP14 184UL -#define METAL_SIFIVE_AON0_BACKUP15 188UL -#define METAL_SIFIVE_AON0_BACKUP16 192UL -#define METAL_SIFIVE_AON0_BACKUP17 196UL -#define METAL_SIFIVE_AON0_BACKUP18 200UL -#define METAL_SIFIVE_AON0_BACKUP19 204UL -#define METAL_SIFIVE_AON0_BACKUP20 208UL -#define METAL_SIFIVE_AON0_BACKUP21 212UL -#define METAL_SIFIVE_AON0_BACKUP22 216UL -#define METAL_SIFIVE_AON0_BACKUP23 220UL -#define METAL_SIFIVE_AON0_BACKUP24 224UL -#define METAL_SIFIVE_AON0_BACKUP25 228UL -#define METAL_SIFIVE_AON0_BACKUP26 232UL -#define METAL_SIFIVE_AON0_BACKUP27 236UL -#define METAL_SIFIVE_AON0_BACKUP28 240UL -#define METAL_SIFIVE_AON0_BACKUP29 244UL -#define METAL_SIFIVE_AON0_BACKUP30 248UL -#define METAL_SIFIVE_AON0_BACKUP31 252UL -#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL -#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL -#define METAL_SIFIVE_AON0_PMUIE 320UL -#define METAL_SIFIVE_AON0_PMUCAUSE 324UL -#define METAL_SIFIVE_AON0_PMUSLEEP 328UL -#define METAL_SIFIVE_AON0_PMUKEY 332UL - -/* From clock@3 */ - -#define METAL_SIFIVE_FE310_G000_HFROSC - -/* From clock@1 */ - -#define METAL_SIFIVE_FE310_G000_HFXOSC - -/* From prci@10008000 */ -#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL -#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL -#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL -#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL - -#define METAL_SIFIVE_FE310_G000_PRCI -#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL -#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL -#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL -#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL - -/* From clock@4 */ -#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL - -#define METAL_SIFIVE_FE310_G000_PLL - -/* From gpio@10012000 */ -#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL -#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL -#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL -#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL - -#define METAL_SIFIVE_GPIO0 -#define METAL_SIFIVE_GPIO0_VALUE 0UL -#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL -#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL -#define METAL_SIFIVE_GPIO0_PORT 12UL -#define METAL_SIFIVE_GPIO0_PUE 16UL -#define METAL_SIFIVE_GPIO0_DS 20UL -#define METAL_SIFIVE_GPIO0_RISE_IE 24UL -#define METAL_SIFIVE_GPIO0_RISE_IP 28UL -#define METAL_SIFIVE_GPIO0_FALL_IE 32UL -#define METAL_SIFIVE_GPIO0_FALL_IP 36UL -#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL -#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL -#define METAL_SIFIVE_GPIO0_LOW_IE 48UL -#define METAL_SIFIVE_GPIO0_LOW_IP 52UL -#define METAL_SIFIVE_GPIO0_IOF_EN 56UL -#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL -#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL - -/* From led@0red */ - -/* From led@0green */ - -/* From led@0blue */ - -#define METAL_SIFIVE_GPIO_LEDS - -/* From i2c@10016000 */ -#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL -#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL -#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL -#define METAL_SIFIVE_I2C0_0_SIZE 4096UL - -#define METAL_SIFIVE_I2C0 -#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL -#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL -#define METAL_SIFIVE_I2C0_CONTROL 8UL -#define METAL_SIFIVE_I2C0_TRANSMIT 12UL -#define METAL_SIFIVE_I2C0_RECEIVE 12UL -#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 - -#define METAL_SIFIVE_PWM0 -#define METAL_SIFIVE_PWM0_PWMCFG 0UL -#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL -#define METAL_SIFIVE_PWM0_PWMS 16UL -#define METAL_SIFIVE_PWM0_PWMCMP0 32UL -#define METAL_SIFIVE_PWM0_PWMCMP1 36UL -#define METAL_SIFIVE_PWM0_PWMCMP2 40UL -#define METAL_SIFIVE_PWM0_PWMCMP3 44UL - -/* 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 - -#define METAL_SIFIVE_SPI0 -#define METAL_SIFIVE_SPI0_SCKDIV 0UL -#define METAL_SIFIVE_SPI0_SCKMODE 4UL -#define METAL_SIFIVE_SPI0_CSID 16UL -#define METAL_SIFIVE_SPI0_CSDEF 20UL -#define METAL_SIFIVE_SPI0_CSMODE 24UL -#define METAL_SIFIVE_SPI0_DELAY0 40UL -#define METAL_SIFIVE_SPI0_DELAY1 44UL -#define METAL_SIFIVE_SPI0_FMT 64UL -#define METAL_SIFIVE_SPI0_TXDATA 72UL -#define METAL_SIFIVE_SPI0_RXDATA 76UL -#define METAL_SIFIVE_SPI0_TXMARK 80UL -#define METAL_SIFIVE_SPI0_RXMARK 84UL -#define METAL_SIFIVE_SPI0_FCTRL 96UL -#define METAL_SIFIVE_SPI0_FFMT 100UL -#define METAL_SIFIVE_SPI0_IE 112UL -#define METAL_SIFIVE_SPI0_IP 116UL - -/* From serial@10013000 */ -#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL -#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL -#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL -#define METAL_SIFIVE_UART0_0_SIZE 4096UL - -#define METAL_SIFIVE_UART0 -#define METAL_SIFIVE_UART0_TXDATA 0UL -#define METAL_SIFIVE_UART0_RXDATA 4UL -#define METAL_SIFIVE_UART0_TXCTRL 8UL -#define METAL_SIFIVE_UART0_RXCTRL 12UL -#define METAL_SIFIVE_UART0_IE 16UL -#define METAL_SIFIVE_UART0_IP 20UL -#define METAL_SIFIVE_UART0_DIV 24UL - -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.default.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.default.lds deleted file mode 100644 index 7070af7e8..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.default.lds +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -OUTPUT_ARCH("riscv") - -ENTRY(_enter) - -MEMORY -{ - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 - flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120 -} - -PHDRS -{ - flash PT_LOAD; - ram_init PT_LOAD; - itim_init PT_LOAD; - ram PT_NULL; - itim PT_NULL; -} - -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); - - - .init : - { - KEEP (*(.text.metal.init.enter)) - KEEP (*(SORT_NONE(.init))) - KEEP (*(.text.libgloss.start)) - } >flash AT>flash :flash - - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.itim .itim.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash - - - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash - - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >flash AT>flash :flash - - - . = ALIGN(4); - - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >flash AT>flash :flash - - - .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 - - - .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 - - - .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 - - - .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 - - - .litimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_source_start = . ); - } >flash AT>flash :flash - - - .ditimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_target_start = . ); - } >ram AT>flash :ram_init - - - .itim : - { - *(.itim .itim.*) - } >flash AT>flash :flash - - - . = ALIGN(8); - PROVIDE( metal_segment_itim_target_end = . ); - - - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - PROVIDE( metal_segment_data_source_start = . ); - } >flash AT>flash :flash - - - .dalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_data_target_start = . ); - } >ram AT>flash :ram_init - - - .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 - - -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.h deleted file mode 100644 index f76dbd632..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/bsp/metal.h +++ /dev/null @@ -1,872 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - -#ifndef ASSEMBLY - -#include - -#ifdef __METAL_MACHINE_MACROS - -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____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_NUM_PARENTS 1 - -#ifndef __METAL_PLIC_SUBINTERRUPTS -#define __METAL_PLIC_SUBINTERRUPTS 0 -#endif -#ifndef __METAL_PLIC_NUM_PARENTS -#define __METAL_PLIC_NUM_PARENTS 0 -#endif -#ifndef __METAL_CLIC_SUBINTERRUPTS -#define __METAL_CLIC_SUBINTERRUPTS 0 -#endif - -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ - -#else /* ! __METAL_MACHINE_MACROS */ - -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H - -#define __METAL_CLINT_2000000_INTERRUPTS 2 - -#define METAL_MAX_CLINT_INTERRUPTS 2 - -#define __METAL_CLINT_NUM_PARENTS 2 - -#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 - -#define __METAL_PLIC_SUBINTERRUPTS 27 - -#define METAL_MAX_PLIC_INTERRUPTS 1 - -#define __METAL_PLIC_NUM_PARENTS 1 - -#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_GLOBAL_EXT_INTERRUPTS 0 - -#define __METAL_GPIO_10012000_INTERRUPTS 16 - -#define METAL_MAX_GPIO_INTERRUPTS 16 - -#define __METAL_SERIAL_10013000_INTERRUPTS 1 - -#define METAL_MAX_UART_INTERRUPTS 1 - - -#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; - -/* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; - -/* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; - -struct metal_memory __metal_dt_mem_dtim_80000000; - -struct metal_memory __metal_dt_mem_spi_10014000; - -/* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; - -/* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; - -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; - -struct metal_pmp __metal_dt_pmp; - -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; - -/* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; - -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; - -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; - -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; - -/* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; - -/* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; - -/* From clock@3 */ -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; - -/* From clock@4 */ -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; - - - -/* --------------------- fixed_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; - } - else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) { - return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY; - } - else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { - return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; - } - else { - return 0; - } -} - - - -/* --------------------- fixed_factor_clock ------------ */ - - -/* --------------------- sifive_clint0 ------------ */ -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else if (idx == 1) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; - } - else { - return NULL; - } -} - -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) -{ - if (idx == 0) { - return 3; - } - else if (idx == 1) { - return 7; - } - else { - return 0; - } -} - - - -/* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) -{ - if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 0; - } - else { - return -1; - } -} - -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) -{ - if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; - } - else { - return 0; - } -} - -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; - } - else { - return NULL; - } -} - -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; - } - else { - return 0; - } -} - - - -/* --------------------- sifive_plic0 ------------ */ -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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) -{ - if (idx == 0) { - return 11; - } - else if (idx == 0) { - return 11; - } - else { - return 0; - } -} - - - -/* --------------------- 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) -{ - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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; - } - else { - return 0; - } -} - -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))) { - return 9; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { - return 10; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { - return 11; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { - return 12; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { - return 13; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { - return 14; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { - return 15; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { - return 16; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { - return 17; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { - return 18; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { - return 19; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { - return 20; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { - return 21; - } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { - return 22; - } - else { - return 0; - } -} - - - -/* --------------------- sifive_gpio_button ------------ */ - - -/* --------------------- sifive_gpio_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) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; - } - else { - return NULL; - } -} - -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) -{ - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return 22; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return 19; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return 21; - } - else { - return 0; - } -} - -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) -{ - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return "LD0red"; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return "LD0green"; - } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return "LD0blue"; - } - else { - return ""; - } -} - - - -/* --------------------- sifive_gpio_switch ------------ */ - - -/* --------------------- sifive_spi0 ------------ */ -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 { - return 0; - } -} - -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 { - return 0; - } -} - -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) -{ - return (struct metal_clock *)&__metal_dt_clock_4.clock; -} - -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) -{ - return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; -} - -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) -{ - return 60; -} - -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) -{ - return 60; -} - - - -/* --------------------- sifive_test0 ------------ */ - - -/* --------------------- sifive_uart0 ------------ */ -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 { - return 0; - } -} - -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 { - return 0; - } -} - -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 { - return 0; - } -} - -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 { - return NULL; - } -} - -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) -{ - return 5; -} - -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) -{ - return (struct metal_clock *)&__metal_dt_clock_4.clock; -} - -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) -{ - return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; -} - -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) -{ - return 196608; -} - -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) -{ - return 196608; -} - - - -/* --------------------- sifive_fe310_g000_hfrosc ------------ */ -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) -{ - 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) -{ - return &__metal_driver_vtable_sifive_fe310_g000_prci; -} - -static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) -{ - return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; -} - - - -/* --------------------- sifive_fe310_g000_hfxosc ------------ */ -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) -{ - 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) -{ - return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; -} - - - -/* --------------------- sifive_fe310_g000_pll ------------ */ -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) -{ - 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) -{ - 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) -{ - return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; -} - -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( ) -{ - return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; -} - -static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) -{ - return 16000000; -} - - - -/* --------------------- sifive_fe310_g000_prci ------------ */ -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( ) -{ - 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( ) -{ - return &__metal_driver_vtable_sifive_fe310_g000_prci; -} - - - -/* --------------------- sifive_fu540_c000_l2 ------------ */ - - -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); -struct metal_memory *__metal_memory_table[] = { - &__metal_dt_mem_dtim_80000000, - &__metal_dt_mem_spi_10014000}; - -/* From serial@10013000 */ -#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart) - -#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart) - -#define __METAL_DT_STDOUT_UART_BAUD 115200 - -/* From clint@2000000 */ -#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller) - -#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller) - -#define __METAL_DT_MAX_HARTS 1 - -asm (".weak __metal_cpu_table"); -struct __metal_driver_cpu *__metal_cpu_table[] = { - &__metal_dt_cpu_0}; - -/* From interrupt_controller@c000000 */ -#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) - -#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller) - -#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"); -struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { - &__metal_dt_gpio_10012000}; - -#define __METAL_DT_MAX_BUTTONS 0 - -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"); -struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { - &__metal_dt_led_0red, - &__metal_dt_led_0green, - &__metal_dt_led_0blue}; - -#define __METAL_DT_MAX_SWITCHES 0 - -asm (".weak __metal_switch_table"); -struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { - NULL }; -#define __METAL_DT_MAX_SPIS 1 - -asm (".weak __metal_spi_table"); -struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; - -/* 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 /* ! __METAL_MACHINE_MACROS */ - -#endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url deleted file mode 100644 index f59b1cedd..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url +++ /dev/null @@ -1,5 +0,0 @@ -[{000214A0-0000-0000-C000-000000000046}] -Prop3=19,11 -[InternetShortcut] -IDList= -URL=https://github.com/sifive/freedom-metal-docs diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/crt0.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/crt0.S deleted file mode 100644 index 920ee4b9f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/crt0.S +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (c) 2017-2018 SiFive Inc. All rights reserved. - - This copyrighted material is made available to anyone wishing to use, - modify, copy, or redistribute it subject to the terms and conditions - of the FreeBSD License. This program is distributed in the hope that - it will be useful, but WITHOUT ANY WARRANTY expressed or implied, - including the implied warranties of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. A copy of this license is available at - http://www.opensource.org/licenses. -*/ - -/* crt0.S: Entry point for RISC-V METAL programs. */ - -.section .text.libgloss.start -.global _start -.type _start, @function - - /* _start is defined by the METAL to have been called with the following - * arguments: - * a0: the hart ID of the currently executing hart. Harts can start at - * any arbitrary point, it's the C library's job to ensure the code is - * safe. - * a1: a pointer to a description of the machine on which this code is - * currently executing. This is probably 0 on an embedded system - * because they tend to not be dynamically portable. As such, newlib - * ignores this argument. - * a2: a pointer to a function that must be run after the envirnoment has - * been initialized, but before user code can be expected to be run. - * If this is 0 then there is no function to be run. */ -_start: -.cfi_startproc -.cfi_undefined ra - - /* This is a bit funky: it's not usually sane for _start to return, but in - * this case we actually want to in order to signal an error to the METAL. */ - mv s0, ra - - /* Before doing anything we must initialize the global pointer, as we cannot - * safely perform any access that may be relaxed without GP being set. This - * is done with relaxation disabled to avoid relaxing the address calculation - * to just "addi gp, gp, 0". */ -.option push -.option norelax - la gp, __global_pointer$ -.option pop - - /* The METAL is designed for a bare-metal environment and therefor is expected - * to define its own stack pointer. We also align the stack pointer here - * because the only RISC-V ABI that's currently defined mandates 16-byte - * stack alignment. */ - la sp, _sp - - /* Increment by hartid number of stack sizes */ - li t0, 0 - la t1, __stack_size -1: - beq t0, a0, 1f - add sp, sp, t1 - addi t0, t0, 1 - j 1b -1: - andi sp, sp, -16 - - /* If we're not hart 0, skip the initialization work */ - la t0, __metal_boot_hart - bne a0, t0, _skip_init - - /* Embedded systems frequently require relocating the data segment before C - * code can be run -- for example, the data segment may exist in flash upon - * boot and then need to get relocated into a non-persistant writable memory - * before C code can execute. If this is the case we do so here. This step - * is optional: if the METAL provides an environment in which this relocation - * is not necessary then it must simply set metal_segment_data_source_start to - * be equal to metal_segment_data_target_start. */ - la t0, metal_segment_data_source_start - la t1, metal_segment_data_target_start - la t2, metal_segment_data_target_end - - beq t0, t1, 2f - bge t1, t2, 2f - -1: -#if __riscv_xlen == 32 - lw a0, 0(t0) - addi t0, t0, 4 - sw a0, 0(t1) - addi t1, t1, 4 - blt t1, t2, 1b -#else - ld a0, 0(t0) - addi t0, t0, 8 - sd a0, 0(t1) - addi t1, t1, 8 - blt t1, t2, 1b -#endif -2: - - /* Copy the ITIM section */ - la t0, metal_segment_itim_source_start - la t1, metal_segment_itim_target_start - la t2, metal_segment_itim_target_end - - beq t0, t1, 2f - bge t1, t2, 2f - -1: -#if __riscv_xlen == 32 - lw a0, 0(t0) - addi t0, t0, 4 - sw a0, 0(t1) - addi t1, t1, 4 - blt t1, t2, 1b -#else - ld a0, 0(t0) - addi t0, t0, 8 - sd a0, 0(t1) - addi t1, t1, 8 - blt t1, t2, 1b -#endif -2: - - /* Fence all subsequent instruction fetches until after the ITIM writes - complete */ - fence.i - - /* Zero the BSS segment. */ - la t1, metal_segment_bss_target_start - la t2, metal_segment_bss_target_end - - bge t1, t2, 2f - -1: -#if __riscv_xlen == 32 - sw x0, 0(t1) - addi t1, t1, 4 - blt t1, t2, 1b -#else - sd x0, 0(t1) - addi t1, t1, 8 - blt t1, t2, 1b -#endif -2: - - /* At this point we're in an environment that can execute C code. The first - * thing to do is to make the callback to the parent environment if it's been - * requested to do so. */ - beqz a2, 1f - jalr a2 -1: - - /* The RISC-V port only uses new-style constructors and destructors. */ - la a0, __libc_fini_array - call atexit - call __libc_init_array - -_skip_init: - - /* Synchronize harts so that secondary harts wait until hart 0 finishes - initializing */ - call __metal_synchronize_harts - - /* Check RISC-V isa and enable FS bits if Floating Point architecture. */ - csrr a5, misa - li a4, 0x10028 - and a5, a5, a4 - beqz a5, 1f - csrr a5, mstatus - lui a4, 0x2 - or a5, a5, a4 - csrw mstatus, a5 - csrwi fcsr, 0 -1: - - /* This is a C runtime, so main() is defined to have some arguments. Since - * there's nothing sane the METAL can pass we don't bother with that but - * instead just setup as close to a NOP as we can. */ - li a0, 1 /* argc=1 */ - la a1, argv /* argv = {"libgloss", NULL} */ - la a2, envp /* envp = {NULL} */ - call secondary_main - - /* Call exit to handle libc's cleanup routines. Under normal contains this - * shouldn't even get called, but I'm still not using a tail call here - * because returning to the METAL is the right thing to do in pathological - * situations. */ - call exit - - /* And here's where we return. Again, it's a bit odd but the METAL defines - * this as a bad idea (ie, as opposed to leaving it undefined) and at this - * point it's really the only thing left to do. */ - mv ra, s0 - ret - -.cfi_endproc - -/* RISC-V systems always use __libc_{init,fini}_array, but for compatibility we - * define _{init,fini} to do nothing. */ -.global _init -.type _init, @function -.global _fini -.type _fini, @function -_init: -_fini: - ret -.size _init, .-_init -.size _fini, .-_fini - -/* By default, secondary_main will cause secondary harts to spin forever. - * Users can redefine secondary_main themselves to run code on secondary harts */ -.weak secondary_main -.global secondary_main -.type secondary_main, @function - -secondary_main: - addi sp, sp, -16 -#if __riscv_xlen == 32 - sw ra, 4(sp) -#else - sd ra, 8(sp) -#endif - csrr t0, mhartid - la t1, __metal_boot_hart - beq t0, t1, 2f -1: - wfi - j 1b -2: - call main -#if __riscv_xlen == 32 - lw ra, 4(sp) -#else - ld ra, 8(sp) -#endif - addi sp, sp, 16 - ret - -/* This shim allows main() to be passed a set of arguments that can satisfy the - * requirements of the C API. */ -.section .rodata.libgloss.start -argv: -.dc.a name -envp: -.dc.a 0 -name: -.asciz "libgloss" - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/nanosleep.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/nanosleep.c deleted file mode 100644 index 8be22104e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/nanosleep.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -nanosleep(const struct timespec *rqtp, struct timespec *rmtp) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/synchronize_harts.c deleted file mode 100644 index 3e857d1df..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/synchronize_harts.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include -#include - -#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) -#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) -#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) - -/* - * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for - * hart 0 to finish copying the datat section, zeroing the BSS, and running - * the libc contstructors. - */ -void _synchronize_harts() { -#if __METAL_DT_MAX_HARTS > 1 - - int hart = metal_cpu_get_current_hartid(); - uintptr_t msip_base = 0; - - /* Get the base address of the MSIP registers */ -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); - msip_base += METAL_RISCV_CLINT0_MSIP_BASE; -#elif __METAL_DT_RISCV_CLIC0_HANDLE - msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); - msip_base += METAL_RISCV_CLIC0_MSIP_BASE; -#else -#warning No handle for CLINT or CLIC found, harts may be unsynchronized after init! -#endif - - /* Disable machine interrupts as a precaution */ - __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); - - if (hart == 0) { - /* Hart 0 waits for all harts to set their MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - while (METAL_MSIP(msip_base, i) == 0) ; - } - - /* Hart 0 clears everyone's MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - METAL_MSIP(msip_base, i) = 0; - } - } else { - /* Other harts set their MSIP bit to indicate they're ready */ - METAL_MSIP(msip_base, hart) = 1; - __asm__ volatile ("fence w,rw"); - - /* Wait for hart 0 to clear the MSIP bit */ - while (METAL_MSIP(msip_base, hart) == 1) ; - } - -#endif /* __METAL_DT_MAX_HARTS > 1 */ -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_access.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_access.c deleted file mode 100644 index c0bc1534d..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_access.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_access(const char *file, int mode) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chdir.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chdir.c deleted file mode 100644 index f33d26a44..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chdir.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_chdir(const char *path) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chmod.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chmod.c deleted file mode 100644 index 67412bf7d..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chmod.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_chmod(const char *path, mode_t mode) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chown.c deleted file mode 100644 index 302952eb1..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_chown.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_chown(const char *path, uid_t owner, gid_t group) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_close.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_close.c deleted file mode 100644 index 26dd6a59e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_close.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_close(int file) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_execve.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_execve.c deleted file mode 100644 index 9ae9f7e50..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_execve.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_execve(const char *name, char *const argv[], char *const env[]) -{ - errno = ENOMEM; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_exit.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_exit.c deleted file mode 100644 index 35f5f1a16..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_exit.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -void -_exit(int exit_status) -{ - metal_shutdown(exit_status); - while (1); -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_faccessat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_faccessat.c deleted file mode 100644 index 873d52c2e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_faccessat.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_faccessat(int dirfd, const char *file, int mode, int flags) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fork.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fork.c deleted file mode 100644 index 64e67569f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fork.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_fork() -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstat.c deleted file mode 100644 index fedc28977..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstat.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_fstat(int file, struct stat *st) -{ - errno = -ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstatat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstatat.c deleted file mode 100644 index f2f43bd9e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_fstatat.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_fstatat(int dirfd, const char *file, struct stat *st, int flags) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_ftime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_ftime.c deleted file mode 100644 index 65c156398..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_ftime.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_ftime(struct timeb *tp) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getcwd.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getcwd.c deleted file mode 100644 index 82e8404ee..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getcwd.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -char * -_getcwd(char *buf, size_t size) -{ - errno = -ENOSYS; - return NULL; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getpid.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getpid.c deleted file mode 100644 index 589ad117c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_getpid.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int -_getpid() -{ - return 1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c deleted file mode 100644 index 409b2ce2f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include - -int -_gettimeofday(struct timeval *tp, void *tzp) -{ - int rv; - unsigned long long mcc, timebase; - rv = metal_timer_get_cyclecount(0, &mcc); - if (rv != 0) { - return -1; - } - rv = metal_timer_get_timebase_frequency(0, &timebase); - if (rv != 0) { - return -1; - } - tp->tv_sec = mcc / timebase; - tp->tv_usec = mcc % timebase * 1000000 / timebase; - return 0; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_isatty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_isatty.c deleted file mode 100644 index dd4f1461b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_isatty.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int -_isatty(int file) -{ - return (file == STDOUT_FILENO); -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_kill.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_kill.c deleted file mode 100644 index 9003f266f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_kill.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_kill(int pid, int sig) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_link.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_link.c deleted file mode 100644 index 40d5912bc..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_link.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int _link(const char *old_name, const char *new_name) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lseek.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lseek.c deleted file mode 100644 index d28a781f8..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lseek.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -off_t -_lseek(int file, off_t ptr, int dir) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lstat.c deleted file mode 100644 index 97a45855f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_lstat.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -int _lstat(const char *file, struct stat *st) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_open.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_open.c deleted file mode 100644 index a59f627f0..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_open.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_open(const char *name, int flags, int mode) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_openat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_openat.c deleted file mode 100644 index 206de3bde..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_openat.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_openat(int dirfd, const char *name, int flags, int mode) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_read.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_read.c deleted file mode 100644 index 15833cabb..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_read.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -ssize_t -_read(int file, void *ptr, size_t len) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sbrk.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sbrk.c deleted file mode 100644 index cc01c8ffb..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sbrk.c +++ /dev/null @@ -1,39 +0,0 @@ -#include - -/* brk is handled entirely within the C library. This limits METAL programs that - * use the C library to be disallowed from dynamically allocating memory - * without talking to the C library, but that sounds like a sane way to go - * about it. Note that there is no error checking anywhere in this file, users - * will simply get the relevant error when actually trying to use the memory - * that's been allocated. */ -extern char metal_segment_heap_target_start; -extern char metal_segment_heap_target_end; -static char *brk = &metal_segment_heap_target_start; - -int -_brk(void *addr) -{ - brk = addr; - return 0; -} - -char * -_sbrk(ptrdiff_t incr) -{ - char *old = brk; - - /* If __heap_size == 0, we can't allocate memory on the heap */ - if(&metal_segment_heap_target_start == &metal_segment_heap_target_end) { - return (void *)-1; - } - - /* Don't move the break past the end of the heap */ - if ((brk + incr) < &metal_segment_heap_target_end) { - brk += incr; - } else { - brk = &metal_segment_heap_target_end; - return (void *)-1; - } - - return old; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_stat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_stat.c deleted file mode 100644 index 3c2e41910..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_stat.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int -_stat(const char *file, struct stat *st) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sysconf.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sysconf.c deleted file mode 100644 index 452a252ae..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_sysconf.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -/* Get configurable system variables. */ - -long -_sysconf(int name) -{ - switch (name) - { - case _SC_CLK_TCK: - return CLOCKS_PER_SEC; - } - - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_times.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_times.c deleted file mode 100644 index 6beedcb30..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_times.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include - -extern int _gettimeofday(struct timeval *, void *); - -/* Timing information for current process. From - newlib/libc/include/sys/times.h the tms struct fields are as follows: - - - clock_t tms_utime : user clock ticks - - clock_t tms_stime : system clock ticks - - clock_t tms_cutime : children's user clock ticks - - clock_t tms_cstime : children's system clock ticks - - Since maven does not currently support processes we set both of the - children's times to zero. Eventually we might want to separately - account for user vs system time, but for now we just return the total - number of cycles since starting the program. */ -clock_t -_times(struct tms *buf) -{ - int rv; - // when called for the first time, initialize t0 - static struct timeval t0; - if (t0.tv_sec == 0 && t0.tv_usec == 0) - _gettimeofday (&t0, 0); - - struct timeval t; - _gettimeofday (&t, 0); - - unsigned long long timebase; - rv = metal_timer_get_timebase_frequency(0, &timebase); - if (rv != 0) { - return -1; - } - - long long utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); - buf->tms_utime = utime * timebase / 1000000; - buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0; - return 0; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_unlink.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_unlink.c deleted file mode 100644 index b369d2017..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_unlink.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -_unlink(const char *name) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_utime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_utime.c deleted file mode 100644 index 33d557aa7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_utime.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -struct utimbuf; - -int -_utime(const char *path, const struct utimbuf *times) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_wait.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_wait.c deleted file mode 100644 index 9d459f14c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_wait.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int _wait(int *status) -{ - errno = ENOSYS; - return -1; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_write.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_write.c deleted file mode 100644 index bfcf0cb2b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/gloss/sys_write.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include -#include - -/* Write to a file. */ -ssize_t -_write(int file, const void *ptr, size_t len) -{ - if (file != STDOUT_FILENO) { - errno = ENOSYS; - return -1; - } - - const char *bptr = ptr; - for (size_t i = 0; i < len; ++i) - metal_tty_putc(bptr[i]); - return 0; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/button.h deleted file mode 100644 index 3ae1c143e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/button.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__BUTTON_H -#define METAL__BUTTON_H - -/*! - * @file button.h - * API for interfacing with physical buttons - */ - -#include - -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); - int (*get_interrupt_id)(struct metal_button *button); -}; - -/*! - * @brief A button device handle - * - * A `struct metal_button` is an implementation-defined object which represents - * a button on a development board. - */ -struct metal_button { - const struct metal_button_vtable *vtable; -}; - -/*! - * @brief Get a reference to a button - * - * @param label The DeviceTree label for the button - * @return A handle for the button - */ -struct metal_button* metal_button_get(char *label); - - -/*! - * @brief Get the interrupt controller for a button - * - * @param button The handle for the button - * @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); } - -/*! - * @brief Get the interrupt id for a button - * - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cache.h deleted file mode 100644 index bad026480..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cache.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__CACHE_H -#define METAL__CACHE_H - -/*! - * @file cache.h - * - * @brief API for configuring caches - */ -#include - -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); -}; - -/*! - * @brief a handle for a cache - */ -struct metal_cache { - const struct __metal_cache_vtable *vtable; -}; - -/*! - * @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. - */ -__inline__ void metal_cache_init(struct metal_cache *cache, int ways) { - cache->vtable->init(cache, ways); -} - -/*! - * @brief Get the current number of enabled cache ways - * @param cache The handle for the cache - * @return The current number of enabled cache ways - */ -__inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { - return cache->vtable->get_enabled_ways(cache); -} - -/*! - * @brief Enable the requested number of cache ways - * @param cache The handle for the cache - * @param ways The number of ways to enabled - * @return 0 if the ways are successfully enabled - */ -__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { - return cache->vtable->set_enabled_ways(cache, 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); - -/*! - * @brief Flush icache for L1 on the requested core - * @param hartid The core to flush - * @return None - */ -void metal_icache_l1_flush(int hartid); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/clock.h deleted file mode 100644 index 622fc9470..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/clock.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#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. - */ - -struct metal_clock; - -#include - -/* The generic interface to all clocks. */ -struct __metal_clock_vtable { - long (*get_rate_hz)(const struct metal_clock *clk); - long (*set_rate_hz)(struct metal_clock *clk, long hz); -}; - -/*! - * @brief Function signature of clock rate change callbacks - */ -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 Type for the linked list of callbacks for clock rate changes - */ -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. - * - * 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 linked list */ - metal_clock_callback *_pre_rate_change_callback; - - /* Post-rate change callback linked list */ - metal_clock_callback *_post_rate_change_callback; -}; - -/*! - * @brief Returns the current rate of the given 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); } - -/*! - * @brief Set the current rate of a clock - * - * @param clk The handle for the clock - * @param hz The desired rate in Hz - * @return The new rate of the clock in Hz. - * - * Attempts to set the current rate of the given clock to as close as possible - * 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. - */ -__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); - - _metal_clock_call_all_callbacks(clk->_post_rate_change_callback); - - return out; -} - -/*! - * @brief Register a callback that must be called before a rate change - * - * @param clk The handle for the clock - * @param cb The callback to be registered - */ -__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); -} - -/*! - * @brief Registers a callback that must be called after a rate change - * - * @param clk The handle for the clock - * @param cb The callback to be registered - */ -__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_FreedomStudio/freedom-metal/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/compiler.h deleted file mode 100644 index 62c0ea975..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/compiler.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__COMPILER_H -#define METAL__COMPILER_H - -#define __METAL_DECLARE_VTABLE(type) \ - extern const struct type type; - -#define __METAL_DEFINE_VTABLE(type) \ - const struct type type - -#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))) - -void _metal_trap(int ecode); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cpu.h deleted file mode 100644 index dbd3dbfb5..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/cpu.h +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ - -/* SPDX-License-Identifier: Apache-2.0 */ - -/*! @file cpu.h - * @brief API for accessing CPU capabilities. - */ - -#ifndef METAL__CPU_H -#define METAL__CPU_H - -#include -#include - -struct metal_cpu; - -/*! - * @brief Function signature for exception handlers - */ -typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode); - -struct metal_cpu_vtable { - 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); - int (*get_tmr_interrupt_id)(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); - 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); -}; - -/*! @brief A device handle for a CPU hart - */ -struct metal_cpu { - const struct metal_cpu_vtable *vtable; -}; - -/*! @brief Get a reference to a CPU hart - * - * @param hartid The ID of the desired CPU hart - * @return A pointer to the CPU device handle - */ -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(void); - -/*! @brief Get the number of CPU harts - * - * @return The number of CPU harts */ -int metal_cpu_get_num_harts(void); - -/*! @brief Get the CPU cycle count timer value - * - * Get the value of the cycle count timer for a given CPU - * - * @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->mcycle_get(cpu); } - -/*! @brief Get the timebase of the CPU - * - * Get the value of the timebase of the cycle count timer - * - * @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); } - -/*! @brief Get the value of the mtime RTC - * - * Get the value of the mtime real-time clock. The CPU interrupt controller - * must be initialized before this function is called or the return value - * will be 0. - * - * @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); } - -/*! @brief Set the value of the RTC mtimecmp RTC - * - * Set the value of the mtime real-time clock compare register. The CPU - * interrupt controller must be initialized before this function is called - * or the return value will be -1; - * - * @param cpu The CPU device handle - * @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); } - -/*! @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. - * - * @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); } - -/*! @brief Get the RTC timer interrupt id - * - * Get the interrupt ID of the real-time clock interrupt - * - * @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); } - -/*! @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. - * - * @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); } - -/*! @brief Get the software interrupt id - * - * Get the interrupt ID for the software/inter-process interrupt - * - * @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); } - -/*! - * @brief Set the inter-process interrupt for a hart - * - * Trigger a software/inter-process interrupt for a hart. The CPU interrupt - * controller for the CPU handle passed to this function must be initialized - * before this function is called. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Clear the inter-process interrupt for a hart - * - * Clear the software/inter-process interrupt for a hart. The CPU interrupt - * controller for the CPU handle passed to this function must be initialized - * before this function is called. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Get the value of MSIP for the given hart - * - * Get the value of the machine software interrupt pending bit for - * the given hart. The CPU interrupt controller for the CPU handle passed - * as argument to this function must be initialized before this function - * is called. - * - * @param cpu the CPU device handle - * @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); } - -/*! - * @brief Get the interrupt controller for the CPU - * - * Get the CPU interrupt controller. The controller returned by this - * function must be initialized before any interrupts are registered - * or enabled and before any exception handlers are registered with - * this CPU. - * - * @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); } - -/*! - * @brief Register an exception handler - * - * 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); } - -/*! - * @brief Get the length of an instruction in bytes - * - * Get the length of an instruction in bytes. - * - * On RISC-V platforms, this is useful for detecting whether an instruction is - * compressed (2 bytes long) or uncompressed (4 bytes long). - * - * This function is useful in conjuction with `metal_cpu_get_exception_pc()` - * and `metal_cpu_set_exception_pc()` in order to cause the exception handler to - * return execution after the faulting instruction. - * - * @param cpu The CPU device handle - * @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); } - -/*! - * @brief Get the program counter of the current exception. - * - * This function must be called within an exception handler. The behavior is - * undefined outside of an exception handler. - * - * @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); } - -/*! - * @brief Set the exception program counter - * - * This function must be called within an exception handler. The behavior - * is undefined outside of an exception handler. - * - * This function can be used to cause an exception handler to return execution - * to an address other than the one that caused the exception. - * - * @param cpu the CPU device handle - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h deleted file mode 100644 index 2647c5981..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__FIXED_CLOCK_H -#define METAL__DRIVERS__FIXED_CLOCK_H - -struct __metal_driver_fixed_clock; - -#include -#include - -struct __metal_driver_vtable_fixed_clock { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_clock) - -struct __metal_driver_fixed_clock { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h deleted file mode 100644 index 936ce8d77..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__FIXED_FACTOR_CLOCK_H -#define METAL__DRIVERS__FIXED_FACTOR_CLOCK_H - -struct __metal_driver_fixed_factor_clock; - -#include -#include - -struct __metal_driver_vtable_fixed_factor_clock { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_fixed_factor_clock) - -struct __metal_driver_fixed_factor_clock { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h deleted file mode 100644 index 08d571e1c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_CLINT0_H -#define METAL__DRIVERS__RISCV_CLINT0_H - -#include -#include - -struct __metal_driver_vtable_riscv_clint0 { - struct metal_interrupt_vtable clint_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_clint0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_riscv_clint0 { - struct metal_interrupt controller; - int init_done; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h deleted file mode 100644 index ca91e0a95..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_CPU_H -#define METAL__DRIVERS__RISCV_CPU_H - -#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_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_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 -#if __riscv_xlen == 32 -#define METAL_MCAUSE_INTR 0x80000000UL -#define METAL_MCAUSE_CAUSE 0x000003FFUL -#else -#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_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 */ -/* 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_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_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_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_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_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_interrup_cmd_e; - -typedef struct __metal_interrupt_data { - long long pad : 64; - metal_interrupt_handler_t handler; - void *sub_int; - void *exint_data; -} __metal_interrupt_data; - -/* CPU interrupt controller */ - -uintptr_t __metal_myhart_id(void); - -struct __metal_driver_vtable_riscv_cpu_intc { - struct metal_interrupt_vtable controller_vtable; -}; - - -void __metal_interrupt_global_enable(void); -void __metal_interrupt_global_disable(void); -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) - -struct __metal_driver_riscv_cpu_intc { - struct metal_interrupt controller; - int init_done; - uintptr_t metal_mtvec_table[METAL_MAX_MI]; - __metal_interrupt_data metal_int_table[METAL_MAX_MI]; - metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; -}; - -/* CPU driver*/ -struct __metal_driver_vtable_cpu { - struct metal_cpu_vtable cpu_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) - -struct __metal_driver_cpu { - struct metal_cpu cpu; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h deleted file mode 100644 index 159ee6d69..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__RISCV_PLIC0_H -#define METAL__DRIVERS__RISCV_PLIC0_H - -#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 - -struct __metal_driver_vtable_riscv_plic0 { - struct metal_interrupt_vtable plic_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_plic0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_riscv_plic0 { - struct metal_interrupt controller; - int init_done; - metal_interrupt_handler_t metal_exint_table[__METAL_PLIC_SUBINTERRUPTS]; - __metal_interrupt_data metal_exdata_table[__METAL_PLIC_SUBINTERRUPTS]; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h deleted file mode 100644 index 2153cf384..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H -#define METAL__DRIVERS__SIFIVE_CCACHE0_H - -#include -#include - -struct __metal_driver_vtable_sifive_ccache0 { - struct __metal_cache_vtable cache; -}; - -struct __metal_driver_sifive_ccache0; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_ccache0) - -struct __metal_driver_sifive_ccache0 { - struct metal_cache cache; -}; - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h deleted file mode 100644 index 7fef38d19..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_CLIC0_H -#define METAL__DRIVERS__SIFIVE_CLIC0_H - -#include -#include - -#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_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) - -struct __metal_driver_vtable_sifive_clic0 { - struct metal_interrupt_vtable clic_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) - -#define __METAL_MACHINE_MACROS -#include -struct __metal_driver_sifive_clic0 { - struct metal_interrupt controller; - int init_done; - int pad[14]; - metal_interrupt_vector_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; - __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; -}; -#undef __METAL_MACHINE_MACROS - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h deleted file mode 100644 index d311f0cf2..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H - -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) - -struct __metal_driver_sifive_fe310_g000_hfrosc { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h deleted file mode 100644 index b86926fba..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfxosc.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_HFXOSC_H - -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_hfxosc { - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) - -struct __metal_driver_sifive_fe310_g000_hfxosc { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h deleted file mode 100644 index 64985c6bb..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h deleted file mode 100644 index 67f818f7b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_pll.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_PLL_H - -struct __metal_driver_sifive_fe310_g000_pll; - -#include -#include -#include - -struct __metal_driver_vtable_sifive_fe310_g000_pll { - void (*init)(struct __metal_driver_sifive_fe310_g000_pll *pll); - struct __metal_clock_vtable clock; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) - -struct __metal_driver_sifive_fe310_g000_pll { - struct metal_clock clock; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h deleted file mode 100644 index 387130be5..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H -#define METAL__DRIVERS__SIFIVE_FE310_G000_PRCI_H - -#include -#include - -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); -}; - -__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_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h deleted file mode 100644 index bb98f169e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/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 - -#include -#include - -struct __metal_driver_vtable_sifive_fu540_c000_l2 { - struct __metal_cache_vtable cache; -}; - -struct __metal_driver_sifive_fu540_c000_l2; - -__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_FreedomStudio/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h deleted file mode 100644 index 9e6f2faf6..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_global-external-interrupts0.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H -#define METAL__DRIVERS__SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0_H - -#include -#include - -struct __metal_driver_vtable_sifive_global_external_interrupts0 { - struct metal_interrupt_vtable global0_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) - -struct __metal_driver_sifive_global_external_interrupts0 { - struct metal_interrupt irc; - int init_done; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h deleted file mode 100644 index a0caeaba8..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H -#define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_button { - struct metal_button_vtable button_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) - -struct __metal_driver_sifive_gpio_button { - struct metal_button button; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h deleted file mode 100644 index a8dacf116..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H -#define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_led { - struct metal_led_vtable led_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) - -struct __metal_driver_sifive_gpio_led { - struct metal_led led; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h deleted file mode 100644 index c9c7839e9..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H -#define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H - -#include -#include -#include - -struct __metal_driver_vtable_sifive_switch { - struct metal_switch_vtable switch_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) - -struct __metal_driver_sifive_gpio_switch { - struct metal_switch flip; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h deleted file mode 100644 index cc56dc722..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_GPIO0_H -#define METAL__DRIVERS__SIFIVE_GPIO0_H - -#include -#include - -struct __metal_driver_vtable_sifive_gpio0 { - const struct __metal_gpio_vtable gpio; -}; - -//struct __metal_driver_sifive_gpio0; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) - -struct __metal_driver_sifive_gpio0 { - struct metal_gpio gpio; -}; - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h deleted file mode 100644 index aa8d63078..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H -#define METAL__DRIVERS__SIFIVE_EXTERNAL_INTERRUPTS0_H - -#include -#include - -struct __metal_driver_vtable_sifive_local_external_interrupts0 { - struct metal_interrupt_vtable local0_vtable; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) - -struct __metal_driver_sifive_local_external_interrupts0 { - struct metal_interrupt irc; - int init_done; -}; - - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h deleted file mode 100644 index b0ed143bf..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h +++ /dev/null @@ -1,27 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h deleted file mode 100644 index c4a6848e7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_SPI0_H -#define METAL__DRIVERS__SIFIVE_SPI0_H - -#include -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_spi0 { - const struct metal_spi_vtable spi; -}; - -__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_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h deleted file mode 100644 index e87db2c83..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_TEST0_H -#define METAL__DRIVERS__SIFIVE_TEST0_H - -#include -#include - -struct __metal_driver_vtable_sifive_test0 { - const struct __metal_shutdown_vtable shutdown; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_test0) - -struct __metal_driver_sifive_test0 { - struct __metal_shutdown shutdown; -}; - - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_trace.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_trace.h deleted file mode 100644 index 3c67522f4..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_trace.h +++ /dev/null @@ -1,23 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h deleted file mode 100644 index 5d585e783..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_UART0_H -#define METAL__DRIVERS__SIFIVE_UART0_H - -#include -#include -#include -#include -#include -#include - -struct __metal_driver_vtable_sifive_uart0 { - const struct metal_uart_vtable uart; -}; - -struct __metal_driver_sifive_uart0; - -__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_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h deleted file mode 100644 index 12b143d58..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h +++ /dev/null @@ -1,26 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/gpio.h deleted file mode 100644 index 7645494ff..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/gpio.h +++ /dev/null @@ -1,284 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__GPIO_H -#define METAL__GPIO_H - -#include -#include - -/*! - * @file gpio.h - * @brief API for manipulating general-purpose input/output - */ - -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; -}; - -/*! - * @brief Get a GPIO device handle - * @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(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 - * @param gpio The handle for the GPIO interface - * @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; - } - - return gpio->vtable->disable_input(gpio, (1 << pin)); -} - -/*! - * @brief Enable 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 enabled - */ -__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 - * @param pin The pin number indexed from 0 - * @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; - } - - if(value == 0) { - return gpio->vtable->output_clear(gpio, (1 << pin)); - } else { - return gpio->vtable->output_set(gpio, (1 << pin)); - } -} - -/*! - * @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_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; - } else { - return 0; - } -} - -/*! - * @brief Clears the value of the GPIO pin - * @param gpio The handle for the GPIO interface - * @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; - } - - return gpio->vtable->output_clear(gpio, (1 << pin)); -} - -/*! - * @brief Toggles the value of the GPIO pin - * @param gpio The handle for the GPIO interface - * @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; - } - - return gpio->vtable->output_toggle(gpio, (1 << pin)); -} - -/*! - * @brief Enables and sets the pinmux for a GPIO pin - * @param gpio The handle for the GPIO interface - * @param pin The bitmask for the pin to enable pinmux on - * @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; - } - - 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_FreedomStudio/freedom-metal/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/interrupt.h deleted file mode 100644 index 4f59bd36b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/interrupt.h +++ /dev/null @@ -1,461 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__INTERRUPT_H -#define METAL__INTERRUPT_H - -/*! @file interrupt.h - * @brief API for registering and manipulating interrupts - */ - -#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_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 Function signature for interrupt callback handlers - */ -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); - 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); - int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id); - 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); - int (*command_request)(struct metal_interrupt *controller, int cmd, void *data); - int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time); -}; - -/*! - * @brief A handle for an interrupt - */ -struct metal_interrupt { - const struct metal_interrupt_vtable *vtable; -}; - -/*! - * @brief Initialize a given interrupt controller - * - * Initialize a given interrupt controller. This function must be called - * before any interrupts are registered or enabled with the handler. It - * is invalid to initialize an interrupt controller more than once. - * - * @param controller The handle for the interrupt 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 - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to register - * @param handler The interrupt handler callback - * @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); -} - -/*! - * @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); -} - -/*! - * @brief Enable an interrupt - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to enable - * @return 0 upon success - */ -__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id) -{ - return controller->vtable->interrupt_enable(controller, id); -} - -/*! - * @brief Disable an interrupt - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to disable - * @return 0 upon success - */ -__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 Enable an interrupt vector - * @param controller The handle for the interrupt controller - * @param id The interrupt ID to enable - * @return 0 upon success - */ -__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id) -{ - return controller->vtable->interrupt_vector_enable(controller, id); -} - -/*! - * @brief Disable an interrupt vector - * @param controller The handle for the 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) -{ - return controller->vtable->interrupt_vector_disable(controller, id); -} - -/*! - * @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); -} - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/io.h deleted file mode 100644 index d55b4520a..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/io.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__IO_H -#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)) - -/* Allows users to specify arbitrary fences. */ -#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 short __metal_io_u16; -typedef unsigned int __metal_io_u32; -#if __riscv_xlen >= 64 -typedef unsigned long __metal_io_u64; -#endif - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/itim.h deleted file mode 100644 index 1a2a05b8b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/itim.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__ITIM_H -#define METAL__ITIM_H - -/*! @file itim.h - * - * 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"))) - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/led.h deleted file mode 100644 index f2aa39ceb..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/led.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__LED_H -#define METAL__LED_H - -/*! - * @file led.h - * @brief API for manipulating LEDs - */ - -struct metal_led; - -struct metal_led_vtable { - int (*led_exist)(struct metal_led *led, char *label); - void (*led_enable)(struct metal_led *led); - void (*led_on)(struct metal_led *led); - void (*led_off)(struct metal_led *led); - void (*led_toggle)(struct metal_led *led); -}; - -/*! - * @brief A handle for an LED - */ -struct metal_led { - const struct metal_led_vtable *vtable; -}; - -/*! - * @brief Get a handle for an 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); - -/*! - * @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 - */ -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); } - -/*! - * @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); } - -/*! - * @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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/lock.h deleted file mode 100644 index 0702cbf16..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/lock.h +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__LOCK_H -#define METAL__LOCK_H - -#include -#include -#include - -/*! - * @file lock.h - * @brief An API for creating and using a software lock/mutex - */ - -/* 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 - * - * 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 - -/*! - * @brief A handle for a lock - */ -struct metal_lock { - 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. - * - * 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) { -#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) { - return 1; - } - - /* If the memory doesn't support atomics, report an error */ - if(!metal_memory_supports_atomics(lock_mem)) { - return 2; - } - - lock->_state = 0; - - return 0; -#else - return 3; -#endif -} - -/*! - * @brief Take a lock - * @param lock The handle for a lock - * @return 0 if the lock is successfully taken - * - * 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) { -#ifdef __riscv_atomic - int old = 1; - int new = 1; - - 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)) - : "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))); - - /* Trigger a Store/AMO access fault */ - _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); - - /* If execution returns, indicate failure */ - return 1; -#endif -} - -/*! - * @brief Give back a held lock - * @param lock The handle for a lock - * @return 0 if the lock is successfully given - * - * 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) { -#ifdef __riscv_atomic - __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))); - - /* Trigger a Store/AMO access fault */ - _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); - - /* If execution returns, indicate failure */ - return 1; -#endif -} - -#endif /* METAL__LOCK_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/memory.h deleted file mode 100644 index 9de7d6162..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/memory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__MEMORY_H -#define METAL__MEMORY_H - -#include -#include - -/*! - * @file memory.h - * - * @brief API for enumerating memory blocks - */ - -struct _metal_memory_attributes { - 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; -}; - -/*! - * @brief Get the memory block which services the given address - * - * Given a physical memory address, get a handle for the memory block to which - * 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 - */ -struct metal_memory *metal_get_memory_from_address(const uintptr_t address); - -/*! - * @brief Get the base address for a memory block - * @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; -} - -/*! - * @brief Get the size of a memory block - * @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; -} - -/*! - * @brief Query if a memory block supports atomic operations - * @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; -} - -/*! - * @brief Query if a memory block is cacheable - * @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; -} - -#endif /* METAL__MEMORY_H */ - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h deleted file mode 100644 index d948656c8..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/pmp.h +++ /dev/null @@ -1,209 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__PMP_H -#define METAL__PMP_H - -/*! - * @file metal/pmp.h - * - * @brief API for Configuring Physical Memory Protection on RISC-V Cores - * - * 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. - * - * Additional information about the use and configuration rules for PMPs - * can be found by reading the RISC-V Privileged Architecture Specification. - */ - -#include -#include - -struct metal_pmp; - -/*! - * @brief Set of available PMP addressing modes - */ -enum metal_pmp_address_mode { - /*! @brief Disable the PMP region */ - METAL_PMP_OFF = 0, - /*! @brief Use Top-of-Range mode */ - METAL_PMP_TOR = 1, - /*! @brief Use naturally-aligned 4-byte region mode */ - METAL_PMP_NA4 = 2, - /*! @brief Use naturally-aligned power-of-two mode */ - METAL_PMP_NAPOT = 3 -}; - -/*! - * @brief Configuration for a PMP region - */ -struct metal_pmp_config { - /*! @brief Sets whether reads to the PMP region succeed */ - unsigned int R : 1; - /*! @brief Sets whether writes to the PMP region succeed */ - unsigned int W : 1; - /*! @brief Sets whether the PMP region is executable */ - unsigned int X : 1; - - /*! @brief Sets the addressing mode of the PMP region */ - enum metal_pmp_address_mode A : 2; - - int _pad : 2; - - /*! @brief Sets whether the PMP region is locked */ - enum metal_pmp_locked { - METAL_PMP_UNLOCKED = 0, - METAL_PMP_LOCKED = 1 - } L : 1; -}; - -/*! - * @brief A handle for the PMP device - */ -struct metal_pmp { - /* The minimum granularity of the PMP region. Set by metal_pmp_init */ - uintptr_t _granularity[METAL_MAX_CORES]; -}; - -/*! - * @brief Get the PMP device handle - */ -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 - * - * The PMP initialization routine is optional and may be called as many times - * as is desired. The effect of the initialization routine is to attempt to set - * all regions to unlocked and disabled, as well as to clear the X, W, and R - * bits. Only the pmp configuration of the hart which executes the routine will - * be affected. - * - * If any regions are fused to preset values by the implementation or locked, - * those PMP regions will silently remain uninitialized. - */ -void metal_pmp_init(struct metal_pmp *pmp); - -/*! - * @brief Configure a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to configure - * @param config The desired configuration of the PMP region - * @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); - -/*! - * @brief Get the configuration for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @param config Variable to store the PMP region configuration - * @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); - -/*! - * @brief Lock a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to lock - * @return 0 if the region is successfully locked - */ -int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the address for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @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); - -/*! - * @brief Get the address of a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return The address of the PMP region, or 0 if the region could not be read - */ -size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the addressing mode of a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @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); - -/*! - * @brief Get the addressing mode of a PMP region - * @param pmp The PMP device handle - * @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); - -/*! - * @brief Set the executable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param X The desired value of the executable bit - * @return 0 if the executable bit is successfully set - */ -int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X); - -/*! - * @brief Get the executable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the executable bit - */ -int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the writable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param W The desired value of the writable bit - * @return 0 if the writable bit is successfully set - */ -int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W); - -/*! - * @brief Get the writable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the writable bit - */ -int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region); - -/*! - * @brief Set the readable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to set - * @param R The desired value of the readable bit - * @return 0 if the readable bit is successfully set - */ -int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R); - -/*! - * @brief Set the readable bit for a PMP region - * @param pmp The PMP device handle - * @param region The PMP region to read - * @return the value of the readable bit - */ -int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/privilege.h deleted file mode 100644 index 928a936b1..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/privilege.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__PRIVILEGE_H -#define METAL__PRIVILEGE_H - -/*! - * @file metal/privilege.h - * - * @brief API for manipulating the privilege mode of a RISC-V system - * - * Additional information about privilege modes on RISC-V systems can be found - * by reading the RISC-V Privileged Architecture Specification v1.10. - */ - -#include - -enum metal_privilege_mode { - METAL_PRIVILEGE_USER = 0, - METAL_PRIVILEGE_SUPERVISOR = 1, - METAL_PRIVILEGE_MACHINE = 3, -}; - -#if __riscv_xlen == 32 -typedef uint32_t metal_xreg_t; -#elif __riscv_xlen == 64 -typedef uint64_t metal_xreg_t; -#endif - -#if __riscv_flen == 32 -typedef uint32_t metal_freg_t; -#elif __riscv_flen == 64 -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 t0; - metal_xreg_t t1; - metal_xreg_t t2; - - 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; -#ifndef __riscv_32e - 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 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 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 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; -#endif /* __riscv_flen */ -}; - -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); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/rtc.h deleted file mode 100644 index 2e742ea38..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/rtc.h +++ /dev/null @@ -1,127 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/shutdown.h deleted file mode 100644 index 8d4020b5c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/shutdown.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SHUTDOWN_H -#define METAL__SHUTDOWN_H - -/*! - * @file shutdown.h - * @brief API for shutting down a machine - */ - -struct __metal_shutdown; - -struct __metal_shutdown_vtable { - 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); } - -/*! - * @brief The public METAL shutdown interface - * - * Shuts down the machine, if the machine enables an interface for - * shutting down. When no interface is provided, will cause the machine - * to spin indefinitely. - * - * @param code The return code to set. 0 indicates program success. - */ -void metal_shutdown(int code) __attribute__((noreturn)); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/spi.h deleted file mode 100644 index 635e3c151..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/spi.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SPI_H -#define METAL__SPI_H - -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; - - /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ - unsigned int polarity : 1; - /*! @brief The phase of the SPI transfer, equivalent to CPHA */ - unsigned int phase : 1; - /*! @brief The endianness of the SPI transfer */ - unsigned int little_endian : 1; - /*! @brief The active state of the chip select line */ - 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 (*get_baud_rate)(struct metal_spi *spi); - int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); -}; - -/*! @brief A handle for a SPI device */ -struct metal_spi { - const struct metal_spi_vtable *vtable; -}; - -/*! @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(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); } - -/*! @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. - * @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) { - return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); -} - -/*! @brief Get the current baud rate of the SPI device - * @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); } - -/*! @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/switch.h deleted file mode 100644 index 61f0efe56..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/switch.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__SWITCH_H -#define METAL__SWITCH_H - -/*! - * @file switch.h - * @brief API for reading toggle switches - */ - -#include - -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); - int (*get_interrupt_id)(struct metal_switch *sw); -}; - -/*! - * @brief A handle for a switch - */ -struct metal_switch { - const struct metal_switch_vtable *vtable; -}; - -/*! - * @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 - */ -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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/time.h deleted file mode 100644 index 5c33b6f1b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/time.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__TIME_H -#define METAL__TIME_H - -#include - -/*! - * @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_FreedomStudio/freedom-metal/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/timer.h deleted file mode 100644 index eeae1f60b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/timer.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__TIMER_H -#define METAL__TIMER_H - -/*! - * @file timer.h - * @brief API for reading and manipulating the machine timer - */ - -/*! - * @brief Read the machine cycle count - * @param hartid The hart ID to read the cycle count of - * @param cyclecount The variable to hold the value - * @return 0 upon success - */ -int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); - -/*! - * @brief Get the machine timebase frequency - * @param hartid The hart ID to read the timebase of - * @param timebase The variable to hold the value - * @return 0 upon success - */ -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 - * @return 0 upon success - */ -int metal_timer_set_tick(int hartid, int second); - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/tty.h deleted file mode 100644 index fe4c000db..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/tty.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__TTY_H -#define METAL__TTY_H - -/*! - * @file tty.h - * @brief API for emulated serial teriminals - */ - -/*! - * @brief Write a character to the default output device - * - * Write a character to the default output device, which for most - * targets is the UART serial port. - * - * putc() does CR/LF mapping. - * putc_raw() does not. - * - * @param c The character to write to the terminal - * @return 0 on success, or -1 on failure. - */ -int metal_tty_putc(int c); - -/*! - * @brief Write a raw character to the default output device - * - * Write a character to the default output device, which for most - * targets is the UART serial port. - * - * putc() does CR/LF mapping. - * putc_raw() does not. - * - * @param c The character to write to the terminal - * @return 0 on success, or -1 on failure. - */ -int metal_tty_putc_raw(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_FreedomStudio/freedom-metal/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/uart.h deleted file mode 100644 index e9e4d0436..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/uart.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__UART_H -#define METAL__UART_H - -/*! - * @file uart.h - * @brief API for UART serial ports - */ - -#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, 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); - int (*get_interrupt_id)(struct metal_uart *uart); -}; - -/*! - * @brief Handle for a UART serial device - */ -struct metal_uart { - const struct metal_uart_vtable *vtable; -}; - -/*! - * @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. - * - * @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) { uart->vtable->init(uart, baud_rate); } - -/*! - * @brief Output a character over the UART - * @param uart The UART device handle - * @param c The character to send over the UART - * @return 0 upon success - */ -__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, 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); } - -/*! - * @brief Set the baud rate of the UART peripheral - * @param uart The UART device handle - * @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); } - -/*! - * @brief Get the interrupt controller of the UART peripheral - * - * Get the interrupt controller for the UART peripheral. The interrupt - * controller must be initialized before any interrupts can be registered - * or enabled with it. - * - * @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); } - -/*! - * @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); } - -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/watchdog.h deleted file mode 100644 index b5ff48697..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/metal/watchdog.h +++ /dev/null @@ -1,163 +0,0 @@ -/* 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_FreedomStudio/freedom-metal/src/button.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/button.c deleted file mode 100644 index efd645334..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/button.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -struct metal_button* metal_button_get (char *label) -{ - int i; - struct metal_button *button; - - if ((__METAL_DT_MAX_BUTTONS == 0) || (label == NULL)) { - return NULL; - } - - for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { - button = (struct metal_button*)__metal_button_table[i]; - if (button->vtable->button_exist(button, label)) { - return button; - } - } - return NULL; -} - -extern __inline__ struct metal_interrupt* - metal_button_interrupt_controller(struct metal_button *button); -extern __inline__ int metal_button_get_interrupt_id(struct metal_button *button); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cache.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cache.c deleted file mode 100644 index 024ba52ad..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cache.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -extern __inline__ void metal_cache_init(struct metal_cache *cache, int ways); -extern __inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache); -extern __inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways); - -int metal_dcache_l1_available(int hartid) { - switch (hartid) { - case 0: -#ifdef __METAL_CPU_0_DCACHE_HANDLE - return __METAL_CPU_0_DCACHE_HANDLE; -#endif - break; - case 1: -#ifdef __METAL_CPU_1_DCACHE_HANDLE - return __METAL_CPU_1_DCACHE_HANDLE; -#endif - break; - case 2: -#ifdef __METAL_CPU_2_DCACHE_HANDLE - return __METAL_CPU_2_DCACHE_HANDLE; -#endif - break; - case 3: -#ifdef __METAL_CPU_3_DCACHE_HANDLE - return __METAL_CPU_3_DCACHE_HANDLE; -#endif - break; - case 4: -#ifdef __METAL_CPU_4_DCACHE_HANDLE - return __METAL_CPU_4_DCACHE_HANDLE; -#endif - break; - case 5: -#ifdef __METAL_CPU_5_DCACHE_HANDLE - return __METAL_CPU_5_DCACHE_HANDLE; -#endif - break; - case 6: -#ifdef __METAL_CPU_6_DCACHE_HANDLE - return __METAL_CPU_6_DCACHE_HANDLE; -#endif - break; - case 7: -#ifdef __METAL_CPU_7_DCACHE_HANDLE - return __METAL_CPU_7_DCACHE_HANDLE; -#endif - break; - case 8: -#ifdef __METAL_CPU_8_DCACHE_HANDLE - return __METAL_CPU_8_DCACHE_HANDLE; -#endif - break; - } - return 0; -} - -int metal_icache_l1_available(int hartid) { - switch (hartid) { - case 0: -#ifdef __METAL_CPU_0_ICACHE_HANDLE - return __METAL_CPU_0_ICACHE_HANDLE; -#endif - break; - case 1: -#ifdef __METAL_CPU_1_ICACHE_HANDLE - return __METAL_CPU_1_ICACHE_HANDLE; -#endif - break; - case 2: -#ifdef __METAL_CPU_2_ICACHE_HANDLE - return __METAL_CPU_2_ICACHE_HANDLE; -#endif - break; - case 3: -#ifdef __METAL_CPU_3_ICACHE_HANDLE - return __METAL_CPU_3_ICACHE_HANDLE; -#endif - break; - case 4: -#ifdef __METAL_CPU_4_ICACHE_HANDLE - return __METAL_CPU_4_ICACHE_HANDLE; -#endif - break; - case 5: -#ifdef __METAL_CPU_5_ICACHE_HANDLE - return __METAL_CPU_5_ICACHE_HANDLE; -#endif - break; - case 6: -#ifdef __METAL_CPU_6_ICACHE_HANDLE - return __METAL_CPU_6_ICACHE_HANDLE; -#endif - break; - case 7: -#ifdef __METAL_CPU_7_ICACHE_HANDLE - return __METAL_CPU_7_ICACHE_HANDLE; -#endif - break; - case 8: -#ifdef __METAL_CPU_8_ICACHE_HANDLE - return __METAL_CPU_8_ICACHE_HANDLE; -#endif - break; - } - return 0; -} - -/*! - * @brief CFlush.D.L1 instruction is a custom instruction implemented as a - * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 - * |--------|--------|--------|--------|--------|--------|--------|--------| - * +-------------+------------+----------+------+--------+-----------------+ - * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | - * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| - * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x40 20 15 0 12 x0 7 0x73 0 - * +--------+--------+--------+----------+------+--------+--------+--------+ - * where, - * rs1 = 0x0, CFLUSH.D.L1 writes back and invalidates all lines in the L1 D$ - * rs1 != x0, CFLUSH.D.L1 writes back and invalidates the L1 D$ line containing - * the virtual address in integer register rs1. - */ -void metal_dcache_l1_flush(int hartid, uintptr_t address) -{ - if (metal_dcache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x40" : : "r" (address)); - __asm__ __volatile__ ("fence.i"); // FENCE - } -} - -/*! - * @brief CDiscard.D.L1 instruction is a custom instruction implemented as a - * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 - * |--------|--------|--------|--------|--------|--------|--------|--------| - * +-------------+------------+----------+------+--------+-----------------+ - * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | - * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| - * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x3E 20 15 0 12 x0 7 0x73 0 - * +--------+--------+--------+----------+------+--------+--------+--------+ - * where, - * rs1 = 0x0, CDISCARD.D.L1 invalidates all lines in the L1 D$ with no writes back. - * rs1 != x0, CDISCARD.D.L1 invalidates the L1 D$ line containing the virtual address - * in integer register rs1, with no writes back. - */ -void metal_dcache_l1_discard(int hartid, uintptr_t address) -{ - if (metal_dcache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x3E" : : "r" (address)); - __asm__ __volatile__ ("fence.i"); // FENCE - } -} - -/*! - * @brief CFlush.I.L1 instruction is a custom instruction implemented as a state - * machine in L1 Instruction Cache (I$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 - * |--------|--------|--------|--------|--------|--------|--------|--------| - * +-------------+------------+----------+------+--------+-----------------+ - * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | - * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-0-0-0-0-0|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| - * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x3F 20 15 0 12 x0 7 0x73 0 - * +--------+--------+--------+----------+------+--------+--------+--------+ - * CFLUSH.I.L1 invalidates all lines in the L1 I$. - */ -void metal_icache_l1_flush(int hartid) -{ - if (metal_icache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, x0, -0x3F" : : ); - __asm__ __volatile__ ("fence.i"); // FENCE - } -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/clock.c deleted file mode 100644 index cc3f4dcf3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/clock.c +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -extern __inline__ void _metal_clock_call_all_callbacks(const metal_clock_callback *const list); -extern __inline__ metal_clock_callback *_metal_clock_append_to_callbacks(metal_clock_callback *list, metal_clock_callback *const cb); - -extern __inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk); -extern __inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz); -extern __inline__ void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); -extern __inline__ void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cpu.c deleted file mode 100644 index 25fda5de7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/cpu.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -struct metal_cpu* metal_cpu_get(unsigned int hartid) -{ - if (hartid < __METAL_DT_MAX_HARTS) { - return (struct metal_cpu *)__metal_cpu_table[hartid]; - } - return NULL; -} - -int metal_cpu_get_current_hartid() -{ -#ifdef __riscv - int mhartid; - __asm__ volatile("csrr %0, mhartid" : "=r" (mhartid)); - return mhartid; -#endif -} - -int metal_cpu_get_num_harts() -{ - return __METAL_DT_MAX_HARTS; -} - -extern __inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu); - -extern __inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu); - -extern __inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time); - -extern __inline__ struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu); - -extern __inline__ struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid); - -extern __inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid); - -extern __inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid); - -extern __inline__ struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler); - -extern __inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc); - -extern __inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu); - -extern __inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c deleted file mode 100644 index 92c61d023..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright 2018 SiFive, Inc. */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_FIXED_CLOCK - -#include -#include -#include - -long __metal_driver_fixed_clock_get_rate_hz(const struct metal_clock *gclk) -{ - return __metal_driver_fixed_clock_rate(gclk); -} - -long __metal_driver_fixed_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) -{ - return __metal_driver_fixed_clock_get_rate_hz(gclk); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_fixed_clock) = { - .clock.get_rate_hz = __metal_driver_fixed_clock_get_rate_hz, - .clock.set_rate_hz = __metal_driver_fixed_clock_set_rate_hz, -}; - -#endif /* METAL_FIXED_CLOCK */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c deleted file mode 100644 index 57d83af87..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2018 SiFive, Inc. */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_FIXED_FACTOR_CLOCK - -#include -#include -#include - -long __metal_driver_fixed_factor_clock_get_rate_hz(const struct metal_clock *gclk) -{ - struct metal_clock *parent = __metal_driver_fixed_factor_clock_parent(gclk); - long parent_rate = 1; - if(parent) { - parent_rate = parent->vtable->get_rate_hz(parent); - } - - return __metal_driver_fixed_factor_clock_mult(gclk) * parent_rate / __metal_driver_fixed_factor_clock_div(gclk); -} - -long __metal_driver_fixed_factor_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) -{ - return __metal_driver_fixed_factor_clock_get_rate_hz(gclk); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_fixed_factor_clock) = { - .clock.get_rate_hz = __metal_driver_fixed_factor_clock_get_rate_hz, - .clock.set_rate_hz = __metal_driver_fixed_factor_clock_set_rate_hz, -}; -#endif /* METAL_FIXED_FACTOR_CLOCK */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/inline.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/inline.c deleted file mode 100644 index 50c0c5c21..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/inline.c +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c deleted file mode 100644 index d0488b317..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_RISCV_CLINT0 - -#include -#include -#include -#include - -unsigned long long __metal_clint0_mtime_get (struct __metal_driver_riscv_clint0 *clint) -{ - __metal_io_u32 lo, hi; - unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); - - /* Guard against rollover when reading */ - do { - hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)); - lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME)); - } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)) != hi); - - return (((unsigned long long)hi) << 32) | lo; -} - -int __metal_driver_riscv_clint0_mtimecmp_set(struct metal_interrupt *controller, - int hartid, - unsigned long long time) -{ - struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); - /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, - * and are NOT internally latched for multiword transfers. - * Need to be careful about sequencing to avoid triggering - * spurious interrupts: For that set the high word to a max - * value first. - */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE)) = (__metal_io_u32)time; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); - return 0; -} - -static struct metal_interrupt *_get_cpu_intc() -{ - int hartid = 0; - __asm__ volatile("csrr %[hartid], mhartid" - : [hartid] "=r" (hartid) :: "memory"); - - struct metal_cpu *cpu = metal_cpu_get(hartid); - - return metal_cpu_interrupt_controller(cpu); -} - -void __metal_driver_riscv_clint0_init (struct metal_interrupt *controller) -{ - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); - struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); - - if ( !clint->init_done ) { - /* Register its interrupts with with parent controller, aka sw and timerto its default isr */ - for (int i = 0; i < num_interrupts; i++) { - struct metal_interrupt *intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc->vtable->interrupt_register(intc, line, NULL, controller); - } - clint->init_done = 1; - } -} - -int __metal_driver_riscv_clint0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - int rc = -1; - metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); - struct metal_interrupt *intc = NULL; - struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); - - if ( (mode != METAL_VECTOR_MODE) && (mode != METAL_DIRECT_MODE) ) { - return rc; - } - - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - if (cpu_intc == intc && id == line) { - break; - } - intc = NULL; - } - - /* Register its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_register(intc, id, isr, priv); - } - return rc; -} - -int __metal_driver_riscv_clint0_vector_register (struct metal_interrupt *controller, - int id, metal_interrupt_vector_handler_t isr, - void *priv) -{ - /* Not supported. User can override the 'weak' handler with their own */ - int rc = -1; - return rc; -} - -metal_vector_mode __metal_driver_riscv_clint0_get_vector_mode (struct metal_interrupt *controller) -{ - return __metal_controller_interrupt_vector_mode(); -} - -int __metal_driver_riscv_clint0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) -{ - int rc = -1; - struct metal_interrupt *intc = _get_cpu_intc(); - - if (intc) { - /* Valid vector modes are VECTOR and DIRECT, anything else is invalid (-1) */ - switch (mode) { - case METAL_VECTOR_MODE: - case METAL_DIRECT_MODE: - rc = intc->vtable->interrupt_set_vector_mode(intc, mode); - break; - case METAL_HARDWARE_VECTOR_MODE: - case METAL_SELECTIVE_NONVECTOR_MODE: - case METAL_SELECTIVE_VECTOR_MODE: - break; - } - } - return rc; -} - -int __metal_driver_riscv_clint0_enable (struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if ( id ) { - struct metal_interrupt *intc = NULL; - struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); - - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - if(cpu_intc == intc && id == line) { - break; - } - intc = NULL; - } - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_enable(intc, id); - } - } - - return rc; -} - -int __metal_driver_riscv_clint0_disable (struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if ( id ) { - struct metal_interrupt *intc = NULL; - struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); - - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - if(cpu_intc == intc && id == line) { - break; - } - intc = NULL; - } - - /* Disable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_disable(intc, id); - } - } - - return rc; -} - -int __metal_driver_riscv_clint0_command_request (struct metal_interrupt *controller, - int command, void *data) -{ - int hartid; - int rc = -1; - struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clint0_control_base(controller); - - switch (command) { - case METAL_TIMER_MTIME_GET: - if (data) { - *(unsigned long long *)data = __metal_clint0_mtime_get(clint); - rc = 0; - } - break; - case METAL_SOFTWARE_IPI_CLEAR: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_DISABLE; - rc = 0; - } - break; - case METAL_SOFTWARE_IPI_SET: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_ENABLE; - /* Callers of this function assume it's blocking, in the sense that - * the IPI is guarnteed to have been delivered before the function - * returns. We can't really guarnteed it's delivered, but we can - * read back the control register after writing it in at least an - * attempt to provide some semblence of ordering here. The fence - * ensures the read is order after the write -- it wouldn't be - * necessary under RVWMO because this is the same address, but we - * don't have an IO memory model so I'm being a bit overkill here. - */ - __METAL_IO_FENCE(o,i); - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); - rc = 0; - } - break; - case METAL_SOFTWARE_MSIP_GET: - rc = 0; - if (data) { - hartid = *(int *)data; - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); - } - break; - default: - break; - } - - return rc; -} - -int __metal_driver_riscv_clint0_clear_interrupt (struct metal_interrupt *controller, int id) -{ - int hartid = metal_cpu_get_current_hartid(); - return __metal_driver_riscv_clint0_command_request(controller, - METAL_SOFTWARE_IPI_CLEAR, &hartid); -} - -int __metal_driver_riscv_clint0_set_interrupt (struct metal_interrupt *controller, int id) -{ - int hartid = metal_cpu_get_current_hartid(); - return __metal_driver_riscv_clint0_command_request(controller, - METAL_SOFTWARE_IPI_SET, &hartid); -} - - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_clint0) = { - .clint_vtable.interrupt_init = __metal_driver_riscv_clint0_init, - .clint_vtable.interrupt_register = __metal_driver_riscv_clint0_register, - .clint_vtable.interrupt_vector_register = __metal_driver_riscv_clint0_vector_register, - .clint_vtable.interrupt_enable = __metal_driver_riscv_clint0_enable, - .clint_vtable.interrupt_disable = __metal_driver_riscv_clint0_disable, - .clint_vtable.interrupt_get_vector_mode = __metal_driver_riscv_clint0_get_vector_mode, - .clint_vtable.interrupt_set_vector_mode = __metal_driver_riscv_clint0_set_vector_mode, - .clint_vtable.interrupt_clear = __metal_driver_riscv_clint0_clear_interrupt, - .clint_vtable.interrupt_set = __metal_driver_riscv_clint0_set_interrupt, - .clint_vtable.command_request = __metal_driver_riscv_clint0_command_request, - .clint_vtable.mtimecmp_set = __metal_driver_riscv_clint0_mtimecmp_set, -}; - -#endif /* METAL_RISCV_CLINT0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c deleted file mode 100644 index b693f312a..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c +++ /dev/null @@ -1,999 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include -#include - -extern void __metal_vector_table(); -unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu); -int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, unsigned long long time); - -struct metal_cpu *__metal_driver_cpu_get(int hartid) -{ - if (hartid < __METAL_DT_MAX_HARTS) { - return &(__metal_cpu_table[hartid]->cpu); - } - return (struct metal_cpu *)NULL; -} - -uintptr_t __metal_myhart_id (void) -{ - uintptr_t myhart; - __asm__ volatile ("csrr %0, mhartid" : "=r"(myhart)); - return myhart; -} - -void __metal_zero_memory (unsigned char *base, unsigned int size) -{ - volatile unsigned char *ptr; - for (ptr = base; ptr < (base + size); ptr++){ - *ptr = 0; - } -} - -void __metal_interrupt_global_enable (void) { - uintptr_t m; - __asm__ volatile ("csrrs %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); -} - -void __metal_interrupt_global_disable (void) { - uintptr_t m; - __asm__ volatile ("csrrc %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); -} - -void __metal_interrupt_software_enable (void) { - uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); -} - -void __metal_interrupt_software_disable (void) { - uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); -} - -void __metal_interrupt_timer_enable (void) { - uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); -} - -void __metal_interrupt_timer_disable (void) { - uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); -} - -void __metal_interrupt_external_enable (void) { - uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); -} - -void __metal_interrupt_external_disable (void) { - unsigned long m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); -} - -void __metal_interrupt_local_enable (int id) { - uintptr_t b = 1 << id; - uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(b)); -} - -void __metal_interrupt_local_disable (int id) { - uintptr_t b = 1 << id; - uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(b)); -} - -void __metal_default_exception_handler (struct metal_cpu *cpu, int ecode) { - metal_shutdown(100); -} - -void __metal_default_interrupt_handler (int id, void *priv) { - metal_shutdown(200); -} - -/* The metal_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_interrupt_vector_handler (void) { - metal_shutdown(300); -} - -/* The metal_software_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_SW].handler(METAL_INTERRUPT_ID_SW, priv); - } -} - -void __metal_default_sw_handler (int id, void *priv) { - uintptr_t mcause; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE]((struct metal_cpu *)cpu, id); - } -} - -/* The metal_timer_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_TMR].handler(METAL_INTERRUPT_ID_TMR, priv); - } -} - -void __metal_default_timer_handler (int id, void *priv) { - struct metal_cpu *cpu = __metal_driver_cpu_get(__metal_myhart_id()); - unsigned long long time = __metal_driver_cpu_mtime_get(cpu); - - /* Set a 10 cycle timer */ - __metal_driver_cpu_mtimecmp_set(cpu, time + 10); -} - -/* The metal_external_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_EXT].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_EXT].handler(METAL_INTERRUPT_ID_EXT, priv); - } -} - -void __metal_exception_handler(void) __attribute__((interrupt, aligned(128))); -void __metal_exception_handler (void) { - int id; - void *priv; - uintptr_t mcause, mepc, mtval, mtvec; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); - __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); - __asm__ volatile ("csrr %0, mtval" : "=r"(mtval)); - __asm__ volatile ("csrr %0, mtvec" : "=r"(mtvec)); - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - id = mcause & METAL_MCAUSE_CAUSE; - if (mcause & METAL_MCAUSE_INTR) { - if ((id < METAL_INTERRUPT_ID_CSW) || - ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) { - priv = intc->metal_int_table[id].exint_data; - intc->metal_int_table[id].handler(id, priv); - return; - } - if ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_CLIC) { - uintptr_t mtvt; - metal_interrupt_handler_t mtvt_handler; - - __asm__ volatile ("csrr %0, 0x307" : "=r"(mtvt)); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; - mtvt_handler = (metal_interrupt_handler_t)*(uintptr_t *)mtvt; - mtvt_handler(id, priv); - return; - } - } else { - intc->metal_exception_table[id]((struct metal_cpu *)cpu, id); - } - } -} - -/* The metal_lc0_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC0].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC0].handler(METAL_INTERRUPT_ID_LC0, priv); - } -} - -/* The metal_lc1_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC1].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC1].handler(METAL_INTERRUPT_ID_LC1, priv); - } -} - -/* The metal_lc2_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC2].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC2].handler(METAL_INTERRUPT_ID_LC2, priv); - } -} - -/* The metal_lc3_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC3].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC3].handler(METAL_INTERRUPT_ID_LC3, priv); - } -} - -/* The metal_lc4_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC4].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC4].handler(METAL_INTERRUPT_ID_LC4, priv); - } -} - -/* The metal_lc5_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC5].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC5].handler(METAL_INTERRUPT_ID_LC5, priv); - } -} - -/* The metal_lc6_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC6].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC6].handler(METAL_INTERRUPT_ID_LC6, priv); - } -} - -/* The metal_lc7_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC7].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC7].handler(METAL_INTERRUPT_ID_LC7, priv); - } -} - -/* The metal_lc8_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC8].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC8].handler(METAL_INTERRUPT_ID_LC8, priv); - } -} - -/* The metal_lc9_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC9].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC9].handler(METAL_INTERRUPT_ID_LC9, priv); - } -} - -/* The metal_lc10_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC10].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC10].handler(METAL_INTERRUPT_ID_LC10, priv); - } -} - -/* The metal_lc11_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC11].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC11].handler(METAL_INTERRUPT_ID_LC11, priv); - } -} - -/* The metal_lc12_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC12].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC12].handler(METAL_INTERRUPT_ID_LC12, priv); - } -} - -/* The metal_lc13_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC13].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC13].handler(METAL_INTERRUPT_ID_LC13, priv); - } -} - -/* The metal_lc14_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC14].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC14].handler(METAL_INTERRUPT_ID_LC14, priv); - } -} - -/* The metal_lc15_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC15].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC15].handler(METAL_INTERRUPT_ID_LC15, priv); - } -} - -metal_vector_mode __metal_controller_interrupt_vector_mode (void) -{ - uintptr_t val; - - asm volatile ("csrr %0, mtvec" : "=r"(val)); - val &= METAL_MTVEC_MASK; - - switch (val) { - case METAL_MTVEC_CLIC: - return METAL_SELECTIVE_VECTOR_MODE; - case METAL_MTVEC_CLIC_VECTORED: - return METAL_HARDWARE_VECTOR_MODE; - case METAL_MTVEC_VECTORED: - return METAL_VECTOR_MODE; - } - return METAL_DIRECT_MODE; -} - -void __metal_controller_interrupt_vector (metal_vector_mode mode, void *vec_table) -{ - uintptr_t trap_entry, val; - - __asm__ volatile ("csrr %0, mtvec" : "=r"(val)); - val &= ~(METAL_MTVEC_CLIC_VECTORED | METAL_MTVEC_CLIC_RESERVED); - trap_entry = (uintptr_t)vec_table; - - switch (mode) { - case METAL_SELECTIVE_NONVECTOR_MODE: - case METAL_SELECTIVE_VECTOR_MODE: - __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); - __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC)); - break; - case METAL_HARDWARE_VECTOR_MODE: - __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); - __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC_VECTORED)); - break; - case METAL_VECTOR_MODE: - __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry | METAL_MTVEC_VECTORED)); - break; - case METAL_DIRECT_MODE: - __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED)); - break; - } -} - -int __metal_valid_interrupt_id (int id) -{ - switch (id) { - case METAL_INTERRUPT_ID_SW: - case METAL_INTERRUPT_ID_TMR: - case METAL_INTERRUPT_ID_EXT: - case METAL_INTERRUPT_ID_LC0: - case METAL_INTERRUPT_ID_LC1: - case METAL_INTERRUPT_ID_LC2: - case METAL_INTERRUPT_ID_LC3: - case METAL_INTERRUPT_ID_LC4: - case METAL_INTERRUPT_ID_LC5: - case METAL_INTERRUPT_ID_LC6: - case METAL_INTERRUPT_ID_LC7: - case METAL_INTERRUPT_ID_LC8: - case METAL_INTERRUPT_ID_LC9: - case METAL_INTERRUPT_ID_LC10: - case METAL_INTERRUPT_ID_LC11: - case METAL_INTERRUPT_ID_LC12: - case METAL_INTERRUPT_ID_LC13: - case METAL_INTERRUPT_ID_LC14: - case METAL_INTERRUPT_ID_LC15: - return 1; - default: - break; - } - - return 0; -} - - -int __metal_local_interrupt_enable (struct metal_interrupt *controller, - metal_interrupt_id_e id, int enable) -{ - int rc = 0; - - if ( !controller) { - return -1; - } - - switch (id) { - case METAL_INTERRUPT_ID_BASE: - if (enable) { - __metal_interrupt_global_enable(); - } else { - __metal_interrupt_global_disable(); - } - break; - case METAL_INTERRUPT_ID_SW: - if (enable) { - __metal_interrupt_software_enable(); - } else { - __metal_interrupt_software_disable(); - } - break; - case METAL_INTERRUPT_ID_TMR: - if (enable) { - __metal_interrupt_timer_enable(); - } else { - __metal_interrupt_timer_disable(); - } - break; - case METAL_INTERRUPT_ID_EXT: - if (enable) { - __metal_interrupt_external_enable(); - } else { - __metal_interrupt_external_disable(); - } - break; - case METAL_INTERRUPT_ID_LC0: - case METAL_INTERRUPT_ID_LC1: - case METAL_INTERRUPT_ID_LC2: - case METAL_INTERRUPT_ID_LC3: - case METAL_INTERRUPT_ID_LC4: - case METAL_INTERRUPT_ID_LC5: - case METAL_INTERRUPT_ID_LC6: - case METAL_INTERRUPT_ID_LC7: - case METAL_INTERRUPT_ID_LC8: - case METAL_INTERRUPT_ID_LC9: - case METAL_INTERRUPT_ID_LC10: - case METAL_INTERRUPT_ID_LC11: - case METAL_INTERRUPT_ID_LC12: - case METAL_INTERRUPT_ID_LC13: - case METAL_INTERRUPT_ID_LC14: - case METAL_INTERRUPT_ID_LC15: - if (enable) { - __metal_interrupt_local_enable(id); - } else { - __metal_interrupt_local_disable(id); - } - break; - default: - rc = -1; - } - return rc; -} - -int __metal_exception_register (struct metal_interrupt *controller, - int ecode, metal_exception_handler_t isr) -{ - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - - if ((ecode < METAL_MAX_EXCEPTION_CODE) && isr) { - intc->metal_exception_table[ecode] = isr; - return 0; - } - return -1; -} - -void __metal_driver_riscv_cpu_controller_interrupt_init (struct metal_interrupt *controller) -{ - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - uintptr_t val; - - if ( !intc->init_done ) { - /* Disable and clear all interrupt sources */ - __asm__ volatile ("csrc mie, %0" :: "r"(-1)); - __asm__ volatile ("csrc mip, %0" :: "r"(-1)); - - /* Read the misa CSR to determine if the delegation registers exist */ - uintptr_t misa; - __asm__ volatile ("csrr %0, misa" : "=r" (misa)); - - /* The delegation CSRs exist if user mode interrupts (N extension) or - * supervisor mode (S extension) are supported */ - if((misa & METAL_ISA_N_EXTENSIONS) || (misa & METAL_ISA_S_EXTENSIONS)) { - /* Disable interrupt and exception delegation */ - __asm__ volatile ("csrc mideleg, %0" :: "r"(-1)); - __asm__ volatile ("csrc medeleg, %0" :: "r"(-1)); - } - - /* The satp CSR exists if supervisor mode (S extension) is supported */ - if(misa & METAL_ISA_S_EXTENSIONS) { - /* Clear the entire CSR to make sure that satp.MODE = 0 */ - __asm__ volatile ("csrc satp, %0" :: "r"(-1)); - } - - /* Default to use direct interrupt, setup sw cb table*/ - for (int i = 0; i < METAL_MAX_MI; i++) { - intc->metal_int_table[i].handler = NULL; - intc->metal_int_table[i].sub_int = NULL; - intc->metal_int_table[i].exint_data = NULL; - } - for (int i = 0; i < METAL_MAX_ME; i++) { - intc->metal_exception_table[i] = __metal_default_exception_handler; - } - __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); - __asm__ volatile ("csrr %0, misa" : "=r"(val)); - if (val & (METAL_ISA_D_EXTENSIONS | METAL_ISA_F_EXTENSIONS | METAL_ISA_Q_EXTENSIONS)) { - /* Floating point architecture, so turn on FP register saving*/ - __asm__ volatile ("csrr %0, mstatus" : "=r"(val)); - __asm__ volatile ("csrw mstatus, %0" :: "r"(val | METAL_MSTATUS_FS_INIT)); - } - intc->init_done = 1; - } -} - -int __metal_driver_riscv_cpu_controller_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - int rc = 0; - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - - if ( !__metal_valid_interrupt_id(id) ) { - return -11; - } - - if (isr) { - intc->metal_int_table[id].handler = isr; - intc->metal_int_table[id].exint_data = priv; - } else { - switch (id) { - case METAL_INTERRUPT_ID_SW: - intc->metal_int_table[id].handler = __metal_default_sw_handler; - intc->metal_int_table[id].sub_int = priv; - break; - case METAL_INTERRUPT_ID_TMR: - intc->metal_int_table[id].handler = __metal_default_timer_handler; - intc->metal_int_table[id].sub_int = priv; - break; - case METAL_INTERRUPT_ID_EXT: - case METAL_INTERRUPT_ID_LC0: - case METAL_INTERRUPT_ID_LC1: - case METAL_INTERRUPT_ID_LC2: - case METAL_INTERRUPT_ID_LC3: - case METAL_INTERRUPT_ID_LC4: - case METAL_INTERRUPT_ID_LC5: - case METAL_INTERRUPT_ID_LC6: - case METAL_INTERRUPT_ID_LC7: - case METAL_INTERRUPT_ID_LC8: - case METAL_INTERRUPT_ID_LC9: - case METAL_INTERRUPT_ID_LC10: - case METAL_INTERRUPT_ID_LC11: - case METAL_INTERRUPT_ID_LC12: - case METAL_INTERRUPT_ID_LC13: - case METAL_INTERRUPT_ID_LC14: - case METAL_INTERRUPT_ID_LC15: - intc->metal_int_table[id].handler = __metal_default_interrupt_handler; - intc->metal_int_table[id].sub_int = priv; - break; - default: - rc = -12; - } - } - return rc; -} - -int __metal_driver_riscv_cpu_controller_interrupt_enable (struct metal_interrupt *controller, - int id) -{ - return __metal_local_interrupt_enable(controller, id, METAL_ENABLE); -} - -int __metal_driver_riscv_cpu_controller_interrupt_disable (struct metal_interrupt *controller, - int id) -{ - return __metal_local_interrupt_enable(controller, id, METAL_DISABLE); -} - -int __metal_driver_riscv_cpu_controller_interrupt_enable_vector(struct metal_interrupt *controller, - int id, metal_vector_mode mode) -{ - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - - if (id == METAL_INTERRUPT_ID_BASE) { - if (mode == METAL_DIRECT_MODE) { - __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); - return 0; - } - if (mode == METAL_VECTOR_MODE) { - __metal_controller_interrupt_vector(mode, (void *)&intc->metal_mtvec_table); - return 0; - } - } - return -1; -} - -int __metal_driver_riscv_cpu_controller_interrupt_disable_vector(struct metal_interrupt *controller, - int id) -{ - if (id == METAL_INTERRUPT_ID_BASE) { - __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); - return 0; - } - return -1; -} - -metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode (struct metal_interrupt *controller) -{ - return __metal_controller_interrupt_vector_mode(); -} - -int __metal_driver_riscv_cpu_controller_set_vector_mode (struct metal_interrupt *controller, - metal_vector_mode mode) -{ - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - ( void ) intc; - - if (mode == METAL_DIRECT_MODE) { - __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); - return 0; - } - if (mode == METAL_VECTOR_MODE) { - __metal_controller_interrupt_vector(mode, (void *)__metal_vector_table); - return 0; - } - return -1; -} - -int __metal_driver_riscv_cpu_controller_command_request (struct metal_interrupt *controller, - int cmd, void *data) -{ - /* NOP for now, unless local interrupt lines the like of clic, clint, plic */ - return 0; -} - -/* CPU driver !!! */ - -unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu) -{ - unsigned long long val = 0; - -#if __riscv_xlen == 32 - unsigned long hi, hi1, lo; - - __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi)); - __asm__ volatile ("csrr %0, mcycle" : "=r"(lo)); - __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi1)); - if (hi == hi1) { - val = ((unsigned long long)hi << 32) | lo; - } -#else - __asm__ volatile ("csrr %0, mcycle" : "=r"(val)); -#endif - - return val; -} - -unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) -{ - int timebase; - if (!cpu) { - return 0; - } - - timebase = __metal_driver_cpu_timebase((struct metal_cpu *)cpu); - return timebase; -} - -unsigned long long __metal_driver_cpu_mtime_get (struct metal_cpu *cpu) -{ - unsigned long long time = 0; - struct metal_interrupt *tmr_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; - if (tmr_intc) { - tmr_intc->vtable->command_request(tmr_intc, - METAL_TIMER_MTIME_GET, &time); - } - } - return time; -} - -int __metal_driver_cpu_mtimecmp_set (struct metal_cpu *cpu, unsigned long long time) -{ - int rc = -1; - struct metal_interrupt *tmr_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; - if (tmr_intc) { - rc = tmr_intc->vtable->mtimecmp_set(tmr_intc, - __metal_driver_cpu_hartid(cpu), - time); - } - } - return rc; -} - -struct metal_interrupt * -__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) -{ -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - return __METAL_DT_RISCV_CLINT0_HANDLE; -#else -#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE - return __METAL_DT_SIFIVE_CLIC0_HANDLE; -#else -#pragma message("There is no interrupt controller for Timer interrupt") - return NULL; -#endif -#endif -} - -int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu) -{ - return METAL_INTERRUPT_ID_TMR; -} - -struct metal_interrupt * -__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) -{ -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - return __METAL_DT_RISCV_CLINT0_HANDLE; -#else -#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE - return __METAL_DT_SIFIVE_CLIC0_HANDLE; -#else -#pragma message("There is no interrupt controller for Software interrupt") - return NULL; -#endif -#endif -} - -int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu) -{ - return METAL_INTERRUPT_ID_SW; -} - -int __metal_driver_cpu_set_sw_ipi (struct metal_cpu *cpu, int hartid) -{ - int rc = -1; - struct metal_interrupt *sw_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; - if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_IPI_SET, &hartid); - } - } - return rc; -} - -int __metal_driver_cpu_clear_sw_ipi (struct metal_cpu *cpu, int hartid) -{ - int rc = -1; - struct metal_interrupt *sw_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; - if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_IPI_CLEAR, &hartid); - } - } - return rc; -} - -int __metal_driver_cpu_get_msip (struct metal_cpu *cpu, int hartid) -{ - int rc = 0; - struct metal_interrupt *sw_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; - if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_MSIP_GET, &hartid); - } - } - return rc; -} - -struct metal_interrupt * -__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu) -{ - return __metal_driver_cpu_interrupt_controller(cpu); -} - -int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv) -{ - if ( __metal_driver_cpu_interrupt_controller(cpu) ) { - /* Only support machine mode for now */ - __metal_interrupt_global_enable(); - return 0; - } - return -1; -} - -int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv) -{ - if ( __metal_driver_cpu_interrupt_controller(cpu) ) { - /* Only support machine mode for now */ - __metal_interrupt_global_disable(); - return 0; - } - return -1; -} - -int __metal_driver_cpu_exception_register(struct metal_cpu *cpu, int ecode, - metal_exception_handler_t isr) -{ - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); - - if (intc) { - return __metal_exception_register((struct metal_interrupt *)intc, ecode, isr); - } - return -1; -} - -int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc) -{ - /** - * Per ISA compressed instruction has last two bits of opcode set. - * The encoding '00' '01' '10' are used for compressed instruction. - * Only enconding '11' isn't regarded as compressed instruction (>16b). - */ - return ((*(unsigned short*)epc & METAL_INSN_LENGTH_MASK) - == METAL_INSN_NOT_COMPRESSED) ? 4 : 2; -} - -uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu) -{ - uintptr_t mepc; - __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); - return mepc; -} - -int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc) -{ - __asm__ volatile ("csrw mepc, %0" :: "r"(mepc)); - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) = { - .controller_vtable.interrupt_init = __metal_driver_riscv_cpu_controller_interrupt_init, - .controller_vtable.interrupt_register = __metal_driver_riscv_cpu_controller_interrupt_register, - .controller_vtable.interrupt_enable = __metal_driver_riscv_cpu_controller_interrupt_enable, - .controller_vtable.interrupt_disable = __metal_driver_riscv_cpu_controller_interrupt_disable, - .controller_vtable.interrupt_get_vector_mode = __metal_driver_riscv_cpu_controller_get_vector_mode, - .controller_vtable.interrupt_set_vector_mode = __metal_driver_riscv_cpu_controller_set_vector_mode, - .controller_vtable.command_request = __metal_driver_riscv_cpu_controller_command_request, -}; - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = { - .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get, - .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get, - .cpu_vtable.mtime_get = __metal_driver_cpu_mtime_get, - .cpu_vtable.mtimecmp_set = __metal_driver_cpu_mtimecmp_set, - .cpu_vtable.tmr_controller_interrupt = __metal_driver_cpu_timer_controller_interrupt, - .cpu_vtable.get_tmr_interrupt_id = __metal_driver_cpu_get_timer_interrupt_id, - .cpu_vtable.sw_controller_interrupt = __metal_driver_cpu_sw_controller_interrupt, - .cpu_vtable.get_sw_interrupt_id = __metal_driver_cpu_get_sw_interrupt_id, - .cpu_vtable.set_sw_ipi = __metal_driver_cpu_set_sw_ipi, - .cpu_vtable.clear_sw_ipi = __metal_driver_cpu_clear_sw_ipi, - .cpu_vtable.get_msip = __metal_driver_cpu_get_msip, - .cpu_vtable.controller_interrupt = __metal_driver_cpu_controller_interrupt, - .cpu_vtable.exception_register = __metal_driver_cpu_exception_register, - .cpu_vtable.get_ilen = __metal_driver_cpu_get_instruction_length, - .cpu_vtable.get_epc = __metal_driver_cpu_get_exception_pc, - .cpu_vtable.set_epc = __metal_driver_cpu_set_exception_pc, -}; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c deleted file mode 100644 index 3272f1c66..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c +++ /dev/null @@ -1,195 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_RISCV_PLIC0 - -#include -#include -#include -#include - -unsigned int __metal_plic0_claim_interrupt (struct __metal_driver_riscv_plic0 *plic) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_CLAIM)); -} - -void __metal_plic0_complete_interrupt(struct __metal_driver_riscv_plic0 *plic, - unsigned int id) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_CLAIM)) = id; -} - -int __metal_plic0_set_threshold(struct metal_interrupt *controller, unsigned int threshold) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_THRESHOLD)) = threshold; - return 0; -} - -unsigned int __metal_plic0_get_threshold(struct metal_interrupt *controller) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); - - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_THRESHOLD)); -} - -int __metal_plic0_set_priority(struct metal_interrupt *controller, int id, unsigned int priority) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)controller); - unsigned int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)controller); - if ( (max_priority) && (priority < max_priority) ) { - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_PRIORITY_BASE + - (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = priority; - return 0; - } - return -1; -} - -unsigned int __metal_plic0_get_priority(struct metal_interrupt *controller, int id) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); - - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_PRIORITY_BASE + - (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))); -} - -void __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, int id, int enable) -{ - unsigned int current; - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); - - current = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_ENABLE_BASE + - (id >> METAL_PLIC_SOURCE_SHIFT) * 4)); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_ENABLE_BASE + - ((id >> METAL_PLIC_SOURCE_SHIFT) * 4))) = - enable ? (current | (1 << (id & METAL_PLIC_SOURCE_MASK))) - : (current & ~(1 << (id & METAL_PLIC_SOURCE_MASK))); -} - -void __metal_plic0_default_handler (int id, void *priv) { - metal_shutdown(300); -} - -void __metal_plic0_handler (int id, void *priv) -{ - struct __metal_driver_riscv_plic0 *plic = priv; - unsigned int idx = __metal_plic0_claim_interrupt(plic); - unsigned int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic); - - if ( (idx < num_interrupts) && (plic->metal_exint_table[idx]) ) { - plic->metal_exint_table[idx](idx, - plic->metal_exdata_table[idx].exint_data); - } - - __metal_plic0_complete_interrupt(plic, idx); -} - -void __metal_driver_riscv_plic0_init (struct metal_interrupt *controller) -{ - struct __metal_driver_riscv_plic0 *plic = (void *)(controller); - - if ( !plic->init_done ) { - int num_interrupts, line; - struct metal_interrupt *intc; - - for(int parent = 0; parent < __METAL_PLIC_NUM_PARENTS; parent++) { - num_interrupts = __metal_driver_sifive_plic0_num_interrupts(controller); - intc = __metal_driver_sifive_plic0_interrupt_parents(controller, parent); - line = __metal_driver_sifive_plic0_interrupt_lines(controller, parent); - - /* Initialize ist parent controller, aka cpu_intc. */ - intc->vtable->interrupt_init(intc); - - for (int i = 0; i < num_interrupts; i++) { - __metal_plic0_enable(plic, i, METAL_DISABLE); - __metal_plic0_set_priority(controller, i, 0); - plic->metal_exint_table[i] = NULL; - plic->metal_exdata_table[i].sub_int = NULL; - plic->metal_exdata_table[i].exint_data = NULL; - } - - __metal_plic0_set_threshold(controller, 0); - - /* Register plic (ext) interrupt with with parent controller */ - intc->vtable->interrupt_register(intc, line, NULL, plic); - /* Register plic handler for dispatching its device interrupts */ - intc->vtable->interrupt_register(intc, line, __metal_plic0_handler, plic); - /* Enable plic (ext) interrupt with with parent controller */ - intc->vtable->interrupt_enable(intc, line); - } - plic->init_done = 1; - } -} - -int __metal_driver_riscv_plic0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - struct __metal_driver_riscv_plic0 *plic = (void *)(controller); - - if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { - return -1; - } - - if (isr) { - __metal_plic0_set_priority(controller, id, 2); - plic->metal_exint_table[id] = isr; - plic->metal_exdata_table[id].exint_data = priv; - } else { - __metal_plic0_set_priority(controller, id, 1); - plic->metal_exint_table[id] = __metal_plic0_default_handler; - plic->metal_exdata_table[id].sub_int = priv; - } - - return 0; -} - -int __metal_driver_riscv_plic0_enable (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_riscv_plic0 *plic = (void *)(controller); - - if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { - return -1; - } - - __metal_plic0_enable(plic, id, METAL_ENABLE); - return 0; -} - -int __metal_driver_riscv_plic0_disable (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_riscv_plic0 *plic = (void *)(controller); - - if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { - return -1; - } - __metal_plic0_enable(plic, id, METAL_DISABLE); - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_plic0) = { - .plic_vtable.interrupt_init = __metal_driver_riscv_plic0_init, - .plic_vtable.interrupt_register = __metal_driver_riscv_plic0_register, - .plic_vtable.interrupt_enable = __metal_driver_riscv_plic0_enable, - .plic_vtable.interrupt_disable = __metal_driver_riscv_plic0_disable, - .plic_vtable.interrupt_get_threshold = __metal_plic0_get_threshold, - .plic_vtable.interrupt_set_threshold = __metal_plic0_set_threshold, - .plic_vtable.interrupt_get_priority = __metal_plic0_get_priority, - .plic_vtable.interrupt_set_priority = __metal_plic0_set_priority, -}; - -#endif /* METAL_RISCV_PLIC0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c deleted file mode 100644 index 6f8723735..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_CCACHE0 - -#include -#include -#include -#include - -#define L2_CONFIG_WAYS_SHIFT 8 -#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) - -void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways); - -static void metal_driver_sifive_ccache0_init(void) __attribute__((constructor)); -static void metal_driver_sifive_ccache0_init(void) -{ -#ifdef __METAL_DT_SIFIVE_CCACHE0_HANDLE - /* Get the handle for the L2 cache controller */ - struct metal_cache *l2 = __METAL_DT_SIFIVE_CCACHE0_HANDLE; - if(!l2) { - return; - } - - /* Get the number of available ways per bank */ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(l2); - uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_CONFIG)); - ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); - - /* Enable all the ways */ - __metal_driver_sifive_ccache0_init(l2, ways); -#endif -} - -void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways) -{ - metal_cache_set_enabled_ways(l2, ways); -} - -int __metal_driver_sifive_ccache0_get_enabled_ways(struct metal_cache *cache) -{ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); - - uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)); - - /* The stored number is the index, so add one */ - return (0xFF & way_enable) + 1; -} - -int __metal_driver_sifive_ccache0_set_enabled_ways(struct metal_cache *cache, int ways) -{ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); - - /* We can't decrease the number of enabled ways */ - if(metal_cache_get_enabled_ways(cache) > ways) { - return -2; - } - - /* The stored value is the index, so subtract one */ - uint32_t value = 0xFF & (ways - 1); - - /* Set the number of enabled ways */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)) = value; - - /* Make sure the number of ways was set correctly */ - if(metal_cache_get_enabled_ways(cache) != ways) { - return -3; - } - - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_ccache0) = { - .cache.init = __metal_driver_sifive_ccache0_init, - .cache.get_enabled_ways = __metal_driver_sifive_ccache0_get_enabled_ways, - .cache.set_enabled_ways = __metal_driver_sifive_ccache0_set_enabled_ways, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c deleted file mode 100644 index 12c3dac06..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c +++ /dev/null @@ -1,736 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_CLIC0 - -#include -#include -#include -#include -#include - -typedef enum metal_clic_vector_{ - METAL_CLIC_NONVECTOR = 0, - METAL_CLIC_VECTORED = 1 -} metal_clic_vector; - -struct __metal_clic_cfg { - unsigned char : 1, - nmbits : 2, - nlbits : 4, - nvbit : 1; -}; - -const struct __metal_clic_cfg __metal_clic_defaultcfg = { - .nmbits = METAL_INTR_PRIV_M_MODE, - .nlbits = 0, - .nvbit = METAL_CLIC_NONVECTOR - }; - -void __metal_clic0_handler(int id, void *priv) __attribute__((aligned(64))); - -void __metal_clic0_default_vector_handler (void) __attribute__((interrupt, aligned(64))); - -struct __metal_clic_cfg __metal_clic0_configuration (struct __metal_driver_sifive_clic0 *clic, - struct __metal_clic_cfg *cfg) -{ - volatile unsigned char val; - struct __metal_clic_cfg cliccfg; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - - if ( cfg ) { - val = cfg->nmbits << 5 | cfg->nlbits << 1 | cfg->nvbit; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICCFG)) = val; - } - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICCFG)); - cliccfg.nmbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK) >> 5; - cliccfg.nlbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK) >> 1; - cliccfg.nvbit = val & METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK; - return cliccfg; -} - -int __metal_clic0_interrupt_set_mode (struct __metal_driver_sifive_clic0 *clic, int id, int mode) -{ - uint8_t mask, val; - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - - if (mode >= (cfg.nmbits << 1)) { - /* Do nothing, mode request same or exceed what configured in CLIC */ - return 0; - } - - /* Mask out nmbits and retain other values */ - mask = ((uint8_t)(-1)) >> cfg.nmbits; - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) & mask; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = val | (mode << (8 - cfg.nmbits)); - return 0; -} - -int __metal_clic0_interrupt_set_level (struct __metal_driver_sifive_clic0 *clic, int id, unsigned int level) -{ - uint8_t mask, nmmask, nlmask, val; - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - - /* Drop the LSBs that don't fit in nlbits */ - level = level >> (METAL_CLIC_MAX_NLBITS - cfg.nlbits); - - nmmask = ~( ((uint8_t)(-1)) >> (cfg.nmbits) ); - nlmask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits); - mask = ~(nlmask | nmmask); - - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, level); - return 0; -} - -unsigned int __metal_clic0_interrupt_get_level (struct __metal_driver_sifive_clic0 *clic, int id) -{ - int level; - uint8_t mask, val, freebits, nlbits; - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - - if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { - nlbits = num_intbits - cfg.nmbits; - } else { - nlbits = cfg.nlbits; - } - - mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); - freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; - - if (mask == 0) { - level = (1 << METAL_CLIC_MAX_NLBITS) - 1; - } else { - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - val = __METAL_GET_FIELD(val, mask); - level = (val << (METAL_CLIC_MAX_NLBITS - nlbits)) | freebits; - } - - return level; -} - -int __metal_clic0_interrupt_set_priority (struct __metal_driver_sifive_clic0 *clic, int id, int priority) -{ - uint8_t mask, npmask, val, npbits; - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - - if ((cfg.nmbits + cfg.nlbits) < num_intbits) { - npbits = num_intbits - (cfg.nmbits + cfg.nlbits); - priority = priority >> (8 - npbits); - - mask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits + npbits); - npmask = ~(((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits)); - mask = ~(mask | npmask); - - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, priority); - } - return 0; -} - -int __metal_clic0_interrupt_get_priority (struct __metal_driver_sifive_clic0 *clic, int id) -{ - int priority; - uint8_t mask, val, freebits, nlbits; - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - - if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { - nlbits = num_intbits - cfg.nmbits; - } else { - nlbits = cfg.nlbits; - } - - mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); - freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; - - if (mask == 0) { - priority = (1 << METAL_CLIC_MAX_NLBITS) - 1; - } else { - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - priority = __METAL_GET_FIELD(val, freebits); - } - return priority; -} - -int __metal_clic0_interrupt_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, int id, int enable) -{ - uint8_t mask, val; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - - mask = 1 << (8 - num_intbits); - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - /* Ensure its value is 1 bit wide */ - enable &= 0x1; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, enable); - return 0; -} - -int __metal_clic0_interrupt_is_vectored (struct __metal_driver_sifive_clic0 *clic, int id) -{ - uint8_t mask, val; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - - mask = 1 << (8 - num_intbits); - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - return __METAL_GET_FIELD(val, mask); -} - -int __metal_clic0_interrupt_enable (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id >= num_subinterrupts) { - return -1; - } - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_ENABLE; - return 0; -} - -int __metal_clic0_interrupt_disable (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id >= num_subinterrupts) { - return -1; - } - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_DISABLE; - return 0; -} - -int __metal_clic0_interrupt_is_enabled (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id >= num_subinterrupts) { - return 0; - } - return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)); -} - -int __metal_clic0_interrupt_is_pending (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id >= num_subinterrupts) { - return 0; - } - return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)); -} - -int __metal_clic0_interrupt_set (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id < num_subinterrupts) { - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_ENABLE; - return 0; - } - return -1; -} - -int __metal_clic0_interrupt_clear (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if (id < num_subinterrupts) { - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_DISABLE; - return 0; - } - return -1; -} - -int __metal_clic0_configure_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, metal_vector_mode mode) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - - switch (mode) { - case METAL_SELECTIVE_NONVECTOR_MODE: - cfg.nvbit = METAL_CLIC_NONVECTOR; - __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); - break; - case METAL_SELECTIVE_VECTOR_MODE: - cfg.nvbit = METAL_CLIC_VECTORED; - __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); - break; - case METAL_HARDWARE_VECTOR_MODE: - cfg.nvbit = METAL_CLIC_VECTORED; - __metal_controller_interrupt_vector(mode, &clic->metal_mtvt_table); - break; - default: - return -1; - } - __metal_clic0_configuration(clic, &cfg); - return 0; -} - -metal_vector_mode __metal_clic0_configure_get_vector_mode (struct __metal_driver_sifive_clic0 *clic) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); - - if (mode == METAL_SELECTIVE_VECTOR_MODE) { - if (cfg.nvbit) { - return METAL_SELECTIVE_VECTOR_MODE; - } else { - return METAL_SELECTIVE_NONVECTOR_MODE; - } - } else { - return mode; - } -} - -int __metal_clic0_configure_set_privilege (struct __metal_driver_sifive_clic0 *clic, metal_intr_priv_mode priv) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - - cfg.nmbits = priv; - __metal_clic0_configuration(clic, &cfg); - return 0; -} - -metal_intr_priv_mode __metal_clic0_configure_get_privilege (struct __metal_driver_sifive_clic0 *clic) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - - return cfg.nmbits; -} - -int __metal_clic0_configure_set_level (struct __metal_driver_sifive_clic0 *clic, int level) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - - cfg.nlbits = level & 0xF; - __metal_clic0_configuration(clic, &cfg); - return 0; -} - -int __metal_clic0_configure_get_level (struct __metal_driver_sifive_clic0 *clic) -{ - struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - - return cfg.nlbits; -} - -unsigned long long __metal_clic0_mtime_get (struct __metal_driver_sifive_clic0 *clic) -{ - __metal_io_u32 lo, hi; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - - /* Guard against rollover when reading */ - do { - hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)); - lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME)); - } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)) != hi); - - return (((unsigned long long)hi) << 32) | lo; -} - -int __metal_driver_sifive_clic0_mtimecmp_set(struct metal_interrupt *controller, - int hartid, - unsigned long long time) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, - * and are NOT internally latched for multiword transfers. - * Need to be careful about sequencing to avoid triggering - * spurious interrupts: For that set the high word to a max - * value first. - */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE)) = (__metal_io_u32)time; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); - return 0; -} - -void __metal_clic0_handler (int id, void *priv) -{ - struct __metal_driver_sifive_clic0 *clic = priv; - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); - - if ( (id < num_subinterrupts) && (clic->metal_exint_table[id].handler) ) { - clic->metal_exint_table[id].handler(id, clic->metal_exint_table[id].exint_data); - } -} - -void __metal_clic0_default_handler (int id, void *priv) { - metal_shutdown(300); -} - -void __metal_clic0_default_vector_handler (void) { - metal_shutdown(400); -} - -void __metal_driver_sifive_clic0_init (struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - - if ( !clic->init_done ) { - int level, max_levels, line, num_interrupts, num_subinterrupts; - struct __metal_clic_cfg cfg = __metal_clic_defaultcfg; - struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); - - /* Initialize ist parent controller, aka cpu_intc. */ - intc->vtable->interrupt_init(intc); - __metal_controller_interrupt_vector(METAL_SELECTIVE_NONVECTOR_MODE, - &clic->metal_mtvt_table); - - /* - * Register its interrupts with with parent controller, - * aka sw, timer and ext to its default isr - */ - num_interrupts = __metal_driver_sifive_clic0_num_interrupts(controller); - for (int i = 0; i < num_interrupts; i++) { - line = __metal_driver_sifive_clic0_interrupt_lines(controller, i); - intc->vtable->interrupt_register(intc, line, NULL, clic); - } - - /* Default CLIC mode to per dts */ - max_levels = __metal_driver_sifive_clic0_max_levels(controller); - cfg.nlbits = (max_levels > METAL_CLIC_MAX_NLBITS) ? - METAL_CLIC_MAX_NLBITS : max_levels; - __metal_clic0_configuration(clic, &cfg); - - level = (1 << cfg.nlbits) - 1; - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); - clic->metal_mtvt_table[0] = &__metal_clic0_handler; - for (int i = 1; i < num_subinterrupts; i++) { - clic->metal_mtvt_table[i] = NULL; - clic->metal_exint_table[i].handler = NULL; - clic->metal_exint_table[i].sub_int = NULL; - clic->metal_exint_table[i].exint_data = NULL; - __metal_clic0_interrupt_disable(clic, i); - __metal_clic0_interrupt_set_level(clic, i, level); - } - clic->init_done = 1; - } -} - -int __metal_driver_sifive_clic0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - int rc = -1; - int num_subinterrupts; - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); - metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - - if ( ( (mode == METAL_SELECTIVE_VECTOR_MODE) && - (__metal_clic0_interrupt_is_vectored(clic, id)) ) || - (mode == METAL_HARDWARE_VECTOR_MODE) || - (mode == METAL_VECTOR_MODE) || - (mode == METAL_DIRECT_MODE) ) { - return rc; - } - - /* Register its interrupts with parent controller */ - if (id < METAL_INTERRUPT_ID_CSW) { - return intc->vtable->interrupt_register(intc, id, isr, priv); - } - - /* - * CLIC (sub-interrupts) devices interrupts start at 16 but offset from 0 - * Reset the IDs to reflects this. - */ - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); - if (id < num_subinterrupts) { - if ( isr) { - clic->metal_exint_table[id].handler = isr; - clic->metal_exint_table[id].exint_data = priv; - } else { - clic->metal_exint_table[id].handler = __metal_clic0_default_handler; - clic->metal_exint_table[id].sub_int = priv; - } - rc = 0; - } - return rc; -} - -int __metal_driver_sifive_clic0_vector_register (struct metal_interrupt *controller, - int id, metal_interrupt_vector_handler_t isr, - void *priv) -{ - int rc = -1; - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); - metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - - if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { - return rc; - } - if ((mode == METAL_SELECTIVE_VECTOR_MODE) && - (__metal_clic0_interrupt_is_vectored(clic, id) == 0) ) { - return rc; - } - if (id < num_subinterrupts) { - if ( isr) { - clic->metal_mtvt_table[id] = isr; - clic->metal_exint_table[id].exint_data = priv; - } else { - clic->metal_mtvt_table[id] = __metal_clic0_default_vector_handler; - clic->metal_exint_table[id].sub_int = priv; - } - rc = 0; - } - return rc; -} - -int __metal_driver_sifive_clic0_enable (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_enable(clic, id); -} - -int __metal_driver_sifive_clic0_disable (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_disable(clic, id); -} - -int __metal_driver_sifive_clic0_enable_interrupt_vector(struct metal_interrupt *controller, int id) -{ - int rc = -1; - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - - if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { - return rc; - } - if (id < num_subinterrupts) { - __metal_clic0_interrupt_set_vector_mode(clic, id, METAL_ENABLE); - return 0; - } - return -1; -} - -int __metal_driver_sifive_clic0_disable_interrupt_vector(struct metal_interrupt *controller, int id) -{ - int num_subinterrupts; - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); - if (id < num_subinterrupts) { - __metal_clic0_interrupt_set_vector_mode(clic, id, METAL_DISABLE); - return 0; - } - return -1; -} - -metal_vector_mode __metal_driver_sifive_clic0_get_vector_mode (struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_get_vector_mode(clic); -} - -int __metal_driver_sifive_clic0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_set_vector_mode(clic, mode); -} - -metal_intr_priv_mode __metal_driver_sifive_clic0_get_privilege (struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_get_privilege(clic); -} - -int __metal_driver_sifive_clic0_set_privilege (struct metal_interrupt *controller, metal_intr_priv_mode priv) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_set_privilege(clic, priv); -} - -unsigned int __metal_driver_sifive_clic0_get_threshold (struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_get_level(clic); -} - -int __metal_driver_sifive_clic0_set_threshold (struct metal_interrupt *controller, unsigned int level) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_configure_set_level(clic, level); -} - -unsigned int __metal_driver_sifive_clic0_get_priority (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_get_priority(clic, id); -} - -int __metal_driver_sifive_clic0_set_priority (struct metal_interrupt *controller, int id, unsigned int priority) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_set_priority(clic, id, priority); -} - -int __metal_driver_sifive_clic0_clear_interrupt (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_clear(clic, id); -} - -int __metal_driver_sifive_clic0_set_interrupt (struct metal_interrupt *controller, int id) -{ - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - return __metal_clic0_interrupt_set(clic, id); -} - -int __metal_driver_sifive_clic0_command_request (struct metal_interrupt *controller, - int command, void *data) -{ - int hartid; - int rc = -1; - struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clic0_control_base(controller); - - switch (command) { - case METAL_TIMER_MTIME_GET: - if (data) { - *(unsigned long long *)data = __metal_clic0_mtime_get(clic); - rc = 0; - } - break; - case METAL_SOFTWARE_IPI_CLEAR: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_DISABLE; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_DISABLE; - rc = 0; - } - break; - case METAL_SOFTWARE_IPI_SET: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_ENABLE; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_ENABLE; - rc = 0; - } - break; - case METAL_SOFTWARE_MSIP_GET: - rc = 0; - if (data) { - hartid = *(int *)data; - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); - } - break; - default: - break; - } - - return rc; -} -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_clic0) = { - .clic_vtable.interrupt_init = __metal_driver_sifive_clic0_init, - .clic_vtable.interrupt_register = __metal_driver_sifive_clic0_register, - .clic_vtable.interrupt_vector_register = __metal_driver_sifive_clic0_vector_register, - .clic_vtable.interrupt_enable = __metal_driver_sifive_clic0_enable, - .clic_vtable.interrupt_disable = __metal_driver_sifive_clic0_disable, - .clic_vtable.interrupt_vector_enable = __metal_driver_sifive_clic0_enable_interrupt_vector, - .clic_vtable.interrupt_vector_disable = __metal_driver_sifive_clic0_disable_interrupt_vector, - .clic_vtable.interrupt_get_vector_mode = __metal_driver_sifive_clic0_get_vector_mode, - .clic_vtable.interrupt_set_vector_mode = __metal_driver_sifive_clic0_set_vector_mode, - .clic_vtable.interrupt_get_privilege = __metal_driver_sifive_clic0_get_privilege, - .clic_vtable.interrupt_set_privilege = __metal_driver_sifive_clic0_set_privilege, - .clic_vtable.interrupt_get_threshold = __metal_driver_sifive_clic0_get_threshold, - .clic_vtable.interrupt_set_threshold = __metal_driver_sifive_clic0_set_threshold, - .clic_vtable.interrupt_get_priority = __metal_driver_sifive_clic0_get_priority, - .clic_vtable.interrupt_set_priority = __metal_driver_sifive_clic0_set_priority, - .clic_vtable.interrupt_clear = __metal_driver_sifive_clic0_clear_interrupt, - .clic_vtable.interrupt_set = __metal_driver_sifive_clic0_set_interrupt, - .clic_vtable.command_request = __metal_driver_sifive_clic0_command_request, - .clic_vtable.mtimecmp_set = __metal_driver_sifive_clic0_mtimecmp_set, -}; - -#endif /* METAL_SIFIVE_CLIC0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c deleted file mode 100644 index 61af8d314..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FE310_G000_HFROSC - -#include -#include - -#define CONFIG_DIVIDER 0x0000003FUL -#define CONFIG_TRIM 0x001F0000UL -#define CONFIG_ENABLE 0x40000000UL -#define CONFIG_READY 0x80000000UL - -long __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfrosc_ref(clock); - long config_offset = __metal_driver_sifive_fe310_g000_hfrosc_config_offset(clock); - struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_hfrosc_config_base(clock); - const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); - long cfg = vtable->get_reg(config_base, config_offset); - - if ((cfg & CONFIG_ENABLE) == 0) - return -1; - if ((cfg & CONFIG_READY) == 0) - return -1; - return metal_clock_get_rate_hz(ref) / ((cfg & CONFIG_DIVIDER) + 1); -} - -long __metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz(struct metal_clock *clock, long rate) -{ - return __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(clock); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfrosc) = { - .clock.get_rate_hz = &__metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz, - .clock.set_rate_hz = &__metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz, -}; -#endif /* METAL_SIFIVE_FE310_G000_HFROSC */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c deleted file mode 100644 index 9ed7a0bf3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FE310_G000_HFXOSC - -#include -#include - -#define CONFIG_ENABLE 0x40000000UL -#define CONFIG_READY 0x80000000UL - -long __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfxosc_ref(clock); - long config_offset = __metal_driver_sifive_fe310_g000_hfxosc_config_offset(clock); - struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_hfxosc_config_base(clock); - const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); - long cfg = vtable->get_reg(config_base, config_offset); - - if ((cfg & CONFIG_ENABLE) == 0) - return -1; - if ((cfg & CONFIG_READY) == 0) - return -1; - return metal_clock_get_rate_hz(ref); -} - -long __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz(struct metal_clock *clock, long rate) -{ - return __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(clock); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_hfxosc) = { - .clock.get_rate_hz = __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz, - .clock.set_rate_hz = __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz, -}; - -#endif /* METAL_SIFIVE_FE310_G000_HFXOSC */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c deleted file mode 100644 index 324382b9d..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FE310_G000_LFROSC - -#include -#include - -/* LFROSCCFG */ -#define METAL_LFROSCCFG_DIV_MASK 0x3F -#define METAL_LFROSCCFG_TRIM_SHIFT 16 -#define METAL_LFROSCCFG_TRIM_MASK (0x1F << METAL_LFROSCCFG_TRIM_SHIFT) -#define METAL_LFROSCCFG_EN (1 << 30) -#define METAL_LFROSCCFG_RDY (1 << 31) - -/* LFCLKMUX */ -#define METAL_LFCLKMUX_SEL 1 -#define METAL_LFCLKMUX_EXT_MUX_STATUS (1 << 31) - -#define LFROSC_REGW(addr) (__METAL_ACCESS_ONCE((__metal_io_u32 *)addr)) - -long __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *internal_ref = __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(clock); - struct metal_clock *external_ref = __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(clock); - - unsigned long int cfg_reg = __metal_driver_sifive_fe310_g000_lfrosc_config_reg(clock); - unsigned long int mux_reg = __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(clock); - - if(LFROSC_REGW(mux_reg) & METAL_LFCLKMUX_EXT_MUX_STATUS) { - return metal_clock_get_rate_hz(external_ref); - } - - const unsigned long int div = (LFROSC_REGW(cfg_reg) & METAL_LFROSCCFG_DIV_MASK) + 1; - - return metal_clock_get_rate_hz(internal_ref) / div; -} - -long __metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz(struct metal_clock *clock, long rate) -{ - return __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(clock); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc) = { - .clock.get_rate_hz = &__metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz, - .clock.set_rate_hz = &__metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz, -}; -#endif /* METAL_SIFIVE_FE310_G000_LFROSC */ - -typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c deleted file mode 100644 index 2ca468f43..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FE310_G000_PLL - -#include -#include - -#include -#include -#include - -#define PLL_R 0x00000007UL -#define PLL_F 0x000003F0UL -#define PLL_Q 0x00000C00UL -#define PLL_SEL 0x00010000UL -#define PLL_REFSEL 0x00020000UL -#define PLL_BYPASS 0x00040000UL -#define PLL_LOCK 0x80000000UL - -#define DIV_DIV 0x0000003FUL -#define DIV_1 0x00000100UL - -#define PLL_R_SHIFT(r) ((r << 0) & PLL_R) -#define PLL_F_SHIFT(f) ((f << 4) & PLL_F) -#define PLL_Q_SHIFT(q) ((q << 10) & PLL_Q) -#define PLL_DIV_SHIFT(d) ((d << 0) & DIV_DIV) - -struct pll_config_t { - unsigned long multiplier; - unsigned long divisor; - unsigned long min_input_rate; - unsigned long max_input_rate; - unsigned long r; - unsigned long f; - unsigned long q; - long d; /* < 0 if disabled */ -}; - -static const struct pll_config_t pll_configs[] = { - /* - * multiplier - * ^ divisor - * | ^ min_input_rate - * | | ^ max_input_rate - * | | | ^ r - * | | | | ^ f - * | | | | | ^ q - * | | | | | | ^ d - * | | | | | | | ^ - * | | | | | | | | */ - { 1, 32, 12000000, 24000000, 1, 31, 3, 63}, - { 1, 32, 24000000, 48000000, 3, 31, 2, 63}, - { 1, 16, 6000000, 12000000, 0, 31, 3, 63}, - { 1, 16, 12000000, 24000000, 1, 31, 2, 63}, - { 1, 16, 24000000, 48000000, 3, 31, 2, 31}, - { 1, 8, 6000000, 12000000, 0, 31, 3, 31}, - { 1, 8, 12000000, 24000000, 1, 31, 2, 31}, - { 1, 8, 24000000, 48000000, 3, 31, 2, 15}, - { 1, 4, 6000000, 12000000, 0, 31, 3, 15}, - { 1, 4, 12000000, 24000000, 1, 31, 2, 15}, - { 1, 4, 24000000, 48000000, 3, 31, 2, 7}, - { 1, 2, 6000000, 12000000, 0, 31, 2, 15}, - { 1, 2, 12000000, 24000000, 1, 31, 1, 15}, - { 1, 2, 24000000, 48000000, 3, 31, 1, 7}, - { 2, 1, 6000000, 12000000, 0, 31, 1, 7}, - { 2, 1, 12000000, 24000000, 1, 31, 1, 3}, - { 2, 1, 24000000, 48000000, 3, 31, 3, -1}, - { 4, 1, 6000000, 12000000, 0, 31, 3, 0}, - { 4, 1, 12000000, 24000000, 1, 31, 3, -1}, - { 4, 1, 24000000, 48000000, 3, 31, 2, -1}, - { 6, 1, 6000000, 10666666, 0, 35, 1, 2}, - { 6, 1, 10666666, 12000000, 0, 23, 3, -1}, - { 6, 1, 12000000, 16000000, 1, 47, 3, -1}, - { 6, 1, 16000000, 18000000, 1, 23, 2, -1}, - { 6, 1, 18000000, 21333333, 2, 35, 2, -1}, - { 8, 1, 6000000, 12000000, 0, 31, 3, -1}, - { 8, 1, 12000000, 24000000, 1, 31, 2, -1}, - { 8, 1, 24000000, 48000000, 3, 31, 1, -1}, - {10, 1, 6000000, 9600000, 0, 39, 3, -1}, - {10, 1, 9600000, 12000000, 0, 19, 2, -1}, - {10, 1, 12000000, 19200000, 1, 39, 2, -1}, - {10, 1, 19200000, 24000000, 1, 19, 1, -1}, - {10, 1, 24000000, 38400000, 3, 39, 1, -1}, - {12, 1, 6000000, 8000000, 0, 47, 3, -1}, - {12, 1, 8000000, 12000000, 0, 23, 2, -1}, - {12, 1, 12000000, 16000000, 1, 47, 2, -1}, - {12, 1, 16000000, 24000000, 1, 23, 1, -1}, - {12, 1, 24000000, 30000000, 3, 47, 1, -1}, - {12, 1, 30000000, 32000000, 3, 47, 1, -1}, - {14, 1, 6000000, 6857142, 0, 55, 3, -1}, - {14, 1, 6857143, 12000000, 0, 27, 2, -1}, - {14, 1, 12000000, 13714285, 1, 55, 2, -1}, - {14, 1, 13714286, 24000000, 1, 27, 1, -1}, - {14, 1, 24000000, 27428571, 3, 55, 1, -1}, - {16, 1, 6000000, 12000000, 0, 31, 2, -1}, - {16, 1, 12000000, 24000000, 1, 31, 1, -1}, - {18, 1, 6000000, 10666666, 0, 35, 2, -1}, - {18, 1, 10666667, 12000000, 0, 17, 1, -1}, - {18, 1, 12000000, 21333333, 1, 35, 1, -1}, - {20, 1, 6000000, 9600000, 0, 39, 2, -1}, - {20, 1, 9600000, 12000000, 0, 19, 1, -1}, - {20, 1, 12000000, 19200000, 1, 39, 1, -1}, - {22, 1, 6000000, 8727272, 0, 43, 2, -1}, - {22, 1, 8727273, 12000000, 0, 21, 1, -1}, - {22, 1, 12000000, 17454545, 1, 43, 1, -1}, - {24, 1, 6000000, 8000000, 0, 47, 2, -1}, - {24, 1, 8000000, 12000000, 0, 23, 1, -1}, - {24, 1, 12000000, 16000000, 1, 47, 1, -1}, - {26, 1, 6000000, 7384615, 0, 51, 2, -1}, - {26, 1, 7384616, 12000000, 0, 25, 1, -1}, - {26, 1, 12000000, 14768230, 1, 51, 1, -1}, - {28, 1, 6000000, 6857142, 0, 55, 2, -1}, - {28, 1, 6857143, 12000000, 0, 27, 1, -1}, - {28, 1, 12000000, 13714285, 1, 55, 1, -1}, - {30, 1, 6000000, 6400000, 0, 59, 2, -1}, - {30, 1, 6400000, 12000000, 0, 29, 1, -1}, - {30, 1, 12000000, 12800000, 1, 59, 1, -1}, - {32, 1, 6000000, 12000000, 0, 31, 1, -1} -}; - -#define PLL_CONFIG_NOT_VALID -1 - -void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll); - -/* Given the rate of the PLL input frequency and a PLL configuration, what - * will the resulting PLL output frequency be? - * Arguments: - * - pll_input_rate the PLL input frequency in hertz - * - config the PLL configuration - * Returns: - * - PLL_CONFIG_NOT_VALID if the configuration is not valid for the input frequency - * - the output frequency, in hertz */ -static long get_pll_config_freq(unsigned long pll_input_rate, const struct pll_config_t *config) -{ - if(pll_input_rate < config->min_input_rate || pll_input_rate > config->max_input_rate) - return PLL_CONFIG_NOT_VALID; - - return pll_input_rate * config->multiplier / config->divisor; -} - -#ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE - -static void metal_sifive_fe310_g000_pll_init(void) __attribute__((constructor)); -static void metal_sifive_fe310_g000_pll_init(void) { - long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); - /* If the PLL init_rate is zero, don't initialize the PLL */ - if(init_rate != 0) - __metal_driver_sifive_fe310_g000_pll_init(__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE); -} - -#endif /* __METAL_DT_SIFIVE_FE310_G000__PLL_HANDLE */ - -void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll) { - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(&(pll->clock)); - long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); - long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(); - long base = __metal_driver_sifive_fe310_g000_prci_base(); - - __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); - - /* If the PLL clock has had a _pre_rate_change_callback configured, call it */ - _metal_clock_call_all_callbacks(pll->clock._pre_rate_change_callback); - - /* If we're running off of the PLL, switch off before we start configuring it*/ - if((__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) == 0) - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_SEL); - - /* Make sure we're running off of the external oscillator for stability */ - if(pllref != NULL) - __METAL_ACCESS_ONCE(pllcfg) |= PLL_REFSEL; - - /* Configure the PLL to run at the requested init frequency. - * Using the vtable instead of the user API because we want to control - * when the callbacks occur. */ - pll->clock.vtable->set_rate_hz(&(pll->clock), init_rate); - - /* If the PLL clock has had a rate_change_callback configured, call it */ - _metal_clock_call_all_callbacks(pll->clock._post_rate_change_callback); -} - -long __metal_driver_sifive_fe310_g000_pll_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); - struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); - long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); - struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_pll_config_base(clock); - long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); - struct __metal_driver_sifive_fe310_g000_prci *divider_base = - __metal_driver_sifive_fe310_g000_pll_divider_base(clock); - const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); - - long cfg = vtable->get_reg(config_base, config_offset); - long div = vtable->get_reg(divider_base, divider_offset); - - /* At the end of the PLL there's one big mux: it either selects the HFROSC - * (bypassing the PLL entirely) or uses the PLL. */ - if (__METAL_GET_FIELD(cfg, PLL_SEL) == 0) - return metal_clock_get_rate_hz(pllsel0); - - /* There's a clock mux before the PLL that selects between the HFROSC adn - * the HFXOSC as the PLL's input clock. */ - long ref_hz = metal_clock_get_rate_hz(__METAL_GET_FIELD(cfg, PLL_REFSEL) ? pllref : pllsel0); - - /* It's possible to bypass the PLL, which is an internal bpyass. This - * still obays the PLL's input clock mu. */ - if (__METAL_GET_FIELD(cfg, PLL_BYPASS)) - return ref_hz; - - /* Logically the PLL is a three stage div-mul-div. */ - long div_r = __METAL_GET_FIELD(cfg, PLL_R) + 1; - long mul_f = 2 * (__METAL_GET_FIELD(cfg, PLL_F) + 1); - if (__METAL_GET_FIELD(cfg, PLL_Q) == 0) - return -1; - long div_q = 1 << __METAL_GET_FIELD(cfg, PLL_Q); - - /* In addition to the dividers inherent in the PLL, there's an additional - * clock divider that lives after the PLL and lets us pick a more - * interesting range of frequencies. */ - long pllout = (((ref_hz / div_r) * mul_f) / div_q); - if (__METAL_GET_FIELD(div, DIV_1)) - return pllout; - - return pllout / (2 * (__METAL_GET_FIELD(div, DIV_DIV) + 1)); -} - -/* Find a valid configuration for the PLL which is closest to the desired - * output frequency. - * Arguments: - * - ref_hz PLL input frequency - * - rate desired PLL output frequency - * Returns: - * -1 if no valid configuration is available - * the index into pll_configs of a valid configuration */ -static int find_closest_config(long ref_hz, long rate) -{ - int closest_index = -1; - long closest_diff = LONG_MAX; - - /* We're probably trying for a fast output frequency, so start from - * the high end of the configs. */ - for(int i = (sizeof(pll_configs) / sizeof(pll_configs[0])) - 1; i >= 0; i--) - { - long config_freq = get_pll_config_freq(ref_hz, &(pll_configs[i])); - if(config_freq != PLL_CONFIG_NOT_VALID) - { - long freq_diff = abs(config_freq - rate); - if(freq_diff < closest_diff) - { - closest_index = i; - closest_diff = freq_diff; - } - } - } - - return closest_index; -} - -/* Configure the PLL and wait for it to lock */ -static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, const struct pll_config_t *config) -{ - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_R); - __METAL_ACCESS_ONCE(pllcfg) |= PLL_R_SHIFT(config->r); - - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_F); - __METAL_ACCESS_ONCE(pllcfg) |= PLL_F_SHIFT(config->f); - - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_Q); - __METAL_ACCESS_ONCE(pllcfg) |= PLL_Q_SHIFT(config->q); - - if(config->d < 0) - { - /* disable final divider */ - __METAL_ACCESS_ONCE(plloutdiv) |= DIV_1; - - __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); - __METAL_ACCESS_ONCE(plloutdiv) |= PLL_DIV_SHIFT(1); - } - else - { - __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_1); - - __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); - __METAL_ACCESS_ONCE(plloutdiv) |= PLL_DIV_SHIFT(config->d); - } - - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_BYPASS); - - /* Wait for PLL to lock */ - while((__METAL_ACCESS_ONCE(pllcfg) & PLL_LOCK) == 0) ; -} - -long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, long rate) -{ - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); - struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); - long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); - long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); - long base = __metal_driver_sifive_fe310_g000_prci_base(); - - __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); - __metal_io_u32 *plloutdiv = (__metal_io_u32 *) (base + divider_offset); - - /* We can't modify the PLL if coreclk is driven by it, so switch it off */ - if (__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) - __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_SEL); - - /* There's a clock mux before the PLL that selects between the HFROSC and - * the HFXOSC as the PLL's input clock. */ - long ref_hz = metal_clock_get_rate_hz(__METAL_ACCESS_ONCE(pllcfg) & PLL_REFSEL ? pllref : pllsel0); - - /* if the desired rate is within 75%-125% of the input clock, bypass the PLL */ - if((ref_hz * 3 / 4) <= rate && (ref_hz * 5 / 4) >= rate) - { - __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; - } - else - { - int config_index = find_closest_config(ref_hz, rate); - if(config_index != -1) - { - configure_pll(pllcfg, plloutdiv, &(pll_configs[config_index])); - } - else - { - /* unable to find a valid configuration */ - __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; - } - } - - /* Enable the PLL */ - __METAL_ACCESS_ONCE(pllcfg) |= PLL_SEL; - - return __metal_driver_sifive_fe310_g000_pll_get_rate_hz(clock); -} - -#ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE -static void use_hfxosc(void) __attribute__((constructor)); -static void use_hfxosc(void) -{ - long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); - metal_clock_set_rate_hz( - &__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE->clock, init_rate - ); -} -#endif - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_pll) = { - .init = __metal_driver_sifive_fe310_g000_pll_init, - .clock.get_rate_hz = __metal_driver_sifive_fe310_g000_pll_get_rate_hz, - .clock.set_rate_hz = __metal_driver_sifive_fe310_g000_pll_set_rate_hz, -}; - -#endif /* METAL_SIFIVE_FE310_G000_PLL */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c deleted file mode 100644 index 1236eca3b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FE310_G000_PRCI - -#include -#include - -long __metal_driver_sifive_fe310_g000_prci_get_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset) { - unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)); -} - -long __metal_driver_sifive_fe310_g000_prci_set_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset, long value) { - unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)) = value; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) = { - .get_reg = __metal_driver_sifive_fe310_g000_prci_get_reg, - .set_reg = __metal_driver_sifive_fe310_g000_prci_set_reg, -}; - -#endif /* METAL_SIFIVE_FE310_G000_PRCI */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c deleted file mode 100644 index aafc6e5e3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_FU540_C000_L2 - -#include -#include -#include -#include - -#define L2_CONFIG_WAYS_SHIFT 8 -#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) - -void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways); - -static void metal_driver_sifive_fu540_c000_l2_init(void) __attribute__((constructor)); -static void metal_driver_sifive_fu540_c000_l2_init(void) -{ -#ifdef __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE - /* Get the handle for the L2 cache controller */ - struct metal_cache *l2 = __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE; - if(!l2) { - return; - } - - /* Get the number of available ways per bank */ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(l2); - uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_CONFIG)); - ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); - - /* Enable all the ways */ - __metal_driver_sifive_fu540_c000_l2_init(l2, ways); -#endif -} - -void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways) -{ - metal_cache_set_enabled_ways(l2, ways); -} - -int __metal_driver_sifive_fu540_c000_l2_get_enabled_ways(struct metal_cache *cache) -{ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); - - uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)); - - /* The stored number is the index, so add one */ - return (0xFF & way_enable) + 1; -} - -int __metal_driver_sifive_fu540_c000_l2_set_enabled_ways(struct metal_cache *cache, int ways) -{ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); - - /* We can't decrease the number of enabled ways */ - if(metal_cache_get_enabled_ways(cache) > ways) { - return -2; - } - - /* The stored value is the index, so subtract one */ - uint32_t value = 0xFF & (ways - 1); - - /* Set the number of enabled ways */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)) = value; - - /* Make sure the number of ways was set correctly */ - if(metal_cache_get_enabled_ways(cache) != ways) { - return -3; - } - - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) = { - .cache.init = __metal_driver_sifive_fu540_c000_l2_init, - .cache.get_enabled_ways = __metal_driver_sifive_fu540_c000_l2_get_enabled_ways, - .cache.set_enabled_ways = __metal_driver_sifive_fu540_c000_l2_set_enabled_ways, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c deleted file mode 100644 index 0d56bafef..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0 - -#include -#include -#include -#include - -void __metal_driver_sifive_global_external_interrupt_init(struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_global_external_interrupts0 *global0; - - global0 = (struct __metal_driver_sifive_global_external_interrupts0 *)(controller); - if ( !global0->init_done ) { - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - if (intc) { - intc->vtable->interrupt_init(intc); - /* Register its interrupts with with parent controller */ - for (int i = 0; - i < __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); - i++) { - intc->vtable->interrupt_register(intc, - __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, i), - NULL, controller); - } - global0->init_done = 1; - } - } -} - -int __metal_driver_sifive_global_external_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_register(intc, id, isr, priv); - } - } - return rc; -} - -int __metal_driver_sifive_global_external_interrupt_enable(struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_enable(intc, id); - } - } - return rc; -} - -int __metal_driver_sifive_global_external_interrupt_disable(struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_disable(intc, id); - } - } - return rc; -} - -int __metal_driver_sifive_global_external_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int threshold) -{ - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - if (intc) { - return intc->vtable->interrupt_set_threshold(intc, threshold); - } - return -1; -} - -unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struct metal_interrupt *controller) -{ - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - if (intc) { - return intc->vtable->interrupt_get_threshold(intc); - } - return 0; -} - -int __metal_driver_sifive_global_external_interrupt_set_priority(struct metal_interrupt *controller, - int id, unsigned int priority) -{ - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - if (intc) { - return intc->vtable->interrupt_set_priority(intc, id, priority); - } - return -1; -} - -unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct metal_interrupt *controller, int id) -{ - struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - if (intc) { - return intc->vtable->interrupt_get_priority(intc, id); - } - return 0; -} - -int __metal_driver_sifive_global_external_command_request (struct metal_interrupt *controller, - int command, void *data) -{ - int idx; - int rc = -1; - - switch (command) { - case METAL_MAX_INTERRUPT_GET: - rc = __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); - break; - case METAL_INDEX_INTERRUPT_GET: - rc = 0; - if (data) { - idx = *(int *)data; - rc = __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, idx); - } - break; - default: - break; - } - - return rc; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) = { - .global0_vtable.interrupt_init = __metal_driver_sifive_global_external_interrupt_init, - .global0_vtable.interrupt_register = __metal_driver_sifive_global_external_interrupt_register, - .global0_vtable.interrupt_enable = __metal_driver_sifive_global_external_interrupt_enable, - .global0_vtable.interrupt_disable = __metal_driver_sifive_global_external_interrupt_disable, - .global0_vtable.interrupt_get_threshold = __metal_driver_sifive_global_external_interrupt_get_threshold, - .global0_vtable.interrupt_set_threshold = __metal_driver_sifive_global_external_interrupt_set_threshold, - .global0_vtable.interrupt_get_priority = __metal_driver_sifive_global_external_interrupt_get_priority, - .global0_vtable.interrupt_set_priority = __metal_driver_sifive_global_external_interrupt_set_priority, - .global0_vtable.command_request = __metal_driver_sifive_global_external_command_request, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c deleted file mode 100644 index 923fe2711..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_GPIO_BUTTONS - -#include -#include -#include -#include - -int __metal_driver_button_exist (struct metal_button *button, char *label) -{ - if (strcmp(__metal_driver_sifive_gpio_button_label(button), label) == 0) { - return 1; - } - return 0; -} - -struct metal_interrupt * -__metal_driver_button_interrupt_controller(struct metal_button *button) -{ - return __metal_driver_sifive_gpio_button_interrupt_controller(button); -} - -int __metal_driver_button_get_interrupt_id(struct metal_button *button) -{ - int irq, max_irq; - struct metal_interrupt *irc; - - irq = __metal_driver_sifive_gpio_button_interrupt_line(button); - irc = __metal_driver_sifive_gpio_button_interrupt_controller(button); - - if (irc != NULL) { - max_irq = _metal_interrupt_command_request(irc, - METAL_MAX_INTERRUPT_GET, - NULL); - - if (irq < max_irq) { - return _metal_interrupt_command_request(irc, - METAL_INDEX_INTERRUPT_GET, - (void *)&irq); - } - } - return METAL_INTERRUPT_ID_LCMX; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_button) = { - .button_vtable.button_exist = __metal_driver_button_exist, - .button_vtable.interrupt_controller = __metal_driver_button_interrupt_controller, - .button_vtable.get_interrupt_id = __metal_driver_button_get_interrupt_id, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c deleted file mode 100644 index a6b627458..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_GPIO_LEDS - -#include -#include -#include -#include - -int __metal_driver_led_exist (struct metal_led *led, char *label) -{ - if (strcmp(__metal_driver_sifive_gpio_led_label(led), label) == 0) { - return 1; - } - return 0; -} - -void __metal_driver_led_enable (struct metal_led *led) -{ - int pin; - struct metal_gpio *gpio; - - pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); - - if (gpio != NULL) { - /* Configure LED as output */ - metal_gpio_disable_input((struct metal_gpio *) gpio, pin); - metal_gpio_enable_output((struct metal_gpio *) gpio, pin); - } -} - -void __metal_driver_led_on (struct metal_led *led) -{ - int pin; - struct metal_gpio *gpio; - - pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); - - if (gpio != NULL) { - metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 1); - } -} - -void __metal_driver_led_off (struct metal_led *led) -{ - int pin; - struct metal_gpio *gpio; - - pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); - - if (gpio != NULL) { - metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 0); - } -} - -void __metal_driver_led_toggle (struct metal_led *led) -{ - int pin; - struct metal_gpio *gpio; - - pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); - - if (gpio != NULL) { - metal_gpio_toggle_pin((struct metal_gpio *) gpio, pin); - } -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_led) = { - .led_vtable.led_exist = __metal_driver_led_exist, - .led_vtable.led_enable = __metal_driver_led_enable, - .led_vtable.led_on = __metal_driver_led_on, - .led_vtable.led_off = __metal_driver_led_off, - .led_vtable.led_toggle = __metal_driver_led_toggle, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c deleted file mode 100644 index fa0a819f1..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_GPIO_SWITCHES - -#include -#include -#include -#include - -int __metal_driver_switch_exist (struct metal_switch *flip, char *label) -{ - if (strcmp(__metal_driver_sifive_gpio_switch_label(flip), label) == 0) { - return 1; - } - return 0; -} - -struct metal_interrupt * -__metal_driver_switch_interrupt_controller(struct metal_switch *flip) -{ - return __metal_driver_sifive_gpio_switch_interrupt_controller(flip); -} - -int __metal_driver_switch_get_interrupt_id(struct metal_switch *flip) -{ - int irq, max_irq; - struct metal_interrupt *irc; - - irq = __metal_driver_sifive_gpio_switch_interrupt_line(flip); - irc = __metal_driver_sifive_gpio_switch_interrupt_controller(flip); - if (irc != NULL) { - max_irq = _metal_interrupt_command_request(irc, - METAL_MAX_INTERRUPT_GET, - NULL); - - if (irq < max_irq) { - return _metal_interrupt_command_request(irc, - METAL_INDEX_INTERRUPT_GET, - (void *)&irq); - } - } - return METAL_INTERRUPT_ID_LCMX; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_switch) = { - .switch_vtable.switch_exist = __metal_driver_switch_exist, - .switch_vtable.interrupt_controller = __metal_driver_switch_interrupt_controller, - .switch_vtable.get_interrupt_id = __metal_driver_switch_get_interrupt_id, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c deleted file mode 100644 index 9ebbea03c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_GPIO0 - -#include -#include -#include - -int __metal_driver_sifive_gpio0_enable_input(struct metal_gpio *ggpio, long source) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) |= source; - - return 0; -} - -int __metal_driver_sifive_gpio0_disable_input(struct metal_gpio *ggpio, long source) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) &= ~source; - - return 0; -} - -long __metal_driver_sifive_gpio0_input(struct metal_gpio *ggpio) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_VALUE)); -} - -long __metal_driver_sifive_gpio0_output(struct metal_gpio *ggpio) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)); -} - - -int __metal_driver_sifive_gpio0_disable_output(struct metal_gpio *ggpio, long source) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) &= ~source; - - return 0; -} - -int __metal_driver_sifive_gpio0_enable_output(struct metal_gpio *ggpio, long source) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) |= source; - - return 0; -} - -int __metal_driver_sifive_gpio0_output_set(struct metal_gpio *ggpio, long value) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) |= value; - - return 0; -} - -int __metal_driver_sifive_gpio0_output_clear(struct metal_gpio *ggpio, long value) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) &= ~value; - - return 0; -} - -int __metal_driver_sifive_gpio0_output_toggle(struct metal_gpio *ggpio, long value) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) = - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) ^ value; - - return 0; -} - -int __metal_driver_sifive_gpio0_enable_io(struct metal_gpio *ggpio, long source, long dest) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_SEL)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) |= dest; - - return 0; -} - -int __metal_driver_sifive_gpio0_disable_io(struct metal_gpio *ggpio, long source) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) &= ~source; - - return 0; -} - -int __metal_driver_sifive_gpio0_config_int(struct metal_gpio *ggpio, long source, int intr_type) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - switch (intr_type) - { - case METAL_GPIO_INT_DISABLE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) &= ~source; - break; - case METAL_GPIO_INT_RISING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - break; - case METAL_GPIO_INT_FALLING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - break; - case METAL_GPIO_INT_BOTH_EDGE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - break; - case METAL_GPIO_INT_HIGH: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - break; - case METAL_GPIO_INT_LOW: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; - case METAL_GPIO_INT_BOTH_LEVEL: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; - case METAL_GPIO_INT_MAX: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; - } - return 0; -} - -int __metal_driver_sifive_gpio0_clear_int(struct metal_gpio *ggpio, long source, int intr_type) -{ - long base = __metal_driver_sifive_gpio0_base(ggpio); - - switch (intr_type) - { - case METAL_GPIO_INT_RISING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - break; - case METAL_GPIO_INT_FALLING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - break; - case METAL_GPIO_INT_BOTH_EDGE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - break; - case METAL_GPIO_INT_HIGH: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - break; - case METAL_GPIO_INT_LOW: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; - case METAL_GPIO_INT_BOTH_LEVEL: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; - case METAL_GPIO_INT_MAX: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; - } - return 0; -} - -struct metal_interrupt * -__metal_driver_gpio_interrupt_controller(struct metal_gpio *gpio) -{ - return __metal_driver_sifive_gpio0_interrupt_parent(gpio); -} - -int __metal_driver_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) -{ - int irq; - irq = __metal_driver_sifive_gpio0_interrupt_lines(gpio, pin); - return irq; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_gpio0) = { - .gpio.disable_input = __metal_driver_sifive_gpio0_disable_input, - .gpio.enable_input = __metal_driver_sifive_gpio0_enable_input, - .gpio.input = __metal_driver_sifive_gpio0_input, - .gpio.output = __metal_driver_sifive_gpio0_output, - .gpio.disable_output = __metal_driver_sifive_gpio0_disable_output, - .gpio.enable_output = __metal_driver_sifive_gpio0_enable_output, - .gpio.output_set = __metal_driver_sifive_gpio0_output_set, - .gpio.output_clear = __metal_driver_sifive_gpio0_output_clear, - .gpio.output_toggle = __metal_driver_sifive_gpio0_output_toggle, - .gpio.enable_io = __metal_driver_sifive_gpio0_enable_io, - .gpio.disable_io = __metal_driver_sifive_gpio0_disable_io, - .gpio.config_int = __metal_driver_sifive_gpio0_config_int, - .gpio.clear_int = __metal_driver_sifive_gpio0_clear_int, - .gpio.interrupt_controller = __metal_driver_gpio_interrupt_controller, - .gpio.get_interrupt_id = __metal_driver_gpio_get_interrupt_id, -}; - -#endif /* METAL_SIFIVE_GPIO0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c deleted file mode 100644 index 1c34ca447..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 - -#include -#include -#include - -void __metal_driver_sifive_local_external_interrupt_init(struct metal_interrupt *controller) -{ - struct __metal_driver_sifive_local_external_interrupts0 *local0; - - local0 = (struct __metal_driver_sifive_local_external_interrupts0 *)(controller); - if ( !local0->init_done ) { - struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); - - if (intc) { - /* Register its interruptswith with parent controller, aka all external to default isr */ - for (int i = 0; - i < __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); - i++) { - intc->vtable->interrupt_register(intc, - __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, i), - NULL, controller); - } - local0->init_done = 1; - } - } -} - -int __metal_driver_sifive_local_external_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_register(intc, id, isr, priv); - } - } - return rc; -} - -int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_enable(intc, id); - } - } - return rc; -} - -int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrupt *controller, int id) -{ - int rc = -1; - - if (id != 0) { - struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); - - /* Enable its interrupts with parent controller */ - if (intc) { - rc = intc->vtable->interrupt_disable(intc, id); - } - } - return rc; -} - -int __metal_driver_sifive_local_external_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int threshold) -{ - /* Core controller does not support threshold configuration */ - return -1; -} - -unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold(struct metal_interrupt *controller) -{ - /* Core controller does not support threshold configuration */ - return 0; -} - - -int __metal_driver_sifive_local_external_interrupt_set_priority(struct metal_interrupt *controller, - int id, unsigned int priority) -{ - /* Core controller does not support priority configuration */ - return -1; -} - -unsigned int __metal_driver_sifive_local_external_interrupt_get_priority(struct metal_interrupt *controller, int id) -{ - /* Core controller does not support priority configuration */ - return 0; -} - -int __metal_driver_sifive_local_external_command_request (struct metal_interrupt *controller, - int command, void *data) -{ - int idx; - int rc = -1; - - switch (command) { - case METAL_MAX_INTERRUPT_GET: - rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); - break; - case METAL_INDEX_INTERRUPT_GET: - rc = 0; - if (data) { - idx = *(int *)data; - rc = __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, idx); - } - break; - default: - break; - } - - return rc; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) = { - .local0_vtable.interrupt_init = __metal_driver_sifive_local_external_interrupt_init, - .local0_vtable.interrupt_register = __metal_driver_sifive_local_external_interrupt_register, - .local0_vtable.interrupt_enable = __metal_driver_sifive_local_external_interrupt_enable, - .local0_vtable.interrupt_disable = __metal_driver_sifive_local_external_interrupt_disable, - .local0_vtable.interrupt_get_threshold = __metal_driver_sifive_local_external_interrupt_get_threshold, - .local0_vtable.interrupt_set_threshold = __metal_driver_sifive_local_external_interrupt_set_threshold, - .local0_vtable.interrupt_get_priority = __metal_driver_sifive_local_external_interrupt_get_priority, - .local0_vtable.interrupt_set_priority = __metal_driver_sifive_local_external_interrupt_set_priority, - .local0_vtable.command_request = __metal_driver_sifive_local_external_command_request, -}; - -#endif - -typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c deleted file mode 100644 index 79b81e7bf..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_RTC0 - -#include -#include - -#include - -/* RTCCFG */ -#define METAL_RTCCFG_RTCSCALE_MASK 0xF -#define METAL_RTCCFG_ENALWAYS (1 << 12) -#define METAL_RTCCFG_IP0 (1 << 28) - -/* RTCCMP0 */ -#define METAL_RTCCMP0_MAX UINT32_MAX - -#define RTC_REG(base, offset) (((unsigned long)base + offset)) -#define RTC_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)RTC_REG(base, offset))) - -uint64_t __metal_driver_sifive_rtc0_get_rate(const struct metal_rtc *const rtc) { - const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); - return metal_clock_get_rate_hz(clock); -} - -uint64_t __metal_driver_sifive_rtc0_set_rate(const struct metal_rtc *const rtc, const uint64_t rate) { - const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); - return metal_clock_get_rate_hz(clock); -} - -uint64_t __metal_driver_sifive_rtc0_get_compare(const struct metal_rtc *const rtc) { - const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - - const uint32_t shift = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) & METAL_RTCCFG_RTCSCALE_MASK; - - return ((uint64_t)RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) << shift); -} - -uint64_t __metal_driver_sifive_rtc0_set_compare(const struct metal_rtc *const rtc, const uint64_t compare) { - const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - - /* Determine the bit shift and shifted value to store in rtccmp0/rtccfg.scale */ - uint32_t shift = 0; - uint64_t comp_shifted = compare; - while (comp_shifted > METAL_RTCCMP0_MAX) { - shift += 1; - comp_shifted = comp_shifted >> shift; - } - - /* Set the value of rtccfg.scale */ - uint32_t cfg = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG); - cfg &= ~(METAL_RTCCFG_RTCSCALE_MASK); - cfg |= (METAL_RTCCFG_RTCSCALE_MASK & shift); - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) = cfg; - - /* Set the value of rtccmp0 */ - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) = (uint32_t) comp_shifted; - - return __metal_driver_sifive_rtc0_get_compare(rtc); -} - -uint64_t __metal_driver_sifive_rtc0_get_count(const struct metal_rtc *const rtc) { - const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - - uint64_t count = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI); - count <<= 32; - count |= RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTLO); - - return count; -} - -uint64_t __metal_driver_sifive_rtc0_set_count(const struct metal_rtc *const rtc, const uint64_t count) { - const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI) = (UINT_MAX & (count >> 32)); - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTLO) = (UINT_MAX & count); - - return __metal_driver_sifive_rtc0_get_count(rtc); -} - -int __metal_driver_sifive_rtc0_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option) { - const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - - switch (option) { - default: - case METAL_RTC_STOP: - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) &= ~(METAL_RTCCFG_ENALWAYS); - break; - case METAL_RTC_RUN: - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) |= METAL_RTCCFG_ENALWAYS; - break; - } - - return 0; -} - -struct metal_interrupt *__metal_driver_sifive_rtc0_get_interrupt(const struct metal_rtc *const rtc) { - return __metal_driver_sifive_rtc0_interrupt_parent(rtc); -} - -int __metal_driver_sifive_rtc0_get_interrupt_id(const struct metal_rtc *const rtc) { - return __metal_driver_sifive_rtc0_interrupt_line(rtc); -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_rtc0) = { - .rtc.get_rate = __metal_driver_sifive_rtc0_get_rate, - .rtc.set_rate = __metal_driver_sifive_rtc0_set_rate, - .rtc.get_compare = __metal_driver_sifive_rtc0_get_compare, - .rtc.set_compare = __metal_driver_sifive_rtc0_set_compare, - .rtc.get_count = __metal_driver_sifive_rtc0_get_count, - .rtc.set_count = __metal_driver_sifive_rtc0_set_count, - .rtc.run = __metal_driver_sifive_rtc0_run, - .rtc.get_interrupt = __metal_driver_sifive_rtc0_get_interrupt, - .rtc.get_interrupt_id = __metal_driver_sifive_rtc0_get_interrupt_id, -}; - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c deleted file mode 100644 index 2a346354f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c +++ /dev/null @@ -1,405 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_SPI0 -#include -#include -#include -#include -#include - -/* Register fields */ -#define METAL_SPI_SCKDIV_MASK 0xFFF - -#define METAL_SPI_SCKMODE_PHA_SHIFT 0 -#define METAL_SPI_SCKMODE_POL_SHIFT 1 - -#define METAL_SPI_CSMODE_MASK 3 -#define METAL_SPI_CSMODE_AUTO 0 -#define METAL_SPI_CSMODE_HOLD 2 -#define METAL_SPI_CSMODE_OFF 3 - -#define METAL_SPI_PROTO_MASK 3 -#define METAL_SPI_PROTO_SINGLE 0 -#define METAL_SPI_PROTO_DUAL 1 -#define METAL_SPI_PROTO_QUAD 2 - -#define METAL_SPI_ENDIAN_LSB 4 - -#define METAL_SPI_DISABLE_RX 8 - -#define METAL_SPI_FRAME_LEN_SHIFT 16 -#define METAL_SPI_FRAME_LEN_MASK (0xF << METAL_SPI_FRAME_LEN_SHIFT) - -#define METAL_SPI_TXDATA_FULL (1 << 31) -#define METAL_SPI_RXDATA_EMPTY (1 << 31) -#define METAL_SPI_TXMARK_MASK 7 -#define METAL_SPI_TXWM 1 -#define METAL_SPI_TXRXDATA_MASK (0xFF) - -#define METAL_SPI_INTERVAL_SHIFT 16 - -#define METAL_SPI_CONTROL_IO 0 -#define METAL_SPI_CONTROL_MAPPED 1 - -#define METAL_SPI_REG(offset) (((unsigned long)control_base + offset)) -#define METAL_SPI_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)METAL_SPI_REG(offset))) -#define METAL_SPI_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_SPI_REG(offset))) - -#define METAL_SPI_RXDATA_TIMEOUT 1 - -static int configure_spi(struct __metal_driver_sifive_spi0 *spi, struct metal_spi_config *config) -{ - long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); - /* Set protocol */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_PROTO_MASK); - switch (config->protocol) { - case METAL_SPI_SINGLE: - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; - break; - case METAL_SPI_DUAL: - if (config->multi_wire == MULTI_WIRE_ALL) - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_DUAL; - else - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; - break; - case METAL_SPI_QUAD: - if (config->multi_wire == MULTI_WIRE_ALL) - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_QUAD; - else - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_SINGLE; - break; - default: - /* Unsupported value */ - return -1; - } - - /* Set Polarity */ - if(config->polarity) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_PHA_SHIFT); - } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_PHA_SHIFT); - } - - /* Set Phase */ - if(config->phase) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_POL_SHIFT); - } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_POL_SHIFT); - } - - /* Set Endianness */ - if(config->little_endian) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_ENDIAN_LSB; - } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_ENDIAN_LSB); - } - - /* Always populate receive FIFO */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_DISABLE_RX); - - /* Set CS Active */ - if(config->cs_active_high) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 0; - } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 1; - } - - /* Set frame length */ - if((METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) & METAL_SPI_FRAME_LEN_MASK) != (8 << METAL_SPI_FRAME_LEN_SHIFT)) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_FRAME_LEN_MASK); - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= (8 << METAL_SPI_FRAME_LEN_SHIFT); - } - - /* Set CS line */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSID) = 1 << (config->csid); - - /* Toggle off memory-mapped SPI flash mode, toggle on programmable IO mode - * It seems that with this line uncommented, the debugger cannot have access - * to the chip at all because it assumes the chip is in memory-mapped mode. - * I have to compile the code with this line commented and launch gdb, - * reset cores, reset $pc, set *((int *) 0x20004060) = 0, (set the flash - * interface control register to programmable I/O mode) and then continue - * Alternative, comment out the "flash" line in openocd.cfg */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FCTRL) = METAL_SPI_CONTROL_IO; - - return 0; -} - -static void spi_mode_switch(struct __metal_driver_sifive_spi0 *spi, - struct metal_spi_config *config, - unsigned int trans_stage) { - long control_base = - __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); - - if (config->multi_wire == trans_stage) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_PROTO_MASK); - switch (config->protocol) { - case METAL_SPI_DUAL: - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_DUAL; - break; - case METAL_SPI_QUAD: - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_PROTO_QUAD; - break; - default: - /* Unsupported value */ - return; - } - } -} - -int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, - struct metal_spi_config *config, - size_t len, - char *tx_buf, - char *rx_buf) -{ - struct __metal_driver_sifive_spi0 *spi = (void *)gspi; - long control_base = __metal_driver_sifive_spi0_control_base(gspi); - int rc = 0; - size_t i = 0; - - rc = configure_spi(spi, config); - if(rc != 0) { - return rc; - } - - /* Hold the chip select line for all len transferred */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) |= METAL_SPI_CSMODE_HOLD; - - unsigned long rxdata; - - /* Declare time_t variables to break out of infinite while loop */ - time_t endwait; - - for (i = 0; i < config->cmd_num; i++) { - - while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) - ; - - if (tx_buf) { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; - } else { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; - } - - endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; - - while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & - METAL_SPI_RXDATA_EMPTY) { - if (metal_time() > endwait) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= - ~(METAL_SPI_CSMODE_MASK); - - return 1; - } - } - - if (rx_buf) { - rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); - } - } - - /* switch to Dual/Quad mode */ - spi_mode_switch(spi, config, MULTI_WIRE_ADDR_DATA); - - /* Send Addr data */ - for (; i < (config->cmd_num + config->addr_num); i++) { - - while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) - ; - - if (tx_buf) { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; - } else { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; - } - - endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; - - while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & - METAL_SPI_RXDATA_EMPTY) { - if (metal_time() > endwait) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= - ~(METAL_SPI_CSMODE_MASK); - - return 1; - } - } - - if (rx_buf) { - rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); - } - } - - /* Send Dummy data */ - for (; i < (config->cmd_num + config->addr_num + config->dummy_num); i++) { - - while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) - ; - - if (tx_buf) { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; - } else { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; - } - - endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; - - while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & - METAL_SPI_RXDATA_EMPTY) { - if (metal_time() > endwait) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= - ~(METAL_SPI_CSMODE_MASK); - return 1; - } - } - if (rx_buf) { - rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); - } - } - - /* switch to Dual/Quad mode */ - spi_mode_switch(spi, config, MULTI_WIRE_DATA_ONLY); - - for (; i < len; i++) { - /* Master send bytes to the slave */ - - /* Wait for TXFIFO to not be full */ - while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL); - - /* Transfer byte by modifying the least significant byte in the TXDATA register */ - if (tx_buf) { - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; - } else { - /* Transfer a 0 byte if the sending buffer is NULL */ - METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = 0; - } - - /* Master receives bytes from the RX FIFO */ - - /* Wait for RXFIFO to not be empty, but break the nested loops if timeout - * this timeout method needs refining, preferably taking into account - * the device specs */ - endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; - - while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & METAL_SPI_RXDATA_EMPTY) { - if (metal_time() > endwait) { - /* If timeout, deassert the CS */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); - - /* If timeout, return error code 1 immediately */ - return 1; - } - } - - /* Only store the dequeued byte if the receive_buffer is not NULL */ - if (rx_buf) { - rx_buf[i] = (char) (rxdata & METAL_SPI_TXRXDATA_MASK); - } - } - - /* On the last byte, set CSMODE to auto so that the chip select transitions back to high - * The reason that CS pin is not deasserted after transmitting out the byte buffer is timing. - * The code on the host side likely executes faster than the ability of FIFO to send out bytes. - * After the host iterates through the array, fifo is likely not cleared yet. If host deasserts - * the CS pin immediately, the following bytes in the output FIFO will not be sent consecutively. - * There needs to be a better way to handle this. */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); - - return 0; -} - -int __metal_driver_sifive_spi0_get_baud_rate(struct metal_spi *gspi) -{ - struct __metal_driver_sifive_spi0 *spi = (void *)gspi; - return spi->baud_rate; -} - -int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, int baud_rate) -{ - long control_base = __metal_driver_sifive_spi0_control_base(gspi); - struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); - struct __metal_driver_sifive_spi0 *spi = (void *)gspi; - - spi->baud_rate = baud_rate; - - if (clock != NULL) { - long clock_rate = clock->vtable->get_rate_hz(clock); - - /* Calculate divider */ - long div = (clock_rate / (2 * baud_rate)) - 1; - - if(div > METAL_SPI_SCKDIV_MASK) { - /* The requested baud rate is lower than we can support at - * the current clock rate */ - return -1; - } - - /* Set divider */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) &= ~METAL_SPI_SCKDIV_MASK; - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) |= (div & METAL_SPI_SCKDIV_MASK); - } - - return 0; -} - -static void pre_rate_change_callback_func(void *priv) -{ - long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)priv); - - /* Detect when the TXDATA is empty by setting the transmit watermark count - * to one and waiting until an interrupt is pending (indicating an empty TXFIFO) */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) &= ~(METAL_SPI_TXMARK_MASK); - METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) |= (METAL_SPI_TXMARK_MASK & 1); - - while((METAL_SPI_REGW(METAL_SIFIVE_SPI0_IP) & METAL_SPI_TXWM) == 0) ; -} - -static void post_rate_change_callback_func(void *priv) -{ - struct __metal_driver_sifive_spi0 *spi = priv; - metal_spi_set_baud_rate(&spi->spi, spi->baud_rate); -} - -void __metal_driver_sifive_spi0_init(struct metal_spi *gspi, int baud_rate) -{ - struct __metal_driver_sifive_spi0 *spi = (void *)(gspi); - struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); - struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_spi0_pinmux(gspi); - - if(clock != NULL) { - spi->pre_rate_change_callback.callback = &pre_rate_change_callback_func; - spi->pre_rate_change_callback.priv = spi; - metal_clock_register_pre_rate_change_callback(clock, &(spi->pre_rate_change_callback)); - - spi->post_rate_change_callback.callback = &post_rate_change_callback_func; - spi->post_rate_change_callback.priv = spi; - metal_clock_register_post_rate_change_callback(clock, &(spi->post_rate_change_callback)); - } - - metal_spi_set_baud_rate(&(spi->spi), baud_rate); - - if (pinmux != NULL) { - long pinmux_output_selector = __metal_driver_sifive_spi0_pinmux_output_selector(gspi); - long pinmux_source_selector = __metal_driver_sifive_spi0_pinmux_source_selector(gspi); - pinmux->gpio.vtable->enable_io( - (struct metal_gpio *) pinmux, - pinmux_output_selector, - pinmux_source_selector - ); - } -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_spi0) = { - .spi.init = __metal_driver_sifive_spi0_init, - .spi.transfer = __metal_driver_sifive_spi0_transfer, - .spi.get_baud_rate = __metal_driver_sifive_spi0_get_baud_rate, - .spi.set_baud_rate = __metal_driver_sifive_spi0_set_baud_rate, -}; -#endif /* METAL_SIFIVE_SPI0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c deleted file mode 100644 index 79deebbf5..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_TEST0 - -#include - -#include - -#include -#include - -void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); -void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) -{ - long base = __metal_driver_sifive_test0_base(sd); - uint32_t out = (code << 16) + (code == 0 ? 0x5555 : 0x3333); - while (1) { - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_TEST0_FINISHER_OFFSET)) = out; - } -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_test0) = { - .shutdown.exit = &__metal_driver_sifive_test0_exit, -}; -#endif /* METAL_SIFIVE_TEST0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c deleted file mode 100644 index 8b63fbd28..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_TRACE - -#include -#include - -#define TRACE_REG(offset) (((unsigned long)base + (offset))) -#define TRACE_REG8(offset) \ - (__METAL_ACCESS_ONCE((__metal_io_u8 *)TRACE_REG(offset))) -#define TRACE_REG16(offset) \ - (__METAL_ACCESS_ONCE((__metal_io_u16 *)TRACE_REG(offset))) -#define TRACE_REG32(offset) \ - (__METAL_ACCESS_ONCE((__metal_io_u32 *)TRACE_REG(offset))) - -static void write_itc_uint32(struct metal_uart *trace, uint32_t data) { - long base = __metal_driver_sifive_trace_base(trace); - - TRACE_REG32(METAL_SIFIVE_TRACE_ITCSTIMULUS) = data; -} - -static void write_itc_uint16(struct metal_uart *trace, uint16_t data) { - long base = __metal_driver_sifive_trace_base(trace); - - TRACE_REG16(METAL_SIFIVE_TRACE_ITCSTIMULUS + 2) = data; -} - -static void write_itc_uint8(struct metal_uart *trace, uint8_t data) { - long base = __metal_driver_sifive_trace_base(trace); - - TRACE_REG8(METAL_SIFIVE_TRACE_ITCSTIMULUS + 3) = data; -} - -int __metal_driver_sifive_trace_putc(struct metal_uart *trace, - unsigned char c) { - static uint32_t buffer = 0; - static int bytes_in_buffer = 0; - - buffer |= (((uint32_t)c) << (bytes_in_buffer * 8)); - - bytes_in_buffer += 1; - - if (bytes_in_buffer >= 4) { - write_itc_uint32(trace, buffer); - - buffer = 0; - bytes_in_buffer = 0; - } else if ((c == '\n') || (c == '\r')) { // partial write - switch (bytes_in_buffer) { - case 3: // do a full word write - write_itc_uint16(trace, (uint16_t)(buffer)); - write_itc_uint8(trace, (uint8_t)(buffer >> 16)); - break; - case 2: // do a 16 bit write - write_itc_uint16(trace, (uint16_t)buffer); - break; - case 1: // do a 1 byte write - write_itc_uint8(trace, (uint8_t)buffer); - break; - } - - buffer = 0; - bytes_in_buffer = 0; - } - - return (int)c; -} - -void __metal_driver_sifive_trace_init(struct metal_uart *trace, int baud_rate) { - // The only init we do here is to make sure ITC 0 is enabled. It is up to - // Freedom Studio or other mechanisms to make sure tracing is enabled. If we - // try to enable tracing here, it will likely conflict with Freedom Studio, - // and they will just fight with each other. - - long base = __metal_driver_sifive_trace_base(trace); - - TRACE_REG32(METAL_SIFIVE_TRACE_ITCTRACEENABLE) |= 0x00000001; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_trace) = { - .uart.init = __metal_driver_sifive_trace_init, - .uart.putc = __metal_driver_sifive_trace_putc, - .uart.getc = NULL, - - .uart.get_baud_rate = NULL, - .uart.set_baud_rate = NULL, - - .uart.controller_interrupt = NULL, - .uart.get_interrupt_id = NULL, -}; - -#endif /* METAL_SIFIVE_TRACE */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c deleted file mode 100644 index 2e8098aa7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_UART0 - -#include -#include - -/* TXDATA Fields */ -#define UART_TXEN (1 << 0) -#define UART_TXFULL (1 << 31) - -/* RXDATA Fields */ -#define UART_RXEN (1 << 0) -#define UART_RXEMPTY (1 << 31) - -/* TXCTRL Fields */ -#define UART_NSTOP (1 << 1) -#define UART_TXCNT(count) ((0x7 & count) << 16) - -/* IP Fields */ -#define UART_TXWM (1 << 0) - -#define UART_REG(offset) (((unsigned long)control_base + offset)) -#define UART_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)UART_REG(offset))) -#define UART_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset))) - -struct metal_interrupt * -__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart) -{ - return __metal_driver_sifive_uart0_interrupt_parent(uart); -} - -int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart) -{ - return (__metal_driver_sifive_uart0_interrupt_line(uart) + METAL_INTERRUPT_ID_GL0); -} - - -int __metal_driver_sifive_uart0_txready(struct metal_uart *uart) -{ - long control_base = __metal_driver_sifive_uart0_control_base(uart); - - return !((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL)); -} - - -int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, int c) -{ - long control_base = __metal_driver_sifive_uart0_control_base(uart); - - while (!__metal_driver_sifive_uart0_txready(uart)) { - /* wait */ - } - UART_REGW(METAL_SIFIVE_UART0_TXDATA) = c; - return 0; -} - - -int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, int *c) -{ - uint32_t ch; - long control_base = __metal_driver_sifive_uart0_control_base(uart); - /* No seperate status register, we get status and the byte at same time */ - ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA);; - if( ch & UART_RXEMPTY ){ - *c = -1; /* aka: EOF in most of the world */ - } else { - *c = ch & 0x0ff; - } - return 0; -} - - -int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart) -{ - struct __metal_driver_sifive_uart0 *uart = (void *)guart; - return uart->baud_rate; -} - -int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud_rate) -{ - struct __metal_driver_sifive_uart0 *uart = (void *)guart; - long control_base = __metal_driver_sifive_uart0_control_base(guart); - struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); - - uart->baud_rate = baud_rate; - - if (clock != NULL) { - long clock_rate = clock->vtable->get_rate_hz(clock); - UART_REGW(METAL_SIFIVE_UART0_DIV) = clock_rate / baud_rate - 1; - UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXEN; - UART_REGW(METAL_SIFIVE_UART0_RXCTRL) |= UART_RXEN; - } - return 0; -} - -static void pre_rate_change_callback_func(void *priv) -{ - struct __metal_driver_sifive_uart0 *uart = priv; - long control_base = __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv); - struct metal_clock *clock = __metal_driver_sifive_uart0_clock((struct metal_uart *)priv); - - /* Detect when the TXDATA is empty by setting the transmit watermark count - * to one and waiting until an interrupt is pending */ - - UART_REGW(METAL_SIFIVE_UART0_TXCTRL) &= ~(UART_TXCNT(0x7)); - UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(1); - - while((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) ; - - /* When the TXDATA clears, the UART is still shifting out the last byte. - * Calculate the time we must drain to finish transmitting and then wait - * that long. */ - - long bits_per_symbol = (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10; - long clk_freq = clock->vtable->get_rate_hz(clock); - long cycles_to_wait = bits_per_symbol * clk_freq / uart->baud_rate; - - for(volatile long x = 0; x < cycles_to_wait; x++) - __asm__("nop"); -} - -static void post_rate_change_callback_func(void *priv) -{ - struct __metal_driver_sifive_uart0 *uart = priv; - metal_uart_set_baud_rate(&uart->uart, uart->baud_rate); -} - -void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate) -{ - struct __metal_driver_sifive_uart0 *uart = (void *)(guart); - struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); - struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_uart0_pinmux(guart); - - if(clock != NULL) { - uart->pre_rate_change_callback.callback = &pre_rate_change_callback_func; - uart->pre_rate_change_callback.priv = guart; - metal_clock_register_pre_rate_change_callback(clock, &(uart->pre_rate_change_callback)); - - uart->post_rate_change_callback.callback = &post_rate_change_callback_func; - uart->post_rate_change_callback.priv = guart; - metal_clock_register_post_rate_change_callback(clock, &(uart->post_rate_change_callback)); - } - - metal_uart_set_baud_rate(&(uart->uart), baud_rate); - - if (pinmux != NULL) { - long pinmux_output_selector = __metal_driver_sifive_uart0_pinmux_output_selector(guart); - long pinmux_source_selector = __metal_driver_sifive_uart0_pinmux_source_selector(guart); - pinmux->gpio.vtable->enable_io( - (struct metal_gpio *) pinmux, - pinmux_output_selector, - pinmux_source_selector - ); - } -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_uart0) = { - .uart.init = __metal_driver_sifive_uart0_init, - .uart.putc = __metal_driver_sifive_uart0_putc, - .uart.getc = __metal_driver_sifive_uart0_getc, - .uart.get_baud_rate = __metal_driver_sifive_uart0_get_baud_rate, - .uart.set_baud_rate = __metal_driver_sifive_uart0_set_baud_rate, - .uart.controller_interrupt = __metal_driver_sifive_uart0_interrupt_controller, - .uart.get_interrupt_id = __metal_driver_sifive_uart0_get_interrupt_id, -}; - -#endif /* METAL_SIFIVE_UART0 */ - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c deleted file mode 100644 index 1a6cf362e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#ifdef METAL_SIFIVE_WDOG0 - -#include -#include - -#include - -/* WDOGCFG */ -#define METAL_WDOGCFG_SCALE_MASK 7 -#define METAL_WDOGCFG_RSTEN (1 << 8) -#define METAL_WDOGCFG_ZEROCMP (1 << 9) -#define METAL_WDOGCFG_ENALWAYS (1 << 12) -#define METAL_WDOGCFG_COREAWAKE (1 << 13) -#define METAL_WDOGCFG_IP (1 << 28) - -/* WDOGCMP */ -#define METAL_WDOGCMP_MASK 0xFFFF - -#define WDOG_REG(base, offset) (((unsigned long)base + offset)) -#define WDOG_REGB(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)WDOG_REG(base, offset))) -#define WDOG_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)WDOG_REG(base, offset))) - -/* All writes to watchdog registers must be precedded by a write of - * a magic number to WDOGKEY */ -#define WDOG_UNLOCK(base) (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGKEY) = METAL_SIFIVE_WDOG0_MAGIC_KEY) - -/* Unlock the watchdog and then perform a register access */ -#define WDOG_UNLOCK_REGW(base, offset) \ - WDOG_UNLOCK(base);\ - WDOG_REGW(base, offset) - -int __metal_driver_sifive_wdog0_feed(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGFEED) = METAL_SIFIVE_WDOG0_MAGIC_FOOD; - - return 0; -} - -long int __metal_driver_sifive_wdog0_get_rate(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); - - const long int clock_rate = metal_clock_get_rate_hz(clock); - - if (clock_rate == 0) - return -1; - - const unsigned int scale = (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) & METAL_WDOGCFG_SCALE_MASK); - - return clock_rate / (1 << scale); -} - -long int __metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const wdog, const long int rate) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); - - const long int clock_rate = metal_clock_get_rate_hz(clock); - - if (rate >= clock_rate) { - /* We can't scale the rate above the driving clock. Clear the scale - * field and return the driving clock rate */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); - return clock_rate; - } - - /* Look for the closest scale value */ - long min_diff = LONG_MAX; - unsigned int min_scale = 0; - for (int i = 0; i < METAL_WDOGCFG_SCALE_MASK; i++) { - const long int new_rate = clock_rate / (1 << i); - - long int diff = rate - new_rate; - if (diff < 0) - diff *= -1; - - if (diff < min_diff) { - min_diff = diff; - min_scale = i; - } - } - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= (METAL_WDOGCFG_SCALE_MASK & min_scale); - - return clock_rate / (1 << min_scale); -} - -long int __metal_driver_sifive_wdog0_get_timeout(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - return (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) & METAL_WDOGCMP_MASK); -} - -long int __metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *const wdog, const long int timeout) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - /* Cap the timeout at the max value */ - const long int set_timeout = timeout > METAL_WDOGCMP_MASK ? METAL_WDOGCMP_MASK : timeout; - - /* If we edit the timeout value in-place by masking the compare value to 0 and - * then writing it, we cause a spurious interrupt because the compare value - * is temporarily 0. Instead, read the value into a local variable, modify it - * there, and then write the whole register back */ - uint32_t wdogcmp = WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP); - - wdogcmp &= ~(METAL_WDOGCMP_MASK); - wdogcmp |= set_timeout; - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) = wdogcmp; - - return set_timeout; -} - -int __metal_driver_sifive_wdog0_set_result(const struct metal_watchdog *const wdog, - const enum metal_watchdog_result result) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - /* Turn off reset enable and counter reset */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_RSTEN | METAL_WDOGCFG_ZEROCMP); - - switch (result) { - default: - case METAL_WATCHDOG_NO_RESULT: - break; - case METAL_WATCHDOG_INTERRUPT: - /* Reset counter to zero after match */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ZEROCMP; - break; - case METAL_WATCHDOG_FULL_RESET: - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_RSTEN; - break; - } - - return 0; -} - -int __metal_driver_sifive_wdog0_run(const struct metal_watchdog *const wdog, - const enum metal_watchdog_run_option option) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_ENALWAYS | METAL_WDOGCFG_COREAWAKE); - - switch (option) { - default: - case METAL_WATCHDOG_STOP: - break; - case METAL_WATCHDOG_RUN_ALWAYS: - /* Feed the watchdog before starting to reset counter */ - __metal_driver_sifive_wdog0_feed(wdog); - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ENALWAYS; - break; - case METAL_WATCHDOG_RUN_AWAKE: - /* Feed the watchdog before starting to reset counter */ - __metal_driver_sifive_wdog0_feed(wdog); - - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_COREAWAKE; - break; - } - - return 0; -} - -struct metal_interrupt *__metal_driver_sifive_wdog0_get_interrupt(const struct metal_watchdog *const wdog) -{ - return __metal_driver_sifive_wdog0_interrupt_parent(wdog); -} - -int __metal_driver_sifive_wdog0_get_interrupt_id(const struct metal_watchdog *const wdog) -{ - return __metal_driver_sifive_wdog0_interrupt_line(wdog); -} - -int __metal_driver_sifive_wdog0_clear_interrupt(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - - /* Clear the interrupt pending bit */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_IP); - - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_wdog0) = { - .watchdog.feed = __metal_driver_sifive_wdog0_feed, - .watchdog.get_rate = __metal_driver_sifive_wdog0_get_rate, - .watchdog.set_rate = __metal_driver_sifive_wdog0_set_rate, - .watchdog.get_timeout = __metal_driver_sifive_wdog0_get_timeout, - .watchdog.set_timeout = __metal_driver_sifive_wdog0_set_timeout, - .watchdog.set_result = __metal_driver_sifive_wdog0_set_result, - .watchdog.run = __metal_driver_sifive_wdog0_run, - .watchdog.get_interrupt = __metal_driver_sifive_wdog0_get_interrupt, - .watchdog.get_interrupt_id = __metal_driver_sifive_wdog0_get_interrupt_id, - .watchdog.clear_interrupt = __metal_driver_sifive_wdog0_clear_interrupt, -}; - -#endif /* METAL_SIFIVE_WDOG0 */ - -typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/entry.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/entry.S deleted file mode 100644 index 97da3fd33..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/entry.S +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* This code executes before _start, which is contained inside the C library. - * In embedded systems we want to ensure that _enter, which contains the first - * code to be executed, can be loaded at a specific address. To enable this - * feature we provide the '.text.metal.init.enter' section, which is - * defined to have the first address being where execution should start. */ -.section .text.metal.init.enter -.global _enter -_enter: - .cfi_startproc - - /* Inform the debugger that there is nowhere to backtrace past _enter. */ - .cfi_undefined ra - - /* The absolute first thing that must happen is configuring the global - * pointer register, which must be done with relaxation disabled because - * it's not valid to obtain the address of any symbol without GP - * configured. The C environment might go ahead and do this again, but - * that's safe as it's a fixed register. */ -.option push -.option norelax - la gp, __global_pointer$ -.option pop - - /* Set up a simple trap vector to catch anything that goes wrong early in - * the boot process. */ - la t0, early_trap_vector - csrw mtvec, t0 - /* enable chicken bit if core is bullet series*/ - la t0, __metal_chicken_bit - beqz t0, 1f - csrwi 0x7C1, 0 -1: - - /* There may be pre-initialization routines inside the MBI code that run in - * C, so here we set up a C environment. First we set up a stack pointer, - * which is left as a weak reference in order to allow initialization - * routines that do not need a stack to be set up to transparently be - * called. */ - .weak __metal_stack_pointer - la sp, __metal_stack_pointer - - /* Check for an initialization routine and call it if one exists, otherwise - * just skip over the call entirely. Note that __metal_initialize isn't - * actually a full C function, as it doesn't end up with the .bss or .data - * segments having been initialized. This is done to avoid putting a - * burden on systems that can be initialized without having a C environment - * set up. */ - .weak __metal_before_start - la ra, __metal_before_start - beqz ra, 1f - jalr ra -1: - - /* At this point we can enter the C runtime's startup file. The arguments - * to this function are designed to match those provided to the SEE, just - * so we don't have to write another ABI. */ - csrr a0, mhartid - li a1, 0 - li a2, 0 - call _start - - /* If we've made it back here then there's probably something wrong. We - * allow the METAL to register a handler here. */ - .weak __metal_after_main - la ra, __metal_after_main - beqz ra, 1f - jalr ra -1: - - /* If that handler returns then there's not a whole lot we can do. Just - * try to make some noise. */ - la t0, 1f - csrw mtvec, t0 -1: - lw t1, 0(x0) - j 1b - - .cfi_endproc - -/* For sanity's sake we set up an early trap vector that just does nothing. If - * you end up here then there's a bug in the early boot code somewhere. */ -.section .text.metal.init.trapvec -.align 2 -early_trap_vector: - .cfi_startproc - csrr t0, mcause - csrr t1, mepc - csrr t2, mtval - j early_trap_vector - .cfi_endproc - -/* The GCC port might not emit a __register_frame_info symbol, which eventually - * results in a weak undefined reference that eventually causes crash when it - * is dereference early in boot. We really shouldn't need to put this here, - * but to deal with what I think is probably a bug in the linker script I'm - * going to leave this in for now. At least it's fairly cheap :) */ -.weak __register_frame_info -.global __register_frame_info -.section .text.metal.init.__register_frame_info -__register_frame_info: - .cfi_startproc - ret - .cfi_endproc diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/gpio.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/gpio.c deleted file mode 100644 index 504526eb3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/gpio.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -extern __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_set_pin(struct metal_gpio *, int pin, int value); -extern __inline__ int metal_gpio_clear_pin(struct metal_gpio *, int pin); -extern __inline__ int metal_gpio_toggle_pin(struct metal_gpio *, int pin); -extern __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *, int pin, int io_function); -extern __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *, int pin); -extern __inline__ struct metal_interrupt* metal_gpio_interrupt_controller(struct metal_gpio *gpio); -extern __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type); -extern __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type); - -struct metal_gpio *metal_gpio_get_device(unsigned int device_num) -{ - if(device_num > __MEE_DT_MAX_GPIOS) { - return NULL; - } - - return (struct metal_gpio *) __metal_gpio_table[device_num]; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/interrupt.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/interrupt.c deleted file mode 100644 index eeb88b26f..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/interrupt.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include - -struct metal_interrupt* metal_interrupt_get_controller (metal_intr_cntrl_type cntrl, - int id) -{ - switch (cntrl) { - case METAL_CPU_CONTROLLER: - break; - case METAL_CLINT_CONTROLLER: -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - return __METAL_DT_RISCV_CLINT0_HANDLE; -#endif - break; - case METAL_CLIC_CONTROLLER: -#ifdef __METAL_DT_SIFIVE_CLIC0_HANDLE - return __METAL_DT_SIFIVE_CLIC0_HANDLE; -#endif - break; - case METAL_PLIC_CONTROLLER: -#ifdef __METAL_DT_RISCV_PLIC0_HANDLE - return __METAL_DT_RISCV_PLIC0_HANDLE; -#endif - break; - } - return NULL; -} - -extern __inline__ void metal_interrupt_init(struct metal_interrupt *controller); - -extern __inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller, - metal_vector_mode mode); -extern __inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller); - -extern __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, - metal_intr_priv_mode mode); -extern __inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller); - -extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int level); -extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); - -extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); - -extern __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_handler_t handler, - void *priv); - -extern __inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_vector_handler_t handler, - void *priv_data); - -extern __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id); - -extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); - -extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int threshold); - -extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); - -extern __inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id); - -extern __inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id); - -extern __inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller, - int cmd, void *data); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/led.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/led.c deleted file mode 100644 index 91b74dbde..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/led.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include - -struct metal_led* metal_led_get_rgb (char *label, char *color) -{ - int i; - struct metal_led *led; - char led_label[100]; - - if ((__METAL_DT_MAX_LEDS == 0) || - (label == NULL) || (color == NULL)) { - return NULL; - } - - strcpy(led_label, label); - strcat(led_label, color); - for (i = 0; i < __METAL_DT_MAX_LEDS; i++) { - led = (struct metal_led*)__metal_led_table[i]; - if (led->vtable->led_exist(led, led_label)) { - return led; - } - } - return NULL; -} - -struct metal_led* metal_led_get (char *label) -{ - return metal_led_get_rgb(label, ""); -} - -extern __inline__ void metal_led_enable(struct metal_led *led); -extern __inline__ void metal_led_on(struct metal_led *led); -extern __inline__ void metal_led_off(struct metal_led *led); -extern __inline__ void metal_led_toggle(struct metal_led *led); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/lock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/lock.c deleted file mode 100644 index 9e04230a3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/lock.c +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -extern __inline__ int metal_lock_init(struct metal_lock *lock); -extern __inline__ int metal_lock_take(struct metal_lock *lock); -extern __inline__ int metal_lock_give(struct metal_lock *lock); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/memory.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/memory.c deleted file mode 100644 index 05ab7ead2..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/memory.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -struct metal_memory *metal_get_memory_from_address(const uintptr_t address) { - for(int i = 0; i < __METAL_DT_MAX_MEMORIES; i++) { - struct metal_memory *mem = __metal_memory_table[i]; - - uintptr_t lower_bound = metal_memory_get_base_address(mem); - uintptr_t upper_bound = lower_bound + metal_memory_get_size(mem); - - if((address >= lower_bound) && (address < upper_bound)) { - return mem; - } - } - - return NULL; -} - -extern __inline__ uintptr_t metal_memory_get_base_address(const struct metal_memory *memory); -extern __inline__ size_t metal_memory_get_size(const struct metal_memory *memory); -extern __inline__ int metal_memory_supports_atomics(const struct metal_memory *memory); -extern __inline__ int metal_memory_is_cachable(const struct metal_memory *memory); - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/pmp.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/pmp.c deleted file mode 100644 index 5c2f68ada..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/pmp.c +++ /dev/null @@ -1,586 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include - -#define CONFIG_TO_INT(_config) (*((char *) &(_config))) -#define INT_TO_CONFIG(_int) (*((struct metal_pmp_config *)(char *) &(_int))) - -struct metal_pmp *metal_pmp_get_device(void) -{ -#ifdef __METAL_DT_PMP_HANDLE - return __METAL_DT_PMP_HANDLE; -#else - return NULL; -#endif -} - -/* This function calculates the minimum granularity from the address - * that pmpaddr takes on after writing all ones to pmpaddr when pmpcfg = 0. - * - * Detect the address granularity based on the position of the - * least-significant 1 set in the address. - * - * For example, if the value read from pmpaddr is 0x3ffffc00, the - * least-significant set bit is in bit 10 (counting from 0), resulting - * in a detected granularity of 2^(10 + 2) = 4096. - */ -static uintptr_t _get_detected_granularity(uintptr_t address) { - if(address == 0) { - return (uintptr_t) -1; - } - - /* Get the index of the least significant set bit */ - int index = 0; - while(((address >> index) & 0x1) == 0) { - index += 1; - } - - /* The granularity is equal to 2^(index + 2) bytes */ - return (1 << (index + 2)); -} - -/* This function calculates the granularity requested by the user's provided - * value for pmpaddr. - * - * Calculate the requested granularity based on the position of the - * least-significant unset bit. - * - * For example, if the requested address is 0x20009ff, the least-significant - * unset bit is at index 9 (counting from 0), resulting in a requested - * granularity of 2^(9 + 3) = 4096. - */ -static uintptr_t _get_pmpaddr_granularity(uintptr_t address) { - /* Get the index of the least significant unset bit */ - int index = 0; - while(((address >> index) & 0x1) == 1) { - index += 1; - } - - /* The granularity is equal to 2^(index + 3) bytes */ - return (1 << (index + 3)); -} - -/* Get the number of pmp regions for the given hart */ -int metal_pmp_num_regions(int hartid) -{ - struct metal_cpu *cpu = metal_cpu_get(hartid); - - return __metal_driver_cpu_num_pmp_regions(cpu); -} - -/* Get the number of pmp regions for the current hart */ -static unsigned int _pmp_regions() { - return metal_pmp_num_regions(metal_cpu_get_current_hartid()); -} - -void metal_pmp_init(struct metal_pmp *pmp) { - if(!pmp) { - return; - } - - struct metal_pmp_config init_config = { - .L = METAL_PMP_UNLOCKED, - .A = METAL_PMP_OFF, - .X = 0, - .W = 0, - .R = 0, - }; - - for(unsigned int i = 0; i < _pmp_regions(); i++) { - metal_pmp_set_region(pmp, i, init_config, 0); - } - - /* Detect the region granularity by writing all 1s to pmpaddr0 while - * pmpcfg0 = 0. */ - if(metal_pmp_set_address(pmp, 0, -1) != 0) { - /* Failed to detect granularity */ - return; - } - - /* Calculate the granularity based on the value that pmpaddr0 takes on */ - pmp->_granularity[metal_cpu_get_current_hartid()] = _get_detected_granularity(metal_pmp_get_address(pmp, 0)); - - /* Clear pmpaddr0 */ - metal_pmp_set_address(pmp, 0, 0); -} - -int metal_pmp_set_region(struct metal_pmp *pmp, - unsigned int region, - struct metal_pmp_config config, - size_t address) -{ - struct metal_pmp_config old_config; - size_t old_address; - size_t cfgmask; - size_t pmpcfg; - int rc = 0; - - if(!pmp) { - /* Device handle cannot be NULL */ - return 1; - } - - if(region > _pmp_regions()) { - /* Region outside of supported range */ - return 2; - } - - if(config.A == METAL_PMP_NA4 && pmp->_granularity[metal_cpu_get_current_hartid()] > 4) { - /* The requested granularity is too small */ - return 3; - } - - if(config.A == METAL_PMP_NAPOT && - pmp->_granularity[metal_cpu_get_current_hartid()] > _get_pmpaddr_granularity(address)) - { - /* The requested granularity is too small */ - return 3; - } - - rc = metal_pmp_get_region(pmp, region, &old_config, &old_address); - if(rc) { - /* Error reading region */ - return rc; - } - - if(old_config.L == METAL_PMP_LOCKED) { - /* Cannot modify locked region */ - return 4; - } - - /* Update the address first, because if the region is being locked we won't - * be able to modify it after we set the config */ - if(old_address != address) { - switch(region) { - case 0: - __asm__("csrw pmpaddr0, %[addr]" - :: [addr] "r" (address) :); - break; - case 1: - __asm__("csrw pmpaddr1, %[addr]" - :: [addr] "r" (address) :); - break; - case 2: - __asm__("csrw pmpaddr2, %[addr]" - :: [addr] "r" (address) :); - break; - case 3: - __asm__("csrw pmpaddr3, %[addr]" - :: [addr] "r" (address) :); - break; - case 4: - __asm__("csrw pmpaddr4, %[addr]" - :: [addr] "r" (address) :); - break; - case 5: - __asm__("csrw pmpaddr5, %[addr]" - :: [addr] "r" (address) :); - break; - case 6: - __asm__("csrw pmpaddr6, %[addr]" - :: [addr] "r" (address) :); - break; - case 7: - __asm__("csrw pmpaddr7, %[addr]" - :: [addr] "r" (address) :); - break; - case 8: - __asm__("csrw pmpaddr8, %[addr]" - :: [addr] "r" (address) :); - break; - case 9: - __asm__("csrw pmpaddr9, %[addr]" - :: [addr] "r" (address) :); - break; - case 10: - __asm__("csrw pmpaddr10, %[addr]" - :: [addr] "r" (address) :); - break; - case 11: - __asm__("csrw pmpaddr11, %[addr]" - :: [addr] "r" (address) :); - break; - case 12: - __asm__("csrw pmpaddr12, %[addr]" - :: [addr] "r" (address) :); - break; - case 13: - __asm__("csrw pmpaddr13, %[addr]" - :: [addr] "r" (address) :); - break; - case 14: - __asm__("csrw pmpaddr14, %[addr]" - :: [addr] "r" (address) :); - break; - case 15: - __asm__("csrw pmpaddr15, %[addr]" - :: [addr] "r" (address) :); - break; - } - } - -#if __riscv_xlen==32 - if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { - /* Mask to clear old pmpcfg */ - cfgmask = (0xFF << (8 * (region % 4)) ); - pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 4)) ); - - switch(region / 4) { - case 0: - __asm__("csrc pmpcfg0, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg0, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - case 1: - __asm__("csrc pmpcfg1, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg1, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - case 2: - __asm__("csrc pmpcfg2, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg2, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - case 3: - __asm__("csrc pmpcfg3, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg3, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - } - } -#elif __riscv_xlen==64 - if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { - /* Mask to clear old pmpcfg */ - cfgmask = (0xFF << (8 * (region % 8)) ); - pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 8)) ); - - switch(region / 8) { - case 0: - __asm__("csrc pmpcfg0, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg0, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - case 1: - __asm__("csrc pmpcfg2, %[mask]" - :: [mask] "r" (cfgmask) :); - - __asm__("csrs pmpcfg2, %[cfg]" - :: [cfg] "r" (pmpcfg) :); - break; - } - } -#else -#error XLEN is not set to supported value for PMP driver -#endif - - return 0; -} - -int metal_pmp_get_region(struct metal_pmp *pmp, - unsigned int region, - struct metal_pmp_config *config, - size_t *address) -{ - size_t pmpcfg = 0; - char *pmpcfg_convert = (char *)&pmpcfg; - - if(!pmp || !config || !address) { - /* NULL pointers are invalid arguments */ - return 1; - } - - if(region > _pmp_regions()) { - /* Region outside of supported range */ - return 2; - } - -#if __riscv_xlen==32 - switch(region / 4) { - case 0: - __asm__("csrr %[cfg], pmpcfg0" - : [cfg] "=r" (pmpcfg) ::); - break; - case 1: - __asm__("csrr %[cfg], pmpcfg1" - : [cfg] "=r" (pmpcfg) ::); - break; - case 2: - __asm__("csrr %[cfg], pmpcfg2" - : [cfg] "=r" (pmpcfg) ::); - break; - case 3: - __asm__("csrr %[cfg], pmpcfg3" - : [cfg] "=r" (pmpcfg) ::); - break; - } - - pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 4)) ) ); - -#elif __riscv_xlen==64 - switch(region / 8) { - case 0: - __asm__("csrr %[cfg], pmpcfg0" - : [cfg] "=r" (pmpcfg) ::); - break; - case 1: - __asm__("csrr %[cfg], pmpcfg2" - : [cfg] "=r" (pmpcfg) ::); - break; - } - - pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 8)) ) ); - -#else -#error XLEN is not set to supported value for PMP driver -#endif - - *config = INT_TO_CONFIG(*pmpcfg_convert); - - switch(region) { - case 0: - __asm__("csrr %[addr], pmpaddr0" - : [addr] "=r" (*address) ::); - break; - case 1: - __asm__("csrr %[addr], pmpaddr1" - : [addr] "=r" (*address) ::); - break; - case 2: - __asm__("csrr %[addr], pmpaddr2" - : [addr] "=r" (*address) ::); - break; - case 3: - __asm__("csrr %[addr], pmpaddr3" - : [addr] "=r" (*address) ::); - break; - case 4: - __asm__("csrr %[addr], pmpaddr4" - : [addr] "=r" (*address) ::); - break; - case 5: - __asm__("csrr %[addr], pmpaddr5" - : [addr] "=r" (*address) ::); - break; - case 6: - __asm__("csrr %[addr], pmpaddr6" - : [addr] "=r" (*address) ::); - break; - case 7: - __asm__("csrr %[addr], pmpaddr7" - : [addr] "=r" (*address) ::); - break; - case 8: - __asm__("csrr %[addr], pmpaddr8" - : [addr] "=r" (*address) ::); - break; - case 9: - __asm__("csrr %[addr], pmpaddr9" - : [addr] "=r" (*address) ::); - break; - case 10: - __asm__("csrr %[addr], pmpaddr10" - : [addr] "=r" (*address) ::); - break; - case 11: - __asm__("csrr %[addr], pmpaddr11" - : [addr] "=r" (*address) ::); - break; - case 12: - __asm__("csrr %[addr], pmpaddr12" - : [addr] "=r" (*address) ::); - break; - case 13: - __asm__("csrr %[addr], pmpaddr13" - : [addr] "=r" (*address) ::); - break; - case 14: - __asm__("csrr %[addr], pmpaddr14" - : [addr] "=r" (*address) ::); - break; - case 15: - __asm__("csrr %[addr], pmpaddr15" - : [addr] "=r" (*address) ::); - break; - } - - return 0; -} - -int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { - return rc; - } - - if(config.L == METAL_PMP_LOCKED) { - return 0; - } - - config.L = METAL_PMP_LOCKED; - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - - -int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address) -{ - struct metal_pmp_config config; - size_t old_address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &old_address); - if(rc) { - return rc; - } - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - -size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address = 0; - - metal_pmp_get_region(pmp, region, &config, &address); - - return address; -} - - -int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode) -{ - struct metal_pmp_config config; - size_t address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { - return rc; - } - - config.A = mode; - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - -enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address = 0; - - metal_pmp_get_region(pmp, region, &config, &address); - - return config.A; -} - - -int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X) -{ - struct metal_pmp_config config; - size_t address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { - return rc; - } - - config.X = X; - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - -int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address = 0; - - metal_pmp_get_region(pmp, region, &config, &address); - - return config.X; -} - - -int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W) -{ - struct metal_pmp_config config; - size_t address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { - return rc; - } - - config.W = W; - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - -int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address = 0; - - metal_pmp_get_region(pmp, region, &config, &address); - - return config.W; -} - - -int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R) -{ - struct metal_pmp_config config; - size_t address; - int rc = 0; - - rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { - return rc; - } - - config.R = R; - - rc = metal_pmp_set_region(pmp, region, config, address); - - return rc; -} - -int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region) -{ - struct metal_pmp_config config; - size_t address = 0; - - metal_pmp_get_region(pmp, region, &config, &address); - - return config.R; -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/privilege.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/privilege.c deleted file mode 100644 index 54bfcfc2c..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/privilege.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -#include - -#define METAL_MSTATUS_MIE_OFFSET 3 -#define METAL_MSTATUS_MPIE_OFFSET 7 -#define METAL_MSTATUS_SIE_OFFSET 1 -#define METAL_MSTATUS_SPIE_OFFSET 5 -#define METAL_MSTATUS_UIE_OFFSET 0 -#define METAL_MSTATUS_UPIE_OFFSET 4 - -#define METAL_MSTATUS_MPP_OFFSET 11 -#define METAL_MSTATUS_MPP_MASK 3 - -void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point) -{ - uintptr_t mstatus; - __asm__ volatile("csrr %0, mstatus" : "=r" (mstatus)); - - /* Set xPIE bits based on current xIE bits */ - if(mstatus && (1 << METAL_MSTATUS_MIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_MPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_MPIE_OFFSET); - } - if(mstatus && (1 << METAL_MSTATUS_SIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_SPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_SPIE_OFFSET); - } - if(mstatus && (1 << METAL_MSTATUS_UIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_UPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_UPIE_OFFSET); - } - - /* Set MPP to the requested privilege mode */ - mstatus &= ~(METAL_MSTATUS_MPP_MASK << METAL_MSTATUS_MPP_OFFSET); - mstatus |= (mode << METAL_MSTATUS_MPP_OFFSET); - - __asm__ volatile("csrw mstatus, %0" :: "r" (mstatus)); - - /* Set the entry point in MEPC */ - __asm__ volatile("csrw mepc, %0" :: "r" (entry_point)); - - /* Set the register file */ - __asm__ volatile("mv ra, %0" :: "r" (regfile.ra)); - __asm__ volatile("mv sp, %0" :: "r" (regfile.sp)); - - __asm__ volatile("mret"); -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/rtc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/rtc.c deleted file mode 100644 index 8b79892df..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/rtc.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2019 SiFive, Inc. */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -#include - -extern inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, const uint64_t rate); -extern inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, const uint64_t compare); -extern inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, const uint64_t count); -extern inline int metal_rtc_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option); -extern inline struct metal_interrupt *metal_rtc_get_interrupt(const struct metal_rtc *const rtc); -extern inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc); - -struct metal_rtc *metal_rtc_get_device(int index) { -#ifdef __METAL_DT_MAX_RTCS - if (index < __METAL_DT_MAX_RTCS) { - return (struct metal_rtc *) __metal_rtc_table[index]; - } -#endif - return NULL; -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/shutdown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/shutdown.c deleted file mode 100644 index c3b5255a7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/shutdown.c +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -extern __inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code); - -#if defined(__METAL_DT_SHUTDOWN_HANDLE) -void metal_shutdown(int code) -{ - __metal_shutdown_exit(__METAL_DT_SHUTDOWN_HANDLE, code); -} -#else -#pragma message("There is no defined shutdown mechanism, metal_shutdown() will spin.") -void metal_shutdown(int code) -{ - while (1) { - __asm__ volatile ("nop"); - } -} -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/spi.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/spi.c deleted file mode 100644 index de8cda737..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/spi.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -extern __inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate); -extern __inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf); -extern __inline__ int metal_spi_get_baud_rate(struct metal_spi *spi); -extern __inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate); - -struct metal_spi *metal_spi_get_device(unsigned int device_num) -{ -#if __METAL_DT_MAX_SPIS > 0 - if (device_num < __METAL_DT_MAX_SPIS) { - return (struct metal_spi *) __metal_spi_table[device_num]; - } -#endif - - return NULL; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/switch.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/switch.c deleted file mode 100644 index 4f17229c7..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/switch.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -struct metal_switch* metal_switch_get (char *label) -{ - int i; - struct metal_switch *flip; - - if ((__METAL_DT_MAX_BUTTONS == 0) || (label == NULL)) { - return NULL; - } - - for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { - flip = (struct metal_switch*)__metal_switch_table[i]; - if (flip->vtable->switch_exist(flip, label)) { - return flip; - } - } - return NULL; -} - -extern __inline__ struct metal_interrupt* - metal_switch_interrupt_controller(struct metal_switch *flip); -extern __inline__ int metal_switch_get_interrupt_id(struct metal_switch *flip); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/synchronize_harts.c deleted file mode 100644 index a5338e942..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/synchronize_harts.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include -#include - -#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) -#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) -#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) - -/* - * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for - * hart 0 to finish copying the datat section, zeroing the BSS, and running - * the libc contstructors. - */ -__attribute__((section(".init"))) -void __metal_synchronize_harts() { -#if __METAL_DT_MAX_HARTS > 1 - - int hart; - __asm__ volatile("csrr %0, mhartid" : "=r" (hart) ::); - - uintptr_t msip_base = 0; - - /* Get the base address of the MSIP registers */ -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); - msip_base += METAL_RISCV_CLINT0_MSIP_BASE; -#elif __METAL_DT_RISCV_CLIC0_HANDLE - msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); - msip_base += METAL_RISCV_CLIC0_MSIP_BASE; -#else -#pragma message(No handle for CLINT or CLIC found, harts may be unsynchronized after init!) -#endif - - /* Disable machine interrupts as a precaution */ - __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); - - if (hart == 0) { - /* Hart 0 waits for all harts to set their MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - while (METAL_MSIP(msip_base, i) == 0) ; - } - - /* Hart 0 clears everyone's MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - METAL_MSIP(msip_base, i) = 0; - } - } else { - /* Other harts set their MSIP bit to indicate they're ready */ - METAL_MSIP(msip_base, hart) = 1; - __asm__ volatile ("fence w,rw"); - - /* Wait for hart 0 to clear the MSIP bit */ - while (METAL_MSIP(msip_base, hart) == 1) ; - } - -#endif /* __METAL_DT_MAX_HARTS > 1 */ -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/time.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/time.c deleted file mode 100644 index 529f8bd56..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/time.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include - -int metal_gettimeofday(struct timeval *tp, void *tzp) -{ - int rv; - unsigned long long mcc, timebase; - if ((rv = metal_timer_get_cyclecount(0, &mcc))) { - return -1; - } - if ((rv = metal_timer_get_timebase_frequency(0, &timebase))) { - return -1; - } - tp->tv_sec = mcc / timebase; - tp->tv_usec = mcc % timebase * 1000000 / timebase; - return 0; -} - -time_t metal_time (void) -{ - struct timeval now; - - if (metal_gettimeofday(&now, NULL) < 0) - now.tv_sec = (time_t) -1; - - return now.tv_sec; -} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/timer.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/timer.c deleted file mode 100644 index f58413321..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/timer.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include -#include -#include - -#if defined(__METAL_DT_MAX_HARTS) -/* This implementation serves as a small shim that interfaces with the first - * timer on a system. */ -int metal_timer_get_cyclecount(int hartid, unsigned long long *mcc) -{ - struct metal_cpu *cpu = metal_cpu_get(hartid); - - if ( cpu ) { - *mcc = metal_cpu_get_timer(cpu); - return 0; - } - return -1; -} - -int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase) -{ - struct metal_cpu *cpu = metal_cpu_get(hartid); - - if ( cpu ) { - *timebase = metal_cpu_get_timebase(cpu); - return 0; - } - return -1; -} - -int metal_timer_get_machine_time(int hartid) -{ - struct metal_cpu *cpu = metal_cpu_get(hartid); - - if ( cpu ) { - return metal_cpu_get_mtime(cpu); - } - return 0; -} - -int metal_timer_set_machine_time(int hartid, unsigned long long time) -{ - struct metal_cpu *cpu = metal_cpu_get(hartid); - - if ( cpu ) { - return metal_cpu_set_mtimecmp(cpu, time); - } - return -1; -} - -#else - -/* This implementation of gettimeofday doesn't actually do anything, it's just there to - * provide a shim and return 0 so we can ensure that everything can link to _gettimeofday. - */ -int nop_cyclecount(int id, unsigned long long *c) __attribute__((section(".text.metal.nop.cyclecount"))); -int nop_cyclecount(int id, unsigned long long *c) { return -1; } -int nop_timebase(unsigned long long *t) __attribute__((section(".text.metal.nop.timebase"))); -int nop_timebase(unsigned long long *t) { return -1; } -int nop_tick(int second) __attribute__((section(".text.metal.nop.tick"))); -int nop_tick(int second) { return -1; } -int metal_timer_get_cyclecount(int hartid, unsigned long long *c) __attribute__((weak, alias("nop_cyclecount"))) -{ -#pragma message("There is no default timer device, metal_timer_get_cyclecount() will always return cyclecount -1.") -} -int metal_timer_get_timebase_frequency(unsigned long long *t) __attribute__((weak, alias("nop_timebase"))) -{ -#pragma message("There is no default timer device, metal_timer_get_timebase_frequency() will always return timebase -1.") -} -int metal_timer_set_tick(int second) __attribute__((weak, alias("nop_tick"))) -{ -#pragma message("There is no default timer device, metal_timer_set_tick) will always return -1.") -} - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/trap.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/trap.S deleted file mode 100644 index b55b6656a..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/trap.S +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#define METAL_MSTATUS_MIE_SHIFT 8 -#define METAL_MSTATUS_MPP_M 3 -#define METAL_MSTATUS_MPP_SHIFT 11 - -#define METAL_MTVEC_MODE_MASK 3 - -/* void _metal_trap(int ecode) - * - * Trigger a machine-mode trap with exception code ecode - */ -.global _metal_trap -.type _metal_trap, @function - -_metal_trap: - - /* Store the instruction which called _metal_trap in mepc */ - addi t0, ra, -1 - csrw mepc, t0 - - /* Set mcause to the desired exception code */ - csrw mcause, a0 - - /* Read mstatus */ - csrr t0, mstatus - - /* Set MIE=0 */ - li t1, -1 - xori t1, t1, METAL_MSTATUS_MIE_SHIFT - and t0, t0, t1 - - /* Set MPP=M */ - li t1, METAL_MSTATUS_MPP_M - slli t1, t1, METAL_MSTATUS_MPP_SHIFT - or t0, t0, t1 - - /* Write mstatus */ - csrw mstatus, t0 - - /* Read mtvec */ - csrr t0, mtvec - - /* - * Mask the mtvec MODE bits - * Exceptions always jump to mtvec.BASE regradless of the vectoring mode. - */ - andi t0, t0, METAL_MTVEC_MODE_MASK - - /* Jump to mtvec */ - jr t0 - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/tty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/tty.c deleted file mode 100644 index 306192451..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/tty.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include -#include -#include - -#if defined(__METAL_DT_STDOUT_UART_HANDLE) -/* This implementation serves as a small shim that interfaces with the first - * UART on a system. */ -int metal_tty_putc(int c) -{ - if (c == '\n') { - metal_tty_putc_raw( '\r' ); - } - return metal_tty_putc_raw( c ); -} - -int metal_tty_putc_raw(int c) -{ - return metal_uart_putc(__METAL_DT_STDOUT_UART_HANDLE, c); -} - -int metal_tty_getc(int *c) -{ - do { - metal_uart_getc( __METAL_DT_STDOUT_UART_HANDLE, c ); - /* -1 means no key pressed, getc waits */ - } while( -1 == *c ) - ; - return 0; -} - -#ifndef __METAL_DT_STDOUT_UART_BAUD -#define __METAL_DT_STDOUT_UART_BAUD 115200 -#endif - -static void metal_tty_init(void) __attribute__((constructor)); -static void metal_tty_init(void) -{ - metal_uart_init(__METAL_DT_STDOUT_UART_HANDLE, __METAL_DT_STDOUT_UART_BAUD); -} -#else -/* This implementation of putc doesn't actually do anything, it's just there to - * provide a shim that eats all the characters so we can ensure that everything - * can link to metal_tty_putc. */ -int nop_putc(int c) __attribute__((section(".text.metal.nop.putc"))); -int nop_putc(int c) { return -1; } -int metal_tty_putc(int c) __attribute__((weak, alias("nop_putc"))); -#pragma message("There is no default output device, metal_tty_putc() will throw away all input.") -#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/uart.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/uart.c deleted file mode 100644 index 8981eb8d3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/uart.c +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include - -extern __inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate); -extern __inline__ int metal_uart_putc(struct metal_uart *uart, int c); -extern __inline__ int metal_uart_txready(struct metal_uart *uart); -extern __inline__ int metal_uart_getc(struct metal_uart *uart, int *c); -extern __inline__ int metal_uart_get_baud_rate(struct metal_uart *uart); -extern __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/vector.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/vector.S deleted file mode 100644 index 1da52d2df..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/freedom-metal/src/vector.S +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -/* - * Jump table for CLINT vectored mode - */ -.weak metal_interrupt_vector_handler -.balign 4, 0 -.global metal_interrupt_vector_handler - -.weak metal_software_interrupt_vector_handler -.balign 4, 0 -.global metal_software_interrupt_vector_handler - -.weak metal_timer_interrupt_vector_handler -.balign 4, 0 -.global metal_timer_interrupt_vector_handler - -.weak metal_external_interrupt_vector_handler -.balign 4, 0 -.global metal_external_interrupt_vector_handler - -.weak metal_lc0_interrupt_vector_handler -.balign 4, 0 -.global metal_lc0_interrupt_vector_handler - -.weak metal_lc1_interrupt_vector_handler -.balign 4, 0 -.global metal_lc1_interrupt_vector_handler - -.weak metal_lc2_interrupt_vector_handler -.balign 4, 0 -.global metal_lc2_interrupt_vector_handler - -.weak metal_lc3_interrupt_vector_handler -.balign 4, 0 -.global metal_lc3_interrupt_vector_handler - -.weak metal_lc4_interrupt_vector_handler -.balign 4, 0 -.global metal_lc4_interrupt_vector_handler - -.weak metal_lc5_interrupt_vector_handler -.balign 4, 0 -.global metal_lc5_interrupt_vector_handler - -.weak metal_lc6_interrupt_vector_handler -.balign 4, 0 -.global metal_lc6_interrupt_vector_handler - -.weak metal_lc7_interrupt_vector_handler -.balign 4, 0 -.global metal_lc7_interrupt_vector_handler - -.weak metal_lc8_interrupt_vector_handler -.balign 4, 0 -.global metal_lc8_interrupt_vector_handler - -.weak metal_lc9_interrupt_vector_handler -.balign 4, 0 -.global metal_lc9_interrupt_vector_handler - -.weak metal_lc10_interrupt_vector_handler -.balign 4, 0 -.global metal_lc10_interrupt_vector_handler - -.weak metal_lc11_interrupt_vector_handler -.balign 4, 0 -.global metal_lc11_interrupt_vector_handler - -.weak metal_lc12_interrupt_vector_handler -.balign 4, 0 -.global metal_lc12_interrupt_vector_handler - -.weak metal_lc13_interrupt_vector_handler -.balign 4, 0 -.global metal_lc13_interrupt_vector_handler - -.weak metal_lc14_interrupt_vector_handler -.balign 4, 0 -.global metal_lc14_interrupt_vector_handler - -.weak metal_lc15_interrupt_vector_handler -.balign 4, 0 -.global metal_lc15_interrupt_vector_handler - -#if __riscv_xlen == 32 -.balign 128, 0 -#else -.balign 256, 0 -#endif -.option norvc -.global __metal_vector_table -__metal_vector_table: -IRQ_0: - j metal_interrupt_vector_handler -IRQ_1: - j metal_interrupt_vector_handler -IRQ_2: - j metal_interrupt_vector_handler -IRQ_3: - j metal_software_interrupt_vector_handler -IRQ_4: - j metal_interrupt_vector_handler -IRQ_5: - j metal_interrupt_vector_handler -IRQ_6: - j metal_interrupt_vector_handler -IRQ_7: - j metal_timer_interrupt_vector_handler -IRQ_8: - j metal_interrupt_vector_handler -IRQ_9: - j metal_interrupt_vector_handler -IRQ_10: - j metal_interrupt_vector_handler -IRQ_11: - j metal_interrupt_vector_handler -IRQ_12: - j metal_interrupt_vector_handler -IRQ_13: - j metal_interrupt_vector_handler -IRQ_14: - j metal_interrupt_vector_handler -IRQ_15: - j metal_interrupt_vector_handler -IRQ_LC0: - j metal_lc0_interrupt_vector_handler -IRQ_LC1: - j metal_lc1_interrupt_vector_handler -IRQ_LC2: - j metal_lc2_interrupt_vector_handler -IRQ_LC3: - j metal_lc3_interrupt_vector_handler -IRQ_LC4: - j metal_lc4_interrupt_vector_handler -IRQ_LC5: - j metal_lc5_interrupt_vector_handler -IRQ_LC6: - j metal_lc6_interrupt_vector_handler -IRQ_LC7: - j metal_lc7_interrupt_vector_handler -IRQ_LC8: - j metal_lc8_interrupt_vector_handler -IRQ_LC9: - j metal_lc9_interrupt_vector_handler -IRQ_LC10: - j metal_lc10_interrupt_vector_handler -IRQ_LC11: - j metal_lc11_interrupt_vector_handler -IRQ_LC12: - j metal_lc12_interrupt_vector_handler -IRQ_LC13: - j metal_lc13_interrupt_vector_handler -IRQ_LC14: - j metal_lc14_interrupt_vector_handler -IRQ_LC15: - j metal_lc15_interrupt_vector_handler - - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/RegTest.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/RegTest.S deleted file mode 100644 index f2602c430..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/RegTest.S +++ /dev/null @@ -1,266 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 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! - */ - - .extern ulRegTest1LoopCounter - .extern ulRegTest2LoopCounter - - .global vRegTest1Implementation - .global vRegTest2Implementation - -/*-----------------------------------------------------------*/ - -/* - * The register check tasks are described in the comments at the top of - * main_full.c. - */ - -.align( 4 ) -vRegTest1Implementation: - - /* Fill the core registers with known values. */ - li x5, 0x5 - li x6, 0x6 - li x7, 0x7 - li x8, 0x8 - li x9, 0x9 - li x10, 0xa - li x11, 0xb - li x12, 0xc - li x13, 0xd - li x14, 0xe - li x15, 0xf - li x16, 0x10 - li x17, 0x11 - li x18, 0x12 - li x19, 0x13 - li x20, 0x14 - li x21, 0x15 - li x22, 0x16 - li x23, 0x17 - li x24, 0x18 - li x25, 0x19 - li x26, 0x1a - li x27, 0x1b - li x28, 0x1c - li x29, 0x1d - li x30, 0x1e - -reg1_loop: - - /* Check each register still contains the expected known value. - vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation - uses x5 as the temporary. */ - li x31, 0x5 - bne x31, x5, reg1_error_loop - li x31, 0x6 - bne x31, x6, reg1_error_loop - li x31, 0x7 - bne x31, x7, reg1_error_loop - li x31, 0x8 - bne x31, x8, reg1_error_loop - li x31, 0x9 - bne x31, x9, reg1_error_loop - li x31, 0xa - bne x31, x10, reg1_error_loop - li x31, 0xb - bne x31, x11, reg1_error_loop - li x31, 0xc - bne x31, x12, reg1_error_loop - li x31, 0xd - bne x31, x13, reg1_error_loop - li x31, 0xe - bne x31, x14, reg1_error_loop - li x31, 0xf - bne x31, x15, reg1_error_loop - li x31, 0x10 - bne x31, x16, reg1_error_loop - li x31, 0x11 - bne x31, x17, reg1_error_loop - li x31, 0x12 - bne x31, x18, reg1_error_loop - li x31, 0x13 - bne x31, x19, reg1_error_loop - li x31, 0x14 - bne x31, x20, reg1_error_loop - li x31, 0x15 - bne x31, x21, reg1_error_loop - li x31, 0x16 - bne x31, x22, reg1_error_loop - li x31, 0x17 - bne x31, x23, reg1_error_loop - li x31, 0x18 - bne x31, x24, reg1_error_loop - li x31, 0x19 - bne x31, x25, reg1_error_loop - li x31, 0x1a - bne x31, x26, reg1_error_loop - li x31, 0x1b - bne x31, x27, reg1_error_loop - li x31, 0x1c - bne x31, x28, reg1_error_loop - li x31, 0x1d - bne x31, x29, reg1_error_loop - li x31, 0x1e - bne x31, x30, reg1_error_loop - - /* Everything passed, increment the loop counter. */ - lw x31, ulRegTest1LoopCounterConst - lw x30, 0(x31) - addi x30, x30, 1 - sw x30, 0(x31) - - /* Restore clobbered register reading for next loop. */ - li x30, 0x1e - - /* Yield to increase code coverage. */ - ecall - - /* Start again. */ - jal reg1_loop - -reg1_error_loop: - /* Jump here if a register contains an uxpected value. This stops the loop - counter being incremented so the check task knows an error was found. */ - ebreak - jal reg1_error_loop - -.align( 4 ) -ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter - -/*-----------------------------------------------------------*/ - -.align( 4 ) -vRegTest2Implementation: - - /* Fill the core registers with known values. */ - li x6, 0x61 - li x7, 0x71 - li x8, 0x81 - li x9, 0x91 - li x10, 0xa1 - li x11, 0xb1 - li x12, 0xc1 - li x13, 0xd1 - li x14, 0xe1 - li x15, 0xf1 - li x16, 0x20 - li x17, 0x21 - li x18, 0x22 - li x19, 0x23 - li x20, 0x24 - li x21, 0x25 - li x22, 0x26 - li x23, 0x27 - li x24, 0x28 - li x25, 0x29 - li x26, 0x2a - li x27, 0x2b - li x28, 0x2c - li x29, 0x2d - li x30, 0x2e - li x31, 0x2f - -Reg2_loop: - - /* Check each register still contains the expected known value. - vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation - uses x31 as the temporary. */ - li x5, 0x61 - bne x5, x6, reg2_error_loop - li x5, 0x71 - bne x5, x7, reg2_error_loop - li x5, 0x81 - bne x5, x8, reg2_error_loop - li x5, 0x91 - bne x5, x9, reg2_error_loop - li x5, 0xa1 - bne x5, x10, reg2_error_loop - li x5, 0xb1 - bne x5, x11, reg2_error_loop - li x5, 0xc1 - bne x5, x12, reg2_error_loop - li x5, 0xd1 - bne x5, x13, reg2_error_loop - li x5, 0xe1 - bne x5, x14, reg2_error_loop - li x5, 0xf1 - bne x5, x15, reg2_error_loop - li x5, 0x20 - bne x5, x16, reg2_error_loop - li x5, 0x21 - bne x5, x17, reg2_error_loop - li x5, 0x22 - bne x5, x18, reg2_error_loop - li x5, 0x23 - bne x5, x19, reg2_error_loop - li x5, 0x24 - bne x5, x20, reg2_error_loop - li x5, 0x25 - bne x5, x21, reg2_error_loop - li x5, 0x26 - bne x5, x22, reg2_error_loop - li x5, 0x27 - bne x5, x23, reg2_error_loop - li x5, 0x28 - bne x5, x24, reg2_error_loop - li x5, 0x29 - bne x5, x25, reg2_error_loop - li x5, 0x2a - bne x5, x26, reg2_error_loop - li x5, 0x2b - bne x5, x27, reg2_error_loop - li x5, 0x2c - bne x5, x28, reg2_error_loop - li x5, 0x2d - bne x5, x29, reg2_error_loop - li x5, 0x2e - bne x5, x30, reg2_error_loop - li x5, 0x2f - bne x5, x31, reg2_error_loop - - /* Everything passed, increment the loop counter. */ - lw x5, ulRegTest2LoopCounterConst - lw x6, 0(x5) - addi x6, x6, 1 - sw x6, 0(x5) - - /* Restore clobbered register reading for next loop. */ - li x6, 0x61 - - /* Start again. */ - jal Reg2_loop - -reg2_error_loop: - /* Jump here if a register contains an uxpected value. This stops the loop - counter being incremented so the check task knows an error was found. */ - ebreak - jal reg2_error_loop - -.align( 4 ) -ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter - - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/main_full.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/main_full.c deleted file mode 100644 index 1f25b0174..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/full_demo/main_full.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 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 comprehensive test and demo version. - * - * NOTE 2: This file only contains the source code that is specific to the - * full demo. Generic functions, such FreeRTOS hook functions, and functions - * required to configure the hardware, are defined in main.c. - * - ****************************************************************************** - * - * main_full() creates all the demo application tasks and software timers, then - * starts the scheduler. The web documentation provides more details of the - * standard demo application tasks, which provide no particular functionality, - * but do provide a good example of how to use the FreeRTOS API. - * - * In addition to the standard demo tasks, the following tasks and tests are - * defined and/or created within this file: - * - * "Reg test" tasks - These fill both the core registers with known values, then - * check that each register maintains its expected value for the lifetime of the - * task. Each task uses a different set of values. The reg test tasks execute - * with a very low priority, so get preempted very frequently. A register - * containing an unexpected value is indicative of an error in the context - * switching mechanism. - * - * "Check" task - The check executes every three seconds. It checks that all - * the standard demo tasks, and the register check tasks, are not only still - * executing, but are executing without reporting any errors. The check task - * toggles the LED every three seconds if all the standard demo tasks are - * executing as expected, or every 500ms if a potential error is discovered in - * any task. - */ - -/* Standard includes. */ -#include -#include -#include - -/* Kernel includes. */ -#include "FreeRTOS.h" -#include "task.h" -#include "timers.h" -#include "semphr.h" - -/* Standard demo application includes. */ -#include "dynamic.h" -#include "blocktim.h" -#include "TimerDemo.h" -#include "TaskNotify.h" - -/* Priorities for the demo application tasks. */ -#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) - -/* The period of the check task, in ms, converted to ticks using the -pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have -been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */ -#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL ) -#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL ) - -/* Parameters that are passed into the register check tasks solely for the -purpose of ensuring parameters are passed into tasks correctly. */ -#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) -#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) - -/* The base period used by the timer test tasks. */ -#define mainTIMER_TEST_PERIOD ( 50 ) - -/* The size of the stack allocated to the check task (as described in the -comments at the top of this file. */ -#define mainCHECK_TASK_STACK_SIZE_WORDS 160 - -/* Size of the stacks to allocated for the register check tasks. */ -#define mainREG_TEST_STACK_SIZE_WORDS 90 - -/*-----------------------------------------------------------*/ - -/* - * Called by main() to run the full demo (as opposed to the blinky demo) when - * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. - */ -void main_full( void ); - -/* - * The check task, as described at the top of this file. - */ -static void prvCheckTask( void *pvParameters ); - -/* - * Register check tasks as described at the top of this file. The nature of - * these files necessitates that they are written in an assembly file, but the - * entry points are kept in the C file for the convenience of checking the task - * parameter. - */ -static void prvRegTestTaskEntry1( void *pvParameters ); -extern void vRegTest1Implementation( void ); -static void prvRegTestTaskEntry2( void *pvParameters ); -extern void vRegTest2Implementation( void ); - -/* - * Tick hook used by the full demo, which includes code that interacts with - * some of the tests. - */ -void vFullDemoTickHook( void ); - -/*-----------------------------------------------------------*/ - -/* The following two variables are used to communicate the status of the -register check tasks to the check task. If the variables keep incrementing, -then the register check tasks have not discovered any errors. If a variable -stops incrementing, then an error has been found. */ -uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; -volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter; -volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter; -/*-----------------------------------------------------------*/ - -void main_full( void ) -{ - /* Start all the other standard demo/test tasks. They have no particular - functionality, but do demonstrate how to use the FreeRTOS API and test the - kernel port. */ - vCreateBlockTimeTasks(); - vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); - vStartDynamicPriorityTasks(); - vStartTaskNotifyTask(); - - /* Create the register check tasks, as described at the top of this file. - Use xTaskCreateStatic() to create a task using only statically allocated - memory. */ - xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */ - "Reg1", /* The name of the task. */ - mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */ - mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */ - tskIDLE_PRIORITY, /* Priority of the task. */ - NULL ); /* Can be used to pass out a handle to the created task. */ - xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); - - /* Create the task that performs the 'check' functionality, as described at - the top of this file. */ - xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL ); - - /* Start the scheduler. */ - 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 prvCheckTask( void *pvParameters ) -{ -TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; -TickType_t xLastExecutionTime; -uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; -char * const pcPassMessage = "."; -char * pcStatusMessage = pcPassMessage; -extern void vToggleLED( void ); - - /* Just to stop compiler warnings. */ - ( void ) pvParameters; - - /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() - works correctly. */ - xLastExecutionTime = xTaskGetTickCount(); - - /* Cycle for ever, delaying then checking all the other tasks are still - operating without error. The onboard LED is toggled on each iteration. - If an error is detected then the delay period is decreased from - mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the - effect of increasing the rate at which the onboard LED toggles, and in so - doing gives visual feedback of the system status. */ - for( ;; ) - { - /* Delay until it is time to execute again. */ - vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); - - /* Check all the demo tasks (other than the flash tasks) to ensure - that they are all still running, and that none have detected an error. */ - if( xAreDynamicPriorityTasksStillRunning() == pdFALSE ) - { - pcStatusMessage = "ERROR: Dynamic priority demo/tests.\r\n"; - } - - if( xAreBlockTimeTestTasksStillRunning() == pdFALSE ) - { - pcStatusMessage = "ERROR: Block time demo/tests.\r\n"; - } - - if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE ) - { - pcStatusMessage = "ERROR: Timer demo/tests.\r\n"; - } - - if( xAreTaskNotificationTasksStillRunning() == pdFALSE ) - { - pcStatusMessage = "ERROR: Task notification demo/tests.\r\n"; - } - - /* Check that the register test 1 task is still running. */ - if( ulLastRegTest1Value == ulRegTest1LoopCounter ) - { - pcStatusMessage = "ERROR: Register test 1.\r\n"; - } - ulLastRegTest1Value = ulRegTest1LoopCounter; - - /* Check that the register test 2 task is still running. */ - if( ulLastRegTest2Value == ulRegTest2LoopCounter ) - { - pcStatusMessage = "ERROR: Register test 2.\r\n"; - } - ulLastRegTest2Value = ulRegTest2LoopCounter; - - /* Write the status message to the UART and toggle the LED to show the - system status if the UART is not connected. */ - vToggleLED(); - - /* If an error has been found then increase the LED toggle rate by - increasing the cycle frequency. */ - if( pcStatusMessage != pcPassMessage ) - { - xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; - } - } -} -/*-----------------------------------------------------------*/ - -static void prvRegTestTaskEntry1( void *pvParameters ) -{ - /* Although the regtest task is written in assembler, its entry point is - written in C for convenience of checking the task parameter is being passed - in correctly. */ - if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) - { - /* Start the part of the test that is written in assembler. */ - vRegTest1Implementation(); - } - - /* The following line will only execute if the task parameter is found to - be incorrect. The check task will detect that the regtest loop counter is - not being incremented and flag an error. */ - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -static void prvRegTestTaskEntry2( void *pvParameters ) -{ - /* Although the regtest task is written in assembler, its entry point is - written in C for convenience of checking the task parameter is being passed - in correctly. */ - if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) - { - /* Start the part of the test that is written in assembler. */ - vRegTest2Implementation(); - } - - /* The following line will only execute if the task parameter is found to - be incorrect. The check task will detect that the regtest loop counter is - not being incremented and flag an error. */ - vTaskDelete( NULL ); -} -/*-----------------------------------------------------------*/ - -void vFullDemoTickHook( void ) -{ - /* Called from vApplicationTickHook() when the project is configured to - build the full test/demo applications. */ - - /* Use task notifications from an interrupt. */ - xNotifyTaskFromISR(); -} -/*-----------------------------------------------------------*/ - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/main.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/main.c deleted file mode 100644 index de03b623b..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1_FreedomStudio/main.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 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! - */ - -/****************************************************************************** - * 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 (defined in this file) is used to - * select between the two. The simply blinky demo is implemented and described - * in main_blinky.c. The more comprehensive test and demo application is - * implemented and described in main_full.c. - * - * This file implements the code that is not demo specific, including the - * hardware setup and standard FreeRTOS hook functions. - * - * When running on the HiFive Rev B hardware: - * When executing correctly the blue LED will toggle every three seconds. If - * the blue LED toggles every 500ms then one of the self-monitoring test tasks - * discovered a potential issue. If the red led toggles rapidly then a hardware - * exception occurred. - * - * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON - * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO - * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT! - * - */ - -/* FreeRTOS kernel includes. */ -#include -#include - -/* Freedom metal driver includes. */ -#include -#include - -/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, -or 0 to run the more comprehensive test and demo application. */ -#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 - -/* Index to first HART (there is only one). */ -#define mainHART_0 0 - -/* Registers used to initialise the PLIC. */ -#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) ) -#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) ) -#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) ) -#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) ) - -/*-----------------------------------------------------------*/ - -/* - * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. - * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. - */ -#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 - extern void main_blinky( void ); -#else - extern void main_full( void ); -#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ - -/* - * Prototypes for the standard FreeRTOS callback/hook functions implemented - * within this file. See https://www.freertos.org/a00016.html - */ -void vApplicationMallocFailedHook( void ); -void vApplicationIdleHook( void ); -void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); -void vApplicationTickHook( void ); - -/* - * Setup the hardware to run this demo. - */ -static void prvSetupHardware( void ); - -/* - * Used by the Freedom Metal drivers. - */ -static struct metal_led *pxBlueLED = NULL; - -/*-----------------------------------------------------------*/ - -int main( void ) -{ - prvSetupHardware(); - - /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top - of this file. */ - #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) - { - main_blinky(); - } - #else - { - main_full(); - } - #endif -} -/*-----------------------------------------------------------*/ - -static void prvSetupHardware( void ) -{ -struct metal_cpu *pxCPU; -struct metal_interrupt *pxInterruptController; - - /* Initialise the blue LED. */ - pxBlueLED = metal_led_get_rgb( "LD0", "blue" ); - configASSERT( pxBlueLED ); - metal_led_enable( pxBlueLED ); - metal_led_off( pxBlueLED ); - - /* Initialise the interrupt controller. */ - pxCPU = metal_cpu_get( mainHART_0 ); - configASSERT( pxCPU ); - pxInterruptController = metal_cpu_interrupt_controller( pxCPU ); - configASSERT( pxInterruptController ); - metal_interrupt_init( pxInterruptController ); - - /* Set all interrupt enable bits to 0. */ - mainPLIC_ENABLE_0 = 0UL; - mainPLIC_ENABLE_1 = 0UL; - - /* Clear all pending interrupts. */ - mainPLIC_PENDING_0 = 0UL; - mainPLIC_PENDING_1 = 0UL; -} -/*-----------------------------------------------------------*/ - -void vApplicationMallocFailedHook( void ) -{ - /* vApplicationMallocFailedHook() will only be called if - configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook - function that will get called if a call to pvPortMalloc() fails. - pvPortMalloc() is called internally by the kernel whenever a task, queue, - timer or semaphore is created. It is also called by various parts of the - demo application. If heap_1.c or heap_2.c are used, then the size of the - heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in - FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used - to query the size of free heap space that remains (although it does not - provide information on how the remaining heap might be fragmented). */ - taskDISABLE_INTERRUPTS(); - for( ;; ); -} -/*-----------------------------------------------------------*/ - -void vApplicationIdleHook( void ) -{ - /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set - to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle - task. It is essential that code added to this hook function never attempts - to block in any way (for example, call xQueueReceive() with a block time - specified, or call vTaskDelay()). If the application makes use of the - vTaskDelete() API function (as this demo application does) then it is also - important that vApplicationIdleHook() is permitted to return to its calling - function, because it is the responsibility of the idle task to clean up - memory allocated by the kernel to any task that has since been deleted. */ -} -/*-----------------------------------------------------------*/ - -void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) -{ - ( void ) pcTaskName; - ( void ) pxTask; - - /* Run time stack overflow checking is performed if - configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook - function is called if a stack overflow is detected. */ - taskDISABLE_INTERRUPTS(); - for( ;; ); -} -/*-----------------------------------------------------------*/ - -void vApplicationTickHook( void ) -{ - /* The tests in the full demo expect some interaction with interrupts. */ - #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 ) - { - extern void vFullDemoTickHook( void ); - vFullDemoTickHook(); - } - #endif -} -/*-----------------------------------------------------------*/ - -void vAssertCalled( void ) -{ -static struct metal_led *pxRedLED = NULL; -volatile uint32_t ul; -const uint32_t ulNullLoopDelay = 0x1ffffUL; - - taskDISABLE_INTERRUPTS(); - - /* Initialise the red LED. */ - pxRedLED = metal_led_get_rgb( "LD0", "red" ); - configASSERT( pxRedLED ); - metal_led_enable( pxRedLED ); - metal_led_off( pxRedLED ); - - /* Flash the red LED to indicate that assert was hit - interrupts are off - here to prevent any further tick interrupts or context switches, so the - delay is implemented as a crude loop instead of a peripheral timer. */ - for( ;; ) - { - for( ul = 0; ul < ulNullLoopDelay; ul++ ) - { - __asm volatile( "nop" ); - } - metal_led_toggle( pxRedLED ); - } -} -/*-----------------------------------------------------------*/ - -void handle_trap( void ) -{ -volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPLICPending0Register = 0UL, ulPLICPending1Register = 0UL; - - /* Store a few register values that might be useful when determining why this - function was called. */ - __asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) ); - __asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) ); - ulPLICPending0Register = mainPLIC_PENDING_0; - ulPLICPending1Register = mainPLIC_PENDING_1; - - /* Prevent compiler warnings about unused variables. */ - ( void ) ulPLICPending0Register; - ( void ) ulPLICPending1Register; - - /* Force an assert as this function has not been implemented as the demo - does not use external interrupts. */ - configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); -} -/*-----------------------------------------------------------*/ - -void vToggleLED( void ) -{ - metal_led_toggle( pxBlueLED ); -} -/*-----------------------------------------------------------*/ - -void *malloc( size_t xSize ) -{ - /* The linker script does not define a heap so artificially force an assert() - if something unexpectedly uses the C library heap. See - https://www.freertos.org/a00111.html for more information. */ - configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); - - /* Remove warnings about unused parameter. */ - ( void ) xSize; - return NULL; -} -/*-----------------------------------------------------------*/ - -