]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c
First task running in RISC-V-Qemu-sifive_e-FreedomStudio demo.
[freertos] / FreeRTOS / Source / portable / GCC / RISC-V-RV32 / port.c
index 4fab2fd6a7fae41127274187ffcc67a60e727d33..2754cb40e300c97fc3c600238aa0bff5dbf3e530 100644 (file)
@@ -39,7 +39,7 @@
  * file is weak to allow application writers to change the timer used to\r
  * generate the tick interrupt.\r
  */\r
-void vPortSetupTimerInterrupt( void );\r
+void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));\r
 \r
 /*\r
  * Used to catch tasks that attempt to return from their implementing function.\r
@@ -48,6 +48,13 @@ static void prvTaskExitError( void );
 \r
 /*-----------------------------------------------------------*/\r
 \r
+/* Used to program the machine timer compare register. */\r
+static uint64_t ullNextTime = 0ULL;\r
+static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ );\r
+static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
 void prvTaskExitError( void )\r
 {\r
 volatile uint32_t ulx = 0;\r
@@ -69,6 +76,8 @@ volatile uint32_t ulx = 0;
  */\r
 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
 {\r
+uint32_t mstatus;\r
+const uint32_t ulMPIE_Bit = 0x80, ulMPP_Bits = 0x1800;\r
        /*\r
           X1 to X31 integer registers for the 'I' profile, X1 to X15 for the 'E' profile.\r
 \r
@@ -87,119 +96,164 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
                x28-31          t3-6                    Temporaries                                     Caller\r
        */\r
 \r
+       /* Start task with interrupt enabled. */\r
+       __asm volatile ("csrr %0, mstatus" : "=r"(mstatus));\r
+       mstatus |= ulMPIE_Bit | ulMPP_Bits;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) pxCode; /* X1 */\r
+       *pxTopOfStack = mstatus;\r
+\r
+       /* Numbers correspond to the x register number. */\r
        pxTopOfStack--;\r
-//     *pxTopOfStack = ( StackType_t ) 2; /* Stack pointer is handled separately. */\r
-//     pxTopOfStack--;\r
-//     *pxTopOfStack = ( StackType_t ) 3; /* Global pointer is not manipulated. */\r
-//     pxTopOfStack--;\r
-//     *pxTopOfStack = ( StackType_t ) 4; /* Thread pointer is not manipulated. */\r
-//     pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 5;\r
+       *pxTopOfStack = ( StackType_t ) 31;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 6;\r
+       *pxTopOfStack = ( StackType_t ) 30;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 7;\r
+       *pxTopOfStack = ( StackType_t ) 29;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 8;\r
+       *pxTopOfStack = ( StackType_t ) 28;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 9;\r
+       *pxTopOfStack = ( StackType_t ) 27;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) pvParameters;\r
+       *pxTopOfStack = ( StackType_t ) 26;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 11;\r
+       *pxTopOfStack = ( StackType_t ) 25;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 12;\r
+       *pxTopOfStack = ( StackType_t ) 24;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 13;\r
+       *pxTopOfStack = ( StackType_t ) 23;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 14;\r
+       *pxTopOfStack = ( StackType_t ) 22;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 15;\r
+       *pxTopOfStack = ( StackType_t ) 21;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 16;\r
+       *pxTopOfStack = ( StackType_t ) 20;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 17;\r
+       *pxTopOfStack = ( StackType_t ) 19;\r
        pxTopOfStack--;\r
        *pxTopOfStack = ( StackType_t ) 18;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 19;\r
+       *pxTopOfStack = ( StackType_t ) 17;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 20;\r
+       *pxTopOfStack = ( StackType_t ) 16;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 21;\r
+       *pxTopOfStack = ( StackType_t ) 15;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 22;\r
+       *pxTopOfStack = ( StackType_t ) 14;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 23;\r
+       *pxTopOfStack = ( StackType_t ) 13;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 24;\r
+       *pxTopOfStack = ( StackType_t ) 12;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 25;\r
+       *pxTopOfStack = ( StackType_t ) 11;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 26;\r
+       *pxTopOfStack = ( StackType_t ) pvParameters;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 27;\r
+       *pxTopOfStack = ( StackType_t ) 9;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 28;\r
+       *pxTopOfStack = ( StackType_t ) 8;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 29;\r
+       *pxTopOfStack = ( StackType_t ) 7;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 30;\r
+       *pxTopOfStack = ( StackType_t ) 6;\r
        pxTopOfStack--;\r
-       *pxTopOfStack = ( StackType_t ) 31;\r
+       *pxTopOfStack = ( StackType_t ) 5;\r
+       pxTopOfStack--;\r
+//     *pxTopOfStack = ( StackType_t ) 4;  /* Thread pointer. */\r
+//     pxTopOfStack--;\r
+//     *pxTopOfStack = ( StackType_t ) 3;  /* Global pointer. */\r
+//     pxTopOfStack--;\r
+//     *pxTopOfStack = ( StackType_t ) 2;  /* Stack pointer. */\r
+//     pxTopOfStack--;\r
+       *pxTopOfStack = ( StackType_t ) prvTaskExitError;\r
+       pxTopOfStack--;\r
+       *pxTopOfStack = ( StackType_t ) pxCode;\r
 \r
        return pxTopOfStack;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void vPortSetupTimerInterrupt( void )\r
