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;
|
}
|
}
|
}
|
}
|