1 |
/* |
/* |
2 |
* Copyright (C) 2003-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2003-2007 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.55 2006/10/27 13:12:21 debug Exp $ |
* $Id: dev_ns16550.c,v 1.58 2006/12/30 13:30:58 debug Exp $ |
29 |
* |
* |
30 |
* NS16550 serial controller. |
* NS16550 serial controller. |
31 |
* |
* |
40 |
#include "console.h" |
#include "console.h" |
41 |
#include "cpu.h" |
#include "cpu.h" |
42 |
#include "device.h" |
#include "device.h" |
43 |
|
#include "interrupt.h" |
44 |
#include "machine.h" |
#include "machine.h" |
45 |
#include "memory.h" |
#include "memory.h" |
46 |
#include "misc.h" |
#include "misc.h" |
56 |
struct ns_data { |
struct ns_data { |
57 |
int addrmult; |
int addrmult; |
58 |
int in_use; |
int in_use; |
|
int irqnr; |
|
59 |
char *name; |
char *name; |
60 |
int console_handle; |
int console_handle; |
61 |
int enable_fifo; |
int enable_fifo; |
62 |
|
|
63 |
|
struct interrupt irq; |
64 |
|
|
65 |
unsigned char reg[DEV_NS16550_LENGTH]; |
unsigned char reg[DEV_NS16550_LENGTH]; |
66 |
unsigned char fcr; /* FIFO control register */ |
unsigned char fcr; /* FIFO control register */ |
67 |
int int_asserted; |
int int_asserted; |
96 |
((d->reg[com_ier] & IER_ERXRDY) && (d->reg[com_iir] & IIR_RXRDY))) { |
((d->reg[com_ier] & IER_ERXRDY) && (d->reg[com_iir] & IIR_RXRDY))) { |
97 |
d->reg[com_iir] &= ~IIR_NOPEND; |
d->reg[com_iir] &= ~IIR_NOPEND; |
98 |
if (d->reg[com_mcr] & MCR_IENABLE) { |
if (d->reg[com_mcr] & MCR_IENABLE) { |
99 |
cpu_interrupt(cpu, d->irqnr); |
INTERRUPT_ASSERT(d->irq); |
100 |
d->int_asserted = 1; |
d->int_asserted = 1; |
101 |
} |
} |
102 |
} else { |
} else { |
103 |
d->reg[com_iir] |= IIR_NOPEND; |
d->reg[com_iir] |= IIR_NOPEND; |
104 |
if (d->int_asserted) |
if (d->int_asserted) |
105 |
cpu_interrupt_ack(cpu, d->irqnr); |
INTERRUPT_DEASSERT(d->irq); |
106 |
d->int_asserted = 0; |
d->int_asserted = 0; |
107 |
} |
} |
108 |
} |
} |
109 |
|
|
110 |
|
|
|
/* |
|
|
* dev_ns16550_access(): |
|
|
*/ |
|
111 |
DEVICE_ACCESS(ns16550) |
DEVICE_ACCESS(ns16550) |
112 |
{ |
{ |
113 |
uint64_t idata = 0, odata=0; |
uint64_t idata = 0, odata=0; |
331 |
exit(1); |
exit(1); |
332 |
} |
} |
333 |
memset(d, 0, sizeof(struct ns_data)); |
memset(d, 0, sizeof(struct ns_data)); |
334 |
d->irqnr = devinit->irq_nr; |
|
335 |
d->addrmult = devinit->addr_mult; |
d->addrmult = devinit->addr_mult; |
336 |
d->in_use = devinit->in_use; |
d->in_use = devinit->in_use; |
337 |
d->enable_fifo = 1; |
d->enable_fifo = 1; |
345 |
console_start_slave(devinit->machine, devinit->name2 != NULL? |
console_start_slave(devinit->machine, devinit->name2 != NULL? |
346 |
devinit->name2 : devinit->name, d->in_use); |
devinit->name2 : devinit->name, d->in_use); |
347 |
|
|
348 |
|
INTERRUPT_CONNECT(devinit->interrupt_path, d->irq); |
349 |
|
|
350 |
nlen = strlen(devinit->name) + 10; |
nlen = strlen(devinit->name) + 10; |
351 |
if (devinit->name2 != NULL) |
if (devinit->name2 != NULL) |
352 |
nlen += strlen(devinit->name2); |
nlen += strlen(devinit->name2); |