コード例 #1
0
ファイル: xlltemacif_fifo.c プロジェクト: sevikkk/VP2motion-2
XStatus
init_ll_fifo(struct xemac_s *xemac)
{
    xlltemacif_s *xlltemacif = (xlltemacif_s *)(xemac->state);
#if NO_SYS
    struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif

    /* initialize ll fifo */
    XLlFifo_Initialize(&xlltemacif->llfifo,
                       XLlTemac_LlDevBaseAddress(&xlltemacif->lltemac));

    /* Clear any pending FIFO interrupts */
    XLlFifo_IntClear(&xlltemacif->llfifo, XLLF_INT_ALL_MASK);

    /* enable fifo interrupts */
    XLlFifo_IntEnable(&xlltemacif->llfifo, XLLF_INT_ALL_MASK);

#if NO_SYS
    /* Register temac interrupt with interrupt controller */
    XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
                          xlltemacif->lltemac.Config.TemacIntr,
                          (XInterruptHandler)xlltemac_error_handler,
                          &xlltemacif->lltemac);

    /* connect & enable FIFO interrupt */
    XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
                          xlltemacif->lltemac.Config.LLFifoIntr,
                          (XInterruptHandler)xllfifo_intr_handler,
                          xemac);

    /* Enable EMAC interrupts in the interrupt controller */
    do {
        /* read current interrupt enable mask */
        unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

        /* form new mask enabling SDMA & ll_temac interrupts */
        cur_mask = cur_mask
                   | (1 << xlltemacif->lltemac.Config.LLFifoIntr)
                   | (1 << xlltemacif->lltemac.Config.TemacIntr);

        /* set new mask */
        XIntc_mEnableIntr(xtopologyp->intc_baseaddr, cur_mask);
    } while (0);
#else
    /* connect & enable TEMAC interrupts */
    register_int_handler(xlltemacif->lltemac.Config.TemacIntr,
                         (XInterruptHandler)xlltemac_error_handler,
                         &xlltemacif->lltemac);
    enable_interrupt(xlltemacif->lltemac.Config.TemacIntr);

    /* connect & enable FIFO interrupts */
    register_int_handler(xlltemacif->lltemac.Config.LLFifoIntr,
                         (XInterruptHandler)xllfifo_intr_handler,
                         xemac);
    enable_interrupt(xlltemacif->lltemac.Config.LLFifoIntr);
