Example #1
0
/* Level 1 Block, 1GB, entry in LPAE Descriptor format for the given physical address */
lpaed_t hvmm_mm_lpaed_l1_block( uint64_t pa, uint8_t attr_idx )
{
    /* lpae.c */
	lpaed_t lpaed;

	printh( "[mm] hvmm_mm_lpaed_l1_block:\n\r" );
	printh( " pa:"); uart_print_hex64(pa); printh("\n\r");
	printh( " attr_idx:"); uart_print_hex32((uint32_t) attr_idx); printh("\n\r");

	// Valid Block Entry
	lpaed.pt.valid = 1;
	lpaed.pt.table = 0;

	lpaed.bits &= ~TTBL_L1_OUTADDR_MASK;
	lpaed.bits |= pa & TTBL_L1_OUTADDR_MASK;
	lpaed.pt.sbz = 0;

	// Lower block attributes
	lpaed.pt.ai = attr_idx;
	lpaed.pt.ns = 1;	// Allow Non-secure access
	lpaed.pt.user = 1;
	lpaed.pt.ro = 0;
	lpaed.pt.sh = 2;	// Outher Shareable
	lpaed.pt.af = 1;	// Access Flag set to 1?
	lpaed.pt.ng = 1;

	// Upper block attributes
	lpaed.pt.hint = 0;
	lpaed.pt.pxn = 0;
	lpaed.pt.xn = 0;	// eXecute Never = 0
	return lpaed;
}
Example #2
0
/**
 * @brief Initializes and enables GIC Distributor
 * <pre>
 * Initialization sequence
 * 1. Set Default SPI's polarity.
 * 2. Set Default priority.
 * 3. Diable all interrupts.
 * 4. Route all IRQs to all target processors.
 * 5. Enable Distributor.
 * </pre>
 * @return Always return success.
 */
