コード例 #1
0
ファイル: scheduler.c プロジェクト: AdamRLukaitis/khypervisor
void extra_timer_callback(void *pdata)
{
    HVMM_TRACE_ENTER();


    HVMM_TRACE_EXIT();
}
コード例 #2
0
ファイル: vdev.c プロジェクト: jhkyung/khypervisor
hvmm_status_t vdev_reg_device(vdev_info_t *new_vdev)
{
    hvmm_status_t result = HVMM_STATUS_BUSY;
    int i = 0;

    HVMM_TRACE_ENTER();
    for (i = 0; i < MAX_VDEV; i++) {
        if (vdev_list[i].handler == 0x0 ) {
            vdev_list[i].name = new_vdev->name;
            vdev_list[i].base = new_vdev->base;
            vdev_list[i].size = new_vdev->size;
            vdev_list[i].handler = new_vdev->handler;
            printh("vdev:Registered vdev '%s' at index %d\n", vdev_list[i].name, i);

            result = HVMM_STATUS_SUCCESS;
            break;
        }
    }

    if ( result != HVMM_STATUS_SUCCESS ) {
        printh("vdev:Failed registering vdev '%s', max %d full \n", new_vdev->name, MAX_VDEV);
    }

    HVMM_TRACE_EXIT();
    return result;
}
コード例 #3
0
ファイル: tests_gic_timer.c プロジェクト: jhkyung/khypervisor
void interrupt_nsptimer(int irq, void *pregs, void *pdata )
{
	uint32_t ctl;
	struct arch_regs *regs = pregs;

	uart_print( "=======================================\n\r" );
	HVMM_TRACE_ENTER();

	/* Disable NS Physical Timer Interrupt */
	ctl = read_cntp_ctl();
	ctl &= ~(0x1);
	write_cntp_ctl(ctl);
	

	/* Trigger another interrupt */
	test_start_timer();

	/* Test guest context switch */
	if ( (regs->cpsr & 0x1F) != 0x1A ) {
		/* Not from Hyp, switch the guest context */
		context_dump_regs( regs );
        context_switchto(sched_policy_determ_next());
	}

	HVMM_TRACE_EXIT();
	uart_print( "=======================================\n\r" );
}
コード例 #4
0
void interrupt_pwmtimer(void *pdata)
{
    pwm_timer_disable_int();
    uart_print("=======================================\n\r");
    HVMM_TRACE_ENTER();
    HVMM_TRACE_EXIT();
    uart_print("=======================================\n\r");
    pwm_timer_enable_int();
}
コード例 #5
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
volatile uint32_t *gic_vgic_baseaddr(void)
{
    if (_gic.initialized != GIC_SIGNATURE_INITIALIZED) {
        HVMM_TRACE_ENTER();
        uart_print("gic: ERROR - not initialized\n\r");
        HVMM_TRACE_EXIT();
    }
    return _gic.ba_gich;
}
コード例 #6
0
void callback_test_timer(void *pdata)
{
    vmid_t vmid;
    HVMM_TRACE_ENTER();
    vmid = guest_current_vmid();
    printf("Injecting IRQ 30 to Guest:%d\n", vmid);

    /* SW VIRQ, No PIRQ */
    interrupt_guest_inject(vmid, 30, 0, INJECT_SW);
    HVMM_TRACE_EXIT();
}
コード例 #7
0
ファイル: tests_gic_timer.c プロジェクト: jhkyung/khypervisor
hvmm_status_t hvmm_tests_gic_pwm_timer(void)
{
    /* Testing pwm timer event (timer1, Interrupt ID : 69), Cortex-A15 exynos5250
	 * - Periodically triggers timer interrupt
     * - Just print uart_print
     */
	HVMM_TRACE_ENTER();
    pwm_timer_init();
    pwm_timer_set_callback(&interrupt_pwmtimer);
    pwm_timer_enable_int();
	HVMM_TRACE_EXIT();
	return HVMM_STATUS_SUCCESS;
}
コード例 #8
0
ファイル: tests_gic_timer.c プロジェクト: jhkyung/khypervisor
void callback_timer(void *pdata)
{
    vmid_t vmid;
    HVMM_TRACE_ENTER();
    vmid = context_current_vmid();

    printh( "Injecting IRQ 30 to Guest:%d\n", vmid);
    //vgic_inject_virq_sw( 30, VIRQ_STATE_PENDING, GIC_INT_PRIORITY_DEFAULT, smp_processor_id(), 1);
    /* SW VIRQ, No PIRQ */

    if ( _timer_status[vmid] == 0 )
        virq_inject(vmid, 30, 0, 0);
    HVMM_TRACE_EXIT();
}
コード例 #9
0
/*
 * Configure sp804 timer irq for test
 */