#endif

    return 0;
}
コード例 #2
0
ファイル: timer.c プロジェクト: 0xBADCA7/lk
void platform_init_timer(void)
{
    /* disable timers */
    TIMREG(CNT_CTRL(0)) = 0x1;
    TIMREG(CNT_CTRL(1)) = 0x1;
    TIMREG(CNT_CTRL(2)) = 0x1;

    TIMREG(CLK_CTRL(0)) = (6 << 1) | 1; // prescale 133Mhz/(2^7) == 1039062Hz (close to 1Mhz)

    register_int_handler(TTC0_A_INT, &platform_tick, NULL);
    register_int_handler(TTC0_B_INT, &platform_tick, NULL);
    register_int_handler(TTC0_C_INT, &platform_tick, NULL);
}
コード例 #3
0
ファイル: net.c プロジェクト: 0xBADCA7/lk
status_t ethernet_init(void)
{
    /* check to see if the ethernet feature is turned on */
    if ((*REG(SYSINFO_FEATURES) & SYSINFO_FEATURE_NETWORK) == 0)
        return ERR_NOT_FOUND;

    struct netif *netif = calloc(sizeof(struct netif), 1);
    struct ip_addr *ipaddr = calloc(sizeof(struct ip_addr), 1);
    struct ip_addr *netmask = calloc(sizeof(struct ip_addr), 1);
    struct ip_addr *gw = calloc(sizeof(struct ip_addr), 1);

    struct netif *netifret = netif_add(netif, ipaddr, netmask, gw, NULL, &ethernetif_init, &ip_input);
    if (netifret == NULL) {
        free(netif);
        free(ipaddr);
        free(netmask);
        free(gw);
        return ERR_NOT_FOUND;
    }

    /* register for interrupt handlers */
    register_int_handler(INT_NET, ethernet_int, netif);

    netif_set_default(netif);

    unmask_interrupt(INT_NET, NULL);

    return NO_ERROR;
}
コード例 #4
0
ファイル: pit.c プロジェクト: Ninals-GitHub/TRON
/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 Funtion	:initPit
 Input		:void
 Output		:void
 Return		:ER
 		 < error status >
 Description	:intialize a programmable interval timer
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/
EXPORT ER initPit(void)
{
	ER err;
	uint32_t fperiod;
	
	/* -------------------------------------------------------------------- */
	/* register timer interrupt for irq 0					*/
	/* -------------------------------------------------------------------- */
	err = register_int_handler(INT_IRQ0, pit_intterupt);

	if (err) {
		vd_printf("err[%d]:cannot register pit interrupt handler\n", err);
		return(err);
	}

	if (PIT_CLOCK < TIMER_PERIOD) {
		fperiod = PIT_CLOCK;
		TIMER_PERIOD = PIT_CLOCK;
	} else {
		fperiod = (uint32_t)(1000 / TIMER_PERIOD);
	}

	/* -------------------------------------------------------------------- */
	/* set 10 ms interval							*/
	/* -------------------------------------------------------------------- */
	setPitCounter(fperiod, PIT_COUNTER0, PIT_COM_MODE_SQUAREWAVE);

	/* -------------------------------------------------------------------- */
	/* enable irq 0								*/
	/* -------------------------------------------------------------------- */
	reqEnableIrq(INT_IRQ0);

	return(E_OK);
}
コード例 #5
0
ファイル: timer.c プロジェクト: Mur4ik/swift_lk_bootloader
status_t platform_set_periodic_timer(
	platform_timer_callback callback,
	void *arg, time_t interval)
{
#ifdef PLATFORM_MSM7X30
        unsigned val = 0;
	unsigned mask = (0x1 << 28);
	//Check for the hardware revision
	val = readl(HW_REVISION_NUMBER);
	if(val & mask)
	    writel(1, DGT_CLK_CTL);
#endif
	enter_critical_section();

	timer_callback = callback;
	timer_arg = arg;
	timer_interval = interval;

	writel(timer_interval * (DGT_HZ / 1000), DGT_MATCH_VAL);
	writel(0, DGT_CLEAR);
	writel(DGT_ENABLE_EN | DGT_ENABLE_CLR_ON_MATCH_EN, DGT_ENABLE);
	
	register_int_handler(INT_DEBUG_TIMER_EXP, timer_irq, 0);
	unmask_interrupt(INT_DEBUG_TIMER_EXP);

	exit_critical_section();
	return 0;
}
コード例 #6
0
ファイル: arm_generic_timer.c プロジェクト: cpizano/lk
void arm_generic_timer_init(int irq, uint32_t freq_override)
{
	uint32_t cntfrq;

	if (freq_override == 0) {
		cntfrq = read_cntfrq();

		if (!cntfrq) {
			TRACEF("Failed to initialize timer, frequency is 0\n");
			return;
		}
	} else {
		cntfrq = freq_override;
	}

#if LOCAL_TRACE
	LTRACEF("Test min cntfrq\n");
	arm_generic_timer_init_conversion_factors(1);
	test_time_conversions(1);
	LTRACEF("Test max cntfrq\n");
	arm_generic_timer_init_conversion_factors(~0);
	test_time_conversions(~0);
	LTRACEF("Set actual cntfrq\n");
#endif
	arm_generic_timer_init_conversion_factors(cntfrq);
	test_time_conversions(cntfrq);

	LTRACEF("register irq %d on cpu %d\n", irq, arch_curr_cpu_num());
	register_int_handler(irq, &platform_tick, NULL);
	unmask_interrupt(irq);

	timer_irq = irq;
}
コード例 #7
0
/* Enable BAM and pipe level interrupts */
void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
{

	uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
						P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
	uint32_t val;

	/* Enable BAM error interrupts */
	writel(BAM_ERROR_EN_MASK, BAM_IRQ_EN_REG(bam->base));

	/* Enable the interrupts for the pipe by enabling the relevant bits
	 * in the BAM_PIPE_INTERRUPT_ENABLE register.
	 */
	writel(int_mask,
			BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Enable pipe interrups */
	/* Do read-modify-write */
	val = readl(BAM_IRQ_SRCS_MSK(bam->base));
	writel((1 << bam->pipe[pipe_num].pipe_num) | val,
			BAM_IRQ_SRCS_MSK(bam->base));

	/* Unmask the QGIC interrupts only in the case of
	 * interrupt based transfer.
	 * Use polling othwerwise.
	 */
	if (bam->pipe[pipe_num].int_mode)
	{
		/* Register interrupt handler */
		register_int_handler(bam->pipe[pipe_num].spi_num, bam_interrupt_handler, 0);

		/* Unmask the interrupt */
		unmask_interrupt(bam->pipe[pipe_num].spi_num);
	}
}
コード例 #8
0
ファイル: smd.c プロジェクト: sndnvaps/lk-1
int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
	unsigned ret = 0;

	smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
	ASSERT(smd_channel_alloc_entry);

	ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
							(void*)smd_channel_alloc_entry,
							SMD_CHANNEL_ALLOC_MAX);
	if(ret)
	{
		dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
		return -1;
	}

	smd_get_channel_info(ch, ch_type);

	register_int_handler(SMD_IRQ, smd_irq_handler, ch);
	unmask_interrupt(SMD_IRQ);

	smd_set_state(ch, SMD_SS_OPENING, 1);

	smd_notify_rpm();

	return 0;
}
コード例 #9
0
void platform_init_timer(void)
{
#if 0
	OS_TIMER_CTRL_REG = 0; // stop the timer if it's already running

	register_int_handler(IRQ_OS_TIMER, &os_timer_tick, NULL);
	unmask_interrupt(IRQ_OS_TIMER, NULL);
#endif
}
コード例 #10
0
ファイル: debug.c プロジェクト: gabemblack/lk
void uart_init(void)
{
    /* finish uart init to get rx going */
    cbuf_initialize(&uart_rx_buf, 16);

    register_int_handler(0x24, uart_irq_handler, NULL);
    unmask_interrupt(0x24);

    outp(uart_io_port + 1, 0x1); // enable receive data available interrupt
}
コード例 #11
0
ファイル: timer.c プロジェクト: DSKIM3/lk
void platform_init_timer(void)
{
	/* disable timer */
	TIMREG(CONTROL) = 0;

	/* periodic mode, ints enabled, 32bit, wrapping */
	TIMREG(CONTROL) = (1<<6)|(1<<5)|(1<<1);

	register_int_handler(TIMER01_INT, &platform_tick, NULL);
}
コード例 #12
0
ファイル: arm_cortex_a9_timer.c プロジェクト: cpizano/lk
static void arm_cortex_a9_timer_init_percpu(uint level)
{
    /* disable timer */
    TIMREG(TIMER_CONTROL) = 0;

    /* kill the watchdog */
    TIMREG(WDOG_CONTROL) = 0;

    /* ack any irqs that may be pending */
    TIMREG(TIMER_ISR) = 1;

    /* register the platform tick on each cpu */
    register_int_handler(CPU_PRIV_TIMER_INT, &platform_tick, NULL);
    unmask_interrupt(CPU_PRIV_TIMER_INT);
}
コード例 #13
0
ファイル: sdhci_msm.c プロジェクト: M1cha/lktris
/*
 * Function: sdhci msm init
 * Arg     : MSM specific config data for sdhci
 * Return  : None
 * Flow:   : Enable sdhci mode & do msm specific init
 */
