Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / qemu-palcode / uart.c
1 /*****************************************************************************
2
3        Copyright © 1995, 1996 Digital Equipment Corporation,
4                        Maynard, Massachusetts.
5
6                         All Rights Reserved
7
8 Permission to use, copy, modify, and distribute this software and its 
9 documentation for any purpose and without fee is hereby granted, provided  
10 that the copyright notice and this permission notice appear in all copies  
11 of software and supporting documentation, and that the name of Digital not  
12 be used in advertising or publicity pertaining to distribution of the software 
13 without specific, written prior permission. Digital grants this permission 
14 provided that you prominently mark, as not part of the original, any 
15 modifications made to this software or documentation.
16
17 Digital Equipment Corporation disclaims all warranties and/or guarantees  
18 with regard to this software, including all implied warranties of fitness for 
19 a particular purpose and merchantability, and makes no representations 
20 regarding the use of, or the results of the use of, the software and 
21 documentation in terms of correctness, accuracy, reliability, currentness or
22 otherwise; and you rely on the software, documentation and results solely at 
23 your own risk. 
24
25 ******************************************************************************/
26
27 /*
28  * david.rusling@reo.mts.dec.com
29  *
30  * Modified for QEMU PALcode by rth@twiddle.net.
31  */
32
33 #include "protos.h"
34 #include "uart.h"
35
36 #ifndef SERIAL_SPEED
37 #define SERIAL_SPEED 9600
38 #endif
39
40 int
41 uart_charav(int offset)
42 {
43         return inb(com2Lsr + offset) & 1;
44 }
45
46 int
47 uart_getchar(int offset)
48 {
49         /* If interrupts are enabled, use wtint assuming that either the
50            device itself will wake us, or that a clock interrupt will.  */
51         if ((rdps() & 7) == 0) {
52             while (!uart_charav(offset)) {
53                 wtint(0);
54             }
55         } else {
56             while (!uart_charav(offset))
57                 continue;
58         }
59
60         return inb(com2Rbr + offset);
61 }
62
63 void
64 uart_putchar_raw(int offset, char c)
65 {
66         while ((inb(com2Lsr + offset) & 0x20) == 0)
67                 continue;
68         outb(c, com2Thr + offset);
69 }
70
71 void
72 uart_putchar(int offset, char c)
73 {
74         if (c == '\n')
75                 uart_putchar_raw(offset, '\r');
76         uart_putchar_raw(offset, c);
77 }
78
79 void
80 uart_puts(int offset, const char *s)
81 {
82         while (*s != '\0')
83                 uart_putchar(offset, *s++);
84 }
85
86 void
87 uart_init_line(int offset, int baud)
88 {
89         int i;
90         int baudconst;
91
92         switch (baud) {
93         case 56000:
94                 baudconst = 2;
95                 break;
96         case 38400:
97                 baudconst = 3;
98                 break;
99         case 19200:
100                 baudconst = 6;
101                 break;
102         case 9600:
103                 baudconst = 12;
104                 break;
105         case 4800:
106                 baudconst = 24;
107                 break;
108         case 2400:
109                 baudconst = 48;
110                 break;
111         case 1200:
112                 baudconst = 96;
113                 break;
114         case 300:
115                 baudconst = 384;
116                 break;
117         case 150:
118                 baudconst = 768;
119                 break;
120         default:
121                 baudconst = 12;
122                 break;
123         }
124
125
126         outb(0x87, com2Lcr + offset);
127         outb(0, com2Dlm + offset);
128         outb(baudconst, com2Dll + offset);
129         outb(0x07, com2Lcr + offset);
130         outb(0x0F, com2Mcr + offset);
131
132         for (i = 10; i > 0; i--) {
133                 if (inb(com2Lsr + offset) == 0)
134                         break;
135                 inb(com2Rbr + offset);
136         }
137 }
138
139 void uart_init(void)
140 {
141         uart_init_line(COM1, SERIAL_SPEED);
142         /* uart_init_line(COM2, SERIAL_SPEED); */
143 }