8 * Copyright (C) 1998 by the Board of Trustees
9 * of Leland Stanford Junior University.
10 * Copyright (C) 1998 Digital Equipment Corporation
12 * This file is part of the SimOS distribution.
13 * See LICENSE file for terms of the license.
20 #include "base/inifile.hh"
21 #include "base/str.hh" // for to_number
22 #include "base/trace.hh"
23 #include "dev/console.hh"
24 #include "dev/tsunami_uart.hh"
25 #include "mem/functional_mem/memory_control.hh"
26 #include "sim/builder.hh"
27 #include "targetarch/ev5.hh"
31 #define CONS_INT_TX 0x01 // interrupt enable / state bits
32 #define CONS_INT_RX 0x02
34 TsunamiUart::TsunamiUart(const string
&name
, SimConsole
*c
, Addr a
,
35 MemoryController
*mmu
)
36 : FunctionalMemory(name
), addr(a
), cons(c
), status_store(0),
39 mmu
->add_child(this, Range
<Addr
>(addr
, addr
+ size
));
45 TsunamiUart::read(MemReqPtr
&req
, uint8_t *data
)
47 Addr daddr
= req
->paddr
- (addr
& PA_IMPL_MASK
);
48 DPRINTF(TsunamiUart
, " read register %#x\n", daddr
);
51 case sizeof(uint64_t):
52 *(uint64_t *)data
= 0;
54 case sizeof(uint32_t):
55 *(uint32_t *)data
= 0;
57 case sizeof(uint16_t):
58 *(uint16_t *)data
= 0;
66 case 0x5: // Status Register
68 int status
= cons
->intStatus();
70 valid_char
= cons
->in(next_char
);
72 status
&= ~CONS_INT_RX
;
74 status
|= CONS_INT_RX
;
77 if (status_store
== 3) {
78 // RR3 stuff? Don't really understand it, btw
80 if (status
& CONS_INT_TX
) {
83 } else if (status
& CONS_INT_RX
) {
87 DPRINTF(TsunamiUart
, "spurious read\n");
91 int reg
= (1 << 2) | (1 << 5) | (1 << 6);
92 if (status
& CONS_INT_RX
)
100 case 0x0: // Data register (RX)
102 // panic("Invalid character");
104 DPRINTF(TsunamiUart
, "read data register \'%c\' %#02x\n",
105 isprint(next_char
) ? next_char
: ' ', next_char
);
111 case 0x1: // Interrupt Enable Register
112 // This is the lovely way linux checks there is actually a serial
113 // port at the desired address
116 else if (IER
== 0x0F)
122 *data
= 0; // This means a 8250 serial port, do we want a 16550?
126 // panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);
132 TsunamiUart::write(MemReqPtr
&req
, const uint8_t *data
)
134 Addr daddr
= req
->paddr
- (addr
& PA_IMPL_MASK
);
136 DPRINTF(TsunamiUart
, " write register %#x value %#x\n", daddr
, *(uint8_t*)data
);
139 status_store
= *data
;
141 case 0x03: // going to read RR3
144 case 0x28: // Ack of TX
146 if ((cons
->intStatus() & CONS_INT_TX
) == 0)
147 panic("Ack of transmit, though there was no interrupt");
149 cons
->clearInt(CONS_INT_TX
);
156 // going to write data???
160 DPRINTF(TsunamiUart
, "writing status register %#x \n",
165 case 0x0: // Data register (TX)
166 cons
->out(*(uint64_t *)data
);
169 DPRINTF(TsunamiUart
, "writing to DLM/IER %#x\n", *(uint8_t*)data
);
170 IER
= *(uint8_t*)data
;
173 DPRINTF(TsunamiUart
, "writing to MCR %#x\n", *(uint8_t*)data
);
182 TsunamiUart::serialize(ostream
&os
)
184 SERIALIZE_SCALAR(status_store
);
185 SERIALIZE_SCALAR(next_char
);
186 SERIALIZE_SCALAR(valid_char
);
187 SERIALIZE_SCALAR(IER
);
191 TsunamiUart::unserialize(Checkpoint
*cp
, const std::string
§ion
)
193 UNSERIALIZE_SCALAR(status_store
);
194 UNSERIALIZE_SCALAR(next_char
);
195 UNSERIALIZE_SCALAR(valid_char
);
196 UNSERIALIZE_SCALAR(IER
);
199 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart
)
201 SimObjectParam
<SimConsole
*> console
;
202 SimObjectParam
<MemoryController
*> mmu
;
205 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart
)
207 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart
)
209 INIT_PARAM(console
, "The console"),
210 INIT_PARAM(mmu
, "Memory Controller"),
211 INIT_PARAM(addr
, "Device Address")
213 END_INIT_SIM_OBJECT_PARAMS(TsunamiUart
)
215 CREATE_SIM_OBJECT(TsunamiUart
)
217 return new TsunamiUart(getInstanceName(), console
, addr
, mmu
);
220 REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart
)