hvmm_status_t hvmm_tests_sp804_timer(void) {

	HVMM_TRACE_ENTER();

    /* 
     * Until the guest enables IRQ34, for SP804, through VGICD, we manually enable here for 
     * test purpose so the hypervisor can receive and forward to a designated guest 
     */
    gic_test_configure_irq(34,
        GIC_INT_POLARITY_LEVEL,
        gic_cpumask_current(),
        GIC_INT_PRIORITY_DEFAULT );

	HVMM_TRACE_EXIT();
	return HVMM_STATUS_SUCCESS;
}
コード例 #10
0
hvmm_status_t hvmm_tests_gic_timer(void)
{
    /* Testing Non-secure Physical Timer Event
     * (PPI2, Interrupt ID:30), Cortex-A15
     * - Periodically triggers timer interrupt
     * - switches guest context at every timer interrupt
     */
    HVMM_TRACE_ENTER();
    /* handler */
    interrupt_request(30, &interrupt_nsptimer);
    /* configure and enable interrupt */
    interrupt_host_configure(30);
    /* start timer */
    test_start_timer();
    HVMM_TRACE_EXIT();
    return HVMM_STATUS_SUCCESS;
}
コード例 #11
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
/**
 * @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;
}
コード例 #12
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
/**
 * @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;
}
コード例 #13
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
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();
}
コード例 #14
0
ファイル: virqmap.c プロジェクト: jhkyung/khypervisor
/* 
 * Creates a mapping table between PIRQ and VIRQ.vmid/pirq/coreid.
 * Mapping of between pirq and virq is hard-coded.
 */
hvmm_status_t virqmap_init(void) 
{
    // TODO(wonseok): read file and initialize the mapping.
    HVMM_TRACE_ENTER();
    int i;

    for (i = 0; i < GIC_NUM_MAX_IRQS; i++) {
        _virqmap[i].vmid = VMID_INVALID;
        _virqmap[i].virq = 0;
    }

    // NOTE(wonseok): referenced by https://github.com/kesl/khypervisor/wiki/Hardware-Resources-of-Guest-Linux-on-FastModels-RTSM_VE-Cortex-A15x1
    CFG_GUEST0_VIRQMAP(_virqmap);
    CFG_GUEST1_VIRQMAP(_virqmap);

    vgicd_set_callback_changed_istatus(&virqmap_vgicd_changed_istatus_callback_handler);

    HVMM_TRACE_EXIT();

    return HVMM_STATUS_SUCCESS;
}
コード例 #15
0
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();
}
コード例 #16
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
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;
}
コード例 #17
0
ファイル: tests_gic_timer.c プロジェクト: jhkyung/khypervisor
hvmm_status_t hvmm_tests_gic_timer(void)
{
	/* Testing Non-secure Physical Timer Event (PPI2, Interrupt ID:30), Cortex-A15 
	 * - Periodically triggers timer interrupt
	 * - switches guest context at every timer interrupt
	 */

	HVMM_TRACE_ENTER();
	/* handler */
	gic_test_set_irq_handler( 30, &interrupt_nsptimer, 0 );

	/* configure and enable interrupt */
	gic_test_configure_irq(30, 
		GIC_INT_POLARITY_LEVEL, 
		gic_cpumask_current(), 
		GIC_INT_PRIORITY_DEFAULT );

	/* start timer */
	test_start_timer();

	HVMM_TRACE_EXIT();
	return HVMM_STATUS_SUCCESS;
}
コード例 #18
0
ファイル: gic.c プロジェクト: Jinwoo00/Makefile_Study
hvmm_status_t gic_init(void)
{
    uint32_t cpu = smp_processor_id();
    hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR;

    HVMM_TRACE_ENTER();
    /*
     * Determining VA of GIC base adddress has not been defined yet.
     * Let is use the PA for the time being
     */
    if (!cpu) {
        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
     * For test it
     */
    if (cpu)
        result = HVMM_STATUS_SUCCESS;

    if (result == HVMM_STATUS_SUCCESS)
        result = gic_init_cpui();

    if (result == HVMM_STATUS_SUCCESS)
        _gic.initialized = GIC_SIGNATURE_INITIALIZED;

    HVMM_TRACE_EXIT();
    return result;
}
コード例 #19
0
ファイル: vdev.c プロジェクト: jhkyung/khypervisor
hvmm_status_t vdev_emulate(uint32_t fipa, uint32_t wnr, vdev_access_size_t access_size, uint32_t srt, struct arch_regs *regs) 
{
    hvmm_status_t result = HVMM_STATUS_NOT_FOUND;
    int i = 0;
    uint32_t offset;
    uint8_t isize = 4;

    HVMM_TRACE_ENTER();
    if ( regs->cpsr & 0x20 ) {
        /* Thumb */
        isize = 2;
    }

    for (i = 0; i < MAX_VDEV; i++){
        if ( vdev_list[i].base == 0 ) break;

        offset = fipa - vdev_list[i].base;
        if ( fipa >= vdev_list[i].base && offset < vdev_list[i].size && vdev_list[i].handler != 0) {
            /* fipa is in the rage: base ~ base + size */
            printh("vdev: found %s for fipa %x srt:%x gpr[srt]:%x write:%d vmid:%d\n", vdev_list[i].name, fipa, srt, regs->gpr[srt], wnr, context_current_vmid() );
            result = vdev_list[i].handler(wnr, offset, &(regs->gpr[srt]), access_size);
            if ( wnr == 0 ) {
                printh("vdev: result:%x\n", regs->gpr[srt] );
            }

            /* Update PC regardless handling result */
            regs->pc += isize;
            break;
        } else {
            printh("vdev: fipa %x base %x not matched\n", fipa, vdev_list[i].base );
        }
    }
    HVMM_TRACE_EXIT();

    return result;
}
コード例 #20
0
void callback_timer(void *pdata)
{
    HVMM_TRACE_ENTER();
    vgic_inject_virq_sw( 30, VIRQ_STATE_PENDING, GIC_INT_PRIORITY_DEFAULT, smp_processor_id(), 1);
    HVMM_TRACE_EXIT();
}