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_ssc.c,v 1.27 2006/03/04 12:38:48 debug Exp $ |
* $Id: dev_ssc.c,v 1.29 2007/01/28 00:41:17 debug Exp $ |
29 |
* |
* |
30 |
* Serial controller on DECsystem 5400 and 5800. |
* Serial controller on DECsystem 5400 and 5800. |
31 |
* Known as System Support Chip on VAX 3600 (KA650). |
* Known as System Support Chip on VAX 3600 (KA650). |
59 |
#define SSC_DEBUG |
#define SSC_DEBUG |
60 |
|
|
61 |
struct ssc_data { |
struct ssc_data { |
|
int irq_nr; |
|
62 |
int console_handle; |
int console_handle; |
63 |
int use_fb; |
int use_fb; |
64 |
|
|
65 |
int rx_ctl; |
int rx_ctl; |
66 |
int tx_ctl; |
int tx_ctl; |
67 |
|
|
68 |
uint32_t *csrp; |
struct interrupt irq; |
69 |
}; |
}; |
70 |
|
|
71 |
|
|
85 |
/* rx interrupts enabled, and char avail? */ |
/* rx interrupts enabled, and char avail? */ |
86 |
if (d->rx_ctl & RX_INT_ENABLE && d->rx_ctl & RX_AVAIL) { |
if (d->rx_ctl & RX_INT_ENABLE && d->rx_ctl & RX_AVAIL) { |
87 |
/* TODO: This is for 5800 only! */ |
/* TODO: This is for 5800 only! */ |
88 |
|
unsigned char txvector = 0xf8; |
89 |
if (d->csrp != NULL) { |
cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector, |
90 |
unsigned char txvector = 0xf8; |
1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL); |
91 |
(*d->csrp) |= 0x10000000; |
INTERRUPT_ASSERT(d->irq); |
|
cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector, |
|
|
1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL); |
|
|
cpu_interrupt(cpu, 2); |
|
|
} |
|
92 |
} |
} |
93 |
|
|
94 |
/* tx interrupts enabled? */ |
/* tx interrupts enabled? */ |
95 |
if (d->tx_ctl & TX_INT_ENABLE) { |
if (d->tx_ctl & TX_INT_ENABLE) { |
96 |
/* TODO: This is for 5800 only! */ |
/* TODO: This is for 5800 only! */ |
97 |
|
unsigned char txvector = 0xfc; |
98 |
if (d->csrp != NULL) { |
cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector, |
99 |
unsigned char txvector = 0xfc; |
1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL); |
100 |
(*d->csrp) |= 0x10000000; |
INTERRUPT_ASSERT(d->irq); |
|
cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector, |
|
|
1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL); |
|
|
cpu_interrupt(cpu, 2); |
|
|
} |
|
101 |
} |
} |
102 |
} |
} |
103 |
|
|
104 |
|
|
|
/* |
|
|
* dev_ssc_access(): |
|
|
*/ |
|
105 |
DEVICE_ACCESS(ssc) |
DEVICE_ACCESS(ssc) |
106 |
{ |
{ |
107 |
uint64_t idata = 0, odata = 0; |
uint64_t idata = 0, odata = 0; |
123 |
} else { |
} else { |
124 |
d->rx_ctl = idata; |
d->rx_ctl = idata; |
125 |
|
|
126 |
/* TODO: This only works for 5800 */ |
INTERRUPT_DEASSERT(d->irq); |
127 |
if (d->csrp != NULL) { |
|
|
(*d->csrp) &= ~0x10000000; |
|
|
cpu_interrupt_ack(cpu, 2); |
|
|
} |
|
128 |
#ifdef SSC_DEBUG_TXRX |
#ifdef SSC_DEBUG_TXRX |
129 |
debug("[ ssc: write to 0x%08lx: 0x%02x ]\n", |
debug("[ ssc: write to 0x%08lx: 0x%02x ]\n", |
130 |
(long)relative_addr, (int)idata); |
(long)relative_addr, (int)idata); |
158 |
} else { |
} else { |
159 |
d->tx_ctl = idata; |
d->tx_ctl = idata; |
160 |
|
|
161 |
/* TODO: This only works for 5800 */ |
INTERRUPT_DEASSERT(d->irq); |
162 |
if (d->csrp != NULL) { |
|
|
(*d->csrp) &= ~0x10000000; |
|
|
cpu_interrupt_ack(cpu, 2); |
|
|
} |
|
163 |
#ifdef SSC_DEBUG_TXRX |
#ifdef SSC_DEBUG_TXRX |
164 |
debug("[ ssc: write to 0x%08lx: 0x%02x ]\n", |
debug("[ ssc: write to 0x%08lx: 0x%02x ]\n", |
165 |
(long)relative_addr, (int)idata); |
(long)relative_addr, (int)idata); |
228 |
* dev_ssc_init(): |
* dev_ssc_init(): |
229 |
*/ |
*/ |
230 |
void dev_ssc_init(struct machine *machine, struct memory *mem, |
void dev_ssc_init(struct machine *machine, struct memory *mem, |
231 |
uint64_t baseaddr, int irq_nr, int use_fb, uint32_t *csrp) |
uint64_t baseaddr, char *irq_path, int use_fb) |
232 |
{ |
{ |
233 |
struct ssc_data *d; |
struct ssc_data *d; |
234 |
|
|
238 |
exit(1); |
exit(1); |
239 |
} |
} |
240 |
memset(d, 0, sizeof(struct ssc_data)); |
memset(d, 0, sizeof(struct ssc_data)); |
|
d->irq_nr = irq_nr; |
|
241 |
d->use_fb = use_fb; |
d->use_fb = use_fb; |
|
d->csrp = csrp; |
|
242 |
d->console_handle = console_start_slave(machine, "SSC", 1); |
d->console_handle = console_start_slave(machine, "SSC", 1); |
243 |
|
|
244 |
|
INTERRUPT_CONNECT(irq_path, d->irq); |
245 |
|
|
246 |
memory_device_register(mem, "ssc", baseaddr, DEV_SSC_LENGTH, |
memory_device_register(mem, "ssc", baseaddr, DEV_SSC_LENGTH, |
247 |
dev_ssc_access, d, DM_DEFAULT, NULL); |
dev_ssc_access, d, DM_DEFAULT, NULL); |
248 |
|
|