void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *config)
{
	/* Disable HC mode */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0);

	/* Core power reset */
	RMWREG32((config->pwrctl_base + SDCC_MCI_POWER), CORE_SW_RST_START, CORE_SW_RST_WIDTH, 1);

	/* Wait for the core power reset to complete*/
	 mdelay(1);

	/* Enable sdhc mode */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, SDHCI_HC_MODE_EN);

	/* Set the FF_CLK_SW_RST_DIS to 1 */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1);

	/*
	 * Reset the controller
	 */
	sdhci_reset(host, SDHCI_SOFT_RESET);

	/*
	 * CORE_SW_RST may trigger power irq if previous status of PWRCTL
	 * was either BUS_ON or IO_HIGH. So before we enable the power irq
	 * interrupt in GIC (by registering the interrupt handler), we need to
	 * ensure that any pending power irq interrupt status is acknowledged
	 * otherwise power irq interrupt handler would be fired prematurely.
	 */
	sdhci_clear_power_ctrl_irq(config);

	/*
	 * Register the interrupt handler for pwr irq
	 */
	register_int_handler(config->pwr_irq, sdhci_int_handler, (void *)config);

	unmask_interrupt(config->pwr_irq);

	/* Enable pwr control interrupt */
	writel(SDCC_HC_PWR_CTRL_INT, (config->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG));

	config->tuning_done = false;
	config->calibration_done = false;
	host->tuning_in_progress = false;
}
コード例 #14
0
ファイル: timer.c プロジェクト: M1cha/lk
void platform_init_timer(void)
{
    TRACE_ENTRY;

    /* read the base frequency from the control block */
    timer_freq = *REG32(REFCLK_CNTControl + CNTFID0);
    printf("timer running at %d Hz\n", timer_freq);

    /* calculate the ratio of microseconds and milliseconds */
    usec_ratio = timer_freq / 1000000U;
    msec_ratio = timer_freq / 1000U;

    /* start the physical timer */
    *REG32(REFCLK_CNTControl + CNTCR) = 1;

    mask_interrupt(INT_PPI_NSPHYS_TIMER);
    register_int_handler(INT_PPI_NSPHYS_TIMER, &platform_tick, NULL);
}
コード例 #15
0
ファイル: uart.cpp プロジェクト: saltstar/smartnix
static void imx_uart_init(const void* driver_data, uint32_t length) {
    uint32_t regVal;

    // create circular buffer to hold received data
    cbuf_initialize(&uart_rx_buf, RXBUF_SIZE);

    // register uart irq
    register_int_handler(uart_irq, &uart_irq_handler, NULL);

    // set rx fifo threshold to 1 character
    regVal = UARTREG(MX8_UFCR);
    regVal &= ~UFCR_RXTL(UFCR_MASK);
    regVal &= ~UFCR_TXTL(UFCR_MASK);
    regVal |= UFCR_RXTL(1);
    regVal |= UFCR_TXTL(0x2);
    UARTREG(MX8_UFCR) = regVal;

    // enable rx interrupt
    regVal = UARTREG(MX8_UCR1);
    regVal |= UCR1_RRDYEN;
    if (dlog_bypass() == false) {
        // enable tx interrupt
        regVal |= UCR1_TRDYEN;
    }
    UARTREG(MX8_UCR1) = regVal;

    // enable rx and tx transmisster
    regVal = UARTREG(MX8_UCR2);
    regVal |= UCR2_RXEN | UCR2_TXEN;
    UARTREG(MX8_UCR2) = regVal;

    if (dlog_bypass() == true) {
        uart_tx_irq_enabled = false;
    } else {
        /* start up tx driven output */
        printf("UART: started IRQ driven TX\n");
        uart_tx_irq_enabled = true;
    }

    initialized = true;

    // enable interrupts
    unmask_interrupt(uart_irq);
}
コード例 #16
0
ファイル: smd.c プロジェクト: jaehyek/lk
int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
	unsigned ret = 0;
	int chnl_found = 0;
	uint64_t timeout = SMD_CHANNEL_ACCESS_RETRY;

	smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
	ASSERT(smd_channel_alloc_entry);

	dprintf(INFO, "Waiting for the RPM to populate smd channel table\n");

	do
	{
		ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
									(void*)smd_channel_alloc_entry,
									SMD_CHANNEL_ALLOC_MAX);
		if(ret)
		{
			dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
			return -1;
		}

		chnl_found = smd_get_channel_info(ch, ch_type);
		timeout--;
		udelay(10);
	} while(timeout && chnl_found);

	if (!timeout)
	{
		dprintf(CRITICAL, "Apps timed out waiting for RPM-->APPS channel entry\n");
		ASSERT(0);
	}

	register_int_handler(SMD_IRQ, smd_irq_handler, ch);

	smd_set_state(ch, SMD_SS_OPENING, 1);

	smd_notify_rpm();

	unmask_interrupt(SMD_IRQ);

	return 0;
}
コード例 #17
0
ファイル: timer.c プロジェクト: sndnvaps/lk-1
status_t
platform_set_periodic_timer(platform_timer_callback callback,
			    void *arg, lk_time_t interval)
{
	uint32_t tick_count = interval * platform_tick_rate() / 1000;

	enter_critical_section();

	timer_callback = callback;
	timer_arg = arg;
	timer_interval = interval;

	writel(tick_count, DGT_MATCH_VAL);
	writel(0, DGT_CLEAR);
	writel(DGT_ENABLE_EN | DGT_ENABLE_CLR_ON_MATCH_EN, DGT_ENABLE);

	register_int_handler(INT_DEBUG_TIMER_EXP, timer_irq, 0);
	unmask_interrupt(INT_DEBUG_TIMER_EXP);

	exit_critical_section();
	return 0;
}
コード例 #18
0
ファイル: timer.c プロジェクト: grub4android/lk
status_t
platform_set_periodic_timer(platform_timer_callback callback,
			    void *arg, lk_time_t interval)
{
	uint32_t tick_count = interval * ticks_per_sec / 1000;

	spin_lock_saved_state_t state;
	spin_lock_irqsave(&lock, state);

	timer_callback = callback;
	timer_arg = arg;
	timer_interval = interval;

	writel(tick_count, DGT_MATCH_VAL);
	writel(0, DGT_CLEAR);
	writel(DGT_ENABLE_EN | DGT_ENABLE_CLR_ON_MATCH_EN, DGT_ENABLE);

	register_int_handler(INT_DEBUG_TIMER_EXP, timer_irq, 0);
	unmask_interrupt(INT_DEBUG_TIMER_EXP);

	spin_unlock_irqrestore(&lock, state);
	return 0;
}
コード例 #19
0
ファイル: timer.c プロジェクト: taphier/lk
void platform_init_timer(void)
{
    /* GPT2 */
    RMWREG32(CM_CLKSEL_PER, 0, 1, 1);
    RMWREG32(CM_ICLKEN_PER, 3, 1, 1);
    RMWREG32(CM_FCLKEN_PER, 3, 1, 1);

    // reset the GP timer
    TIMER_REG(TIOCP_CFG) = 0x2;
    while ((TIMER_REG(TISTAT) & 1) == 0)
        ;

    // set GPT2-9 clock inputs over to 32k
    *REG32(CM_CLKSEL_PER) = 0;

    // disable ints
    TIMER_REG(TIER) = 0;
    TIMER_REG(TISR) = 0x7; // clear any pending bits

    // XXX make sure 32K timer is running

    register_int_handler(GPT2_IRQ, &os_timer_tick, NULL);
}
コード例 #20
0
ファイル: keyboard.c プロジェクト: thomasloven/os5
void keyboard_init()
{
  INODE tmp[2];
  new_pipe(1024, tmp);
  keyboard_pipe = tmp[1];
  /* vfs_mount("/dev/kbd", tmp[0]); */
  vfs_open(keyboard_pipe, O_WRONLY);

  // Make keyboard stdin (first entry in file descriptor table)
  process_t *p = current->proc;
  p->fd[0] = calloc(1, sizeof(file_desc_t));
  fd_get(p->fd[0]);
  p->fd[0]->ino = tmp[0];
  p->fd[0]->flags = O_RDONLY;
  vfs_open(tmp[0], O_RDONLY);

  new_pipe(1024, tmp);
  keyboard_raw = tmp[1];
  vfs_mount("/dev/kbdraw", tmp[0]);
  vfs_open(keyboard_raw, O_WRONLY);

  register_int_handler(IRQ2INT(IRQ_KBD), keyboard_handler);
}
コード例 #21
0
ファイル: arm_cortex_a9_timer.c プロジェクト: M1cha/lk
void arm_cortex_a9_timer_init(addr_t _scu_control_base, uint32_t freq)
{
    scu_control_base = _scu_control_base;

    /* disable timer */
    TIMREG(TIMER_CONTROL) = 0;

    /* kill the watchdog */
    TIMREG(WDOG_CONTROL) = 0;

    /* ack any irqs that may be pending */
    TIMREG(TIMER_ISR) = 1;

    /* save the timer frequency for later calculations */
    timer_freq = freq;

    /* precompute the conversion factor for global time to real time */
    fp_32_64_div_32_32(&timer_freq_msec_conversion, timer_freq, 1000);
    fp_32_64_div_32_32(&timer_freq_usec_conversion_inverse, 1000000, timer_freq);
    fp_32_64_div_32_32(&timer_freq_msec_conversion_inverse, 1000, timer_freq);

    register_int_handler(CPU_PRIV_TIMER_INT, &platform_tick, NULL);
    unmask_interrupt(CPU_PRIV_TIMER_INT);
}
コード例 #22
0
ファイル: arm_generic_timer.c プロジェクト: cpizano/lk
static void arm_generic_timer_init_secondary_cpu(uint level)
{
	LTRACEF("register irq %d on cpu %d\n", timer_irq, arch_curr_cpu_num());
	register_int_handler(timer_irq, &platform_tick, NULL);
	unmask_interrupt(timer_irq);
}
コード例 #23
0
ファイル: xaxiemacif_fifo.c プロジェクト: Xilinx/embeddedsw
XStatus init_axi_fifo(struct xemac_s *xemac)
{
	xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state);
