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; }
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); }
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, ðernetif_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; }
/* _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 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); }
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; }
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; }
/* 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); } }
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; }
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 }
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 }
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); }
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); }
/* * 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; }
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); }
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); }
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; }
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; }
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; }
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); }
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); }
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); }
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); }
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; }
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]); }
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); }
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); }
/* * 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; }
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); }
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; }
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; }