Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / qemu-palcode / crb.c
1 /* Console Callback Routines.
2
3    Copyright (C) 2011 Richard Henderson
4
5    This file is part of QEMU PALcode.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the text
15    of the GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; see the file COPYING.  If not see
19    <http://www.gnu.org/licenses/>.  */
20
21 #include "hwrpb.h"
22 #include "protos.h"
23 #include "console.h"
24 #include "uart.h"
25
26
27 /* All routines use the high bit to signal error.  */
28 #define ERR     0x8000000000000000ul
29
30
31 unsigned long
32 crb_getc(long unit)
33 {
34   /* Multiple consoles not yet supported.  */
35   if (unit != 0)
36     return ERR;
37
38   return uart_getchar(COM1);
39 }
40
41 unsigned long
42 crb_process_keycode(long unit, long keycode, long again)
43 {
44   /* This routine might be needed for real keyboards, and mostly for
45      internationalization stuff.  */
46   /* Return Failure: routine not supported.  */
47   return 0xc000000000000000ul;
48 }
49
50 unsigned long
51 crb_puts(long unit, const char *buf, unsigned long length)
52 {
53   unsigned int orig_length = length;
54
55   /* Multiple consoles not yet supported.  */
56   if (unit != 0)
57     return ERR;
58
59   for (; length != 0; --length, ++buf)
60     uart_putchar_raw(COM1, (unsigned char)*buf);
61
62   /* Bits <31:0> of the return value are the number of bytes written.
63      To me that implies that the input value must be 32-bit, but v2
64      of the ARM doesn't explicitly say.  */
65   return orig_length;
66 }
67
68 unsigned long
69 crb_reset_term(long unit)
70 {
71   /* Multiple consoles not yet supported.  */
72   if (unit != 0)
73     return ERR;
74
75   uart_init_line(COM1, 9600);
76   return 0;
77 }
78
79 static unsigned long
80 crb_set_term_ctl(long unit, long ctb)
81 {
82   /* ??? The contents of the CTB do not seem to be defined anywhere.
83      How, therefore, can the user set new contents?  */
84   return ERR;
85 }
86
87 static unsigned long
88 crb_set_term_int(long unit, long mask)
89 {
90   /* We do no buffering, therefore we don't need to support interrupts.  */
91   if (unit != 0 || (mask & 0x22) != 0)
92     return ERR;
93   return 0;
94 }
95
96 unsigned long
97 crb_open(const char *devstr,  unsigned long length)
98 {
99   /* FIXME */
100   return ERR;
101 }
102
103 unsigned long
104 crb_close(long channel)
105 {
106   /* FIXME */
107   return 0;
108 }
109
110 static unsigned long
111 crb_ioctl(long channel)
112 {
113   /* We do not, nor will not, support virtual tapes.  */
114   return ERR;
115 }
116
117 unsigned long
118 crb_read(long channel, unsigned long length, char *buf, unsigned long block)
119 {
120   /* FIXME */
121   return ERR;
122 }
123
124 unsigned long
125 crb_write(long channel, unsigned long length, const char *buf,
126           unsigned long block)
127 {
128   /* FIXME */
129   return ERR;
130 }
131
132 unsigned long
133 crb_get_env(unsigned long id, char *buf, unsigned long length)
134 {
135   /* FIXME */
136   return 0xc000000000000000ul;
137 }
138
139 unsigned long
140 crb_set_env(unsigned long id, const char *buf, unsigned long length)
141 {
142   /* FIXME */
143   return 0xc000000000000000ul;
144 }
145
146 static unsigned long
147 crb_reset_env(unsigned long id, char *buf, unsigned long length)
148 {
149   /* FIXME */
150   return 0xc000000000000000ul;
151 }
152
153 static unsigned long
154 crb_save_env(void)
155 {
156   /* FIXME */
157   return 0xc000000000000000ul;
158 }
159
160 static unsigned long
161 crb_pswitch(long action, long cpu_id)
162 {
163   /* Why would we ever need to support switching primary processor?  */
164   return ERR;
165 }
166
167 static unsigned long __attribute__((used))
168 int_crb_dispatch(long select, long a1, long a2, long a3, long a4)
169 {
170   switch (select)
171     {
172     case CRB_GETC:
173       return crb_getc(a1);
174     case CRB_PUTS:
175       return crb_puts(a1, (const char *)a2, a3);
176     case CRB_RESET_TERM:
177       return crb_reset_term(a1);
178     case CRB_SET_TERM_INT:
179       return crb_set_term_int(a1, a2);
180     case CRB_SET_TERM_CTL:
181       return crb_set_term_ctl(a1, a2);
182     case CRB_PROCESS_KEYCODE:
183       return crb_process_keycode(a1, a2, a3);
184
185     case CRB_OPEN:
186       return crb_open((const char*)a1, a2);
187     case CRB_CLOSE:
188       return crb_close(a1);
189     case CRB_IOCTL:
190       return crb_ioctl(a1);
191     case CRB_READ:
192       return crb_read(a1, a2, (char *)a3, a4);
193     case CRB_WRITE:
194       return crb_write(a1, a2, (const char *)a3, a4);
195
196     case CRB_SET_ENV:
197       return crb_set_env(a1, (const char *)a2, a3);
198     case CRB_RESET_ENV:
199       return crb_reset_env(a1, (char *)a2, a3);
200     case CRB_GET_ENV:
201       return crb_get_env(a1, (char *)a2, a3);
202     case CRB_SAVE_ENV:
203       return crb_save_env();
204
205     case CRB_PSWITCH:
206       return crb_pswitch(a1, a2);
207     }
208   return ERR;
209 }
210
211 static unsigned long __attribute__((used))
212 int_crb_fixup(unsigned long vptptr, unsigned long hwrpb)
213 {
214   /* Given that this console is written to use the KSEG, and not be
215      mapped into any page-table address space, it doesn't seem like
216      we need to do anything at all here.  */
217   return 0;
218 }
219
220 /* The CRB DISPATCH and FIXUP functions are defined to use the VMS
221    calling convention.  This has several effects: 
222      (1) The set of call-saved registers is different.
223      (2) $27 contains the procdesc_struct, not the called function.
224    Map between the two calling conventions here.  */
225
226 asm(".macro     VMStoUNIX name\n"
227 "       .globl  \\name\n"
228 "       .ent    \\name\n"
229 "\\name:\n"
230 "       .frame  $sp, 64, $26, 0\n"
231 "       subq    $sp, 64, $sp\n"
232 "       stq     $26, 0($sp)\n"
233 "       stq     $2, 8($sp)\n"
234 "       stq     $3, 16($sp)\n"
235 "       stq     $4, 24($sp)\n"
236 "       stq     $5, 32($sp)\n"
237 "       stq     $6, 40($sp)\n"
238 "       stq     $7, 48($sp)\n"
239 "       stq     $8, 56($sp)\n"
240 "       .mask   0x40001fc, 0\n"
241 "       .prologue 2\n"
242 "       br      $gp, .+4\n"
243 "       ldgp    $gp, 0($gp)\n"
244 "       bsr     $26, int_\\name !samegp\n"
245 "       ldq     $26, 0($sp)\n"
246 "       ldq     $2, 8($sp)\n"
247 "       ldq     $3, 16($sp)\n"
248 "       ldq     $4, 24($sp)\n"
249 "       ldq     $5, 32($sp)\n"
250 "       ldq     $6, 40($sp)\n"
251 "       ldq     $7, 48($sp)\n"
252 "       ldq     $8, 56($sp)\n"
253 "       addq    $sp, 64, $sp\n"
254 "       ret\n"
255 "       .end    \\name\n"
256 ".endm\n"
257 "       VMStoUNIX       crb_dispatch\n"
258 "       VMStoUNIX       crb_fixup\n"
259 );