#if XPAR_INTC_0_HAS_FAST == 1
	xaxiemacif_fast = xaxiemacif;
	xemac_fast = xemac;
#endif
#if NO_SYS
	struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif
#ifdef OS_IS_FREERTOS
	struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif

	/* initialize ll fifo */
	XLlFifo_Initialize(&xaxiemacif->axififo,
			XAxiEthernet_AxiDevBaseAddress(&xaxiemacif->axi_ethernet));

	/* Clear any pending FIFO interrupts */
	XLlFifo_IntClear(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

	/* enable fifo interrupts */
	XLlFifo_IntEnable(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

#if XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ == 1
	XScuGic_RegisterHandler(xtopologyp->scugic_baseaddr,
				xaxiemacif->axi_ethernet.Config.TemacIntr,
				(XInterruptHandler)xaxiemac_error_handler,
				&xaxiemacif->axi_ethernet);
	XScuGic_RegisterHandler(xtopologyp->scugic_baseaddr,
				xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
				(XInterruptHandler)xllfifo_intr_handler,
				xemac);
	XScuGic_SetPriTrigTypeByDistAddr(INTC_DIST_BASE_ADDR,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			AXIETH_INTR_PRIORITY_SET_IN_GIC,
			TRIG_TYPE_RISING_EDGE_SENSITIVE);
	XScuGic_SetPriTrigTypeByDistAddr(INTC_DIST_BASE_ADDR,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			AXIFIFO_INTR_PRIORITY_SET_IN_GIC,
			TRIG_TYPE_RISING_EDGE_SENSITIVE);

	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR,
				xaxiemacif->axi_ethernet.Config.TemacIntr);
	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR,
				xaxiemacif->axi_ethernet.Config.AxiFifoIntr);
#else
#if NO_SYS
#if XPAR_INTC_0_HAS_FAST == 1
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XFastInterruptHandler)xaxiemac_fasterror_handler);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XFastInterruptHandler)xllfifo_fastintr_handler);
#else
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);

#endif
	/* Enable EMAC interrupts in the interrupt controller */
	do {
		/* read current interrupt enable mask */
		unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

		/* form new mask enabling SDMA & ll_temac interrupts */
		cur_mask = cur_mask
				| (1 << xaxiemacif->axi_ethernet.Config.AxiFifoIntr)
				| (1 << xaxiemacif->axi_ethernet.Config.TemacIntr);

		/* set new mask */
		XIntc_EnableIntr(xtopologyp->intc_baseaddr, cur_mask);
	} while (0);
#else
#ifdef OS_IS_XILKERNEL
	/* connect & enable TEMAC interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.TemacIntr);

	/* connect & enable FIFO interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.AxiFifoIntr);
#else
#if XPAR_INTC_0_HAS_FAST == 1
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XFastInterruptHandler)xaxiemac_fasterror_handler);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XFastInterruptHandler)xllfifo_fastintr_handler);
#else
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);

#endif
	/* Enable EMAC interrupts in the interrupt controller */
	do {
		/* read current interrupt enable mask */
		unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

		/* form new mask enabling SDMA & ll_temac interrupts */
		cur_mask = cur_mask
				| (1 << xaxiemacif->axi_ethernet.Config.AxiFifoIntr)
				| (1 << xaxiemacif->axi_ethernet.Config.TemacIntr);

		/* set new mask */
		XIntc_EnableIntr(xtopologyp->intc_baseaddr, cur_mask);
	} while (0);
