uart8250.cc (12239:ae1686aaebc5) uart8250.cc (13342:1ddb43f47325)
1/*
2 * Copyright (c) 2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 94 unchanged lines hidden (view full) ---

103 Addr daddr = pkt->getAddr() - pioAddr;
104
105 DPRINTF(Uart, " read register %#x\n", daddr);
106
107 switch (daddr) {
108 case 0x0:
109 if (!(LCR & 0x80)) { // read byte
110 if (device->dataAvailable())
1/*
2 * Copyright (c) 2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 94 unchanged lines hidden (view full) ---

103 Addr daddr = pkt->getAddr() - pioAddr;
104
105 DPRINTF(Uart, " read register %#x\n", daddr);
106
107 switch (daddr) {
108 case 0x0:
109 if (!(LCR & 0x80)) { // read byte
110 if (device->dataAvailable())
111 pkt->set(device->readData());
111 pkt->setRaw(device->readData());
112 else {
112 else {
113 pkt->set((uint8_t)0);
113 pkt->setRaw((uint8_t)0);
114 // A limited amount of these are ok.
115 DPRINTF(Uart, "empty read of RX register\n");
116 }
117 status &= ~RX_INT;
118 platform->clearConsoleInt();
119
120 if (device->dataAvailable() && (IER & UART_IER_RDI))
121 scheduleIntr(&rxIntrEvent);
122 } else { // dll divisor latch
123 ;
124 }
125 break;
126 case 0x1:
127 if (!(LCR & 0x80)) { // Intr Enable Register(IER)
114 // A limited amount of these are ok.
115 DPRINTF(Uart, "empty read of RX register\n");
116 }
117 status &= ~RX_INT;
118 platform->clearConsoleInt();
119
120 if (device->dataAvailable() && (IER & UART_IER_RDI))
121 scheduleIntr(&rxIntrEvent);
122 } else { // dll divisor latch
123 ;
124 }
125 break;
126 case 0x1:
127 if (!(LCR & 0x80)) { // Intr Enable Register(IER)
128 pkt->set(IER);
128 pkt->setRaw(IER);
129 } else { // DLM divisor latch MSB
130 ;
131 }
132 break;
133 case 0x2: // Intr Identification Register (IIR)
134 DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
135
136 if (status & RX_INT) /* Rx data interrupt has a higher priority */
129 } else { // DLM divisor latch MSB
130 ;
131 }
132 break;
133 case 0x2: // Intr Identification Register (IIR)
134 DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
135
136 if (status & RX_INT) /* Rx data interrupt has a higher priority */
137 pkt->set(IIR_RXID);
137 pkt->setRaw(IIR_RXID);
138 else if (status & TX_INT) {
138 else if (status & TX_INT) {
139 pkt->set(IIR_TXID);
139 pkt->setRaw(IIR_TXID);
140 //Tx interrupts are cleared on IIR reads
141 status &= ~TX_INT;
142 } else
140 //Tx interrupts are cleared on IIR reads
141 status &= ~TX_INT;
142 } else
143 pkt->set(IIR_NOPEND);
143 pkt->setRaw(IIR_NOPEND);
144
145 break;
146 case 0x3: // Line Control Register (LCR)
144
145 break;
146 case 0x3: // Line Control Register (LCR)
147 pkt->set(LCR);
147 pkt->setRaw(LCR);
148 break;
149 case 0x4: // Modem Control Register (MCR)
148 break;
149 case 0x4: // Modem Control Register (MCR)
150 pkt->set(MCR);
150 pkt->setRaw(MCR);
151 break;
152 case 0x5: // Line Status Register (LSR)
153 uint8_t lsr;
154 lsr = 0;
155 // check if there are any bytes to be read
156 if (device->dataAvailable())
157 lsr = UART_LSR_DR;
158 lsr |= UART_LSR_TEMT | UART_LSR_THRE;
151 break;
152 case 0x5: // Line Status Register (LSR)
153 uint8_t lsr;
154 lsr = 0;
155 // check if there are any bytes to be read
156 if (device->dataAvailable())
157 lsr = UART_LSR_DR;
158 lsr |= UART_LSR_TEMT | UART_LSR_THRE;
159 pkt->set(lsr);
159 pkt->setRaw(lsr);
160 break;
161 case 0x6: // Modem Status Register (MSR)
160 break;
161 case 0x6: // Modem Status Register (MSR)
162 pkt->set((uint8_t)0);
162 pkt->setRaw((uint8_t)0);
163 break;
164 case 0x7: // Scratch Register (SCR)
163 break;
164 case 0x7: // Scratch Register (SCR)
165 pkt->set((uint8_t)0); // doesn't exist with at 8250.
165 pkt->setRaw((uint8_t)0); // doesn't exist with at 8250.
166 break;
167 default:
168 panic("Tried to access a UART port that doesn't exist\n");
169 break;
170 }
171/* uint32_t d32 = *data;
172 DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
173*/

--- 5 unchanged lines hidden (view full) ---

179Uart8250::write(PacketPtr pkt)
180{
181
182 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
183 assert(pkt->getSize() == 1);
184
185 Addr daddr = pkt->getAddr() - pioAddr;
186
166 break;
167 default:
168 panic("Tried to access a UART port that doesn't exist\n");
169 break;
170 }
171/* uint32_t d32 = *data;
172 DPRINTF(Uart, "Register read to register %#x returned %#x\n", daddr, d32);
173*/

--- 5 unchanged lines hidden (view full) ---

