embox

Форк
0
94 строки · 2.6 Кб
1
/**
2
 * @file
3
 *
4
 * @brief Implementation of the RISC-V Core Local Interruptor (CLINT) for interrupt control, including support for SiFive multi-hart architectures.
5
 *
6
 * @date 05.07.2024
7
 * @authored by Suraj Ravindra Sonawane
8
 */
9

10
#include <stdint.h>
11
#include <drivers/irqctrl.h>
12
#include <hal/reg.h>
13
#include <asm/interrupts.h>
14
#include <drivers/interrupt/riscv_clint.h>
15

16
#define CLINT_ADDR      OPTION_GET(NUMBER, base_addr)
17
#define MSIP_OFFSET     OPTION_GET(NUMBER, msip_offset)
18
#define MTIMECMP_OFFSET OPTION_GET(NUMBER, mtimecmp_offset)
19
#define MTIME_OFFSET    OPTION_GET(NUMBER, mtime_offset)
20

21
#define MSIP_ADDR(hart)       (CLINT_ADDR + MSIP_OFFSET + ((hart) * 4))
22
#define MTIMECMP_ADDR(hart)   (CLINT_ADDR + MTIMECMP_OFFSET + ((hart) * 8))
23
#define MTIME_ADDR            (CLINT_ADDR + MTIME_OFFSET)
24

25
/**
26
 * Initializes the CLINT.
27
 *
28
 * This function initializes the CLINT by clearing the MSIP (Software Interrupt) and setting MTIMECMP
29
 * to its maximum value (0xFFFFFFFFFFFFFFFF).
30
 *
31
 * @return 0 on success.
32
 */
33
int clint_init(void) __attribute__((unused));
34
int clint_init(void) {
35
    // Initial configuration: clear MSIP and set MTIMECMP to max value for all harts
36
    for (int hart = 0; hart < 5; hart++) {
37
        REG32_STORE(MSIP_ADDR(hart), 0);                 
38
        REG64_STORE(MTIMECMP_ADDR(hart), 0xFFFFFFFFFFFFFFFF); 
39
    }
40
    REG64_STORE(MTIME_ADDR, 0); 
41
    enable_software_interrupts();
42
    return 0;
43
}
44

45
/**
46
 * Configures the Software Interrupt (MSIP).
47
 *
48
 * This function configures the MSIP by writing a specific value (0 or 1) to its address.
49
 *
50
 * @param value The value (0 or 1) to set for MSIP.
51
 * @param hart_id The hart id (only for SiFive CLINT).
52
 */
53
void clint_configure_msip(uint8_t value
54
#ifdef SIFIVE_CLINT
55
    , int hart_id
56
#endif
57
) {
58
#ifdef SIFIVE_CLINT
59
    REG32_STORE(MSIP_ADDR(hart_id), value & 1);
60
#else
61
    REG32_STORE(MSIP_ADDR(0), value & 1);
62
#endif
63
}
64

65
/**
66
 * Sets the MTIMECMP register value.
67
 *
68
 * This function sets the MTIMECMP register to the provided 64-bit value.
69
 *
70
 * @param value The value to set for MTIMECMP.
71
 * @param hart_id The hart id (only for SiFive CLINT).
72
 */
73
void clint_set_mtimecmp(uint64_t value
74
#ifdef SIFIVE_CLINT
75
    , int hart_id
76
#endif
77
) {
78
#ifdef SIFIVE_CLINT
79
    REG64_STORE(MTIMECMP_ADDR(hart_id), value); // Write 'value' to MTIMECMP_ADDR for the specific hart
80
#else
81
    REG64_STORE(MTIMECMP_ADDR(0), value);
82
#endif
83
}
84

85
/**
86
 * Retrieves the current value of MTIME.
87
 *
88
 * This function reads and returns the current value of MTIME.
89
 *
90
 * @return The current value of MTIME.
91
 */
92
uint64_t clint_get_mtime(void) {
93
    return REG64_LOAD(MTIME_ADDR);
94
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.