rework structure
This commit is contained in:
		@@ -0,0 +1,127 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
#include "sifive/devices/plic.h"
 | 
			
		||||
#include "plic/plic_driver.h"
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "encoding.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Note that there are no assertions or bounds checking on these
 | 
			
		||||
// parameter values.
 | 
			
		||||
 | 
			
		||||
void volatile_memzero(uint8_t * base, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
  volatile uint8_t * ptr;
 | 
			
		||||
  for (ptr = base; ptr < (base + size); ptr++){
 | 
			
		||||
    *ptr = 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PLIC_init (
 | 
			
		||||
                plic_instance_t * this_plic,
 | 
			
		||||
                uintptr_t         base_addr,
 | 
			
		||||
                uint32_t num_sources,
 | 
			
		||||
                uint32_t num_priorities
 | 
			
		||||
                )
 | 
			
		||||
{
 | 
			
		||||
  
 | 
			
		||||
  this_plic->base_addr = base_addr;
 | 
			
		||||
  this_plic->num_sources = num_sources;
 | 
			
		||||
  this_plic->num_priorities = num_priorities;
 | 
			
		||||
  
 | 
			
		||||
  // Disable all interrupts (don't assume that these registers are reset).
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);
 | 
			
		||||
  volatile_memzero((uint8_t*) (this_plic->base_addr +
 | 
			
		||||
                               PLIC_ENABLE_OFFSET +
 | 
			
		||||
                               (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET)),
 | 
			
		||||
                   (num_sources + 8) / 8);
 | 
			
		||||
  
 | 
			
		||||
  // Set all priorities to 0 (equal priority -- don't assume that these are reset).
 | 
			
		||||
  volatile_memzero ((uint8_t *)(this_plic->base_addr +
 | 
			
		||||
                                PLIC_PRIORITY_OFFSET),
 | 
			
		||||
                    (num_sources + 1) << PLIC_PRIORITY_SHIFT_PER_SOURCE);
 | 
			
		||||
 | 
			
		||||
  // Set the threshold to 0.
 | 
			
		||||
  volatile plic_threshold* threshold = (plic_threshold*)
 | 
			
		||||
    (this_plic->base_addr +
 | 
			
		||||
     PLIC_THRESHOLD_OFFSET +
 | 
			
		||||
     (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
 | 
			
		||||
 | 
			
		||||
  *threshold = 0;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PLIC_set_threshold (plic_instance_t * this_plic,
 | 
			
		||||
			 plic_threshold threshold){
 | 
			
		||||
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);  
 | 
			
		||||
  volatile plic_threshold* threshold_ptr = (plic_threshold*) (this_plic->base_addr +
 | 
			
		||||
                                                              PLIC_THRESHOLD_OFFSET +
 | 
			
		||||
                                                              (hart_id << PLIC_THRESHOLD_SHIFT_PER_TARGET));
 | 
			
		||||
 | 
			
		||||
  *threshold_ptr = threshold;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
void PLIC_enable_interrupt (plic_instance_t * this_plic, plic_source source){
 | 
			
		||||
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);
 | 
			
		||||
  volatile uint8_t * current_ptr = (volatile uint8_t *)(this_plic->base_addr +
 | 
			
		||||
                                                        PLIC_ENABLE_OFFSET +
 | 
			
		||||
                                                        (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
 | 
			
		||||
                                                        (source >> 3));
 | 
			
		||||
  uint8_t current = *current_ptr;
 | 
			
		||||
  current = current | ( 1 << (source & 0x7));
 | 
			
		||||
  *current_ptr = current;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PLIC_disable_interrupt (plic_instance_t * this_plic, plic_source source){
 | 
			
		||||
  
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);
 | 
			
		||||
  volatile uint8_t * current_ptr = (volatile uint8_t *) (this_plic->base_addr +
 | 
			
		||||
                                                         PLIC_ENABLE_OFFSET +
 | 
			
		||||
                                                         (hart_id << PLIC_ENABLE_SHIFT_PER_TARGET) +
 | 
			
		||||
                                                         (source >> 3));
 | 
			
		||||
  uint8_t current = *current_ptr;
 | 
			
		||||
  current = current & ~(( 1 << (source & 0x7)));
 | 
			
		||||
  *current_ptr = current;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PLIC_set_priority (plic_instance_t * this_plic, plic_source source, plic_priority priority){
 | 
			
		||||
 | 
			
		||||
  if (this_plic->num_priorities > 0) {
 | 
			
		||||
    volatile plic_priority * priority_ptr = (volatile plic_priority *)
 | 
			
		||||
      (this_plic->base_addr +
 | 
			
		||||
       PLIC_PRIORITY_OFFSET +
 | 
			
		||||
       (source << PLIC_PRIORITY_SHIFT_PER_SOURCE));
 | 
			
		||||
    *priority_ptr = priority;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
plic_source PLIC_claim_interrupt(plic_instance_t * this_plic){
 | 
			
		||||
  
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);
 | 
			
		||||
 | 
			
		||||
  volatile plic_source * claim_addr = (volatile plic_source * )
 | 
			
		||||
    (this_plic->base_addr +
 | 
			
		||||
     PLIC_CLAIM_OFFSET +
 | 
			
		||||
     (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
 | 
			
		||||
 | 
			
		||||
  return  *claim_addr;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PLIC_complete_interrupt(plic_instance_t * this_plic, plic_source source){
 | 
			
		||||
  
 | 
			
		||||
  unsigned long hart_id = read_csr(mhartid);
 | 
			
		||||
  volatile plic_source * claim_addr = (volatile plic_source *) (this_plic->base_addr +
 | 
			
		||||
                                                                PLIC_CLAIM_OFFSET +
 | 
			
		||||
                                                                (hart_id << PLIC_CLAIM_SHIFT_PER_TARGET));
 | 
			
		||||
  *claim_addr = source;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,51 @@
 | 
			
		||||
// See LICENSE file for licence details
 | 
			
		||||
 | 
			
		||||
#ifndef PLIC_DRIVER_H
 | 
			
		||||
#define PLIC_DRIVER_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
typedef struct __plic_instance_t
 | 
			
		||||
{
 | 
			
		||||
  uintptr_t base_addr;
 | 
			
		||||
 | 
			
		||||
  uint32_t num_sources;
 | 
			
		||||
  uint32_t num_priorities;
 | 
			
		||||
  
 | 
			
		||||
} plic_instance_t;
 | 
			
		||||
 | 
			
		||||
typedef uint32_t plic_source;
 | 
			
		||||
typedef uint32_t plic_priority;
 | 
			
		||||
typedef uint32_t plic_threshold;
 | 
			
		||||
 | 
			
		||||
void PLIC_init (
 | 
			
		||||
                plic_instance_t * this_plic,
 | 
			
		||||
                uintptr_t         base_addr,
 | 
			
		||||
                uint32_t num_sources,
 | 
			
		||||
                uint32_t num_priorities
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
void PLIC_set_threshold (plic_instance_t * this_plic,
 | 
			
		||||
			 plic_threshold threshold);
 | 
			
		||||
  
 | 
			
		||||
void PLIC_enable_interrupt (plic_instance_t * this_plic,
 | 
			
		||||
			    plic_source source);
 | 
			
		||||
 | 
			
		||||
void PLIC_disable_interrupt (plic_instance_t * this_plic,
 | 
			
		||||
			     plic_source source);
 | 
			
		||||
  
 | 
			
		||||
void PLIC_set_priority (plic_instance_t * this_plic,
 | 
			
		||||
			plic_source source,
 | 
			
		||||
			plic_priority priority);
 | 
			
		||||
 | 
			
		||||
plic_source PLIC_claim_interrupt(plic_instance_t * this_plic);
 | 
			
		||||
 | 
			
		||||
void PLIC_complete_interrupt(plic_instance_t * this_plic,
 | 
			
		||||
			     plic_source source);
 | 
			
		||||
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user