serial.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include <common.h>
  2. #include <ns16550.h>
  3. #include "short_types.h"
  4. #include "memio.h"
  5. #include "articiaS.h"
  6. DECLARE_GLOBAL_DATA_PTR;
  7. #ifndef CFG_NS16550
  8. static uint32 ComPort1;
  9. uint16 SerialEcho = 1;
  10. #define RECEIVER_HOLDING 0
  11. #define TRANSMITTER_HOLDING 0
  12. #define INTERRUPT_ENABLE 1
  13. #define INTERRUPT_STATUS 2
  14. #define FIFO_CONTROL 2
  15. #define LINE_CONTROL 3
  16. #define MODEM_CONTROL 4
  17. #define LINE_STATUS 5
  18. #define MODEM_STATUS 6
  19. #define SCRATCH_PAD 7
  20. #define DIVISOR_LATCH_LSB 0
  21. #define DIVISOR_LATCH_MSB 1
  22. #define PRESCALER_DIVISION 5
  23. #define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte)
  24. #define COM_READ_BYTE(reg) in_byte((ComPort1+reg))
  25. static int serial_init_done = 0;
  26. void serial_init (void)
  27. {
  28. #if 0
  29. uint32 clock_divisor = 115200 / baudrate;
  30. uint8 cfg;
  31. uint8 a;
  32. uint16 devfn = 7 << 3;
  33. if (serial_init_done)
  34. return;
  35. /* Enter configuration mode */
  36. cfg = pci_read_cfg_byte (0, devfn, 0x85);
  37. pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02);
  38. /* Set serial port COM1 as 3F8 */
  39. out_byte (0x3F0, 0xE7);
  40. out_byte (0x3f1, 0xfe);
  41. /* Set serial port COM2 as 2F8 */
  42. out_byte (0x3f0, 0xe8);
  43. out_byte (0x3f1, 0xeb);
  44. /* Enable */
  45. out_byte (0x3f0, 0xe2);
  46. a = in_byte (0x3f1);
  47. a |= 0xc;
  48. out_byte (0x3f0, 0xe2);
  49. out_byte (0x3f1, a);
  50. /* Reset the configuration mode */
  51. pci_write_cfg_byte (0, devfn, 0x85, cfg);
  52. #endif
  53. ComPort1 = 0x3F8;
  54. /* Disable interrupts */
  55. COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00);
  56. /* Set baud rate */
  57. /* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */
  58. /* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */
  59. /* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */
  60. /* __asm("eieio"); */
  61. /* Set 8-N-1 */
  62. COM_WRITE_BYTE (LINE_CONTROL, 0x03);
  63. __asm ("eieio");
  64. /* Disable FIFO */
  65. COM_WRITE_BYTE (MODEM_CONTROL, 0x03);
  66. COM_WRITE_BYTE (FIFO_CONTROL, 0x07);
  67. __asm ("eieio");
  68. serial_init_done = 1;
  69. }
  70. extern int console_changed;
  71. void serial_putc (const char sendme)
  72. {
  73. if (sendme == '\n') {
  74. while ((in_byte (0x3FD) & 0x40) == 0);
  75. out_byte (0x3f8, 0x0D);
  76. }
  77. while ((in_byte (0x3FD) & 0x40) == 0);
  78. out_byte (0x3f8, sendme);
  79. }
  80. int serial_getc (void)
  81. {
  82. #if 0
  83. uint8 c;
  84. for (;;) {
  85. uint8 x = in_byte (0x3FD);
  86. if (x & 0x01)
  87. break;
  88. if (x & 0x0C)
  89. out_byte (0x3fd, 0x0c);
  90. }
  91. c = in_byte (0x3F8);
  92. return c;
  93. #else
  94. while ((in_byte (0x3FD) & 0x01) == 0) {
  95. if (console_changed != 0) {
  96. printf ("Console changed\n");
  97. console_changed = 0;
  98. return 0;
  99. }
  100. }
  101. return in_byte (0x3F8);
  102. #endif
  103. }
  104. int serial_tstc (void)
  105. {
  106. return (in_byte (0x03FD) & 0x01) != 0;
  107. }
  108. void serial_debug_putc (int c)
  109. {
  110. serial_puts ("DBG");
  111. serial_putc (c);
  112. serial_putc (0x0d);
  113. serial_putc (0x0A);
  114. }
  115. #else
  116. const NS16550_t Com0 = (NS16550_t) CFG_NS16550_COM1;
  117. const NS16550_t Com1 = (NS16550_t) CFG_NS16550_COM2;
  118. int serial_init (void)
  119. {
  120. uint32 clock_divisor = 115200 / gd->baudrate;
  121. NS16550_init (Com0, clock_divisor);
  122. /* NS16550_reinit(Com1, clock_divisor); */
  123. /* serial_puts("COM1: 3F8h initalized"); */
  124. return (0);
  125. }
  126. #if 0
  127. void serial_putc (const char c)
  128. {
  129. NS16550_putc (Com0, c);
  130. if (c == '\n')
  131. NS16550_putc (Com0, 0x0D);
  132. }
  133. int serial_getc (void)
  134. {
  135. return (int) NS16550_getc (Com0);
  136. }
  137. int serial_tstc (void)
  138. {
  139. return NS16550_tstc (Com0);
  140. }
  141. #else
  142. void serial_putc (const char sendme)
  143. {
  144. if (sendme == '\n') {
  145. while ((in_byte (0x3FD) & 0x40) == 0);
  146. out_byte (0x3f8, 0x0D);
  147. }
  148. while ((in_byte (0x3FD) & 0x40) == 0);
  149. out_byte (0x3f8, sendme);
  150. }
  151. extern int console_changed;
  152. int serial_getc (void)
  153. {
  154. #if 0
  155. uint8 c;
  156. for (;;) {
  157. uint8 x = in_byte (0x3FD);
  158. if (x & 0x01)
  159. break;
  160. if (x & 0x0C)
  161. out_byte (0x3fd, 0x0c);
  162. }
  163. c = in_byte (0x3F8);
  164. return c;
  165. #else
  166. while ((in_byte (0x3FD) & 0x01) == 0) {
  167. if (console_changed != 0) {
  168. console_changed = 0;
  169. return 0;
  170. }
  171. }
  172. return in_byte (0x3F8);
  173. #endif
  174. }
  175. int serial_tstc (void)
  176. {
  177. return (in_byte (0x03FD) & 0x01) != 0;
  178. }
  179. #endif
  180. #endif
  181. void serial_puts (const char *string)
  182. {
  183. while (*string)
  184. serial_putc (*string++);
  185. }
  186. void serial_setbrg (void)
  187. {
  188. uint32 clock_divisor = 115200 / gd->baudrate;
  189. NS16550_init (Com0, clock_divisor);
  190. }