Exemplo n.º 1
0
int ipc_request_sync_int(int request_id, int param1, int param2, void * ptr)
{
    int ret;
    ret = mutex_lock(ipc_mutex, OS_WAIT_FOREVER);
    if (ret != E_OS_OK) {
        pr_error(LOG_MODULE_MAIN, "Error locking ipc %d", ret);
        return ret;
    }
    uint32_t flag = interrupt_lock();
    ipc_req_sent = 1;
    pr_debug(LOG_MODULE_MAIN, "send request %d from: %p", request_id, &ret);
    while (MBX_CTRL(tx_chan) & 0x80000000) {
        pr_info(LOG_MODULE_MAIN, "Channel busy %d for request: %d msg: %p",
                tx_chan, request_id, param1);
        pr_info(LOG_MODULE_MAIN, "current request: %p msg: %p",
                MBX_CTRL(tx_chan), MBX_DAT0(tx_chan));
    }

    MBX_STS(rx_ack_chan) = 3;

    MBX_DAT0(tx_chan) = request_id;
    MBX_DAT1(tx_chan) = param1;
    MBX_DAT2(tx_chan) = param2;
    MBX_DAT3(tx_chan) = (unsigned int )ptr;
    MBX_CTRL(tx_chan) = 0x80000000 | IPC_MSG_TYPE_SYNC;
    interrupt_unlock(flag);
    while(!MBX_STS(rx_ack_chan)) {
        if (!shared_data->arc_ready) {
            /* Clear tx channel irq */
            MBX_STS(tx_chan) = 3;
            pr_error(LOG_MODULE_MAIN, "ipc slave down");
            ipc_req_sent = 0;
            mutex_unlock(ipc_mutex, NULL);
            return E_OS_ERR_BUSY;
        }
    }
    ret = MBX_DAT0(rx_ack_chan);
    MBX_DAT0(rx_ack_chan) = 0;

    flag = interrupt_lock();
    MBX_STS(rx_ack_chan) = 3;
    ipc_req_sent = 0;
    interrupt_unlock(flag);

    pr_debug(LOG_MODULE_MAIN, "ipc_request_sync returns: [%d] %p", rx_ack_chan, ret);
    mutex_unlock(ipc_mutex, NULL);
    return ret;
}
Exemplo n.º 2
0
/**
 * Send a message on a queue.
 *
 *     Send / queue a message.
 *     This service may panic if err parameter is NULL and:
 *      -# queue parameter is invalid, or
 *      -# the queue is already full, or
 *
 *     Authorized execution levels:  task, fiber, ISR.
 *
 * @param queue: handler on the queue (value returned by queue_create).
 *
 * @param message (in): pointer to the message to send.
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : a message was read
 *          -# E_OS_ERR_OVERFLOW: the queue is full (message was not posted)
 *          -# E_OS_ERR: invalid parameter
 */
void queue_send_message(T_QUEUE queue, T_QUEUE_MESSAGE message, OS_ERR_TYPE* err )
{
    OS_ERR_TYPE _err;
    queue_impl_t * q = (queue_impl_t*) queue;

    /* check input parameters */
    if( queue_used(q) && q->sema != NULL )
    {
        uint32_t it_mask = interrupt_lock();
        _err = add_data(q, message);
        interrupt_unlock(it_mask);

        if(_err == E_OS_OK)
        {
            semaphore_give(q->sema, &_err);  // signal new message in the queue to the listener.
            error_management (err, E_OS_OK);
        }
        else
        {
            error_management (err, _err);
        }
    }
    else
    {   /* param invalid */
        error_management (err, E_OS_ERR);
    }
    return;
}
Exemplo n.º 3
0
void uart_console_input()
{
	unsigned char c;
	/* handle console input. */
	while (UART_POLL_IN(uart_port, &c) != -1) {
		if (c == '\r')
			c = '\n';

		if (c == BACKSPACE) {
			/* print a backspace and a space to erase last char */
			UART_POLL_OUT(uart_port, '\b');
			UART_POLL_OUT(uart_port, ' ');
			if (conchars > 0)
				conline[--conchars] = '\0';
		}
		if (c == '\n') {
			if (conchars > 0) {
				tcmd_console_read(conline, conchars, uart_putc);
				conchars = 0;
			}
		} else {
			if (conchars < CONLINE_SIZE-1) {
				if (c != BACKSPACE) {
					conline[conchars++] = c;
				}
				unsigned int flags = interrupt_lock();
				UART_POLL_OUT(uart_port, c);
				interrupt_unlock(flags);
			}
		}
	}
}
Exemplo n.º 4
0
/**
 * Return the next free block of a pool and
 *   mark it as reserved/allocated.
 *
 * @param pool index of the pool in mpool
 *
 * @return allocated buffer or NULL if none is
 *   available
 */
