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; }