61 |
/* output Bochs bios info messages */ |
/* output Bochs bios info messages */ |
62 |
//#define DEBUG_BIOS |
//#define DEBUG_BIOS |
63 |
|
|
64 |
|
//#define DEBUG_CMOS |
65 |
|
|
66 |
/* debug PIC */ |
/* debug PIC */ |
67 |
//#define DEBUG_PIC |
//#define DEBUG_PIC |
68 |
|
|
75 |
/* debug PC keyboard : only mouse */ |
/* debug PC keyboard : only mouse */ |
76 |
//#define DEBUG_MOUSE |
//#define DEBUG_MOUSE |
77 |
|
|
78 |
|
//#define DEBUG_SERIAL |
79 |
|
|
80 |
#define PHYS_RAM_BASE 0xac000000 |
#define PHYS_RAM_BASE 0xac000000 |
81 |
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) |
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024) |
82 |
|
|
201 |
#define KERNEL_CS 0x10 |
#define KERNEL_CS 0x10 |
202 |
#define KERNEL_DS 0x18 |
#define KERNEL_DS 0x18 |
203 |
|
|
204 |
#define MAX_IOPORTS 4096 |
/* XXX: use a two level table to limit memory usage */ |
205 |
|
#define MAX_IOPORTS 65536 |
206 |
|
|
207 |
static const char *bios_dir = CONFIG_QEMU_SHAREDIR; |
static const char *bios_dir = CONFIG_QEMU_SHAREDIR; |
208 |
char phys_ram_file[1024]; |
char phys_ram_file[1024]; |
466 |
{ |
{ |
467 |
if (addr == 0x70) { |
if (addr == 0x70) { |
468 |
cmos_index = data & 0x7f; |
cmos_index = data & 0x7f; |
469 |
|
} else { |
470 |
|
#ifdef DEBUG_CMOS |
471 |
|
printf("cmos: write index=0x%02x val=0x%02x\n", |
472 |
|
cmos_index, data); |
473 |
|
#endif |
474 |
|
switch(addr) { |
475 |
|
case RTC_SECONDS_ALARM: |
476 |
|
case RTC_MINUTES_ALARM: |
477 |
|
case RTC_HOURS_ALARM: |
478 |
|
/* XXX: not supported */ |
479 |
|
cmos_data[cmos_index] = data; |
480 |
|
break; |
481 |
|
case RTC_SECONDS: |
482 |
|
case RTC_MINUTES: |
483 |
|
case RTC_HOURS: |
484 |
|
case RTC_DAY_OF_WEEK: |
485 |
|
case RTC_DAY_OF_MONTH: |
486 |
|
case RTC_MONTH: |
487 |
|
case RTC_YEAR: |
488 |
|
cmos_data[cmos_index] = data; |
489 |
|
break; |
490 |
|
case RTC_REG_A: |
491 |
|
case RTC_REG_B: |
492 |
|
cmos_data[cmos_index] = data; |
493 |
|
break; |
494 |
|
case RTC_REG_C: |
495 |
|
case RTC_REG_D: |
496 |
|
/* cannot write to them */ |
497 |
|
break; |
498 |
|
default: |
499 |
|
cmos_data[cmos_index] = data; |
500 |
|
break; |
501 |
|
} |
502 |
} |
} |
503 |
} |
} |
504 |
|
|
509 |
if (addr == 0x70) { |
if (addr == 0x70) { |
510 |
return 0xff; |
return 0xff; |
511 |
} else { |
} else { |
|
/* toggle update-in-progress bit for Linux (same hack as |
|
|
plex86) */ |
|
512 |
ret = cmos_data[cmos_index]; |
ret = cmos_data[cmos_index]; |
513 |
if (cmos_index == RTC_REG_A) |
switch(cmos_index) { |
514 |
|
case RTC_REG_A: |
515 |
|
/* toggle update-in-progress bit for Linux (same hack as |
516 |
|
plex86) */ |
517 |
cmos_data[RTC_REG_A] ^= 0x80; |
cmos_data[RTC_REG_A] ^= 0x80; |
518 |
else if (cmos_index == RTC_REG_C) |
break; |
519 |
|
case RTC_REG_C: |
520 |
|
pic_set_irq(8, 0); |
521 |
cmos_data[RTC_REG_C] = 0x00; |
cmos_data[RTC_REG_C] = 0x00; |
522 |
|
break; |
523 |
|
} |
524 |
|
#ifdef DEBUG_CMOS |
525 |
|
printf("cmos: read index=0x%02x val=0x%02x\n", |
526 |
|
cmos_index, ret); |
527 |
|
#endif |
528 |
return ret; |
return ret; |
529 |
} |
} |
530 |
} |
} |
722 |
irq, |
irq, |
723 |
(double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec); |
(double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec); |
724 |
#endif |
#endif |
725 |
#ifdef DEBUG_PIC |
#if defined(DEBUG_PIC) |
726 |
printf("pic_interrupt: irq=%d\n", irq); |
printf("pic_interrupt: irq=%d\n", irq); |
727 |
#endif |
#endif |
728 |
|
|
1238 |
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ |
#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ |
1239 |
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ |
#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ |
1240 |
|
|
1241 |
|
/* |
1242 |
|
* These are the definitions for the Modem Control Register |
1243 |
|
*/ |
1244 |
|
#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ |
1245 |
|
#define UART_MCR_OUT2 0x08 /* Out2 complement */ |
1246 |
|
#define UART_MCR_OUT1 0x04 /* Out1 complement */ |
1247 |
|
#define UART_MCR_RTS 0x02 /* RTS complement */ |
1248 |
|
#define UART_MCR_DTR 0x01 /* DTR complement */ |
1249 |
|
|
1250 |
|
/* |
1251 |
|
* These are the definitions for the Modem Status Register |
1252 |
|
*/ |
1253 |
|
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ |
1254 |
|
#define UART_MSR_RI 0x40 /* Ring Indicator */ |
1255 |
|
#define UART_MSR_DSR 0x20 /* Data Set Ready */ |
1256 |
|
#define UART_MSR_CTS 0x10 /* Clear to Send */ |
1257 |
|
#define UART_MSR_DDCD 0x08 /* Delta DCD */ |
1258 |
|
#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ |
1259 |
|
#define UART_MSR_DDSR 0x02 /* Delta DSR */ |
1260 |
|
#define UART_MSR_DCTS 0x01 /* Delta CTS */ |
1261 |
|
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ |
1262 |
|
|
1263 |
#define UART_LSR_TEMT 0x40 /* Transmitter empty */ |
#define UART_LSR_TEMT 0x40 /* Transmitter empty */ |
1264 |
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ |
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ |
1265 |
#define UART_LSR_BI 0x10 /* Break interrupt indicator */ |
#define UART_LSR_BI 0x10 /* Break interrupt indicator */ |
1278 |
uint8_t lsr; /* read only */ |
uint8_t lsr; /* read only */ |
1279 |
uint8_t msr; |
uint8_t msr; |
1280 |
uint8_t scr; |
uint8_t scr; |
1281 |
|
/* NOTE: this hidden state is necessary for tx irq generation as |
1282 |
|
it can be reset while reading iir */ |
1283 |
|
int thr_ipending; |
1284 |
} SerialState; |
} SerialState; |
1285 |
|
|
1286 |
SerialState serial_ports[1]; |
SerialState serial_ports[1]; |
1291 |
|
|
1292 |
if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { |
if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { |
1293 |
s->iir = UART_IIR_RDI; |
s->iir = UART_IIR_RDI; |
1294 |
} else if ((s->lsr & UART_LSR_THRE) && (s->ier & UART_IER_THRI)) { |
} else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { |
1295 |
s->iir = UART_IIR_THRI; |
s->iir = UART_IIR_THRI; |
1296 |
} else { |
} else { |
1297 |
s->iir = UART_IIR_NO_INT; |
s->iir = UART_IIR_NO_INT; |
1310 |
int ret; |
int ret; |
1311 |
|
|
1312 |
addr &= 7; |
addr &= 7; |
1313 |
|
#ifdef DEBUG_SERIAL |
1314 |
|
printf("serial: write addr=0x%02x val=0x%02x\n", addr, val); |
1315 |
|
#endif |
1316 |
switch(addr) { |
switch(addr) { |
1317 |
default: |
default: |
1318 |
case 0: |
case 0: |
1319 |
if (s->lcr & UART_LCR_DLAB) { |
if (s->lcr & UART_LCR_DLAB) { |
1320 |
s->divider = (s->divider & 0xff00) | val; |
s->divider = (s->divider & 0xff00) | val; |
1321 |
} else { |
} else { |
1322 |
|
s->thr_ipending = 0; |
1323 |
s->lsr &= ~UART_LSR_THRE; |
s->lsr &= ~UART_LSR_THRE; |
1324 |
serial_update_irq(); |
serial_update_irq(); |
1325 |
|
|
1327 |
do { |
do { |
1328 |
ret = write(1, &ch, 1); |
ret = write(1, &ch, 1); |
1329 |
} while (ret != 1); |
} while (ret != 1); |
1330 |
|
s->thr_ipending = 1; |
1331 |
s->lsr |= UART_LSR_THRE; |
s->lsr |= UART_LSR_THRE; |
1332 |
s->lsr |= UART_LSR_TEMT; |
s->lsr |= UART_LSR_TEMT; |
1333 |
serial_update_irq(); |
serial_update_irq(); |
1386 |
break; |
break; |
1387 |
case 2: |
case 2: |
1388 |
ret = s->iir; |
ret = s->iir; |
1389 |
|
/* reset THR pending bit */ |
1390 |
|
if ((ret & 0x7) == UART_IIR_THRI) |
1391 |
|
s->thr_ipending = 0; |
1392 |
|
serial_update_irq(); |
1393 |
break; |
break; |
1394 |
case 3: |
case 3: |
1395 |
ret = s->lcr; |
ret = s->lcr; |
1401 |
ret = s->lsr; |
ret = s->lsr; |
1402 |
break; |
break; |
1403 |
case 6: |
case 6: |
1404 |
ret = s->msr; |
if (s->mcr & UART_MCR_LOOP) { |
1405 |
|
/* in loopback, the modem output pins are connected to the |
1406 |
|
inputs */ |
1407 |
|
ret = (s->mcr & 0x0c) << 4; |
1408 |
|
ret |= (s->mcr & 0x02) << 3; |
1409 |
|
ret |= (s->mcr & 0x01) << 5; |
1410 |
|
} else { |
1411 |
|
ret = s->msr; |
1412 |
|
} |
1413 |
break; |
break; |
1414 |
case 7: |
case 7: |
1415 |
ret = s->scr; |
ret = s->scr; |
1416 |
break; |
break; |
1417 |
} |
} |
1418 |
|
#ifdef DEBUG_SERIAL |
1419 |
|
printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret); |
1420 |
|
#endif |
1421 |
return ret; |
return ret; |
1422 |
} |
} |
1423 |
|
|
1480 |
SerialState *s = &serial_ports[0]; |
SerialState *s = &serial_ports[0]; |
1481 |
|
|
1482 |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
1483 |
|
s->iir = UART_IIR_NO_INT; |
1484 |
|
|
1485 |
register_ioport_write(0x3f8, 8, serial_ioport_write, 1); |
register_ioport_write(0x3f8, 8, serial_ioport_write, 1); |
1486 |
register_ioport_read(0x3f8, 8, serial_ioport_read, 1); |
register_ioport_read(0x3f8, 8, serial_ioport_read, 1); |
1487 |
} |
} |
2201 |
{ |
{ |
2202 |
KBDState *s = &kbd_state; |
KBDState *s = &kbd_state; |
2203 |
KBDQueue *q; |
KBDQueue *q; |
2204 |
int val; |
int val, index; |
2205 |
|
|
2206 |
q = &s->queues[0]; /* first check KBD data */ |
q = &s->queues[0]; /* first check KBD data */ |
2207 |
if (q->count == 0) |
if (q->count == 0) |
2208 |
q = &s->queues[1]; /* then check AUX data */ |
q = &s->queues[1]; /* then check AUX data */ |
2209 |
if (q->count == 0) { |
if (q->count == 0) { |
2210 |
/* XXX: return something else ? */ |
/* NOTE: if no data left, we return the last keyboard one |
2211 |
val = 0; |
(needed for EMM386) */ |
2212 |
|
/* XXX: need a timer to do things correctly */ |
2213 |
|
q = &s->queues[0]; |
2214 |
|
index = q->rptr - 1; |
2215 |
|
if (index < 0) |
2216 |
|
index = KBD_QUEUE_SIZE - 1; |
2217 |
|
val = q->data[index]; |
2218 |
} else { |
} else { |
2219 |
val = q->data[q->rptr]; |
val = q->data[q->rptr]; |
2220 |
if (++q->rptr == KBD_QUEUE_SIZE) |
if (++q->rptr == KBD_QUEUE_SIZE) |
2829 |
pic_set_irq(0, 1); |
pic_set_irq(0, 1); |
2830 |
pic_set_irq(0, 0); |
pic_set_irq(0, 0); |
2831 |
timer_irq_pending = 0; |
timer_irq_pending = 0; |
2832 |
|
/* XXX: RTC test */ |
2833 |
|
if (cmos_data[RTC_REG_B] & 0x40) { |
2834 |
|
pic_set_irq(8, 1); |
2835 |
|
} |
2836 |
} |
} |
2837 |
|
|
2838 |
/* VGA */ |
/* VGA */ |
3219 |
env->idt.limit = 0xffff; |
env->idt.limit = 0xffff; |
3220 |
env->gdt.limit = 0xffff; |
env->gdt.limit = 0xffff; |
3221 |
env->ldt.limit = 0xffff; |
env->ldt.limit = 0xffff; |
3222 |
|
env->ldt.flags = DESC_P_MASK; |
3223 |
|
env->tr.limit = 0xffff; |
3224 |
|
env->tr.flags = DESC_P_MASK; |
3225 |
|
|
3226 |
/* not correct (CS base=0xffff0000) */ |
/* not correct (CS base=0xffff0000) */ |
3227 |
cpu_x86_load_seg_cache(env, R_CS, 0xf000, (uint8_t *)0x000f0000, 0xffff, 0); |
cpu_x86_load_seg_cache(env, R_CS, 0xf000, (uint8_t *)0x000f0000, 0xffff, 0); |