+{\r
+uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;\r
+volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFFC );\r
+volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFF8 );\r
+\r
+       do\r
+       {\r
+               ulCurrentTimeHigh = *pulTimeHigh;\r
+               ulCurrentTimeLow = *pulTimeLow;\r
+       } while( ulCurrentTimeHigh != *pulTimeHigh );\r
+\r
+       ullNextTime = ( uint64_t ) ulCurrentTimeHigh;\r
+       ullNextTime <<= 32ULL;\r
+       ullNextTime |= ( uint64_t ) ulCurrentTimeLow;\r
+       ullNextTime += ullTimerIncrementsForOneTick;\r
+       *pullMachineTimerCompareRegister = ullNextTime;\r
+\r
+       /* Prepare the time to use after the next tick interrupt. */\r
+       ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
+       /* Enable timer interrupt */\r
+       __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void Software_IRQHandler( void )\r
+{\r
+volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCLINT_BASE_ADDRESS;\r
+\r
+       vTaskSwitchContext();\r
+\r
+       /* Clear software interrupt. */\r
+       *( ( uint32_t * ) configCLINT_BASE_ADDRESS ) &= 0x08UL;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void Timer_IRQHandler( void )\r
+{\r
+extern void vTaskSwitchContext( void );\r
+\r
+       /* Reload for the next timer interrupt. */\r
+       *pullMachineTimerCompareRegister = ullNextTime;\r
+       ullNextTime += ullTimerIncrementsForOneTick;\r
+\r
+       if( xTaskIncrementTick() != pdFALSE )\r
+       {\r
+               vTaskSwitchContext();\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 BaseType_t xPortStartScheduler( void )\r
 {\r
-       __asm volatile\r
-       (\r
-               ".extern pxCurrentTCB                   \r\n"\r
-               "lw             sp, pxCurrentTCB                \r\n" /* Load pxCurrentTCB. */\r
-               "lw             sp, 0x00( sp )                  \r\n" /* Read sp from first TCB member. */\r
-               "lw             x31, 0( sp )                    \r\n" /* X31 */\r
-               "lw             x30, 4( sp )                    \r\n" /* X30 */\r
-               "lw             x29, 8( sp )                    \r\n" /* X29 */\r
-               "lw             x28, 12( sp )                   \r\n" /* X28 */\r
-               "lw             x27, 16( sp )                   \r\n" /* X27 */\r
-               "lw             x26, 20( sp )                   \r\n" /* X26 */\r
-               "lw             x25, 24( sp )                   \r\n" /* X25 */\r
-               "lw             x24, 28( sp )                   \r\n" /* X24 */\r
-               "lw             x23, 32( sp )                   \r\n" /* X23 */\r
-               "lw             x22, 36( sp )                   \r\n" /* X22 */\r
-               "lw             x21, 40( sp )                   \r\n" /* X21 */\r
-               "lw             x20, 44( sp )                   \r\n" /* X20 */\r
-               "lw             x19, 48( sp )                   \r\n" /* X19 */\r
-               "lw             x18, 52( sp )                   \r\n" /* X18 */\r
-               "lw             x17, 56( sp )                   \r\n" /* X17 */\r
-               "lw             x16, 60( sp )                   \r\n" /* X16 */\r
-               "lw             x15, 64( sp )                   \r\n" /* X15 */\r
-               "lw             x14, 68( sp )                   \r\n" /* X14 */\r
-               "lw             x13, 72( sp )                   \r\n" /* X13 */\r
-               "lw             x12, 76( sp )                   \r\n" /* X12 */\r
-               "lw             x11, 80( sp )                   \r\n" /* X11 */\r
-               "lw             x10, 84( sp )                   \r\n" /* X10 */\r
-               "lw             x9, 88( sp )                    \r\n" /* X9 */\r
-               "lw             x8, 92( sp )                    \r\n" /* X8 */\r
-               "lw             x7, 96( sp )                    \r\n" /* X7 */\r
-               "lw             x6, 100( sp )                   \r\n" /* X6 */\r
-               "lw             x5, 104( sp )                   \r\n" /* X5 */\r
-               "lw             x1, 108( sp )                   \r\n" /* X1 */\r
-               "csrs   mstatus, 8                              \r\n" /* Enable interrupts. */\r
-               "ret                                                            "\r
-       );\r
-\r
-       /*Should not get here*/\r
-       return pdFALSE;\r
+extern void xPortStartFirstTask( void );\r
+\r
+       #if( configASSERT_DEFINED == 1 )\r
+       {\r
+               volatile uint32_t mtvec = 0;\r
+\r
+               /* Check the least significant two bits of mtvec are 00 - indicating single\r
+               vector mode. */\r
+               __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) );\r
+               configASSERT( ( mtvec & 0x03UL ) == 0 );\r
+       }\r
+       #endif\r
+\r
+       vPortSetupTimerInterrupt();\r
+       xPortStartFirstTask();\r
+\r
+       /* Should not get here as after calling xPortStartFirstTask() only tasks\r
+       should be executing. */\r
+       return pdFAIL;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vPortYield( void )\r
+void vPortEndScheduler( void )\r
 {\r
+       /* Not implemented. */\r
+       for( ;; );\r
 }\r
 \r
 \r
+\r
+\r