initial commit
This commit is contained in:
		
							
								
								
									
										163
									
								
								fw/bsp/drivers/clic/clic_driver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								fw/bsp/drivers/clic/clic_driver.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| // See LICENSE for license details. | ||||
|  | ||||
| #include "clic/clic_driver.h" | ||||
| #include "platform.h" | ||||
| #include "encoding.h" | ||||
| #include <string.h> | ||||
| #include "../../include/platform/devices/clic.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); | ||||
| } | ||||
|  | ||||
| //sets an interrupt level based encoding of nmbits, nlbits | ||||
| uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level) { | ||||
|   //extract nlbits | ||||
|   uint8_t nlbits = clic_get_cliccfg(this_clic); | ||||
|   nlbits = (nlbits >>1) & 0x7; | ||||
|  | ||||
|   //shift level right to mask off unused bits | ||||
|   level = level>>((this_clic->num_config_bits)-nlbits); //plus this_clic->nmbits which is always 0 for now. | ||||
|   //shift level into correct bit position | ||||
|   level = level << (8-this_clic->num_config_bits) + (this_clic->num_config_bits - nlbits); | ||||
|   | ||||
|   //write to clicintcfg | ||||
|   uint8_t current_intcfg = clic_get_intcfg(this_clic, source); | ||||
|   clic_set_intcfg(this_clic, source, (current_intcfg | level)); | ||||
|  | ||||
|   return level; | ||||
| } | ||||
|  | ||||
| //gets an interrupt level based encoding of nmbits, nlbits | ||||
| uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source) { | ||||
|   uint8_t level; | ||||
|   level = clic_get_intcfg(this_clic, source); | ||||
|  | ||||
|   //extract nlbits | ||||
|   uint8_t nlbits = clic_get_cliccfg(this_clic); | ||||
|   nlbits = (nlbits >>1) & 0x7; | ||||
|  | ||||
|   //shift level | ||||
|   level = level >> (8-(this_clic->num_config_bits)); | ||||
|  | ||||
|   //shift level right to mask off priority bits | ||||
|   level = level>>(this_clic->num_config_bits-nlbits); //this_clic->nmbits which is always 0 for now. | ||||
|  | ||||
|   return level; | ||||
| } | ||||
|  | ||||
| //sets an interrupt priority based encoding of nmbits, nlbits | ||||
| uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority) { | ||||
|   //priority bits = num_config_bits - nlbits | ||||
|   //extract nlbits | ||||
|   uint8_t nlbits = clic_get_cliccfg(this_clic); | ||||
|   nlbits = (nlbits >>1) & 0x7; | ||||
|  | ||||
|   uint8_t priority_bits = this_clic->num_config_bits-nlbits; | ||||
|   if(priority_bits = 0) { | ||||
|     //no bits to set | ||||
|     return 0; | ||||
|   } | ||||
|   //mask off unused bits | ||||
|   priority = priority >> (8-priority_bits); | ||||
|   //shift into the correct bit position | ||||
|   priority = priority << (8-(this_clic->num_config_bits)); | ||||
|  | ||||
|   //write to clicintcfg | ||||
|   uint8_t current_intcfg = clic_get_intcfg(this_clic, source); | ||||
|   clic_set_intcfg(this_clic, source, (current_intcfg | priority)); | ||||
|   return current_intcfg; | ||||
| } | ||||
|  | ||||
| //gets an interrupt priority based encoding of nmbits, nlbits | ||||
| uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source) { | ||||
|   uint8_t priority; | ||||
|   priority = clic_get_intcfg(this_clic, source); | ||||
|  | ||||
|   //extract nlbits | ||||
|   uint8_t nlbits = clic_get_cliccfg(this_clic); | ||||
|   nlbits = (nlbits >>1) & 0x7; | ||||
|  | ||||
|   //shift left to mask off level bits | ||||
|   priority = priority << nlbits; | ||||
|  | ||||
|   //shift priority | ||||
|   priority = priority >> (8-((this_clic->num_config_bits)+nlbits)); | ||||
|  | ||||
|  return priority; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										44
									
								
								fw/bsp/drivers/clic/clic_driver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								fw/bsp/drivers/clic/clic_driver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // See LICENSE file for licence details | ||||
|  | ||||
| #ifndef PLIC_DRIVER_H | ||||
| #define PLIC_DRIVER_H | ||||
|  | ||||
|  | ||||
| __BEGIN_DECLS | ||||
|  | ||||
| #include "platform.h" | ||||
|  | ||||
| typedef void (*interrupt_function_ptr_t) (void); | ||||
|  | ||||
| typedef struct __clic_instance_t | ||||
| { | ||||
|   uintptr_t hart_addr; | ||||
|   interrupt_function_ptr_t* vect_table; | ||||
|   uint32_t num_config_bits; | ||||
|   uint32_t num_sources;   | ||||
| } clic_instance_t; | ||||
|  | ||||
| // 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); | ||||
| void clic_install_handler (clic_instance_t * this_clic, uint32_t source, interrupt_function_ptr_t handler); | ||||
| void clic_enable_interrupt (clic_instance_t * this_clic, uint32_t source); | ||||
| void clic_disable_interrupt (clic_instance_t * this_clic, uint32_t source); | ||||
| void clic_set_pending(clic_instance_t * this_clic, uint32_t source); | ||||
| void clic_clear_pending(clic_instance_t * this_clic, uint32_t source); | ||||
| void clic_set_intcfg (clic_instance_t * this_clic, uint32_t source, uint32_t intcfg); | ||||
| uint8_t clic_get_intcfg (clic_instance_t * this_clic, uint32_t source); | ||||
| void clic_set_cliccfg (clic_instance_t * this_clic, uint32_t cfg); | ||||
| uint8_t clic_get_cliccfg  (clic_instance_t * this_clic); | ||||
| //sets an interrupt level based encoding of nmbits, nlbits | ||||
| uint8_t clic_set_int_level( clic_instance_t * this_clic, uint32_t source, uint8_t level); | ||||
| //get an interrupt level based encoding of nmbits, nlbits | ||||
| uint8_t clic_get_int_level( clic_instance_t * this_clic, uint32_t source); | ||||
| //sets an interrupt priority based encoding of nmbits, nlbits | ||||
| uint8_t clic_set_int_priority( clic_instance_t * this_clic, uint32_t source, uint8_t priority); | ||||
| //sets an interrupt priority based encoding of nmbits, nlbits | ||||
| uint8_t clic_get_int_priority( clic_instance_t * this_clic, uint32_t source); | ||||
|  | ||||
| __END_DECLS | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user