static void *memblock_alloc(uint32_t pool)
{
    uint16_t block;
    uint32_t flags = interrupt_lock();//irq_lock();

    for (block = 0; block < mpool[pool].count; block++) {
        if (((mpool[pool].track)[block / BITS_PER_U32] & 1 <<
             (BITS_PER_U32 - 1 - (block % BITS_PER_U32))) == 0) {
            (mpool[pool].track)[block / BITS_PER_U32] =
                (mpool[pool].track)[block / BITS_PER_U32] |
                (1 << (BITS_PER_U32 - 1 - (block % BITS_PER_U32)));
#ifdef CONFIG_MEMORY_POOLS_BALLOC_STATISTICS
            mpool[pool].cur = mpool[pool].cur + 1;
#ifdef CONFIG_MEMORY_POOLS_BALLOC_TRACK_OWNER
            /* get return address */
            uint32_t ret_a = (uint32_t)__builtin_return_address(0);
            mpool[pool].owners[block] =
                (uint32_t *)(((ret_a & 0xFFFF0U) >> 4) |
                         ((get_uptime_ms() & 0xFFFF0) << 12));
#endif
            if (mpool[pool].cur > mpool[pool].max)
                mpool[pool].max = mpool[pool].cur;
#endif
            interrupt_unlock(flags);//irq_unlock(flags);
            return (void *)(mpool[pool].start +
                    mpool[pool].size * block);
        }
    }
Exemplo n.º 5
0
void cfw_free(void * ptr, OS_ERR_TYPE * err) {
    int flags = interrupt_lock();
#ifdef TRACK_ALLOCS
    alloc_count--;
#endif
    free(ptr);
    interrupt_unlock(flags);
}
Exemplo n.º 6
0
static void
AtomicSet(ATOMIC *atomic, int val)
{
  interrupt_lock();

  atomic->counter = val;

  interrupt_unlock();
}
Exemplo n.º 7
0
void qrk_aonpt_stop(void)
{
	uint32_t flags = interrupt_lock();
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CFG) = 0;
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CTRL) = (AONPT_CLR | AONPT_RST);
	volatile uint32_t time = get_uptime_32k();
	while(get_uptime_32k() - time < 5);
	interrupt_unlock(flags);
}
Exemplo n.º 8
0
void * cfw_alloc(int size, OS_ERR_TYPE * err) {
    void * ptr;
    unsigned int flags = interrupt_lock();
    ptr = malloc(size+sizeof(void*));
    (*(int*) ptr) = size;
#ifdef TRACK_ALLOCS
    alloc_count++;
#endif
    interrupt_unlock(flags);
    return ptr;
}
Exemplo n.º 9
0
void SPIClass::begin()
{
    /* Protect from a scheduler and prevent transactionBegin*/
    uint32_t flags = interrupt_lock();
    if (!initialized) {
        interruptMode = 0;
        interruptMask[0] = 0;
        interruptMask[1] = 0;
        interruptMask[2] = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
        inTransactionFlag = 0;
#endif
        lsbFirst = false;
        frameSize = SPI_8_BIT;

        /* Set SS to high so a connected chip will be "deselected" by default.
         * TODO - confirm that data register is updated even if pin is set as
         * input. */
        digitalWrite(ss_gpio, HIGH);

        /* When the SS pin is set as OUTPUT, it can be used as
         * a general purpose output port (it doesn't influence
         * SPI operations). */
        pinMode(ss_gpio, OUTPUT);

        /* disable controller */
        SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
		
		/* Enable clock to peripheral */
		MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= enable_val;
		
        /* Configure defaults for clock divider, frame size and data mode */
        SPI_M_REG_VAL(spi_addr, BAUDR) = SPI_CLOCK_DIV4;
        SPI_M_REG_VAL(spi_addr, CTRL0) =
                (frameSize << SPI_FSIZE_SHIFT) | (SPI_MODE0 << SPI_MODE_SHIFT);

        /* Disable interrupts */
        SPI_M_REG_VAL(spi_addr, IMR) = SPI_DISABLE_INT;
        /* Enable at least one slave device (mandatory, though
         * SS signals are unused) */
        SPI_M_REG_VAL(spi_addr, SER) = 0x1;
        /* Enable controller */
        SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;

        /* Set SoC pin mux configuration */
        SET_PIN_MODE(g_APinDescription[MOSI].ulSocPin, SPI_MUX_MODE);
        SET_PIN_MODE(g_APinDescription[MISO].ulSocPin, SPI_MUX_MODE);
        SET_PIN_MODE(g_APinDescription[SCK].ulSocPin,  SPI_MUX_MODE);

    }
    initialized++; /* reference count */
    interrupt_unlock(flags);
}
Exemplo n.º 10
0
void variantAdcInit(void)
{
    uint32_t creg;
    uint32_t saved;

    /* read creg slave to get current Power Mode */
    creg = READ_ARC_REG(AR_IO_CREG_SLV0_OBSR);

    /* perform power up to "Normal mode w/o calibration" cycle if not already there */
    if( (creg & ADC_MODE_MASK) != ADC_NORMAL_WO_CALIB){

        /* Protect AR_IO_CREG_MST0_CTRL using lock and unlock of interruptions */
        saved = interrupt_lock();
        /* Read current CREG master */
        creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL);
        creg &= ~(ADC_MODE_MASK);
        /* request ADC to go to Standby mode */
        creg |= ADC_STANDBY | ADC_CLOCK_GATE;
        WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL);
        interrupt_unlock(saved);
        /* Poll CREG Slave 0 for Power Mode status = requested status */
        while ( (creg = READ_ARC_REG(AR_IO_CREG_SLV0_OBSR) & 0x8) == 0);
        /* Protect AR_IO_CREG_MST0_CTRL using lock and unlock of interruptions */
        saved = interrupt_lock();
        creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL);
        creg &= ~(ADC_MODE_MASK);
        /* request ADC to go to Normal mode w/o calibration */
        creg |= ADC_NORMAL_WO_CALIB | ADC_CLOCK_GATE;
        WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL);
        interrupt_unlock(saved);
        /* Poll CREG Slave 0 for Power Mode status = requested status */
        while ( ((creg = READ_ARC_REG(AR_IO_CREG_SLV0_OBSR)) & 0x8) == 0);
    }

    WRITE_ARC_REG(ADC_CLK_ENABLE | ADC_INT_DSB, ADC_CTRL);
    WRITE_ARC_REG(ADC_CONFIG_SETUP, ADC_SET);
    WRITE_ARC_REG(ADC_CLOCK_RATIO & ADC_CLK_RATIO_MASK, ADC_DIVSEQSTAT);

}
Exemplo n.º 11
0
void SPIClass::end() {
    uint32_t flags = interrupt_lock(); // Protect from a scheduler and prevent transactionBegin
    // Decrease the reference counter
    if (initialized)
        initialized--;
    // If there are no more references disable SPI
    if (!initialized) {
        SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
        MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= DISABLE_SPI_MASTER_1;
#ifdef SPI_TRANSACTION_MISMATCH_LED
        inTransactionFlag = 0;
#endif
    }
    interrupt_unlock(flags);
}
Exemplo n.º 12
0
void * cfw_alloc(int size, OS_ERR_TYPE * err) {
    void * ptr;
    unsigned int flags = interrupt_lock();
    ptr = malloc(size+sizeof(void*));
    if (ptr != NULL) {
        (*(int*) ptr) = size;
#ifdef TRACK_ALLOCS
        alloc_count++;
        pr_info(0, "alloc_count - %d", alloc_count);
#endif
        interrupt_unlock(flags);
        return ptr;
    } else
        return 0;
}
Exemplo n.º 13
0
void ipc_request_notify_panic(int core_id)
{
    uint32_t flags = interrupt_lock();
    if (ipc_req_sent) {
        /* We are interrupting an IPC request, wait for finish */
        while(!MBX_STS(rx_ack_chan));
    }
    MBX_STS(rx_ack_chan) = 3;

    MBX_DAT0(tx_chan) = IPC_PANIC_NOTIFICATION;
    MBX_DAT1(tx_chan) = core_id;
    MBX_CTRL(tx_chan) = 0x80000000 | IPC_MSG_TYPE_SYNC;
    MBX_DAT0(rx_ack_chan) = 0;
    interrupt_unlock(flags);
}
Exemplo n.º 14
0
static int
AtomicCmpXchg(ATOMIC *atomic, int oldval, int newval)
{
  int retval;

  interrupt_lock();

  retval = atomic->counter;
  if (retval == oldval)
    atomic->counter = newval;

  interrupt_unlock();

  return retval;
}
Exemplo n.º 15
0
/**
 * Read a message from a queue.
 *
 *     Read and dequeue a message.
 *     This service may panic if err parameter is NULL and:
 *      -# queue parameter is invalid, or
 *      -# message parameter is NULL, or
 *      -# when called from an ISR.
 *
 *     Authorized execution levels:  task, fiber.
 *
 * @param queue : handler on the queue (value returned by queue_create).
 *
 * @param message (out): pointer to read message.
 *
 * @param timeout: maximum number of milliseconds to wait for the message. Special
 *                values OS_NO_WAIT and OS_WAIT_FOREVER may be used.
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : a message was read
 *          -# E_OS_ERR_TIMEOUT: no message was received
 *          -# E_OS_ERR_EMPTY: the queue is empty
 *          -# E_OS_ERR: invalid parameter
 *          -# E_OS_ERR_NOT_ALLOWED: service cannot be executed from ISR context.
 */
