| 85 |
int thr_ipending; |
int thr_ipending; |
| 86 |
int irq; |
int irq; |
| 87 |
CharDriverState *chr; |
CharDriverState *chr; |
| 88 |
|
int last_break_enable; |
| 89 |
}; |
}; |
| 90 |
|
|
| 91 |
static void serial_update_irq(SerialState *s) |
static void serial_update_irq(SerialState *s) |
| 104 |
} |
} |
| 105 |
} |
} |
| 106 |
|
|
| 107 |
|
static void serial_update_parameters(SerialState *s) |
| 108 |
|
{ |
| 109 |
|
int speed, parity, data_bits, stop_bits; |
| 110 |
|
|
| 111 |
|
if (s->lcr & 0x08) { |
| 112 |
|
if (s->lcr & 0x10) |
| 113 |
|
parity = 'E'; |
| 114 |
|
else |
| 115 |
|
parity = 'O'; |
| 116 |
|
} else { |
| 117 |
|
parity = 'N'; |
| 118 |
|
} |
| 119 |
|
if (s->lcr & 0x04) |
| 120 |
|
stop_bits = 2; |
| 121 |
|
else |
| 122 |
|
stop_bits = 1; |
| 123 |
|
data_bits = (s->lcr & 0x03) + 5; |
| 124 |
|
if (s->divider == 0) |
| 125 |
|
return; |
| 126 |
|
speed = 115200 / s->divider; |
| 127 |
|
#if 0 |
| 128 |
|
printf("speed=%d parity=%c data=%d stop=%d\n", |
| 129 |
|
speed, parity, data_bits, stop_bits); |
| 130 |
|
#endif |
| 131 |
|
} |
| 132 |
|
|
| 133 |
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| 134 |
{ |
{ |
| 135 |
SerialState *s = opaque; |
SerialState *s = opaque; |
| 144 |
case 0: |
case 0: |
| 145 |
if (s->lcr & UART_LCR_DLAB) { |
if (s->lcr & UART_LCR_DLAB) { |
| 146 |
s->divider = (s->divider & 0xff00) | val; |
s->divider = (s->divider & 0xff00) | val; |
| 147 |
|
serial_update_parameters(s); |
| 148 |
} else { |
} else { |
| 149 |
s->thr_ipending = 0; |
s->thr_ipending = 0; |
| 150 |
s->lsr &= ~UART_LSR_THRE; |
s->lsr &= ~UART_LSR_THRE; |
| 160 |
case 1: |
case 1: |
| 161 |
if (s->lcr & UART_LCR_DLAB) { |
if (s->lcr & UART_LCR_DLAB) { |
| 162 |
s->divider = (s->divider & 0x00ff) | (val << 8); |
s->divider = (s->divider & 0x00ff) | (val << 8); |
| 163 |
|
serial_update_parameters(s); |
| 164 |
} else { |
} else { |
| 165 |
s->ier = val & 0x0f; |
s->ier = val & 0x0f; |
| 166 |
if (s->lsr & UART_LSR_THRE) { |
if (s->lsr & UART_LSR_THRE) { |
| 172 |
case 2: |
case 2: |
| 173 |
break; |
break; |
| 174 |
case 3: |
case 3: |
| 175 |
s->lcr = val; |
{ |
| 176 |
|
int break_enable; |
| 177 |
|
s->lcr = val; |
| 178 |
|
serial_update_parameters(s); |
| 179 |
|
break_enable = (val >> 6) & 1; |
| 180 |
|
if (break_enable != s->last_break_enable) { |
| 181 |
|
s->last_break_enable = break_enable; |
| 182 |
|
qemu_chr_set_serial_break(s, break_enable); |
| 183 |
|
} |
| 184 |
|
} |
| 185 |
break; |
break; |
| 186 |
case 4: |
case 4: |
| 187 |
s->mcr = val & 0x1f; |
s->mcr = val & 0x1f; |