static hvmm_status_t gic_init_dist(void)
{
    uint32_t type;
    int i;
    uint32_t cpumask;
    HVMM_TRACE_ENTER();
    /* Disable Distributor */
    _gic.ba_gicd[GICD_CTLR] = 0;
    type = _gic.ba_gicd[GICD_TYPER];
    _gic.lines = 32 * ((type & GICD_TYPE_LINES_MASK) + 1);
    _gic.cpus = 1 + ((type & GICD_TYPE_CPUS_MASK) >> GICD_TYPE_CPUS_SHIFT);
    uart_print("GIC: lines:");
    uart_print_hex32(_gic.lines);
    uart_print(" cpus:");
    uart_print_hex32(_gic.cpus);
    uart_print(" IID:");
    uart_print_hex32(_gic.ba_gicd[GICD_IIDR]);
    uart_print("\n\r");
    /* Interrupt polarity for SPIs (Global Interrupts) active-low */
    for (i = 32; i < _gic.lines; i += 16)
        _gic.ba_gicd[GICD_ICFGR + i / 16] = 0x0;

    /* Default Priority for all Interrupts
     * Private/Banked interrupts will be configured separately
     */
    for (i = 32; i < _gic.lines; i += 4)
        _gic.ba_gicd[GICD_IPRIORITYR + i / 4] = GIC_INT_PRIORITY_DEFAULT_WORD;

    /* Disable all global interrupts.
     * Private/Banked interrupts will be configured separately
     */
    for (i = 32; i < _gic.lines; i += 32)
        _gic.ba_gicd[GICD_ICENABLER + i / 32] = 0xFFFFFFFF;

    /* Route all global IRQs to this CPU */
    cpumask = 1 << smp_processor_id();
    cpumask |= cpumask << 8;
    cpumask |= cpumask << 16;
    for (i = 32; i < _gic.lines; i += 4)
        _gic.ba_gicd[GICD_ITARGETSR + i / 4] = cpumask;

    /* Enable Distributor */
    _gic.ba_gicd[GICD_CTLR] = GICD_CTLR_ENABLE;
    HVMM_TRACE_EXIT();
    return HVMM_STATUS_SUCCESS;
}
Example #3
0
void nrm_loop(void) 
{
	int i = 0;

    uart_init();
	uart_print(GUEST_LABEL); uart_print("=== Starting...\n\r");

    gic_init();

    /* We are ready to accept irqs with GIC. Enable it now */

    irq_enable();

    /* Test the sample virtual device 
     * - Uncomment the following line of code only if 'vdev_sample' is registered at the monitor
     * - Otherwise, the monitor will hang with data abort
     */
     
#ifdef TESTS_ENABLE_VDEV_SAMPLE
    test_vdev_sample();
#endif
    
#ifdef TESTS_ENABLE_PWM_TIMER
    hvmm_tests_pwm_timer();
#endif

#ifdef TESTS_ENABLE_SP804_TIMER
    /* Test the SP804 timer */
    hvmm_tests_sp804_timer();
#endif
	for( i = 0; i < NUM_ITERATIONS; i++ ) {
		uart_print(GUEST_LABEL); uart_print("iteration "); uart_print_hex32( i ); uart_print( "\n\r" );
		nrm_delay();

#ifdef __MONITOR_CALL_HVC__
	    /* Hyp monitor guest run in Non-secure supervisor mode. 
           Request test hvc ping and yield one after another 
         */
		if (i & 0x1) {
			uart_print(GUEST_LABEL); uart_print( "hsvc_ping()\n\r" );
			hsvc_ping();
			uart_print(GUEST_LABEL); uart_print( "returned from hsvc_ping() \n\r" );
		} else {
			uart_print(GUEST_LABEL); uart_print( "hsvc_yield()\n\r" );
			hsvc_yield();
			uart_print(GUEST_LABEL); uart_print( "returned from hsvc_yield() \n\r" );
		}
#else
        /* Secure monitor guest run in Non-secure supervisor mode
           Request for switch to Secure mode (sec_loop() in the monitor)
         */
		SWITCH_MANUAL();	
#endif
		nrm_delay();
	}
	uart_print(GUEST_LABEL); uart_print("done\n\r");
	while(1);
}
Example #4
0
/**
 * @brief   Return address of GIC memory map to _gic.baseaddr.
 * @param   va_base Base address(Physical) of GIC.
 * @return  If target architecture is Cortex-A15 then return success,
 *          otherwise return failed.
 */