void queue_get_message (T_QUEUE queue, T_QUEUE_MESSAGE* message, int timeout, OS_ERR_TYPE* err)
{
    OS_ERR_TYPE _err;
    T_EXEC_LEVEL execLvl = _getExecLevel();
    queue_impl_t * q = (queue_impl_t*) queue;

    /* check input parameters */
    if( (message == NULL) || (!queue_used(q)) || (q->sema==NULL) || (timeout<OS_WAIT_FOREVER) )
    {
        error_management (err, E_OS_ERR);
        return;
    }

    /* check execution level */
    if ((E_EXEC_LVL_FIBER == execLvl) || (E_EXEC_LVL_TASK == execLvl))
    {
        _err = semaphore_take(q->sema, timeout);
        switch(_err){

        case E_OS_OK:
        {
            uint32_t it_mask = interrupt_lock();
            _err = remove_data(q, message);
            interrupt_unlock(it_mask);
            error_management (err, E_OS_OK);
        }
            break;
        case E_OS_ERR_TIMEOUT:
            error_management (err, E_OS_ERR_TIMEOUT);
            break;
        case E_OS_ERR_BUSY:
            if(err){
                //QUEUE EMPTY, is a common use case, do not panic even if err == NULL
                *err = E_OS_ERR_EMPTY;
            }
            break;
        default:
            //unknown error
            panic(E_OS_ERR_UNKNOWN);
        }
    }
    else
    {
        error_management (err, E_OS_ERR_NOT_ALLOWED);
    }

    return;
}
Exemplo n.º 16
0
void SPIClass::end() {
    /* Protect from a scheduler and prevent transactionBegin */
    uint32_t flags = interrupt_lock();
    /* Decrease the reference counter */
    if (initialized)
        initialized--;
    /* If there are no more references disable SPI */
    if (!initialized) {
        SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
        MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= disable_val;
#ifdef SPI_TRANSACTION_MISMATCH_LED
        inTransactionFlag = 0;
#endif
    }
    interrupt_unlock(flags);
}
Exemplo n.º 17
0
/** Provides a serial buffer transfer implementation for the BMI160 base class
 *  to use for accessing device registers.  This implementation uses the SPI
 *  bus on the Intel Curie module to communicate with the BMI160.
 */
