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/bus/bus.hh"
26 #include "mem/bus/pio_interface.hh"
27 #include "mem/bus/pio_interface_impl.hh"
28 #include "mem/functional_mem/memory_control.hh"
29 #include "sim/builder.hh"
30 #include "targetarch/ev5.hh"
34 #define CONS_INT_TX 0x01 // interrupt enable / state bits
35 #define CONS_INT_RX 0x02
37 TsunamiUart::TsunamiUart(const string
&name
, SimConsole
*c
,
38 MemoryController
*mmu
, Addr a
,
39 HierParams
*hier
, Bus
*bus
)
40 : PioDevice(name
), addr(a
), cons(c
), status_store(0), valid_char(false)
42 mmu
->add_child(this, Range
<Addr
>(addr
, addr
+ size
));
45 pioInterface
= newPioInterface(name
, hier
, bus
, this,
46 &TsunamiUart::cacheAccess
);
47 pioInterface
->addAddrRange(addr
, addr
+ size
- 1);
54 TsunamiUart::read(MemReqPtr
&req
, uint8_t *data
)
56 Addr daddr
= req
->paddr
- (addr
& PA_IMPL_MASK
);
57 DPRINTF(TsunamiUart
, " read register %#x\n", daddr
);
60 case sizeof(uint64_t):
61 *(uint64_t *)data
= 0;
63 case sizeof(uint32_t):
64 *(uint32_t *)data
= 0;
66 case sizeof(uint16_t):
67 *(uint16_t *)data
= 0;
76 case 0x5: // Status Register
78 int status
= cons
->intStatus();
80 valid_char
= cons
->in(next_char
);
82 status
&= ~CONS_INT_RX
;
84 status
|= CONS_INT_RX
;
87 if (status_store
== 3) {
88 // RR3 stuff? Don't really understand it, btw
90 if (status
& CONS_INT_TX
) {
93 } else if (status
& CONS_INT_RX
) {
97 DPRINTF(TsunamiUart
, "spurious read\n");
101 int reg
= (1 << 2) | (1 << 5) | (1 << 6);
102 if (status
& CONS_INT_RX
)
110 case 0x0: // Data register (RX)
112 // panic("Invalid character");
114 DPRINTF(TsunamiUart
, "read data register \'%c\' %#02x\n",
115 isprint(next_char
) ? next_char
: ' ', next_char
);
121 case 0x1: // Interrupt Enable Register
122 // This is the lovely way linux checks there is actually a serial
123 // port at the desired address
126 else if (IER
== 0x0F)
132 *data
= 0; // This means a 8250 serial port, do we want a 16550?
136 // panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);
142 TsunamiUart::write(MemReqPtr
&req
, const uint8_t *data
)
144 Addr daddr
= req
->paddr
- (addr
& PA_IMPL_MASK
);
146 DPRINTF(TsunamiUart
, " write register %#x value %#x\n", daddr
, *(uint8_t*)data
);
150 status_store
= *data
;
152 case 0x03: // going to read RR3
155 case 0x28: // Ack of TX
157 if ((cons
->intStatus() & CONS_INT_TX
) == 0)
158 panic("Ack of transmit, though there was no interrupt");
160 cons
->clearInt(CONS_INT_TX
);
167 // going to write data???
171 DPRINTF(TsunamiUart
, "writing status register %#x \n",
176 case 0x0: // Data register (TX)
178 ourchar
= *(uint64_t *)data
;
179 if ((isprint(ourchar
) || iscntrl(ourchar
)) && (ourchar
!= 0x0C))
181 if (UART_IER_THRI
& IER
)
182 cons
->setInt(CONS_INT_TX
);
186 DPRINTF(TsunamiUart
, "writing to DLM/IER %#x\n", *(uint8_t*)data
);
187 IER
= *(uint8_t*)data
;
188 if (UART_IER_THRI
& IER
)
189 cons
->setInt(CONS_INT_TX
);
193 DPRINTF(TsunamiUart
, "writing to MCR %#x\n", *(uint8_t*)data
);
202 TsunamiUart::cacheAccess(MemReqPtr
&req
)
204 return curTick
+ 1000;
208 TsunamiUart::serialize(ostream
&os
)
210 SERIALIZE_SCALAR(status_store
);
211 SERIALIZE_SCALAR(next_char
);
212 SERIALIZE_SCALAR(valid_char
);
213 SERIALIZE_SCALAR(IER
);
217 TsunamiUart::unserialize(Checkpoint
*cp
, const std::string
§ion
)
219 UNSERIALIZE_SCALAR(status_store
);
220 UNSERIALIZE_SCALAR(next_char
);
221 UNSERIALIZE_SCALAR(valid_char
);
222 UNSERIALIZE_SCALAR(IER
);
225 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart
)
227 SimObjectParam
<SimConsole
*> console
;
228 SimObjectParam
<MemoryController
*> mmu
;
230 SimObjectParam
<Bus
*> io_bus
;
231 SimObjectParam
<HierParams
*> hier
;
234 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart
)
236 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart
)
238 INIT_PARAM(console
, "The console"),
239 INIT_PARAM(mmu
, "Memory Controller"),
240 INIT_PARAM(addr
, "Device Address"),
241 INIT_PARAM_DFLT(io_bus
, "The IO Bus to attach to", NULL
),
242 INIT_PARAM_DFLT(hier
, "Hierarchy global variables", &defaultHierParams
)
244 END_INIT_SIM_OBJECT_PARAMS(TsunamiUart
)
246 CREATE_SIM_OBJECT(TsunamiUart
)
248 return new TsunamiUart(getInstanceName(), console
, mmu
, addr
, hier
, io_bus
);
251 REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart
)