1 |
/* |
/* |
2 |
* Copyright (C) 2003-2005 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: dev_ns16550.c,v 1.46 2005/11/23 18:16:42 debug Exp $ |
* $Id: dev_ns16550.c,v 1.51 2006/02/18 13:42:39 debug Exp $ |
29 |
* |
* |
30 |
* NS16550 serial controller. |
* NS16550 serial controller. |
31 |
* |
* |
84 |
struct ns_data *d = extra; |
struct ns_data *d = extra; |
85 |
|
|
86 |
d->reg[com_iir] &= ~IIR_RXRDY; |
d->reg[com_iir] &= ~IIR_RXRDY; |
87 |
if (d->in_use && console_charavail(d->console_handle)) |
if (console_charavail(d->console_handle)) |
88 |
d->reg[com_iir] |= IIR_RXRDY; |
d->reg[com_iir] |= IIR_RXRDY; |
89 |
|
|
90 |
/* |
/* |
110 |
/* |
/* |
111 |
* dev_ns16550_access(): |
* dev_ns16550_access(): |
112 |
*/ |
*/ |
113 |
int dev_ns16550_access(struct cpu *cpu, struct memory *mem, |
DEVICE_ACCESS(ns16550) |
|
uint64_t relative_addr, unsigned char *data, size_t len, |
|
|
int writeflag, void *extra) |
|
114 |
{ |
{ |
115 |
uint64_t idata = 0, odata=0; |
uint64_t idata = 0, odata=0; |
116 |
int i; |
size_t i; |
117 |
struct ns_data *d = extra; |
struct ns_data *d = extra; |
118 |
|
|
119 |
if (writeflag == MEM_WRITE) |
if (writeflag == MEM_WRITE) |
137 |
d->reg[com_iir] |= ((d->fcr << 5) & 0xc0); |
d->reg[com_iir] |= ((d->fcr << 5) & 0xc0); |
138 |
|
|
139 |
d->reg[com_lsr] &= ~LSR_RXRDY; |
d->reg[com_lsr] &= ~LSR_RXRDY; |
140 |
if (d->in_use && console_charavail(d->console_handle)) |
if (console_charavail(d->console_handle)) |
141 |
d->reg[com_lsr] |= LSR_RXRDY; |
d->reg[com_lsr] |= LSR_RXRDY; |
142 |
|
|
143 |
relative_addr /= d->addrmult; |
relative_addr /= d->addrmult; |
164 |
|
|
165 |
/* Read/write of data: */ |
/* Read/write of data: */ |
166 |
if (writeflag == MEM_WRITE) { |
if (writeflag == MEM_WRITE) { |
167 |
if (d->reg[com_mcr] & MCR_LOOPBACK) { |
if (d->reg[com_mcr] & MCR_LOOPBACK) |
168 |
console_makeavail(d->console_handle, idata); |
console_makeavail(d->console_handle, idata); |
169 |
} else { |
else |
170 |
console_putchar(d->console_handle, idata); |
console_putchar(d->console_handle, idata); |
|
if (console_are_slaves_allowed()) |
|
|
d->in_use = 1; |
|
|
} |
|
171 |
d->reg[com_iir] |= IIR_TXRDY; |
d->reg[com_iir] |= IIR_TXRDY; |
172 |
} else { |
} else { |
173 |
if (d->in_use) |
int x = console_readchar(d->console_handle); |
174 |
odata = console_readchar(d->console_handle); |
odata = x < 0? 0 : x; |
|
else |
|
|
odata = 0; |
|
175 |
} |
} |
176 |
dev_ns16550_tick(cpu, d); |
dev_ns16550_tick(cpu, d); |
177 |
break; |
break; |
316 |
} |
} |
317 |
|
|
318 |
|
|
319 |
/* |
DEVINIT(ns16550) |
|
* devinit_ns16550(): |
|
|
*/ |
|
|
int devinit_ns16550(struct devinit *devinit) |
|
320 |
{ |
{ |
321 |
struct ns_data *d = malloc(sizeof(struct ns_data)); |
struct ns_data *d = malloc(sizeof(struct ns_data)); |
322 |
size_t nlen; |
size_t nlen; |
338 |
d->stopbits = "1"; |
d->stopbits = "1"; |
339 |
d->name = devinit->name2 != NULL? devinit->name2 : ""; |
d->name = devinit->name2 != NULL? devinit->name2 : ""; |
340 |
d->console_handle = |
d->console_handle = |
341 |
console_start_slave(devinit->machine, devinit->name); |
console_start_slave(devinit->machine, devinit->name2 != NULL? |
342 |
|
devinit->name2 : devinit->name, d->in_use); |
343 |
|
|
344 |
nlen = strlen(devinit->name) + 10; |
nlen = strlen(devinit->name) + 10; |
345 |
if (devinit->name2 != NULL) |
if (devinit->name2 != NULL) |