text: #include <common.h>
  #include <ns16550.h>
  #include "short_types.h"
  #include "memio.h"
  #include "articiaS.h"
  
  DECLARE_GLOBAL_DATA_PTR;
  
  #ifndef CONFIG_SYS_NS16550
  static uint32 ComPort1;
  
  uint16 SerialEcho = 1;
  
  
  #define RECEIVER_HOLDING 0
  #define TRANSMITTER_HOLDING 0
  #define INTERRUPT_ENABLE 1
  #define INTERRUPT_STATUS 2
  #define FIFO_CONTROL 2
  #define LINE_CONTROL 3
  #define MODEM_CONTROL 4
  #define LINE_STATUS 5
  #define MODEM_STATUS 6
  #define SCRATCH_PAD 7
  
  #define DIVISOR_LATCH_LSB 0
  #define DIVISOR_LATCH_MSB 1
  #define PRESCALER_DIVISION 5
  
  #define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte)
  #define COM_READ_BYTE(reg) in_byte((ComPort1+reg))
  
  static int serial_init_done = 0;
  
  void serial_init (void)
  {
  #if 0
  	uint32 clock_divisor = 115200 / baudrate;
  	uint8 cfg;
  	uint8 a;
  	uint16 devfn = 7 << 3;
  
  	if (serial_init_done)
  		return;
  
  	/*  Enter configuration mode */
  	cfg = pci_read_cfg_byte (0, devfn, 0x85);
  	pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02);
  
  	/* Set serial port COM1 as 3F8 */
  	out_byte (0x3F0, 0xE7);
  	out_byte (0x3f1, 0xfe);
  
  	/* Set serial port COM2 as 2F8 */
  	out_byte (0x3f0, 0xe8);
  	out_byte (0x3f1, 0xeb);
  
  	/* Enable */
  	out_byte (0x3f0, 0xe2);
  	a = in_byte (0x3f1);
  	a |= 0xc;
  	out_byte (0x3f0, 0xe2);
  	out_byte (0x3f1, a);
  
  	/*  Reset the configuration mode */
  	pci_write_cfg_byte (0, devfn, 0x85, cfg);
  #endif
  
  	ComPort1 = 0x3F8;
  
  	/*  Disable interrupts */
  	COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00);
  
  	/*  Set baud rate */
  	/* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */
  	/* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */
  	/* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */
  	/* __asm__("eieio"); */
  
  	/*  Set 8-N-1 */
  	COM_WRITE_BYTE (LINE_CONTROL, 0x03);
  	__asm__ ("eieio");
  
  	/*  Disable FIFO */
  	COM_WRITE_BYTE (MODEM_CONTROL, 0x03);
  	COM_WRITE_BYTE (FIFO_CONTROL, 0x07);
  
  	__asm__ ("eieio");
  	serial_init_done = 1;
  }
  
  extern int console_changed;
  
  void serial_putc (const char sendme)
  {
  	if (sendme == '\n') {
  		while ((in_byte (0x3FD) & 0x40) == 0);
  		out_byte (0x3f8, 0x0D);
  	}
  
  	while ((in_byte (0x3FD) & 0x40) == 0);
  	out_byte (0x3f8, sendme);
  }
  
  int serial_getc (void)
  {
  #if 0
  	uint8 c;
  
  	for (;;) {
  		uint8 x = in_byte (0x3FD);
  
  		if (x & 0x01)
  			break;
  
  		if (x & 0x0C)
  			out_byte (0x3fd, 0x0c);
  	}
  
  	c = in_byte (0x3F8);
  
  	return c;
  #else
  	while ((in_byte (0x3FD) & 0x01) == 0) {
  		if (console_changed != 0) {
  			printf ("Console changed\n");
  			console_changed = 0;
  			return 0;
  		}
  	}
  	return in_byte (0x3F8);
  #endif
  }
  
  int serial_tstc (void)
  {
  	return (in_byte (0x03FD) & 0x01) != 0;
  }
  
  void serial_debug_putc (int c)
  {
  	serial_puts ("DBG");
  	serial_putc (c);
  	serial_putc (0x0d);
  	serial_putc (0x0A);
  }
  
  #else
  
  const NS16550_t Com0 = (NS16550_t) CONFIG_SYS_NS16550_COM1;
  const NS16550_t Com1 = (NS16550_t) CONFIG_SYS_NS16550_COM2;
  
  int serial_init (void)
  {
  	uint32 clock_divisor = 115200 / gd->baudrate;
  
  	NS16550_init (Com0, clock_divisor);
  	/* NS16550_reinit(Com1, clock_divisor); */
  	/* serial_puts("COM1: 3F8h initalized"); */
  
  	return (0);
  }
  
  #if 0
  void serial_putc (const char c)
  {
  	NS16550_putc (Com0, c);
  	if (c == '\n')
  		NS16550_putc (Com0, 0x0D);
  }
  
  int serial_getc (void)
  {
  	return (int) NS16550_getc (Com0);
  }
  
  int serial_tstc (void)
  {
  	return NS16550_tstc (Com0);
  }
  #else
  void serial_putc (const char sendme)
  {
  	if (sendme == '\n') {
  		while ((in_byte (0x3FD) & 0x40) == 0);
  		out_byte (0x3f8, 0x0D);
  	}
  
  	while ((in_byte (0x3FD) & 0x40) == 0);
  	out_byte (0x3f8, sendme);
  }
  
  
  extern int console_changed;
  
  int serial_getc (void)
  {
  #if 0
  	uint8 c;
  
  	for (;;) {
  		uint8 x = in_byte (0x3FD);
  
  		if (x & 0x01)
  			break;
  
  		if (x & 0x0C)
  			out_byte (0x3fd, 0x0c);
  	}
  
  	c = in_byte (0x3F8);
  
  	return c;
  #else
  	while ((in_byte (0x3FD) & 0x01) == 0) {
  		if (console_changed != 0) {
  			console_changed = 0;
  			return 0;
  		}
  	}
  
  	return in_byte (0x3F8);
  #endif
  }
  
  int serial_tstc (void)
  {
  	return (in_byte (0x03FD) & 0x01) != 0;
  }
  #endif
  
  #endif
  
  void serial_puts (const char *string)
  {
  	while (*string)
  		serial_putc (*string++);
  }
  
  void serial_setbrg (void)
  {
  	uint32 clock_divisor = 115200 / gd->baudrate;
  
  	NS16550_init (Com0, clock_divisor);
  }
  