|
khypervisor
v1
|


Go to the source code of this file.
Defines | |
| #define | GIC_NUM_MAX_IRQS 1024 |
| #define | gic_cpumask_current() (1u << smp_processor_id()) |
| #define | GIC_INT_PRIORITY_DEFAULT 0xa0 |
Typedefs | |
| typedef void(* | gic_irq_handler_t )(int irq, void *regs, void *pdata) |
Enumerations | |
| enum | gic_int_polarity_t { GIC_INT_POLARITY_LEVEL = 0, GIC_INT_POLARITY_EDGE = 1 } |
Functions | |
| void | gic_interrupt (int fiq, void *regs) |
| hvmm_status_t | gic_enable_irq (uint32_t irq) |
| hvmm_status_t | gic_disable_irq (uint32_t irq) |
| hvmm_status_t | gic_init (void) |
| hvmm_status_t | gic_deactivate_irq (uint32_t irq) |
| volatile uint32_t * | gic_vgic_baseaddr (void) |
| hvmm_status_t | gic_test_configure_irq (uint32_t irq, gic_int_polarity_t polarity, uint8_t cpumask, uint8_t priority) |
| hvmm_status_t | gic_test_set_irq_handler (int irq, gic_irq_handler_t handler, void *pdata) |
| #define gic_cpumask_current | ( | ) | (1u << smp_processor_id()) |
| #define GIC_INT_PRIORITY_DEFAULT 0xa0 |
| #define GIC_NUM_MAX_IRQS 1024 |
| typedef void(* gic_irq_handler_t)(int irq, void *regs, void *pdata) |
| enum gic_int_polarity_t |
Definition at line 12 of file gic.h.
{
GIC_INT_POLARITY_LEVEL = 0,
GIC_INT_POLARITY_EDGE = 1
} gic_int_polarity_t;
| hvmm_status_t gic_disable_irq | ( | uint32_t | irq | ) |
Definition at line 214 of file gic.c.
{
_gic.ba_gicd[GICD_ICENABLER + irq / 32] = (1u << (irq % 32));
return HVMM_STATUS_SUCCESS;
}
| hvmm_status_t gic_enable_irq | ( | uint32_t | irq | ) |
Definition at line 208 of file gic.c.
{
_gic.ba_gicd[GICD_ISENABLER + irq / 32] = (1u << (irq % 32));
return HVMM_STATUS_SUCCESS;
}
| hvmm_status_t gic_init | ( | void | ) |
Definition at line 247 of file gic.c.
{
hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;
int i;
HVMM_TRACE_ENTER();
for( i = 0; i < GIC_NUM_MAX_IRQS; i++) {
_gic.handlers[i] = 0;
}
/*
* Determining VA of GIC base adddress has not been defined yet. Let is use the PA for the time being
*/
result = gic_init_baseaddr((void*)CFG_GIC_BASE_PA);
if ( result == HVMM_STATUS_SUCCESS ) {
gic_dump_registers();
}
/*
* Initialize and Enable GIC Distributor
*/
if ( result == HVMM_STATUS_SUCCESS ) {
result = gic_init_dist();
}
/*
* Initialize and Enable GIC CPU Interface for this CPU
*/
if ( result == HVMM_STATUS_SUCCESS ) {
result = gic_init_cpui();
}
if ( result == HVMM_STATUS_SUCCESS ) {
_gic.initialized = GIC_SIGNATURE_INITIALIZED;
}
HVMM_TRACE_EXIT();
return result;
}

| void gic_interrupt | ( | int | fiq, |
| void * | regs | ||
| ) |
Definition at line 337 of file gic.c.
{
/*
* 1. ACK - CPU Interface - GICC_IAR read
* 2. Completion - CPU Interface - GICC_EOIR
* 2.1 Deactivation - CPU Interface - GICC_DIR
*/
uint32_t iar;
uint32_t irq;
struct arch_regs *regs = pregs;
const struct virqmap_entry *virq_entry;
/* ACK */
iar = _gic.ba_gicc[GICC_IAR];
irq = iar & GICC_IAR_INTID_MASK;
if ( irq < _gic.lines ) {
virq_entry = virqmap_for_pirq(irq);
/* ISR */
printh( "ISR(irq):%x\n", irq);
/* IRQ INJECTION */
if(virq_entry != VIRQMAP_ENTRY_NOTFOUND) {
/* priority drop only for hanlding irq in guest */
_gic.ba_gicc[GICC_EOIR] = irq;
virq_inject(virq_entry->vmid, virq_entry->virq, irq, 1);
} else {
if ( _gic.handlers[irq] ) {
_gic.handlers[irq]( irq, regs, 0 );
}
/* Completion & Deactivation */
_gic.ba_gicc[GICC_EOIR] = irq;
_gic.ba_gicc[GICC_DIR] = irq;
}
} else {
printh( "gic:no pending irq:%x\n", irq);
}
}

| hvmm_status_t gic_test_configure_irq | ( | uint32_t | irq, |
| gic_int_polarity_t | polarity, | ||
| uint8_t | cpumask, | ||
| uint8_t | priority | ||
| ) |
Definition at line 294 of file gic.c.
{
hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;
HVMM_TRACE_ENTER();
if ( irq < _gic.lines ) {
uint32_t icfg;
volatile uint8_t *reg8;
/* disable forwarding */
result = gic_disable_irq( irq );
if ( result == HVMM_STATUS_SUCCESS ) {
/* polarity: level or edge */
icfg = _gic.ba_gicd[GICD_ICFGR + irq / 16];
if ( polarity == GIC_INT_POLARITY_LEVEL ) {
icfg &= ~( 2u << (2 * (irq % 16)) );
} else {
icfg |= ( 2u << (2 * (irq % 16)) );
}
_gic.ba_gicd[GICD_ICFGR + irq / 16] = icfg;
/* routing */
reg8 = (uint8_t *) &(_gic.ba_gicd[GICD_ITARGETSR]);
reg8[irq] = cpumask;
/* priority */
reg8 = (uint8_t *) &(_gic.ba_gicd[GICD_IPRIORITYR]);
reg8[irq] = priority;
/* enable forwarding */
result = gic_enable_irq( irq );
}
} else {
uart_print( "invalid irq:"); uart_print_hex32(irq); uart_print("\n\r");
result = HVMM_STATUS_UNSUPPORTED_FEATURE;
}
HVMM_TRACE_EXIT();
return result;
}

| hvmm_status_t gic_test_set_irq_handler | ( | int | irq, |
| gic_irq_handler_t | handler, | ||
| void * | pdata | ||
| ) |
Definition at line 226 of file gic.c.
{
hvmm_status_t result = HVMM_STATUS_BUSY;
if ( irq < GIC_NUM_MAX_IRQS ) {
_gic.handlers[irq] = handler;
result = HVMM_STATUS_SUCCESS;
}
return result;
}
| volatile uint32_t* gic_vgic_baseaddr | ( | void | ) |
Definition at line 236 of file gic.c.
{
if ( _gic.initialized != GIC_SIGNATURE_INITIALIZED ) {
HVMM_TRACE_ENTER();
uart_print("gic: ERROR - not initialized\n\r");
HVMM_TRACE_EXIT();
}
return _gic.ba_gich;
}
1.7.6.1