179Uart8250::write(PacketPtr pkt)
180{
181
182 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
183 assert(pkt->getSize() == 1);
184
185 Addr daddr = pkt->getAddr() - pioAddr;
186
187 DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt->get<uint8_t>());
187 DPRINTF(Uart, " write register %#x value %#x\n", daddr,
188 pkt->getRaw<uint8_t>());
188
189 switch (daddr) {
190 case 0x0:
191 if (!(LCR & 0x80)) { // write byte
189
190 switch (daddr) {
191 case 0x0:
192 if (!(LCR & 0x80)) { // write byte
192 device->writeData(pkt->get());
193 device->writeData(pkt->getRaw<uint8_t>());
193 platform->clearConsoleInt();
194 status &= ~TX_INT;
195 if (UART_IER_THRI & IER)
196 scheduleIntr(&txIntrEvent);
197 } else { // dll divisor latch
198 ;
199 }
200 break;
201 case 0x1:
202 if (!(LCR & 0x80)) { // Intr Enable Register(IER)
194 platform->clearConsoleInt();
195 status &= ~TX_INT;
196 if (UART_IER_THRI & IER)
197 scheduleIntr(&txIntrEvent);
198 } else { // dll divisor latch
199 ;
200 }
201 break;
202 case 0x1:
203 if (!(LCR & 0x80)) { // Intr Enable Register(IER)
203 IER = pkt->get();
204 IER = pkt->getRaw<uint8_t>();
204 if (UART_IER_THRI & IER)
205 {
205 if (UART_IER_THRI & IER)
206 {
206 DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
207 DPRINTF(Uart,
208 "IER: IER_THRI set, scheduling TX intrrupt\n");
207 if (curTick() - lastTxInt > 225 * SimClock::Int::ns) {
208 DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n",
209 curTick(), lastTxInt);
210 txIntrEvent.process();
211 } else {
212 DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n",
213 curTick(), lastTxInt);
214 scheduleIntr(&txIntrEvent);
215 }
216 }
217 else
218 {
209 if (curTick() - lastTxInt > 225 * SimClock::Int::ns) {
210 DPRINTF(Uart, "-- Interrupting Immediately... %d,%d\n",
211 curTick(), lastTxInt);
212 txIntrEvent.process();
213 } else {
214 DPRINTF(Uart, "-- Delaying interrupt... %d,%d\n",
215 curTick(), lastTxInt);
216 scheduleIntr(&txIntrEvent);
217 }
218 }
219 else
220 {
219 DPRINTF(Uart, "IER: IER_THRI cleared, descheduling TX intrrupt\n");
221 DPRINTF(Uart, "IER: IER_THRI cleared, "
222 "descheduling TX intrrupt\n");
220 if (txIntrEvent.scheduled())
221 deschedule(txIntrEvent);
222 if (status & TX_INT)
223 platform->clearConsoleInt();
224 status &= ~TX_INT;
225 }
226
227 if ((UART_IER_RDI & IER) && device->dataAvailable()) {
223 if (txIntrEvent.scheduled())
224 deschedule(txIntrEvent);
225 if (status & TX_INT)
226 platform->clearConsoleInt();
227 status &= ~TX_INT;
228 }
229
230 if ((UART_IER_RDI & IER) && device->dataAvailable()) {
228 DPRINTF(Uart, "IER: IER_RDI set, scheduling RX intrrupt\n");
231 DPRINTF(Uart,
232 "IER: IER_RDI set, scheduling RX intrrupt\n");
229 scheduleIntr(&rxIntrEvent);
230 } else {
233 scheduleIntr(&rxIntrEvent);
234 } else {
231 DPRINTF(Uart, "IER: IER_RDI cleared, descheduling RX intrrupt\n");
235 DPRINTF(Uart, "IER: IER_RDI cleared, "
236 "descheduling RX intrrupt\n");
232 if (rxIntrEvent.scheduled())
233 deschedule(rxIntrEvent);
234 if (status & RX_INT)
235 platform->clearConsoleInt();
236 status &= ~RX_INT;
237 }
238 } else { // DLM divisor latch MSB
239 ;
240 }
241 break;
242 case 0x2: // FIFO Control Register (FCR)
243 break;
244 case 0x3: // Line Control Register (LCR)
237 if (rxIntrEvent.scheduled())
238 deschedule(rxIntrEvent);
239 if (status & RX_INT)
240 platform->clearConsoleInt();
241 status &= ~RX_INT;
242 }
243 } else { // DLM divisor latch MSB
244 ;
245 }
246 break;
247 case 0x2: // FIFO Control Register (FCR)
248 break;
249 case 0x3: // Line Control Register (LCR)
245 LCR = pkt->get();
250 LCR = pkt->getRaw<uint8_t>();
246 break;
247 case 0x4: // Modem Control Register (MCR)
251 break;
252 case 0x4: // Modem Control Register (MCR)
248 if (pkt->get() == (UART_MCR_LOOP | 0x0A))
253 if (pkt->getRaw<uint8_t>() == (UART_MCR_LOOP | 0x0A))
249 MCR = 0x9A;
250 break;
251 case 0x7: // Scratch Register (SCR)
252 // We are emulating a 8250 so we don't have a scratch reg
253 break;
254 default:
255 panic("Tried to access a UART port that doesn't exist\n");
256 break;

--- 70 unchanged lines hidden ---
254 MCR = 0x9A;
255 break;
256 case 0x7: // Scratch Register (SCR)
257 // We are emulating a 8250 so we don't have a scratch reg
258 break;
259 default:
260 panic("Tried to access a UART port that doesn't exist\n");
261 break;

--- 70 unchanged lines hidden ---