#endif
#endif
#endif

	return 0;
}
コード例 #24
0
ファイル: timer.cpp プロジェクト: saltstar/smartnix
static void pc_init_timer(uint level) {
    const struct x86_model_info* cpu_model = x86_get_model();

    constant_tsc = false;
    if (x86_vendor == X86_VENDOR_INTEL) {
        /* This condition taken from Intel 3B 17.15 (Time-Stamp Counter).  This
         * is the negation of the non-Constant TSC section, since the Constant
         * TSC section is incomplete (the behavior is architectural going
         * forward, and modern CPUs are not on the list). */
        constant_tsc = !((cpu_model->family == 0x6 && cpu_model->model == 0x9) ||
                         (cpu_model->family == 0x6 && cpu_model->model == 0xd) ||
                         (cpu_model->family == 0xf && cpu_model->model < 0x3));
    }
    invariant_tsc = x86_feature_test(X86_FEATURE_INVAR_TSC);

    bool has_pvclock = pvclock_is_present();
    if (has_pvclock) {
        zx_status_t status = pvclock_init();
        if (status == ZX_OK) {
            invariant_tsc = pvclock_is_stable();
        } else {
            has_pvclock = false;
        }
    }

    bool has_hpet = hpet_is_present();
    if (has_hpet) {
        calibration_clock = CLOCK_HPET;
        const uint64_t hpet_ms_rate = hpet_ticks_per_ms();
        ASSERT(hpet_ms_rate <= UINT32_MAX);
        printf("HPET frequency: %" PRIu64 " ticks/ms\n", hpet_ms_rate);
        fp_32_64_div_32_32(&ns_per_hpet, 1000 * 1000, static_cast<uint32_t>(hpet_ms_rate));
        // Add 1ns to conservatively deal with rounding
        ns_per_hpet_rounded_up = u32_mul_u64_fp32_64(1, ns_per_hpet) + 1;
    } else {
        calibration_clock = CLOCK_PIT;
    }

    const char* force_wallclock = cmdline_get("kernel.wallclock");
    bool use_invariant_tsc = invariant_tsc && (!force_wallclock || !strcmp(force_wallclock, "tsc"));

    use_tsc_deadline = use_invariant_tsc &&
                       x86_feature_test(X86_FEATURE_TSC_DEADLINE);
    if (!use_tsc_deadline) {
        calibrate_apic_timer();
    }

    if (use_invariant_tsc) {
        calibrate_tsc(has_pvclock);

        // Program PIT in the software strobe configuration, but do not load
        // the count.  This will pause the PIT.
        outp(I8253_CONTROL_REG, 0x38);
        wall_clock = CLOCK_TSC;
    } else {
        if (constant_tsc || invariant_tsc) {
            // Calibrate the TSC even though it's not as good as we want, so we
            // can still let folks still use it for cheap timing.
            calibrate_tsc(has_pvclock);
        }

        if (has_hpet && (!force_wallclock || !strcmp(force_wallclock, "hpet"))) {
            wall_clock = CLOCK_HPET;
            hpet_set_value(0);
            hpet_enable();
        } else {
            if (force_wallclock && strcmp(force_wallclock, "pit")) {
                panic("Could not satisfy kernel.wallclock choice\n");
            }

            wall_clock = CLOCK_PIT;

            set_pit_frequency(1000); // ~1ms granularity

            uint32_t irq = apic_io_isa_to_global(ISA_IRQ_PIT);
            zx_status_t status = register_int_handler(irq, &pit_timer_tick, NULL);
            DEBUG_ASSERT(status == ZX_OK);
            unmask_interrupt(irq);
        }
    }

    printf("timer features: constant_tsc %d invariant_tsc %d tsc_deadline %d\n",
           constant_tsc, invariant_tsc, use_tsc_deadline);
    printf("Using %s as wallclock\n", clock_name[wall_clock]);
}
コード例 #25
0
ファイル: apic.c プロジェクト: bradylee/nautilus_fs
void
apic_timer_setup (struct apic_dev * apic, uint32_t quantum)
{
    uint32_t busfreq;
    uint32_t tmp;
    uint8_t  tmp2;
    cpuid_ret_t ret;

    APIC_DEBUG("Setting up Local APIC timer for APIC 0x%x\n", apic->id);

    cpuid(0x6, &ret);
    if (ret.a & 0x4) {
        APIC_DEBUG("\t[APIC Supports Constant Tick Rate]\n");
    }

    if (register_int_handler(APIC_TIMER_INT_VEC,
            nk_timer_handler,
            NULL) != 0) {
        panic("Could not register APIC timer handler\n");
    }

    /* run the APIC timer in one-shot mode, it shouldn't get to 0 */
    apic_write(apic, APIC_REG_LVTT, APIC_TIMER_ONESHOT | APIC_DEL_MODE_FIXED | APIC_TIMER_INT_VEC);

    /* set up the divider */
    apic_write(apic, APIC_REG_TMDCR, APIC_TIMER_DIVCODE);



    /* set PIT channel 2 to "out" mode */
    outb((inb(KB_CTRL_PORT_B) & 0xfd) | 0x1, 
          KB_CTRL_PORT_B);

    /* configure the PIT channel 2 for one-shot */
    outb(PIT_MODE(PIT_MODE_ONESHOT) |
         PIT_CHAN(PIT_CHAN_SEL_2)   |
         PIT_ACC_MODE(PIT_ACC_MODE_BOTH),
         PIT_CMD_REG);

    /* LSB  (PIT rate) */
    outb((PIT_RATE/NAUT_CONFIG_HZ) & 0xff,
         PIT_CHAN2_DATA);
    inb(KB_CTRL_DATA_OUT);

    /* MSB */
    outb((uint8_t)((PIT_RATE/NAUT_CONFIG_HZ)>>8),
                PIT_CHAN2_DATA);

    /* clear and reset bit 0 of kbd ctrl port to reload
     * current cnt on chan 2 with the new value */
    tmp2 = inb(KB_CTRL_PORT_B) & 0xfe;
    outb(tmp2, KB_CTRL_PORT_B);
    outb(tmp2 | 1, KB_CTRL_PORT_B);

    /* reset timer to our count down value */
    apic_write(apic, APIC_REG_TMICT, 0xffffffff);

/* TODO: need to calibrate timers with TSC on the Phi */
    while (!(inb(KB_CTRL_PORT_B) & 0x20));

    /* disable the timer */
    apic_write(apic, APIC_REG_LVTT, APIC_TIMER_DISABLE);

    /* TODO need to fixup when frequency is way off */
    //busfreq = APIC_TIMER_DIV * NAUT_CONFIG_HZ*(0xffffffff - apic_read(apic, APIC_REG_TMCCT) + 1);
    busfreq = 1100000000;
    APIC_DEBUG("Detected APIC 0x%x bus frequency as %u.%u MHz\n", apic->id, busfreq/1000000, busfreq%1000000);
    tmp = busfreq/(1000/quantum)/APIC_TIMER_DIV;

    APIC_DEBUG("Setting APIC timer Initial Count Reg to %u\n", tmp);
    apic_write(apic, APIC_REG_TMICT, (tmp < APIC_TIMER_DIV) ? APIC_TIMER_DIV : tmp);
    apic_write(apic, APIC_REG_LVTT, 0 | APIC_DEL_MODE_FIXED | APIC_TIMER_INT_VEC | APIC_TIMER_PERIODIC);
    apic_write(apic, APIC_REG_TMDCR, APIC_TIMER_DIVCODE);
}
コード例 #26
0
ファイル: apic.c プロジェクト: bradylee/nautilus_fs
void
apic_init (struct cpu * core)
{
    struct apic_dev * apic = NULL;
    ulong_t base_addr;
    uint32_t val;

    apic = (struct apic_dev*)malloc(sizeof(struct apic_dev));
    if (!apic) {
        panic("Could not allocate apic struct\n");
    }
    memset(apic, 0, sizeof(struct apic_dev));
    core->apic = apic;

    if (!check_apic_avail()) {
        panic("No APIC found on core %u, dying\n", core->id);
    } 

    /* In response to AMD erratum #663 
     * the damn thing may give us lint interrupts
     * even when we have them masked
     */
    if (nk_is_amd()  && cpuid_get_family() == 0x15) {
        APIC_DEBUG("Writing Bridge Ctrl MSR for AMD Errata #663\n");
        msr_write(AMD_MSR_NBRIDGE_CTL, 
                msr_read(AMD_MSR_NBRIDGE_CTL) | 
                (1ULL<<23) | 
                (1ULL<<54));
    }

    base_addr       = apic_get_base_addr();

    /* idempotent when not compiled as HRT */
    apic->base_addr = pa_to_va(base_addr);

#ifndef NAUT_CONFIG_HVM_HRT
    if (core->is_bsp) {
        /* map in the lapic as uncacheable */
        if (nk_map_page_nocache(apic->base_addr, PTE_PRESENT_BIT|PTE_WRITABLE_BIT, PS_4K) == -1) {
            panic("Could not map APIC\n");
        }
    }
#endif

    apic->version   = apic_get_version(apic);
    apic->id        = apic_get_id(apic);

#ifndef NAUT_CONFIG_XEON_PHI
    if (apic->version < 0x10 || apic->version > 0x15) {
        panic("Unsupported APIC version (0x%1x)\n", (unsigned)apic->version);
    }
#endif

    val = apic_read(apic, APIC_REG_LDR) & ~APIC_LDR_MASK;
    val |= SET_APIC_LOGICAL_ID(0);
    apic_write(apic, APIC_REG_LDR, val);

    apic_write(apic, APIC_REG_TPR, apic_read(apic, APIC_REG_TPR) & 0xffffff00);                       // accept all interrupts
    apic_write(apic, APIC_REG_LVTT,    APIC_DEL_MODE_FIXED | APIC_LVT_DISABLED);                      // disable timer interrupts intially
    apic_write(apic, APIC_REG_LVTPC,   APIC_DEL_MODE_FIXED | APIC_LVT_DISABLED | APIC_PC_INT_VEC);    // disable perf cntr interrupts
    apic_write(apic, APIC_REG_LVTTHMR, APIC_DEL_MODE_FIXED | APIC_LVT_DISABLED | APIC_THRML_INT_VEC); // disable thermal interrupts

    /* do we have AMD extended LVT entries to deal with */
    if (nk_is_amd() && amd_has_ext_lvt(apic)) {
        amd_setup_ext_lvt(apic);
    }
            

    /* mask 8259a interrupts */
    apic_write(apic, APIC_REG_LVT0, APIC_DEL_MODE_EXTINT  | APIC_LVT_DISABLED);

    /* only BSP takes NMI interrupts */
    apic_write(apic, APIC_REG_LVT1, 
            APIC_DEL_MODE_NMI | (core->is_bsp ? 0 : APIC_LVT_DISABLED));

    apic_write(apic, APIC_REG_LVTERR, APIC_DEL_MODE_FIXED | APIC_ERROR_INT_VEC); // allow error interrupts

    // clear the ESR
    apic_write(apic, APIC_REG_ESR, 0u);

    apic_global_enable();

    // assign interrupt handlers
    if (core->is_bsp) {

        if (register_int_handler(APIC_NULL_KICK_VEC, null_kick, apic) != 0) {
            panic("Could not register null kick interrupt handler\n");
        }

        if (register_int_handler(APIC_SPUR_INT_VEC, spur_int_handler, apic) != 0) {
            panic("Could not register spurious interrupt handler\n");
        }

        if (register_int_handler(APIC_ERROR_INT_VEC, error_int_handler, apic) != 0) {
            panic("Could not register spurious interrupt handler\n");
            return;
        }

        /* we shouldn't ever get these, but just in case */
        if (register_int_handler(APIC_PC_INT_VEC, pc_int_handler, apic) != 0) {
            panic("Could not register perf counter interrupt handler\n");
            return;
        }

        if (register_int_handler(APIC_THRML_INT_VEC, thermal_int_handler, apic) != 0) {
            panic("Could not register thermal interrupt handler\n");
            return;
        }

        if (register_int_handler(APIC_EXT_LVT_DUMMY_VEC, dummy_int_handler, apic) != 0) {
            panic("Could not register dummy ext lvt handler\n");
            return;
        }
    }

    apic_assign_spiv(apic, APIC_SPUR_INT_VEC);

    /* turn it on */
    apic_sw_enable(apic);

    /* pass in quantum as milliseconds */
#ifndef NAUT_CONFIG_XEON_PHI
    apic_timer_setup(apic, 1000/NAUT_CONFIG_HZ);
#endif

    apic_dump(apic);
}
コード例 #27
0
ファイル: sdhci_msm.c プロジェクト: cancro-dev/lk_candyboot
/*
 * Function: sdhci msm init
 * Arg     : MSM specific config data for sdhci
 * Return  : None
 * Flow:   : Enable sdhci mode & do msm specific init
 */
