OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [peripheral/] [16450.c] - Diff between revs 1308 and 1350

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1308 Rev 1350
Line 29... Line 29...
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
 
 
 
#include "config.h"
 
 
 
#ifdef HAVE_INTTYPES_H
 
#include <inttypes.h>
 
#endif
 
 
 
#include "port.h"
 
#include "arch.h"
#include "abstract.h"
#include "abstract.h"
#include "16450.h"
#include "16450.h"
#include "sim-config.h"
#include "sim-config.h"
#include "pic.h"
#include "pic.h"
#include "vapi.h"
#include "vapi.h"
Line 68... Line 76...
 
 
  return char_clks * bauds_per_char;
  return char_clks * bauds_per_char;
}
}
 
 
/* Set a specific UART register with value. */
/* Set a specific UART register with value. */
void uart_write_byte(unsigned long addr, unsigned long value)
void uart_write_byte(oraddr_t addr, uint32_t value)
{
{
  int chipsel;
  int chipsel;
 
 
  debug(4, "uart_write_byte(%x,%02x)\n", addr, (unsigned)value);
  debug(4, "uart_write_byte(%"PRIxADDR",%02"PRIx32")\n", addr, value);
 
 
  for(chipsel = 0; chipsel < MAX_UARTS; chipsel++)
  for(chipsel = 0; chipsel < MAX_UARTS; chipsel++)
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
      break;
      break;
  if (chipsel >= MAX_UARTS) return;
  if (chipsel >= MAX_UARTS) return;
Line 143... Line 151...
      debug(1, "write out of range (addr %x)\n", addr);
      debug(1, "write out of range (addr %x)\n", addr);
  }
  }
}
}
 
 
/* Read a specific UART register. */
/* Read a specific UART register. */
unsigned long uart_read_byte(unsigned long addr)
uint32_t uart_read_byte(oraddr_t addr)
{
{
  unsigned char value = 0;
  uint8_t value = 0;
  int chipsel;
  int chipsel;
 
 
  debug(4, "uart_read_byte(%x)", addr);
  debug(4, "uart_read_byte(%"PRIxADDR")", addr);
 
 
  for(chipsel = 0; chipsel < MAX_UARTS; chipsel++)
  for(chipsel = 0; chipsel < MAX_UARTS; chipsel++)
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
    if ((addr & ~(UART_ADDR_SPACE-1)) == config.uarts[chipsel].baseaddr)
      break;
      break;
 
 
Line 161... Line 169...
 
 
  if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
  if (uarts[chipsel].regs.lcr & UART_LCR_DLAB) {
    switch (addr % UART_ADDR_SPACE) {
    switch (addr % UART_ADDR_SPACE) {
      case UART_DLL:
      case UART_DLL:
        value = uarts[chipsel].regs.dll;
        value = uarts[chipsel].regs.dll;
        debug(4, "= %x\n", value);
        debug(4, "= %"PRIx8"\n", value);
        return value;
        return value;
      case UART_DLH:
      case UART_DLH:
        value = uarts[chipsel].regs.dlh;
        value = uarts[chipsel].regs.dlh;
        debug(4, "= %x\n", value);
        debug(4, "= %"PRIx8"\n", value);
        return value;
        return value;
    }
    }
  }
  }
 
 
  switch (addr % UART_ADDR_SPACE) {
  switch (addr % UART_ADDR_SPACE) {
Line 221... Line 229...
      break;
      break;
    case UART_SCR:
    case UART_SCR:
      value = uarts[chipsel].regs.scr;
      value = uarts[chipsel].regs.scr;
      break;
      break;
    default:
    default:
      debug(1, "read out of range (addr %x)\n", addr);
      debug(1, "read out of range (addr %"PRIxADDR")\n", addr);
  }
  }
  debug(4, " = %x\n", value);
  debug(4, " = %"PRIx8"\n", value);
  return value;
  return value;
}
}
 
 
/* Function that handles incoming VAPI data.  */
/* Function that handles incoming VAPI data.  */
void uart_vapi_read (unsigned long id, unsigned long data)
void uart_vapi_read (unsigned long id, unsigned long data)
{
{
  int uart;
  int uart;
  debug(4, "UART: id %08x, data %08x\n", id, data);
  debug(4, "UART: id %08lx, data %08lx\n", id, data);
  uart = id & VAPI_DEVICE_ID;
  uart = id & VAPI_DEVICE_ID;
  uarts[uart].vapi_buf[uarts[uart].vapi_buf_head_ptr] = data;
  uarts[uart].vapi_buf[uarts[uart].vapi_buf_head_ptr] = data;
  uarts[uart].vapi_buf_head_ptr = (uarts[uart].vapi_buf_head_ptr + 1) % UART_VAPI_BUF_LEN;
  uarts[uart].vapi_buf_head_ptr = (uarts[uart].vapi_buf_head_ptr + 1) % UART_VAPI_BUF_LEN;
  if (uarts[uart].vapi_buf_tail_ptr == uarts[uart].vapi_buf_head_ptr) {
  if (uarts[uart].vapi_buf_tail_ptr == uarts[uart].vapi_buf_head_ptr) {
    fprintf (stderr, "FATAL: uart VAPI buffer to small.\n");
    fprintf (stderr, "FATAL: uart VAPI buffer to small.\n");
Line 243... Line 251...
  }
  }
}
}
 
 
static void send_char (int uart, int bits_send)
static void send_char (int uart, int bits_send)
{
{
  PRINTF ("%c", uarts[uart].iregs.txser);
  PRINTF ("%c", (char)uarts[uart].iregs.txser);
  debug(4, "TX \'%c\' via UART%d...\n", uarts[uart].iregs.txser, uart);
  debug(4, "TX \'%c\' via UART%d...\n", (char)uarts[uart].iregs.txser, uart);
  if (uarts[uart].regs.mcr & UART_MCR_LOOP)
  if (uarts[uart].regs.mcr & UART_MCR_LOOP)
    uarts[uart].iregs.loopback = uarts[uart].iregs.txser;
    uarts[uart].iregs.loopback = uarts[uart].iregs.txser;
  else {
  else {
    /* Send to either VAPI or to file */
    /* Send to either VAPI or to file */
    if (config.uarts[uart].vapi_id) {
    if (config.uarts[uart].vapi_id) {
Line 305... Line 313...
        fe |= ((packet >> (nbits++)) & 1) ^ 1;
        fe |= ((packet >> (nbits++)) & 1) ^ 1;
 
 
      debug (4, "lcr vapi %02x, uart %02x\n", uarts[uart].vapi.lcr, uarts[uart].regs.lcr);
      debug (4, "lcr vapi %02x, uart %02x\n", uarts[uart].vapi.lcr, uarts[uart].regs.lcr);
      data |= (uarts[uart].vapi.lcr << 8) | (pe << 16) | (fe << 17) | (uarts[uart].vapi.lcr << 8);
      data |= (uarts[uart].vapi.lcr << 8) | (pe << 16) | (fe << 17) | (uarts[uart].vapi.lcr << 8);
      PRINTF ("vapi_send (%08lx, %08x)\n", config.uarts[uart].vapi_id, data);
      PRINTF ("vapi_send (%08lx, %08x)\n", config.uarts[uart].vapi_id, data);
      debug (4, "vapi_send (%08x, %08x)\n", config.uarts[uart].vapi_id, data);
      debug (4, "vapi_send (%08lx, %08x)\n", config.uarts[uart].vapi_id, data);
      vapi_send (config.uarts[uart].vapi_id, data);
      vapi_send (config.uarts[uart].vapi_id, data);
    } else {
    } else {
      char buffer[1] = { uarts[uart].iregs.txser & 0xFF };
      char buffer[1] = { uarts[uart].iregs.txser & 0xFF };
      channel_write(channels[uart], buffer, 1);
      channel_write(channels[uart], buffer, 1);
    }
    }
Line 422... Line 430...
  } else {
  } else {
    if (uarts[i].istat.rxser_full) {
    if (uarts[i].istat.rxser_full) {
      if (uarts[i].char_clks <= uarts[i].istat.rxser_clks++) {
      if (uarts[i].char_clks <= uarts[i].istat.rxser_clks++) {
        /* Set unused character bits to zero and allow lsr register in fifo */
        /* Set unused character bits to zero and allow lsr register in fifo */
        uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1) | 0xff00;
        uarts[i].iregs.rxser &= ((1 << ((uarts[i].regs.lcr & 3) + 5)) - 1) | 0xff00;
        debug(4, "Receiving 0x%02x'%c' via UART%d...\n", uarts[i].iregs.rxser,
        debug(4, "Receiving 0x%02lx'%c' via UART%d...\n", uarts[i].iregs.rxser,
              uarts[i].iregs.rxser, i);
              (char)uarts[i].iregs.rxser, i);
        PRINTF ("%c", uarts[i].iregs.rxser);
        PRINTF ("%c", (char)uarts[i].iregs.rxser);
        uarts[i].istat.rxser_full = 0;
        uarts[i].istat.rxser_full = 0;
        uarts[i].istat.rxser_clks = 0;
        uarts[i].istat.rxser_clks = 0;
        uart_add_char (i, uarts[i].iregs.rxser);
        uart_add_char (i, uarts[i].iregs.rxser);
      }
      }
    }
    }
Line 460... Line 468...
      /* do not handle commands while receiving */
      /* do not handle commands while receiving */
      if (uarts[i].istat.rxser_full) return;
      if (uarts[i].istat.rxser_full) return;
      while (!received) {
      while (!received) {
        if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
        if (uarts[i].vapi_buf_head_ptr != uarts[i].vapi_buf_tail_ptr) {
          unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
          unsigned long data = uarts[i].vapi_buf[uarts[i].vapi_buf_tail_ptr];
          debug(4, "Handling: %08x (%i,%i)\n", data, uarts[i].vapi_buf_head_ptr, uarts[i].vapi_buf_tail_ptr);
          debug(4, "Handling: %08lx (%i,%i)\n", data, uarts[i].vapi_buf_head_ptr, uarts[i].vapi_buf_tail_ptr);
          uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % UART_VAPI_BUF_LEN;
          uarts[i].vapi_buf_tail_ptr = (uarts[i].vapi_buf_tail_ptr + 1) % UART_VAPI_BUF_LEN;
          switch (data >> 24) {
          switch (data >> 24) {
            case 0x00:
            case 0x00:
              uarts[i].vapi.lcr = (data >> 8) & 0xff;
              uarts[i].vapi.lcr = (data >> 8) & 0xff;
              /* Put data into rx fifo */
              /* Put data into rx fifo */
Line 495... Line 503...
            case 0x04:
            case 0x04:
              uarts[i].vapi.next_break_cnt = data & 0xffff;
              uarts[i].vapi.next_break_cnt = data & 0xffff;
              uarts[i].vapi.next_break = (data >> 16) & 1;
              uarts[i].vapi.next_break = (data >> 16) & 1;
              break;
              break;
            default:
            default:
              debug (0, "WARNING: Invalid vapi command %02x\n", data >> 24);
              debug (0, "WARNING: Invalid vapi command %02lx\n", data >> 24);
              break;
              break;
          }
          }
        } else break;
        } else break;
      }
      }
    }
    }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.