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 | 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 --- |