void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *config)
{
	uint32_t io_switch;
	uint32_t caps = 0;
	uint32_t version;

	/* Disable HC mode */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0);

	/* Core power reset */
	RMWREG32((config->pwrctl_base + SDCC_MCI_POWER), CORE_SW_RST_START, CORE_SW_RST_WIDTH, 1);

	/* Wait for the core power reset to complete*/
	 mdelay(1);

	/* Enable sdhc mode */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, SDHCI_HC_MODE_EN);

	/* Set the FF_CLK_SW_RST_DIS to 1 */
	RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1);

	/*
	 * Reset the controller
	 */
	sdhci_reset(host, SDHCI_SOFT_RESET);

	/*
	 * Some platforms have same SDC instance shared between emmc & sd card.
	 * For such platforms the emmc IO voltage has to be switched from 3.3 to
	 * 1.8 for the contoller to work with emmc.
	 */

	if(config->use_io_switch)
	{
		io_switch = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC);
		io_switch |= HC_IO_PAD_PWR_SWITCH | HC_IO_PAD_PWR_SWITCH_EN;
		REG_WRITE32(host, io_switch, SDCC_VENDOR_SPECIFIC_FUNC);
	}

	/*
	 * CORE_SW_RST may trigger power irq if previous status of PWRCTL
	 * was either BUS_ON or IO_HIGH. So before we enable the power irq
	 * interrupt in GIC (by registering the interrupt handler), we need to
	 * ensure that any pending power irq interrupt status is acknowledged
	 * otherwise power irq interrupt handler would be fired prematurely.
	 */
	sdhci_clear_power_ctrl_irq(config);

	/*
	 * Register the interrupt handler for pwr irq
	 */
	register_int_handler(config->pwr_irq, (int_handler)sdhci_int_handler, (void *)config);

	unmask_interrupt(config->pwr_irq);

	/* Enable pwr control interrupt */
	writel(SDCC_HC_PWR_CTRL_INT, (config->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG));

	version = readl(host->msm_host->pwrctl_base + MCI_VERSION);

	host->major = (version & CORE_VERSION_MAJOR_MASK) >> CORE_VERSION_MAJOR_SHIFT;
	host->minor = (version & CORE_VERSION_MINOR_MASK);

	/*
	 * For SDCC5 the capabilities registers does not have voltage advertised
	 * Override the values using SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0
	 */
	if (host->major >= 1 && host->minor != 0x11 && host->minor != 0x12)
	{
		caps = REG_READ32(host, SDHCI_CAPS_REG1);

		if (config->slot == 0x1)
			REG_WRITE32(host, (caps | SDHCI_1_8_VOL_MASK), SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0);
		else
			REG_WRITE32(host, (caps | SDHCI_3_0_VOL_MASK), SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0);
	}

	config->tuning_done = false;
	config->calibration_done = false;
	host->tuning_in_progress = false;
}
コード例 #28
0
ファイル: kinit.c プロジェクト: thomasloven/os5
registers_t *kinit(mboot_info_t *mboot, uint32_t mboot_magic)
{

  kdbg_init();
  assert(mboot_magic == MBOOT_MAGIC2);

  mboot_mod_t *mods = (mboot_mod_t *)(assert_higher(mboot->mods_addr));

  kernel_elf_init(mboot);
  pmm_init(mboot);
  vmm_init(mods[0].mod_end);
  idt_init();
  tss_init();

  register_int_handler(INT_PF, page_fault_handler);
  register_int_handler(INT_SCHEDULE, switch_kernel_thread);

  scheduler_init();
  timer_init(500);
  /* vfs_init(); */
  syscall_init();
  process_init((void(*)(void))&_idle);

  tar_header_t *tarfs_location = assert_higher((tar_header_t *)mods[0].mod_start);
  debug_enabled = 1;

  debug("[info] Mboot flags %x\n", mboot->mods_addr);
  debug("[info] Mounting tarfs as root\n");
  vfs_init();
  vfs_mount("/", tarfs_init(tarfs_location));
  vfs_mount("/mnt/tarfs", tarfs_init(tarfs_location));
  vfs_mount("/dev/debug", debug_dev_init());
  keyboard_init();

  fopen("/dev/debug", "w");
  fopen("/dev/debug", "w");
  /* for(;;); */

  /* vfs_mount("/", tarfs_init(tarfs_location)); */
  /* keyboard_init(); */
  /* vfs_mount("/dev/debug", debug_dev_init()); */

  /* fopen("/dev/kbd", "r"); */
  /* fopen("/dev/debug", "w"); */
  /* fopen("/dev/debug", "w"); */

  execve("/bin/init",0,0);

  debug("[status]========================\n");
  debug("[status] Os5 by Thomas Lovén\n");
  debug("[status] Kernel git data: [%s (%s)] %s\n", __kernel_git_hash, (__kernel_git_dirty)?"dirty":"clean", __kernel_git_date);
  debug("[status] %s: %s\n", __kernel_git_branch, __kernel_git_message);
  debug("[status] Kernel compilation: %s %s\n", __kernel_build_date, __kernel_build_time);
  debug("[status]========================\n");

  thread_t *init = new_thread((void(*)(void))current->proc->mm.code_entry,1);
  init->proc = current->proc;

  debug("[status] Kernel booted\n");
  return switch_kernel_thread(0);
}
コード例 #29
0
ファイル: virtio.c プロジェクト: srodrig1/lk
int virtio_mmio_detect(void *ptr, uint count, const uint irqs[])
{
    LTRACEF("ptr %p, count %u\n", ptr, count);

    DEBUG_ASSERT(ptr);
    DEBUG_ASSERT(irqs);
    DEBUG_ASSERT(!devices);

    /* allocate an array big enough to hold a list of devices */
    devices = calloc(count, sizeof(struct virtio_device));
    if (!devices)
        return ERR_NO_MEMORY;

    int found = 0;
    for (uint i = 0; i < count; i++) {
        volatile struct virtio_mmio_config *mmio = (struct virtio_mmio_config *)((uint8_t *)ptr + i * 0x200);
        struct virtio_device *dev = &devices[i];

        dev->index = i;
        dev->irq = irqs[i];

        mask_interrupt(irqs[i]);
        register_int_handler(irqs[i], &virtio_mmio_irq, (void *)dev);

        LTRACEF("looking at magic 0x%x version 0x%x did 0x%x vid 0x%x\n",
                mmio->magic, mmio->version, mmio->device_id, mmio->vendor_id);

        if (mmio->magic != VIRTIO_MMIO_MAGIC) {
            continue;
        }

#if LOCAL_TRACE
        if (mmio->device_id != 0) {
            dump_mmio_config(mmio);
        }
#endif

#if WITH_DEV_VIRTIO_BLOCK
        if (mmio->device_id == 2) { // block device
            LTRACEF("found block device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_block_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);

                // XXX quick test code, remove
#if 0
                uint8_t buf[512];
                memset(buf, 0x99, sizeof(buf));
                virtio_block_read_write(dev, buf, 0, sizeof(buf), false);
                hexdump8_ex(buf, sizeof(buf), 0);

                buf[0]++;
                virtio_block_read_write(dev, buf, 0, sizeof(buf), true);

                virtio_block_read_write(dev, buf, 0, sizeof(buf), false);
                hexdump8_ex(buf, sizeof(buf), 0);
#endif
            }

        }
#endif // WITH_DEV_VIRTIO_BLOCK
#if WITH_DEV_VIRTIO_NET
        if (mmio->device_id == 1) { // network device
            LTRACEF("found net device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_net_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);
            }
        }
#endif // WITH_DEV_VIRTIO_NET
#if WITH_DEV_VIRTIO_GPU
        if (mmio->device_id == 0x10) { // virtio-gpu
            LTRACEF("found gpu device\n");

            dev->mmio_config = mmio;
            dev->config_ptr = (void *)mmio->config;

            status_t err = virtio_gpu_init(dev, mmio->host_features);
            if (err >= 0) {
                // good device
                dev->valid = true;

                if (dev->irq_driver_callback)
                    unmask_interrupt(dev->irq);

                virtio_gpu_start(dev);
            }
        }
#endif // WITH_DEV_VIRTIO_GPU

        if (dev->valid)
            found++;
    }

    return found;
}
コード例 #30
0
static err_t
low_level_init(struct netif *netif)
{
	struct xemac_s *xemac;
	XEmacLite_Config *config;
	XEmacLite *xemaclitep;
	struct xtopology_t *xtopologyp;
	xemacliteif_s *xemacliteif;

	xemaclitep = mem_malloc(sizeof *xemaclitep);
	if (xemaclitep == NULL) {
		LWIP_DEBUGF(NETIF_DEBUG, ("xemacliteif_init: out of memory\r\n"));
		return ERR_MEM;
	}

	xemac = mem_malloc(sizeof *xemac);
	if (xemac == NULL) {
		LWIP_DEBUGF(NETIF_DEBUG, ("xemacliteif_init: out of memory\r\n"));
		return ERR_MEM;
	}

	xemacliteif = mem_malloc(sizeof *xemacliteif);
	if (xemac == NULL) {
		LWIP_DEBUGF(NETIF_DEBUG, ("xemacliteif_init: out of memory\r\n"));
		return ERR_MEM;
	}

	/* obtain pointer to topology structure for this emac */
	xemac->topology_index = xtopology_find_index((unsigned)(netif->state));
	xtopologyp = &xtopology[xemac->topology_index];

	/* obtain config of this emaclite */
	config = xemaclite_lookup_config((unsigned)(netif->state));

	/* maximum transfer unit */
	netif->mtu = XEL_MTU_SIZE;

	/* broadcast capability */
	netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;

	/* initialize the mac */
	XEmacLite_Initialize(xemaclitep, config->DeviceId);
	xemaclitep->NextRxBufferToUse = 0;

#if NO_SYS
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xtopologyp->intc_emac_intr,
			(XInterruptHandler)XEmacLite_InterruptHandler,
			xemaclitep);
