Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/cris/arch-v10/kernel/debugport.c
15125 views
1
/* Serialport functions for debugging
2
*
3
* Copyright (c) 2000-2007 Axis Communications AB
4
*
5
* Authors: Bjorn Wesen
6
*
7
* Exports:
8
* console_print_etrax(char *buf)
9
* int getDebugChar()
10
* putDebugChar(int)
11
* enableDebugIRQ()
12
* init_etrax_debug()
13
*
14
*/
15
16
#include <linux/console.h>
17
#include <linux/init.h>
18
#include <linux/major.h>
19
#include <linux/delay.h>
20
#include <linux/tty.h>
21
#include <asm/system.h>
22
#include <arch/svinto.h>
23
#include <asm/io.h> /* Get SIMCOUT. */
24
25
extern void reset_watchdog(void);
26
27
struct dbg_port
28
{
29
unsigned int index;
30
const volatile unsigned* read;
31
volatile char* write;
32
volatile unsigned* xoff;
33
volatile char* baud;
34
volatile char* tr_ctrl;
35
volatile char* rec_ctrl;
36
unsigned long irq;
37
unsigned int started;
38
unsigned long baudrate;
39
unsigned char parity;
40
unsigned int bits;
41
};
42
43
struct dbg_port ports[]=
44
{
45
{
46
0,
47
R_SERIAL0_READ,
48
R_SERIAL0_TR_DATA,
49
R_SERIAL0_XOFF,
50
R_SERIAL0_BAUD,
51
R_SERIAL0_TR_CTRL,
52
R_SERIAL0_REC_CTRL,
53
IO_STATE(R_IRQ_MASK1_SET, ser0_data, set),
54
0,
55
115200,
56
'N',
57
8
58
},
59
{
60
1,
61
R_SERIAL1_READ,
62
R_SERIAL1_TR_DATA,
63
R_SERIAL1_XOFF,
64
R_SERIAL1_BAUD,
65
R_SERIAL1_TR_CTRL,
66
R_SERIAL1_REC_CTRL,
67
IO_STATE(R_IRQ_MASK1_SET, ser1_data, set),
68
0,
69
115200,
70
'N',
71
8
72
},
73
{
74
2,
75
R_SERIAL2_READ,
76
R_SERIAL2_TR_DATA,
77
R_SERIAL2_XOFF,
78
R_SERIAL2_BAUD,
79
R_SERIAL2_TR_CTRL,
80
R_SERIAL2_REC_CTRL,
81
IO_STATE(R_IRQ_MASK1_SET, ser2_data, set),
82
0,
83
115200,
84
'N',
85
8
86
},
87
{
88
3,
89
R_SERIAL3_READ,
90
R_SERIAL3_TR_DATA,
91
R_SERIAL3_XOFF,
92
R_SERIAL3_BAUD,
93
R_SERIAL3_TR_CTRL,
94
R_SERIAL3_REC_CTRL,
95
IO_STATE(R_IRQ_MASK1_SET, ser3_data, set),
96
0,
97
115200,
98
'N',
99
8
100
}
101
};
102
103
#ifdef CONFIG_ETRAX_SERIAL
104
extern struct tty_driver *serial_driver;
105
#endif
106
107
struct dbg_port* port =
108
#if defined(CONFIG_ETRAX_DEBUG_PORT0)
109
&ports[0];
110
#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
111
&ports[1];
112
#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
113
&ports[2];
114
#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
115
&ports[3];
116
#else
117
NULL;
118
#endif
119
120
static struct dbg_port* kgdb_port =
121
#if defined(CONFIG_ETRAX_KGDB_PORT0)
122
&ports[0];
123
#elif defined(CONFIG_ETRAX_KGDB_PORT1)
124
&ports[1];
125
#elif defined(CONFIG_ETRAX_KGDB_PORT2)
126
&ports[2];
127
#elif defined(CONFIG_ETRAX_KGDB_PORT3)
128
&ports[3];
129
#else
130
NULL;
131
#endif
132
133
static void
134
start_port(struct dbg_port* p)
135
{
136
unsigned long rec_ctrl = 0;
137
unsigned long tr_ctrl = 0;
138
139
if (!p)
140
return;
141
142
if (p->started)
143
return;
144
p->started = 1;
145
146
if (p->index == 0)
147
{
148
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
149
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
150
}
151
else if (p->index == 1)
152
{
153
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
154
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
155
}
156
else if (p->index == 2)
157
{
158
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
159
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
160
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma3);
161
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma3, par0);
162
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser2, select);
163
}
164
else
165
{
166
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma4);
167
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
168
genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma5);
169
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma5, par1);
170
genconfig_shadow |= IO_STATE(R_GEN_CONFIG, ser3, select);
171
}
172
173
*R_GEN_CONFIG = genconfig_shadow;
174
175
*p->xoff =
176
IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) |
177
IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) |
178
IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0);
179
180
switch (p->baudrate)
181
{
182
case 0:
183
case 115200:
184
*p->baud =
185
IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
186
IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
187
break;
188
case 1200:
189
*p->baud =
190
IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) |
191
IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz);
192
break;
193
case 2400:
194
*p->baud =
195
IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) |
196
IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz);
197
break;
198
case 4800:
199
*p->baud =
200
IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) |
201
IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz);
202
break;
203
case 9600:
204
*p->baud =
205
IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) |
206
IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz);
207
break;
208
case 19200:
209
*p->baud =
210
IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) |
211
IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz);
212
break;
213
case 38400:
214
*p->baud =
215
IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) |
216
IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz);
217
break;
218
case 57600:
219
*p->baud =
220
IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) |
221
IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz);
222
break;
223
default:
224
*p->baud =
225
IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
226
IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
227
break;
228
}
229
230
if (p->parity == 'E') {
231
rec_ctrl =
232
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
233
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
234
tr_ctrl =
235
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
236
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
237
} else if (p->parity == 'O') {
238
rec_ctrl =
239
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) |
240
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
241
tr_ctrl =
242
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd) |
243
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
244
} else {
245
rec_ctrl =
246
IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
247
IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, disable);
248
tr_ctrl =
249
IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
250
IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable);
251
}
252
if (p->bits == 7)
253
{
254
rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
255
tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
256
}
257
else
258
{
259
rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_8bit);
260
tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit);
261
}
262
263
*p->rec_ctrl =
264
IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) |
265
IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) |
266
IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) |
267
IO_STATE(R_SERIAL0_REC_CTRL, sampling, middle) |
268
IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) |
269
rec_ctrl;
270
271
*p->tr_ctrl =
272
IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) |
273
IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) |
274
IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) |
275
IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, one_bit) |
276
IO_STATE(R_SERIAL0_TR_CTRL, tr_stick_par, normal) |
277
tr_ctrl;
278
}
279
280
static void
281
console_write_direct(struct console *co, const char *buf, unsigned int len)
282
{
283
int i;
284
unsigned long flags;
285
286
if (!port)
287
return;
288
289
local_irq_save(flags);
290
291
/* Send data */
292
for (i = 0; i < len; i++) {
293
/* LF -> CRLF */
294
if (buf[i] == '\n') {
295
while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
296
;
297
*port->write = '\r';
298
}
299
/* Wait until transmitter is ready and send.*/
300
while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
301
;
302
*port->write = buf[i];
303
}
304
305
/*
306
* Feed the watchdog, otherwise it will reset the chip during boot.
307
* The time to send an ordinary boot message line (10-90 chars)
308
* varies between 1-8ms at 115200. What makes up for the additional
309
* 90ms that allows the watchdog to bite?
310
*/
311
reset_watchdog();
312
313
local_irq_restore(flags);
314
}
315
316
static void
317
console_write(struct console *co, const char *buf, unsigned int len)
318
{
319
if (!port)
320
return;
321
322
#ifdef CONFIG_SVINTO_SIM
323
/* no use to simulate the serial debug output */
324
SIMCOUT(buf, len);
325
return;
326
#endif
327
328
console_write_direct(co, buf, len);
329
}
330
331
/* legacy function */
332
333
void
334
console_print_etrax(const char *buf)
335
{
336
console_write(NULL, buf, strlen(buf));
337
}
338
339
/* Use polling to get a single character FROM the debug port */
340
341
int
342
getDebugChar(void)
343
{
344
unsigned long readval;
345
346
if (!kgdb_port)
347
return 0;
348
349
do {
350
readval = *kgdb_port->read;
351
} while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
352
353
return (readval & IO_MASK(R_SERIAL0_READ, data_in));
354
}
355
356
/* Use polling to put a single character to the debug port */
357
358
void
359
putDebugChar(int val)
360
{
361
if (!kgdb_port)
362
return;
363
364
while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
365
;
366
*kgdb_port->write = val;
367
}
368
369
/* Enable irq for receiving chars on the debug port, used by kgdb */
370
371
void
372
enableDebugIRQ(void)
373
{
374
if (!kgdb_port)
375
return;
376
377
*R_IRQ_MASK1_SET = kgdb_port->irq;
378
/* use R_VECT_MASK directly, since we really bypass Linux normal
379
* IRQ handling in kgdb anyway, we don't need to use enable_irq
380
*/
381
*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
382
383
*kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
384
}
385
386
static int __init
387
console_setup(struct console *co, char *options)
388
{
389
char* s;
390
391
if (options) {
392
port = &ports[co->index];
393
port->baudrate = 115200;
394
port->parity = 'N';
395
port->bits = 8;
396
port->baudrate = simple_strtoul(options, NULL, 10);
397
s = options;
398
while(*s >= '0' && *s <= '9')
399
s++;
400
if (*s) port->parity = *s++;
401
if (*s) port->bits = *s++ - '0';
402
port->started = 0;
403
start_port(0);
404
}
405
return 0;
406
}
407
408
409
/* This is a dummy serial device that throws away anything written to it.
410
* This is used when no debug output is wanted.
411
*/
412
static struct tty_driver dummy_driver;
413
414
static int dummy_open(struct tty_struct *tty, struct file * filp)
415
{
416
return 0;
417
}
418
419
static void dummy_close(struct tty_struct *tty, struct file * filp)
420
{
421
}
422
423
static int dummy_write(struct tty_struct * tty,
424
const unsigned char *buf, int count)
425
{
426
return count;
427
}
428
429
static int dummy_write_room(struct tty_struct *tty)
430
{
431
return 8192;
432
}
433
434
static const struct tty_operations dummy_ops = {
435
.open = dummy_open,
436
.close = dummy_close,
437
.write = dummy_write,
438
.write_room = dummy_write_room,
439
};
440
441
void __init
442
init_dummy_console(void)
443
{
444
memset(&dummy_driver, 0, sizeof(struct tty_driver));
445
dummy_driver.driver_name = "serial";
446
dummy_driver.name = "ttyS";
447
dummy_driver.major = TTY_MAJOR;
448
dummy_driver.minor_start = 68;
449
dummy_driver.num = 1; /* etrax100 has 4 serial ports */
450
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
451
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
452
dummy_driver.init_termios = tty_std_termios;
453
/* Normally B9600 default... */
454
dummy_driver.init_termios.c_cflag =
455
B115200 | CS8 | CREAD | HUPCL | CLOCAL;
456
dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
457
dummy_driver.init_termios.c_ispeed = 115200;
458
dummy_driver.init_termios.c_ospeed = 115200;
459
460
dummy_driver.ops = &dummy_ops;
461
if (tty_register_driver(&dummy_driver))
462
panic("Couldn't register dummy serial driver\n");
463
}
464
465
static struct tty_driver*
466
etrax_console_device(struct console* co, int *index)
467
{
468
if (port)
469
*index = port->index;
470
else
471
*index = 0;
472
#ifdef CONFIG_ETRAX_SERIAL
473
return port ? serial_driver : &dummy_driver;
474
#else
475
return &dummy_driver;
476
#endif
477
}
478
479
static struct console sercons = {
480
name : "ttyS",
481
write: console_write,
482
read : NULL,
483
device : etrax_console_device,
484
unblank : NULL,
485
setup : console_setup,
486
flags : CON_PRINTBUFFER,
487
index : -1,
488
cflag : 0,
489
next : NULL
490
};
491
static struct console sercons0 = {
492
name : "ttyS",
493
write: console_write,
494
read : NULL,
495
device : etrax_console_device,
496
unblank : NULL,
497
setup : console_setup,
498
flags : CON_PRINTBUFFER,
499
index : 0,
500
cflag : 0,
501
next : NULL
502
};
503
504
static struct console sercons1 = {
505
name : "ttyS",
506
write: console_write,
507
read : NULL,
508
device : etrax_console_device,
509
unblank : NULL,
510
setup : console_setup,
511
flags : CON_PRINTBUFFER,
512
index : 1,
513
cflag : 0,
514
next : NULL
515
};
516
static struct console sercons2 = {
517
name : "ttyS",
518
write: console_write,
519
read : NULL,
520
device : etrax_console_device,
521
unblank : NULL,
522
setup : console_setup,
523
flags : CON_PRINTBUFFER,
524
index : 2,
525
cflag : 0,
526
next : NULL
527
};
528
static struct console sercons3 = {
529
name : "ttyS",
530
write: console_write,
531
read : NULL,
532
device : etrax_console_device,
533
unblank : NULL,
534
setup : console_setup,
535
flags : CON_PRINTBUFFER,
536
index : 3,
537
cflag : 0,
538
next : NULL
539
};
540
/*
541
* Register console (for printk's etc)
542
*/
543
544
int __init
545
init_etrax_debug(void)
546
{
547
static int first = 1;
548
549
if (!first) {
550
unregister_console(&sercons);
551
register_console(&sercons0);
552
register_console(&sercons1);
553
register_console(&sercons2);
554
register_console(&sercons3);
555
init_dummy_console();
556
return 0;
557
}
558
559
first = 0;
560
register_console(&sercons);
561
start_port(port);
562
#ifdef CONFIG_ETRAX_KGDB
563
start_port(kgdb_port);
564
#endif
565
return 0;
566
}
567
__initcall(init_etrax_debug);
568
569