// IBM/MS eject media static void disk_1346(struct bregs *regs, struct drive_s *drive_g) { if (regs->dl < EXTSTART_CD) { // Volume Not Removable disk_ret(regs, DISK_RET_ENOTREMOVABLE); return; } int cdid = regs->dl - EXTSTART_CD; u8 locks = GET_EBDA(cdrom_locks[cdid]); if (locks != 0) { disk_ret(regs, DISK_RET_ELOCKED); return; } // FIXME should handle 0x31 no media in device // FIXME should handle 0xb5 valid request failed // Call removable media eject struct bregs br; memset(&br, 0, sizeof(br)); br.ah = 0x52; call16_int(0x15, &br); if (br.ah || br.flags & F_CF) { disk_ret(regs, DISK_RET_ELOCKED); return; } disk_ret(regs, DISK_RET_SUCCESS); }
// INT09h : Keyboard Hardware Service Entry Point void VISIBLE16 handle_09(void) { if (! CONFIG_PS2PORT) return; debug_isr(DEBUG_ISR_09); // read key from keyboard controller u8 v = inb(PORT_PS2_STATUS); if (v & I8042_STR_AUXDATA) { dprintf(1, "ps2 keyboard irq but found mouse data?!\n"); goto done; } v = inb(PORT_PS2_DATA); if (!(GET_EBDA(ps2ctr) & I8042_CTR_KBDINT)) // Interrupts not enabled. goto done; process_key(v); done: eoi_pic1(); }
// INT74h : PS/2 mouse hardware interrupt void VISIBLE16 handle_74(void) { if (! CONFIG_PS2PORT) return; debug_isr(DEBUG_ISR_74); u8 v = inb(PORT_PS2_STATUS); if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA)) != (I8042_STR_OBF|I8042_STR_AUXDATA)) { dprintf(1, "ps2 mouse irq but no mouse data.\n"); goto done; } v = inb(PORT_PS2_DATA); if (!(GET_EBDA(ps2ctr) & I8042_CTR_AUXINT)) // Interrupts not enabled. goto done; process_mouse(v); done: eoi_pic2(); }
// status static void disk_134502(struct bregs *regs, struct drive_s *drive_g) { int cdid = regs->dl - EXTSTART_CD; u8 locks = GET_EBDA(cdrom_locks[cdid]); regs->al = (locks ? 1 : 0); disk_ret(regs, DISK_RET_SUCCESS); }
static void init_bda(void) { dprintf(3, "init bda\n"); struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); memset(bda, 0, sizeof(*bda)); int esize = EBDA_SIZE_START; SET_BDA(mem_size_kb, BUILD_LOWRAM_END/1024 - esize); u16 ebda_seg = EBDA_SEGMENT_START; SET_BDA(ebda_seg, ebda_seg); // Init ebda struct extended_bios_data_area_s *ebda = get_ebda_ptr(); memset(ebda, 0, sizeof(*ebda)); ebda->size = esize; add_e820((u32)MAKE_FLATPTR(ebda_seg, 0), GET_EBDA(ebda_seg, size) * 1024 , E820_RESERVED); // Init extra stack StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - datalow_base); }
static int __ps2_command(int aux, int command, u8 *param) { int ret2; int receive = (command >> 8) & 0xf; int send = (command >> 12) & 0xf; // Disable interrupts and keyboard/mouse. u8 ps2ctr = GET_EBDA(ps2ctr); u8 newctr = ((ps2ctr | I8042_CTR_AUXDIS | I8042_CTR_KBDDIS) & ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT)); dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr); int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr); if (ret) return ret; // Flush any interrupts already pending. yield(); // Enable port command is being sent to. if (aux) newctr &= ~I8042_CTR_AUXDIS; else newctr &= ~I8042_CTR_KBDDIS; ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr); if (ret) goto fail; if (command == ATKBD_CMD_RESET_BAT) { // Reset is special wrt timeouts and bytes received. // Send command. ret = ps2_sendbyte(aux, command, 1000); if (ret) goto fail; // Receive parameters. ret = ps2_recvbyte(aux, 0, 4000); if (ret < 0) goto fail; param[0] = ret; ret = ps2_recvbyte(aux, 0, 100); if (ret < 0) // Some devices only respond with one byte on reset. ret = 0; param[1] = ret; } else if (command == ATKBD_CMD_GETID) { // Getid is special wrt bytes received. // Send command. ret = ps2_sendbyte(aux, command, 200); if (ret) goto fail; // Receive parameters. ret = ps2_recvbyte(aux, 0, 500); if (ret < 0) goto fail; param[0] = ret; if (ret == 0xab || ret == 0xac || ret == 0x2b || ret == 0x5d || ret == 0x60 || ret == 0x47) { // These ids (keyboards) return two bytes. ret = ps2_recvbyte(aux, 0, 500); if (ret < 0) goto fail; param[1] = ret; } else { param[1] = 0; } } else { // Send command. ret = ps2_sendbyte(aux, command, 200); if (ret) goto fail; // Send parameters (if any). int i; for (i = 0; i < send; i++) { ret = ps2_sendbyte(aux, param[i], 200); if (ret) goto fail; } // Receive parameters (if any). for (i = 0; i < receive; i++) { ret = ps2_recvbyte(aux, 0, 500); if (ret < 0) goto fail; param[i] = ret; } } ret = 0; fail: // Restore interrupts and keyboard/mouse. ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr); if (ret2) return ret2; return ret; }
static int ps2_command(int aux, int command, u8 *param) { int ret2; int receive = (command >> 8) & 0xf; int send = (command >> 12) & 0xf; // Disable interrupts and keyboard/mouse. u8 ps2ctr = GET_EBDA(ps2ctr); u8 newctr = ps2ctr; if (aux) newctr |= I8042_CTR_KBDDIS; else newctr |= I8042_CTR_AUXDIS; newctr &= ~(I8042_CTR_KBDINT|I8042_CTR_AUXINT); dprintf(6, "i8042 ctr old=%x new=%x\n", ps2ctr, newctr); int ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr); if (ret) return ret; if (command == ATKBD_CMD_RESET_BAT) { // Reset is special wrt timeouts. // Send command. ret = ps2_sendbyte(aux, command, 1000); if (ret) goto fail; // Receive parameters. ret = ps2_recvbyte(aux, 0, 4000); if (ret < 0) goto fail; param[0] = ret; ret = ps2_recvbyte(aux, 0, 100); if (ret < 0) // Some devices only respond with one byte on reset. ret = 0; param[1] = ret; } else { // Send command. ret = ps2_sendbyte(aux, command, 200); if (ret) goto fail; // Send parameters (if any). int i; for (i = 0; i < send; i++) { ret = ps2_sendbyte(aux, param[i], 200); if (ret) goto fail; } // Receive parameters (if any). for (i = 0; i < receive; i++) { ret = ps2_recvbyte(aux, 0, 500); if (ret < 0) goto fail; param[i] = ret; } } ret = 0; fail: // Restore interrupts and keyboard/mouse. ret2 = i8042_command(I8042_CMD_CTL_WCTR, &ps2ctr); if (ret2) return ret2; return ret; }