#else
#include "xmk.h"
	register_int_handler(xtopologyp->intc_emac_intr,
			(XInterruptHandler)XEmacLite_InterruptHandler,
			xemaclitep);
	enable_interrupt(xtopologyp->intc_emac_intr);
#endif

	/* set mac address */
	XEmacLite_SetMacAddress(xemaclitep, (Xuint8*)(netif->hwaddr));

	/* flush any frames already received */
	XEmacLite_FlushReceive(xemaclitep);

	/* set Rx, Tx interrupt handlers */
	XEmacLite_SetRecvHandler(xemaclitep, (void *)(xemac), xemacif_recv_handler);
	XEmacLite_SetSendHandler(xemaclitep, (void *)(xemac), xemacif_send_handler);

	/* enable Rx, Tx interrupts */
    	XEmacLite_EnableInterrupts(xemaclitep);

#if !NO_SYS
	xemac->sem_rx_data_available = sys_sem_new(0);
#endif

	/* replace the state in netif (currently the base address of emaclite)
	 * with the xemacliteif instance pointer.
	 * this contains a pointer to the config table entry
	 */
	xemac->type = xemac_type_xps_emaclite;
	xemac->state = (void *)xemacliteif;
	netif->state = (void *)xemac;

	xemacliteif->instance = xemaclitep;
	xemacliteif->recv_q = pq_create_queue();
	if (!xemacliteif->recv_q)
		return ERR_MEM;

	xemacliteif->send_q = pq_create_queue();
	if (!xemacliteif->send_q)
		return ERR_MEM;

	return ERR_OK;
}