Fix PCI code so it builds properly now
[gem5.git] / dev / tsunami_uart.cc
1 /* $Id$ */
2
3 /* @file
4 * Tsunami UART
5 */
6
7 /*
8 * Copyright (C) 1998 by the Board of Trustees
9 * of Leland Stanford Junior University.
10 * Copyright (C) 1998 Digital Equipment Corporation
11 *
12 * This file is part of the SimOS distribution.
13 * See LICENSE file for terms of the license.
14 *
15 */
16
17 #include <string>
18 #include <vector>
19
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"
28
29 using namespace std;
30
31 #define CONS_INT_TX 0x01 // interrupt enable / state bits
32 #define CONS_INT_RX 0x02
33
34 TsunamiUart::TsunamiUart(const string &name, SimConsole *c,
35 Addr addr, Addr mask, MemoryController *mmu)
36 : MmapDevice(name, addr, mask, mmu),
37 cons(c), status_store(0), valid_char(false)
38 {
39 }
40
41 Fault
42 TsunamiUart::read(MemReqPtr &req, uint8_t *data)
43 {
44 Addr daddr = req->paddr & addr_mask;
45 DPRINTF(TsunamiUart, " read register %#x\n", daddr);
46
47 switch (req->size) {
48 case sizeof(uint64_t):
49 *(uint64_t *)data = 0;
50 break;
51 case sizeof(uint32_t):
52 *(uint32_t *)data = 0;
53 break;
54 case sizeof(uint16_t):
55 *(uint16_t *)data = 0;
56 break;
57 case sizeof(uint8_t):
58 *(uint8_t *)data = 0;
59 break;
60 }
61
62 switch (daddr) {
63 case 0xD: // Status Register
64 {
65 int status = cons->intStatus();
66 if (!valid_char) {
67 valid_char = cons->in(next_char);
68 if (!valid_char)
69 status &= ~CONS_INT_RX;
70 } else {
71 status |= CONS_INT_RX;
72 }
73
74 if (status_store == 3) {
75 // RR3 stuff? Don't really understand it, btw
76 status_store = 0;
77 if (status & CONS_INT_TX) {
78 *data = (1 << 4);
79 return No_Fault;
80 } else if (status & CONS_INT_RX) {
81 *data = (1 << 5);
82 return No_Fault;
83 } else {
84 DPRINTF(TsunamiUart, "spurious read\n");
85 return No_Fault;
86 }
87 } else {
88 int reg = (1 << 2) | (1 << 5) | (1 << 6);
89 if (status & CONS_INT_RX)
90 reg |= (1 << 0);
91 *data = reg;
92 return No_Fault;
93 }
94 break;
95 }
96
97 case 0x8: // Data register (RX)
98 if (!valid_char)
99 panic("Invalid character");
100
101 DPRINTF(TsunamiUart, "read data register \'%c\' %#02x\n",
102 isprint(next_char) ? next_char : ' ', next_char);
103
104 *data = next_char;
105 valid_char = false;
106 return No_Fault;
107
108 case 0x9: // Interrupt Enable Register
109 *data = 0;
110 return No_Fault;
111 }
112 *data = 0;
113 // panic("%s: read daddr=%#x type=read *data=%#x\n", name(), daddr, *data);
114
115 return No_Fault;
116 }
117
118 Fault
119 TsunamiUart::write(MemReqPtr &req, const uint8_t *data)
120 {
121 Addr daddr = req->paddr & addr_mask;
122
123 DPRINTF(TsunamiUart, " write register %#x value %#x\n", daddr, *(uint8_t*)data);
124 switch (daddr) {
125 case 0xb:
126 status_store = *data;
127 switch (*data) {
128 case 0x03: // going to read RR3
129 return No_Fault;
130
131 case 0x28: // Ack of TX
132 {
133 if ((cons->intStatus() & CONS_INT_TX) == 0)
134 panic("Ack of transmit, though there was no interrupt");
135
136 cons->clearInt(CONS_INT_TX);
137 return No_Fault;
138 }
139
140 case 0x00:
141 case 0x01:
142 case 0x12:
143 // going to write data???
144 return No_Fault;
145
146 default:
147 DPRINTF(TsunamiUart, "writing status register %#x \n",
148 *(uint64_t *)data);
149 return No_Fault;
150 }
151
152 case 0x8: // Data register (TX)
153 cons->out(*(uint64_t *)data);
154 return No_Fault;
155 case 0x9: // DLM
156 DPRINTF(TsunamiUart, "writing to DLM/IER %#x\n", *(uint8_t*)data);
157 return No_Fault;
158 case 0xc: // MCR
159 DPRINTF(TsunamiUart, "writing to MCR %#x\n", *(uint8_t*)data);
160 return No_Fault;
161
162 }
163
164 return No_Fault;
165 }
166
167 void
168 TsunamiUart::serialize(ostream &os)
169 {
170 SERIALIZE_SCALAR(status_store);
171 SERIALIZE_SCALAR(next_char);
172 SERIALIZE_SCALAR(valid_char);
173 }
174
175 void
176 TsunamiUart::unserialize(Checkpoint *cp, const std::string &section)
177 {
178 UNSERIALIZE_SCALAR(status_store);
179 UNSERIALIZE_SCALAR(next_char);
180 UNSERIALIZE_SCALAR(valid_char);
181 }
182
183 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
184
185 SimObjectParam<SimConsole *> console;
186 SimObjectParam<MemoryController *> mmu;
187 Param<Addr> addr;
188 Param<Addr> mask;
189
190 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiUart)
191
192 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiUart)
193
194 INIT_PARAM(console, "The console"),
195 INIT_PARAM(mmu, "Memory Controller"),
196 INIT_PARAM(addr, "Device Address"),
197 INIT_PARAM(mask, "Address Mask")
198
199 END_INIT_SIM_OBJECT_PARAMS(TsunamiUart)
200
201 CREATE_SIM_OBJECT(TsunamiUart)
202 {
203 return new TsunamiUart(getInstanceName(), console, addr, mask, mmu);
204 }
205
206 REGISTER_SIM_OBJECT("TsunamiUart", TsunamiUart)