int CurieIMUClass::serial_buffer_transfer(uint8_t *buf, unsigned tx_cnt, unsigned rx_cnt)
{
    int flags, status;

    if (rx_cnt) /* For read transfers, assume 1st byte contains register address */
        buf[0] |= (1 << BMI160_SPI_READ_BIT);

    /* Lock interrupts here to
     * - avoid concurrent access to the SPI bus
     * - avoid delays in SPI transfer due to unrelated interrupts
     */
    flags = interrupt_lock();
    status = ss_spi_xfer(buf, tx_cnt, rx_cnt);
    interrupt_unlock(flags);

    return status;
}
Exemplo n.º 18
0
int _cfw_register_service(service_t * svc)
{
    pr_debug(LOG_MODULE_MAIN, "%s: %p id:%d port: %d\n", __func__, svc, svc->service_id,
            svc->port_id);
    int flags = interrupt_lock();
    if (_find_service(svc->service_id) != -1) {
        interrupt_unlock(flags);
        pr_error(LOG_MODULE_MAIN, "Error: service %d already registered\n",
                svc->service_id);
        return -1;
    }

    _add_service(svc);

    notify_service_avail(svc->service_id);

    interrupt_unlock(flags);
    return 0;
}
Exemplo n.º 19
0
DRIVER_API_RC soc_i2s_stop_stream(void)
{
	uint8_t channel = I2S_CHANNEL_TX;
	uint32_t save;

	if (channel >= I2S_NUM_CHANNELS) 
	{
		return DRV_RC_FAIL;
	} 
	else if (!(i2s_info->en[channel])) 
	{
		return DRV_RC_FAIL;
	}

	save = interrupt_lock();
	i2s_disable(channel);
	interrupt_unlock(save);

	return DRV_RC_OK;
}
Exemplo n.º 20
0
/*******************************************************************************
Name        : stboot_ConfigurePLL
Description : 5510 : Configure the PLL, the clock generators
Parameters  : Frequency
Assumptions :
Limitations :
Returns     : Nothing
*******************************************************************************/
void stboot_ConfigurePLL(U32 Frequency)
{
    /* 5510, 5512 */
    /* Protect access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_lock();

    /* Stop the PLL, and wait 1ms to be sure frequency has fallen down to zero */
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PLL), CKG_PLL_PDM);

    /* Release protection of register access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_unlock();

    /* task_delay must be outside the critical region interrupt_lock/interrupt_unlock */
    task_delay( ST_GetClocksPerSecond() / 1000);

    /* Select I/O clock: PCMCLK is generated internally */
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_CFG),
                       CKG_CFG_PCM_INT | CKG_CFG_MEM_INT | CKG_CFG_AUX_INT);

    /* Set PLL parameters: external 27 MHz PIXCLK, N=2, PLL factor depending on Frequency.
    This action starts the PLL (from power down mode to active mode).
    Then wait for 10ms */
    /*    (0x50 | ((((Frequency * 4) / 27) - 7) & 0xF))*/
    /* Added by HG: + 2 for a better rounding of the value in hex */

    /* Protect access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_lock();

    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PLL), (0x50 | (((((Frequency * 4) + 2) / 27000) - 7) & 0xF)));

    /* Release protection of register access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_unlock();

    /* task_delay must be outside the critical region interrupt_lock/interrupt_unlock */
    task_delay( ST_GetClocksPerSecond() / 100);

    /* Set memory clock divider */
    /* Writing to highest address (last one) latches the new configuration */
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_MCK3), 0x00);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_MCK2), 0x00);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_MCK1), 0x0F);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_MCK0), 0xFE);

    /* Initialize AUXclk with a default value : fvco/6 (why not ?) */
    /* Writing to highest address (last one) latches the new configuration */
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_AUX3), 0x23);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_AUX2), 0x00);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_AUX1), 0x0F);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_AUX0), 0xFE);

    /* Protect access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_lock();

    /* Initialize PCM clock with a dummy value (just to have clock running) */
    /* Writing to highest address (last one) latches the new configuration */
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PCM3), 0x32);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PCM2), 0x00);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PCM1), 0x0F);
    STSYS_WriteRegDev8((void *) (CKG_BASE_ADDRESS + CKG_PCM0), 0xFE);

    /* Release protection of register access to CKG_PLL and CKG_PCM which are also used by STAUD */
    interrupt_unlock();

    /* Enable all clocks. Note the new policy where CFG_CCF.PBO
     (Prevent Bitbuffer Overflow on CD FIFOs) is NOT set, because it
     causes problems with video PTS association. Injection from memory
     must be modified (or PBO turned on) to take care not to overflow
     the bit buffers */
    STSYS_WriteRegDev8((void *) (VIDEO_BASE_ADDRESS + CFG_CCF),
                       CFG_CCF_EAI | /* Enable Audio Interface       */
                       CFG_CCF_EOU | /* Enable Ovf/Udf errors        */
                       CFG_CCF_EC3 | /* Enable Clock 3 = clock1/4    */
                       CFG_CCF_EC2 | /* Enable Clock 2 = clock1/2    */
                       CFG_CCF_ECK | /* Enable Clock 1 = SDRAM clock */
                       CFG_CCF_EDI | /* Enable Display Interface     */
                       CFG_CCF_EVI   /* Enable Video Interface       */
                      );

    /* HG: ??? Video and Audio soft reset (see AN879) */

    /* Wait 1ms for PLL to stabilise */
    task_delay( ST_GetClocksPerSecond() / 1000);
}
Exemplo n.º 21
0
void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t * lock, dwc_irqflags_t * flags)
{
	dwc_irqflags_t f;
	f = interrupt_lock();
	*flags = f;
}
Exemplo n.º 22
0
BOOL stboot_FpgaInit()
{
    BOOL RetErr;
    /* Create array with FPGA program information */
    static const char nrssfpga[] = {
#ifdef STBOOT_SUPPORT_SH4_OVERDRIVE
#include "fpga_sh4.ttf"   /* Output file from Maxplus2 FPGA compiler */
#else
#ifdef HARDWARE_EMULATOR
#include "fpga_he.ttf"    /* Output file from Maxplus2 FPGA compiler */
#else
#include "fpga.ttf"       /* Output file from Maxplus2 FPGA compiler */
#endif
#endif
        ,0,0
    };

    /* Define pointers to FPGA registers */
    volatile unsigned short *fpgaprog  = (volatile unsigned short *)(NRSSFPGA_PROGADDR);
    volatile unsigned short *fpgactrl  = (volatile unsigned short *)(NRSSFPGA_CTRLADDR);
    int i, j;

    RetErr = FALSE;

#ifdef STTBX_PRINT
    printf(" *************************************\n");
    printf(" *****      MB295-B Board        *****\n");
#if defined(ST_7020)
    printf(" ***** WITH    STi7020 IC        *****\n");
#else
    printf(" ***** WITH    STi7015 IC        *****\n");
#endif
#ifdef STBOOT_SUPPORT_SH4_OVERDRIVE
    printf(" ***** WITH    SH4 Overdrive     *****\n");
#else
    printf(" ***** WITHOUT SH4 Overdrive     *****\n");
#ifdef HARDWARE_EMULATOR
    printf(" ***** WITH Hardware Emulator    *****\n");
#else
    printf(" ***** WITHOUT Hardware Emulator *****\n");
#endif
#endif
    printf(" *************************************\n");

    printf("STBOOT_FpgaInit: Starting FPGA programming...\n");
#endif
    /* Reset notCONFIG to set NRSSFPGA into "wait to be programmed" mode      */

    /* CONFIG = "1" */
    STSYS_WriteRegDev16LE(fpgactrl, FPGAnotCONFIG);
    delay(1000);

    /* CONFIG = "0" */
    STSYS_WriteRegDev16LE(fpgactrl, 0);
    delay(1000);

    /* CONFIG = "1" */
    STSYS_WriteRegDev16LE(fpgactrl, FPGAnotCONFIG);
    delay(1000);

    /* Waiting for notSTATUS to go high - ready to be programmed */
    while ( (STSYS_ReadRegDev16LE(fpgactrl) & FPGAnotSTATUS)==0)
    {
#ifdef STTBX_PRINT
        printf(".\n");
#endif
    }

    /* Copying data to NRSSFPGA */
    for (i = 0; i < sizeof(nrssfpga); i++)
    {
        for (j=0; j<8; j++)
        {
            /* Copy array to FPGA - bit at a time */
            STSYS_WriteRegDev16LE(fpgaprog, ((nrssfpga[i] >> j) & 0x01));
        }
    }

    /* Waiting for CONFDONE to go high - means the program is complete    */
    while ( (STSYS_ReadRegDev16LE(fpgactrl) & FPGA_CONFDONE)==0)
    {
        STSYS_WriteRegDev16LE(fpgaprog, 0);
    }

    /* Clock another 10 times - gets the device into a working state */
    for (i=0; i<10; i++)
    {
        STSYS_WriteRegDev16LE(fpgaprog, 0);
    }

    /* Now should be ready to use */
#ifdef STTBX_PRINT
    printf("STBOOT_FpgaInit: FPGA programming completed.\n");
#endif

    return RetErr;
} /*STBOOT_FpgaInit () */
#endif

