serial.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include <common.h>
  2. #include <ns16550.h>
  3. #include "short_types.h"
  4. #include "memio.h"
  5. #include "articiaS.h"
  6. #ifndef CFG_NS16550
  7. static uint32 ComPort1;
  8. uint16 SerialEcho = 1;
  9. #define RECEIVER_HOLDING 0
  10. #define TRANSMITTER_HOLDING 0
  11. #define INTERRUPT_ENABLE 1
  12. #define INTERRUPT_STATUS 2
  13. #define FIFO_CONTROL 2
  14. #define LINE_CONTROL 3
  15. #define MODEM_CONTROL 4
  16. #define LINE_STATUS 5
  17. #define MODEM_STATUS 6
  18. #define SCRATCH_PAD 7
  19. #define DIVISOR_LATCH_LSB 0
  20. #define DIVISOR_LATCH_MSB 1
  21. #define PRESCALER_DIVISION 5
  22. #define COM_WRITE_BYTE(reg, byte) out_byte((ComPort1+reg), byte)
  23. #define COM_READ_BYTE(reg) in_byte((ComPort1+reg))
  24. static int serial_init_done = 0;
  25. void serial_init (void)
  26. {
  27. #if 0
  28. uint32 clock_divisor = 115200 / baudrate;
  29. uint8 cfg;
  30. uint8 a;
  31. uint16 devfn = 7 << 3;
  32. if (serial_init_done)
  33. return;
  34. /* Enter configuration mode */
  35. cfg = pci_read_cfg_byte (0, devfn, 0x85);
  36. pci_write_cfg_byte (0, devfn, 0x85, cfg | 0x02);
  37. /* Set serial port COM1 as 3F8 */
  38. out_byte (0x3F0, 0xE7);
  39. out_byte (0x3f1, 0xfe);
  40. /* Set serial port COM2 as 2F8 */
  41. out_byte (0x3f0, 0xe8);
  42. out_byte (0x3f1, 0xeb);
  43. /* Enable */
  44. out_byte (0x3f0, 0xe2);
  45. a = in_byte (0x3f1);
  46. a |= 0xc;
  47. out_byte (0x3f0, 0xe2);
  48. out_byte (0x3f1, a);
  49. /* Reset the configuration mode */
  50. pci_write_cfg_byte (0, devfn, 0x85, cfg);
  51. #endif
  52. ComPort1 = 0x3F8;
  53. /* Disable interrupts */
  54. COM_WRITE_BYTE (INTERRUPT_ENABLE, 0x00);
  55. /* Set baud rate */
  56. /* COM_WRITE_BYTE(LINE_CONTROL, 0x83); */
  57. /* COM_WRITE_BYTE(DIVISOR_LATCH_LSB, (uint8)(clock_divisor & 0xFF)); */
  58. /* COM_WRITE_BYTE(DIVISOR_LATCH_MSB, (uint8)(clock_divisor >> 8)); */
  59. /* __asm("eieio"); */
  60. /* Set 8-N-1 */
  61. COM_WRITE_BYTE (LINE_CONTROL, 0x03);
  62. __asm ("eieio");
  63. /* Disable FIFO */
  64. COM_WRITE_BYTE (MODEM_CONTROL, 0x03);
  65. COM_WRITE_BYTE (FIFO_CONTROL, 0x07);
  66. __asm ("eieio");
  67. serial_init_done = 1;
  68. }
  69. extern int console_changed;
  70. void serial_putc (const char sendme)
  71. {
  72. if (sendme == '\n') {
  73. while ((in_byte (0x3FD) & 0x40) == 0);
  74. out_byte (0x3f8, 0x0D);
  75. }
  76. while ((in_byte (0x3FD) & 0x40) == 0);
  77. out_byte (0x3f8, sendme);
  78. }
  79. int serial_getc (void)
  80. {
  81. #if 0
  82. uint8 c;
  83. for (;;) {
  84. uint8 x = in_byte (0x3FD);
  85. if (x & 0x01)
  86. break;
  87. if (x & 0x0C)
  88. out_byte (0x3fd, 0x0c);
  89. }
  90. c = in_byte (0x3F8);
  91. return c;
  92. #else
  93. while ((in_byte (0x3FD) & 0x01) == 0) {
  94. if (console_changed != 0) {
  95. printf ("Console changed\n");
  96. console_changed = 0;
  97. return 0;
  98. }
  99. }
  100. return in_byte (0x3F8);
  101. #endif
  102. }
  103. int serial_tstc (void)
  104. {
  105. return (in_byte (0x03FD) & 0x01) != 0;
  106. }
  107. void serial_debug_putc (int c)
  108. {
  109. serial_puts ("DBG");
  110. serial_putc (c);
  111. serial_putc (0x0d);
  112. serial_putc (0x0A);
  113. }
  114. #else
  115. const NS16550_t Com0 = (NS16550_t) CFG_NS16550_COM1;
  116. const NS16550_t Com1 = (NS16550_t) CFG_NS16550_COM2;
  117. int serial_init (void)
  118. {
  119. DECLARE_GLOBAL_DATA_PTR;
  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. DECLARE_GLOBAL_DATA_PTR;
  189. uint32 clock_divisor = 115200 / gd->baudrate;
  190. NS16550_init (Com0, clock_divisor);
  191. }