summaryrefslogtreecommitdiff
path: root/bsp/drivers/clic/clic_driver.c
blob: a4c46942014fe13f978bbdf37cc25ad8f5f7dbfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// See LICENSE for license details.

#include "sifive/devices/clic.h"
#include "clic/clic_driver.h"
#include "platform.h"
#include "encoding.h"
#include <string.h>


void volatile_memzero(uint8_t * base, unsigned int size) {
  volatile uint8_t * ptr;
  for (ptr = base; ptr < (base + size); ptr++){
    *ptr = 0;
  }
}

// Note that there are no assertions or bounds checking on these
// parameter values.
void clic_init (
                clic_instance_t * this_clic,
                uintptr_t hart_addr,
                interrupt_function_ptr_t* vect_table,
                interrupt_function_ptr_t default_handler,
                uint32_t num_irq,
                uint32_t num_config_bits
                )
{
  this_clic->hart_addr=  hart_addr;
  this_clic->vect_table= vect_table;
  this_clic->num_config_bits= num_config_bits;

  //initialize vector table
  for(int i=0;i++;i<num_irq)  {
    this_clic->vect_table[i] = default_handler;
  }

  //set base vectors
  write_csr(mtvt, vect_table);


  //clear all interrupt enables and pending
  volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIE), num_irq);
  volatile_memzero((uint8_t*)(this_clic->hart_addr+CLIC_INTIP), num_irq);

  //clear nlbits and nvbits; all interrupts trap to level 15
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG)=0;

}

void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler) {
    this_clic->vect_table[source] = handler;
}

void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source) {
    *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 1;
}

void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source){
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIE+source) = 0;
}

void clic_set_pending(clic_instance_t * this_clic, uint32_t source){
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 1;
}

void clic_clear_pending(clic_instance_t * this_clic, uint32_t source){
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTIP+source) = 0;
}

void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg){
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source) = intcfg;
}

uint8_t clic_get_intcfg  (clic_instance_t * this_clic, uint32_t source){
  return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_INTCFG+source);
}

void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg){
  *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG) = cfg;
}

uint8_t clic_get_cliccfg  (clic_instance_t * this_clic){
  return *(volatile uint8_t*)(this_clic->hart_addr+CLIC_CFG);
}