/************************************************************************
 * Put all resets high in the EPLD.
 * Return : TRUE if error, FALSE if no.
 ************************************************************************/
BOOL stboot_EpldInit()
{
#if defined(mb295)
#if ((defined STTBX_PRINT) || (FPGA_ENABLETEST == TRUE))
    volatile unsigned short *fpgaident = (volatile unsigned short *)(FPGA_IDENTADDR);
#endif
    volatile unsigned short *fpgamode  = (volatile unsigned short *)(0x7043C010);
    BOOL RetErr;

    RetErr = FALSE;

    interrupt_lock();   /* Prevent any glitch on IRQ lines */

#ifdef STTBX_PRINT
    printf("stboot_EpldInit: Raising EPLD resets");
#endif
    STSYS_WriteRegDev16LE(0x70414000, 0x1);  /* SAA7114 reset */
    STSYS_WriteRegDev16LE(0x7041C000, 0x1);  /* Audio reset */
    STSYS_WriteRegDev16LE(0x70420000, 0x1);  /* Tuner reset */
    STSYS_WriteRegDev16LE(0x70424000, 0x1);  /* ATAPI reset */
#ifdef STTBX_PRINT
    printf(" OK\n");

    printf("stboot_EpldInit: Resetting FPGA... ");
#endif
    STSYS_WriteRegDev16LE(0x70428000, 0x1);    /* FPGA reset low */
#ifdef STTBX_PRINT
    printf("OK\n");

    printf("stboot_EpldInit: Enabling MemWait... ");
#endif
    STSYS_WriteRegDev16LE(0x70424000, 0x3);  /* ATAPI reset + MemWaitEn */
#ifdef STTBX_PRINT
    printf("OK\n");

    /* Read the FPGA Ident register */
    printf("stboot_EpldInit: FPGA Identity: %x\n", *fpgaident);
#endif

#ifdef STBOOT_SUPPORT_SH4_OVERDRIVE
    STSYS_WriteRegDev16LE(0x70430000, 0x1);     /* DMA used */
#else
    STSYS_WriteRegDev16LE(0x70430000, 0x0);     /* DMA not used */
#endif

    /* Write default values */
#ifdef HARDWARE_EMULATOR
    *fpgamode = 0x00;   /* SH4 not used, CD clock out disable */
#else
#ifdef STBOOT_SUPPORT_SH4_OVERDRIVE
    *fpgamode = 0x09;   /* SH4 used, CD clock out enable */
#else
    *fpgamode = 0x08;   /* SH4 not used, CD clock out disable */
#endif
#endif /* HARDWARE_EMULATOR */
#ifdef STTBX_PRINT
    if (*fpgamode != 0x4321)
    {
        printf("stboot_EpldInit: FPGA Mode: %x (SH4%sUsed, CD clock output %s)\n",
               *fpgamode,
               (*fpgamode & 0x1) ? " " : " not ",
               (*fpgamode & 0x8) ? "enabled" : "disabled");
    }
    else
    {
        printf("STBOOT_EpldInit: Simplified FPGA");
    }
#endif
    STSYS_WriteRegDev16LE(0x70400000, 0x10); /* Clock control: enable CD clk only */

    /* ICS9161 enables:
     * 0x10: enable CD clk
     * 0x20: enable USRCLK1, USRCLK2
     * 0x40: enable USRCLK3, PIXCLK, RCLK2, PCMCLK
     */
#if defined(ST_7020)
    STSYS_WriteRegDev16LE(0x70400000, 0x50);    /* Clock control: enable CD clk, USRCLK2, PIXCLK */
#elif defined(ST_7015)
    STSYS_WriteRegDev16LE(0x70400000, 0x10);    /* Clock control: enable CD clk only */
#else
#error ERROR:invalid DVD_BACKEND defined
#endif

    /* Wait for CD_CLOCK before setting HardReset high */
    task_delay(ST_GetClocksPerSecond()/2);

    STSYS_WriteRegDev16LE(0x70418000, 0x1);  /* STi7020 reset */
    interrupt_unlock();

#if (FPGA_ENABLETEST == TRUE)
    /* Check if FPGA has been well programed */
    if (STSYS_ReadRegDev16LE(fpgaident) != 0x4321)
    {
#ifdef STTBX_PRINT
        printf("stboot_EpldInit: Bad FPGA, Identity check failed !\n");
#endif
        RetErr = TRUE;
    }
#endif

#if (FPGA_ENABLETEST == TRUE)
    if (RetErr == FALSE)
    {
        /* Check if FPGA allow a correct access to 7015/20 */
        U32 Tmp;

        /* This register does not exist should return 0x1B4 */
        if ((Tmp = STSYS_ReadRegDev32LE(0x60002298)) != 0x1B4)
        {
#ifdef STTBX_PRINT
            printf("STBOOT_FpgaInit: Failed to access to 70xx register read 0x%08x expected 0x%08x.\n", Tmp, 0x1B4);
#endif
            /* If here, fpga found a register where there is not !!!!      */
            RetErr = TRUE;
        }

        /* This register is the IDCOD of the 7015/20, should be constant      */
        if ((Tmp = STSYS_ReadRegDev32LE(0x600001f8)) != IDCOD)
        {
#ifdef STTBX_PRINT
            printf("STBOOT_FpgaInit: Failed to access to 70xx register read 0x%08x expected 0x%08x.\n",
                   Tmp, IDCOD);
#endif
            RetErr = TRUE;
        }
    }
#endif /* (FPGA_ENABLETEST == TRUE) */

    return RetErr;

    /* -------- */

#elif defined(mb290) /* end defined(mb295), now defined(mb295) */

#define ResetReg0setADDR          0x60300000
#define ResetReg0clrADDR          0x60400000
#define ResetReg1setADDR          0x60600000
#define ResetReg1clrADDR          0x60700000
#define cHDMuxRegaddr             0x60D00000
#define DviInPowerDownADDR        0x60F00000

    interrupt_lock();	/* Prevent any glitch on IRQ lines */

#ifdef STTBX_PRINT
    printf("InitEPLD: Raising EPLD resets");
#endif
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x40);     /* SAA7114 enable */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x30);     /* AudioDACs and AudioMux enable */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x04);     /* SIL168 enable */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg1clrADDR, 0x04);     /* SIL159 enable */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(DviInPowerDownADDR, 0x01);   /* SIL159 powerdown */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x01);     /* GS9020 enable */
#ifdef STTBX_PRINT
    printf(".");