static hvmm_status_t gic_init_baseaddr(uint32_t *va_base)
{
    /* MIDR[15:4], CRn:c0, Op1:0, CRm:c0, Op2:0  == 0xC0F (Cortex-A15) */
    /* Cortex-A15 C15 System Control, C15 Registers */
    /* Name: Op1, CRm, Op2 */
    uint32_t midr;
    hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;
    HVMM_TRACE_ENTER();
    midr = read_midr();
    uart_print("midr:");
    uart_print_hex32(midr);
    uart_print("\n\r");
    /*
     * Note:
     * We currently support GICv2 with Cortex-A15 only.
     * Other architectures with GICv2 support will be further
     * listed and added for support later
     */
    if ((midr & MIDR_MASK_PPN) == MIDR_PPN_CORTEXA15) {
        /* fall-back to periphbase addr from cbar */
        if (va_base == 0) {
            va_base = (uint32_t *)(uint32_t)(gic_periphbase_pa() & \
                    0x00000000FFFFFFFFULL);
        }
        _gic.baseaddr = (uint32_t) va_base;
        uart_print("cbar:");
        uart_print_hex32(_gic.baseaddr);
        uart_print("\n\r");
        _gic.ba_gicd = (uint32_t *)(_gic.baseaddr + GIC_OFFSET_GICD);
        _gic.ba_gicc = (uint32_t *)(_gic.baseaddr + GIC_OFFSET_GICC);
        _gic.ba_gich = (uint32_t *)(_gic.baseaddr + GIC_OFFSET_GICH);
        _gic.ba_gicv = (uint32_t *)(_gic.baseaddr + GIC_OFFSET_GICV);
        _gic.ba_gicvi = (uint32_t *)(_gic.baseaddr + GIC_OFFSET_GICVI);
        result = HVMM_STATUS_SUCCESS;
    } else {
        uart_print("GICv2 Unsupported\n\r");
        uart_print("midr.ppn:");
        uart_print_hex32(midr & MIDR_MASK_PPN);
        uart_print("\n\r");
        result = HVMM_STATUS_UNSUPPORTED_FEATURE;
    }
    HVMM_TRACE_EXIT();
    return result;
}
Example #5
0
static void gic_dump_registers(void)
{
    uint32_t midr;
    HVMM_TRACE_ENTER();
    midr = read_midr();
    uart_print("midr:");
    uart_print_hex32(midr);
    uart_print("\n\r");
    if ((midr & MIDR_MASK_PPN) == MIDR_PPN_CORTEXA15) {
        uint32_t value;
        uart_print("cbar:");
        uart_print_hex32(_gic.baseaddr);
        uart_print("\n\r");
        uart_print("ba_gicd:");
        uart_print_hex32((uint32_t)_gic.ba_gicd);
        uart_print("\n\r");
        uart_print("ba_gicc:");
        uart_print_hex32((uint32_t)_gic.ba_gicc);
        uart_print("\n\r");
        uart_print("ba_gich:");
        uart_print_hex32((uint32_t)_gic.ba_gich);
        uart_print("\n\r");
        uart_print("ba_gicv:");
        uart_print_hex32((uint32_t)_gic.ba_gicv);
        uart_print("\n\r");
        uart_print("ba_gicvi:");
        uart_print_hex32((uint32_t)_gic.ba_gicvi);
        uart_print("\n\r");
        value = _gic.ba_gicd[GICD_CTLR];
        uart_print("GICD_CTLR:");
        uart_print_hex32(value);
        uart_print("\n\r");
        value = _gic.ba_gicd[GICD_TYPER];
        uart_print("GICD_TYPER:");
        uart_print_hex32(value);
        uart_print("\n\r");
        value = _gic.ba_gicd[GICD_IIDR];
        uart_print("GICD_IIDR:");
        uart_print_hex32(value);
        uart_print("\n\r");
    }
    HVMM_TRACE_EXIT();
}
Example #6
0
void scheduler_test_switch_to_next_guest(void *pdata){
    struct arch_regs *regs = pdata;
    uint64_t pct = read_cntpct();
    uint32_t tval = read_cnthp_tval();
    uart_print( "cntpct:"); uart_print_hex64(pct); uart_print("\n\r");
    uart_print( "cnth_tval:"); uart_print_hex32(tval); uart_print("\n\r");

    /* Note: As of context_switchto() and context_perform_switch() are available,
       no need to test if trapped from Hyp mode.
       context_perform_switch() takes care of it
     */
    /* Test guest context switch */
    if ( (regs->cpsr & 0x1F) != 0x1A ) {
        scheduler_schedule();
    }
}
static void test_start_timer(void)
{
    uint32_t ctl;
    uint32_t tval;
    uint64_t pct;
    HVMM_TRACE_ENTER();
    /* every second */
    tval = read_cntfrq();
    write_cntp_tval(tval);
    pct = read_cntpct();
    uart_print("cntpct:");
    uart_print_hex64(pct);
    uart_print("\n\r");
    uart_print("cntp_tval:");
    uart_print_hex32(tval);
    uart_print("\n\r");
    /* enable timer */
    ctl = read_cntp_ctl();
    ctl |= 0x1;
    write_cntp_ctl(ctl);
    HVMM_TRACE_EXIT();
}
Example #8
0
hvmm_status_t gic_configure_irq(uint32_t irq,
                enum gic_int_polarity polarity,  uint8_t cpumask,
                uint8_t priority)
{
    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;
}