#endif
    /* Ensure that the HDIN input mux is active and that the HDIN clock (HDCKI)
      is driven during reset. Without this, the output of the HD mux is
      tri-stated, which can cause problems during 7020 reset */

    STSYS_WriteRegDev8(ResetReg0setADDR, 0x08);     /* HDin Mux enable */
    STSYS_WriteRegDev8(cHDMuxRegaddr   , 0x03);     /* HDin Mux select input */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg1setADDR, 0x0A);     /* IO_STEM and STEM reset high */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg1setADDR, 0x90);     /* SPDIF and TUNER reset high */
#ifdef STTBX_PRINT
    printf(".");
#endif
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x80);     /* STi7015/20 Reset */
    STSYS_WriteRegDev8(ResetReg0clrADDR, 0x80);
    STSYS_WriteRegDev8(ResetReg0clrADDR, 0x80);     /* hold reset low for at least 2 microseconds */
    STSYS_WriteRegDev8(ResetReg0clrADDR, 0x80);     /* (each write is about 800 ns) */
    STSYS_WriteRegDev8(ResetReg0setADDR, 0x80);
#ifdef STTBX_PRINT
    printf(" Ok\n");
#endif

    interrupt_unlock();

    return FALSE;

    /* -------- */


#elif defined(mb376) /* end defined(mb290), now defined(mb376) */

    interrupt_lock();	/* Prevent any glitch on IRQ lines */

#ifdef STTBX_PRINT
    printf(" Enabling interrupts through FPGA ...");
#endif

    /* MASK 0 Line 5 from STEM int 0 only */
    STSYS_WriteRegDev8((void *)0x420c0000, 0x20);
    /* MASK 1 Nothing */
    STSYS_WriteRegDev8((void *)0x42100000, 0x00);


#ifdef STTBX_PRINT
    printf(" Ok\n");
#endif

    interrupt_unlock();

    return FALSE;

#else
#error ERROR: Invalid DVD_PLATFORM defined
#endif
} /* stboot_EpldInit () */
Exemplo n.º 23
0
void internal_handle_message(struct cfw_message * msg, void * param)
{
    int free_msg = 1; /* by default free message */
    switch (CFW_MESSAGE_ID(msg))
        {
    case MSG_ID_CFW_ALLOC_PORT:
        {
            //TODO: Enable this, currently relies on sync IPC API.
            //_port_t * port = cfw_port_alloc(NULL);
            //cfw_port_set_handler(port, send_message_ipc, NULL);
            break;
        }

    case MSG_ID_CFW_OPEN_SERVICE:
        {
            cfw_open_conn_req_msg_t * req = (cfw_open_conn_req_msg_t *) msg;
            service_t * svc = cfw_get_service(req->service_id);
            if (svc == NULL) {
                pr_error(LOG_MODULE_MAIN, "try to open non registered service %d", req->service_id);
                cfw_open_conn_rsp_msg_t * resp =
                        (cfw_open_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_OPEN_SERVICE, sizeof(*resp));
                resp->rsp_header.status = E_OS_ERR_UNKNOWN;
                cfw_send_message(resp);
                break;
            }
            uint8_t svc_cpu_id = port_get_cpu_id(svc->port_id);
            if (svc_cpu_id != get_cpu_id()) {
#ifdef INFRA_MULTI_CPU_SUPPORT
                pr_debug(LOG_MODULE_MAIN, "forward open service to proxy");
                CFW_MESSAGE_DST(msg) = proxies[svc_cpu_id].port_id;
                cfw_send_message(msg);
                free_msg = 0; /* the lower layers will free it! */
#else
                pr_error(LOG_MODULE_MAIN, "incorrect cpu_id settings, single cpu!");
#endif
            } else {
                conn_handle_t * conn_handle;

                conn_handle = (conn_handle_t *) balloc(sizeof(*conn_handle),
                        NULL );
                conn_handle->client_port = CFW_MESSAGE_SRC(msg);
                conn_handle->priv_data = NULL;
                conn_handle->svc = svc;
                conn_handle->client_handle = req->client_handle;
                /* For OPEN_SERVICE, conn is not know yet, it is just alloc'ed.
                 * set it here.*/
                req->header.conn = conn_handle;
                if (svc->client_connected != NULL &&
                        svc_cpu_id == get_cpu_id())
                    svc->client_connected(conn_handle);
                cfw_open_conn_rsp_msg_t * resp =
                        (cfw_open_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_OPEN_SERVICE, sizeof(*resp));
                resp->port = svc->port_id;
                resp->cpu_id = svc_cpu_id;
#ifdef SVC_MANAGER_DEBUG
                pr_debug(LOG_MODULE_CFW, "OPEN_SERVICE: %d, svc:%p port:%d", req->service_id,
                        svc, svc->port_id);
#endif
                resp->svc_server_handle = conn_handle;
                resp->client_handle = req->client_handle;
                cfw_send_message(resp);
            }
            break;
        }

    case MSG_ID_CFW_CLOSE_SERVICE:
        {
            cfw_close_conn_req_msg_t * req = (cfw_close_conn_req_msg_t*) msg;
            service_t * svc = cfw_get_service(req->service_id);
            if (svc == NULL) {
                pr_debug(LOG_MODULE_MAIN, "try close unregistered service %d",
                         req->service_id);
                cfw_close_conn_rsp_msg_t * resp =
                        (cfw_close_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                MSG_ID_CFW_CLOSE_SERVICE, sizeof(*resp));
                resp->rsp_header.status = E_OS_ERR_UNKNOWN;
                cfw_send_message(resp);
                break;
            }
            uint8_t svc_cpu_id = port_get_cpu_id(svc->port_id);
            if (svc_cpu_id != get_cpu_id()) {
#ifdef INFRA_MULTI_CPU_SUPPORT
                CFW_MESSAGE_DST(msg) = proxies[svc_cpu_id].port_id;
                cfw_send_message(msg);
                free_msg=0;
#else
                pr_error(LOG_MODULE_MAIN, "incorrect cpu_id!");
#endif
            } else {
                cfw_close_conn_rsp_msg_t * resp =
                            (cfw_close_conn_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                                    MSG_ID_CFW_CLOSE_SERVICE, sizeof(*resp));
                conn_handle_t * conn = (conn_handle_t*) msg->conn;
                if (conn != NULL && conn->svc != NULL
                        && conn->svc->client_disconnected != NULL )
                    conn->svc->client_disconnected(conn);
                cfw_send_message(resp);
                /* Free server-side conn */
                bfree(conn);
            }
            break;
        }

    case MSG_ID_CFW_REGISTER_EVT:
        {
            int * params = (int *) &msg[1];
            int i;
            for (i = 0; i < params[0]; i++) {
                _cfw_register_event((conn_handle_t*) msg->conn, params[i + 1]);
            }
            cfw_register_evt_rsp_msg_t * resp =
                    (cfw_register_evt_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                            MSG_ID_CFW_REGISTER_EVT, (sizeof(*resp)));
            conn_handle_t * conn = (conn_handle_t*) msg->conn;
            if (conn != NULL && conn->svc != NULL
                    && conn->svc->registered_events_changed != NULL )
                conn->svc->registered_events_changed(conn);

            cfw_send_message(resp);
            break;
        }

    case MSG_ID_CFW_REGISTER_SVC_AVAIL:
        {
            bool already_avail = true;
            cfw_register_svc_avail_req_msg_t * req =
                    (cfw_register_svc_avail_req_msg_t *) msg;
            int flags = interrupt_lock();
            if (_find_service(req->service_id) == -1) {
                add_service_avail_listener(CFW_MESSAGE_SRC(msg),
                        req->service_id, msg->priv);
                already_avail = false;
            }
            interrupt_unlock(flags);
            cfw_register_svc_avail_rsp_msg_t * resp =
                (cfw_register_svc_avail_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
                        MSG_ID_CFW_REGISTER_SVC_AVAIL, (sizeof(*resp)));
            cfw_send_message(resp);
            if (already_avail) {
                send_service_avail_evt(req->service_id, CFW_MESSAGE_SRC(msg), msg->priv);
            }
            break;
        }

    default:
        pr_warning(LOG_MODULE_CFW, "%s: unhandled message id: %x", __func__, CFW_MESSAGE_ID(msg));
        break;
        }
    if (free_msg)
        cfw_msg_free(msg);
}
Exemplo n.º 24
0
static void LockResource(ULONG ulHandle)
{
  interrupt_lock();
}