static unsigned int videointerface_readcolormap(struct system_node *self, struct system_node *current, struct service_state *state, void *buffer, unsigned int count, unsigned int offset) { char *c = buffer; unsigned int i; if (count > VGA_COLORMAP_LIMIT) count = VGA_COLORMAP_LIMIT; if (offset > count) return 0; for (i = offset; i < count * 3; i += 3) { io_outb(VGA_REGISTER_DACRINDEX, i / 3); c[i + 0] = io_inb(VGA_REGISTER_DACDATA); c[i + 1] = io_inb(VGA_REGISTER_DACDATA); c[i + 2] = io_inb(VGA_REGISTER_DACDATA); } return i - offset; }
/* * Initialises the CMOS RTC driver. */ static void* rtc_init(device_t *dev) { // Read initial RTC values rtc_read(); // Enable the periodic IRQ IRQ_OFF(); io_outb(CMOS_REG_PORT, 0x8B); uint8_t reg = io_inb(CMOS_DATA_PORT); io_outb(CMOS_REG_PORT, 0x8B); io_outb(CMOS_DATA_PORT, reg | 0x40); // Rate is 2 Hz io_outb(CMOS_REG_PORT, 0x8A); reg = io_inb(CMOS_DATA_PORT); io_outb(CMOS_REG_PORT, 0x8A); io_outb(CMOS_DATA_PORT, (reg & 0xF0) | 0x0F); // Install IRQ handler hal_register_irq_handler(8, rtc_sys_tick, NULL); // Re-enable IRQs IRQ_RES(); return BUS_NO_INIT_DATA; }
static unsigned int videointerface_rcolormap(unsigned int offset, void *buffer, unsigned int count) { char *c = buffer; unsigned int i; if (count > VGA_COLORMAP_LIMIT) count = VGA_COLORMAP_LIMIT; if (offset > count) return 0; for (i = offset; i < count * 3; i += 3) { io_outb(VGA_REGISTER_DACRINDEX, i / 3); c[i + 0] = io_inb(VGA_REGISTER_DACDATA); c[i + 1] = io_inb(VGA_REGISTER_DACDATA); c[i + 2] = io_inb(VGA_REGISTER_DACDATA); } return i - offset; }
void console_write(char *string) { unsigned int curchar, vidmem_off, i; io_outb(0x3d4, 0x0e); /* Get cursor Y position */ vidmem_off = io_inb(0x3d5); vidmem_off <<= 8; io_outb(0x3d4, 0x0f); /* And add cursor X position */ vidmem_off += io_inb(0x3d5); vidmem_off <<= 1; while((curchar=*string++)) /* Loop through the string */ { switch(curchar) /* Is it a special character ? */ { case '\n': /* Newline found */ vidmem_off = (vidmem_off/160)*160 + 160; break; case '\r': /* Carriage return found */ vidmem_off = (vidmem_off/160)*160; break; case '\t': vidmem_off += 8; break; case 8:/* Delete */ vidmem_off-=2; VIDEO_MEMORY[vidmem_off] = 0x20; break; default: /* Normal character */ VIDEO_MEMORY[vidmem_off++] = curchar; VIDEO_MEMORY[vidmem_off++] = 0x07; break; } if(vidmem_off >= 160*25) /* Are we off-screen ? */ { for(i = 0; i < 160*24; i++) /* Scroll the screen up */ { VIDEO_MEMORY[i] = VIDEO_MEMORY[i+160]; } for(i = 0; i < 80; i++) /* Empty the bottom row */ { VIDEO_MEMORY[(160*24)+(i*2)] = 0x20; VIDEO_MEMORY[(160*24)+(i*2)+1] = 0x07; } vidmem_off -= 160; /* We're on the bottom row */ } } vidmem_off >>= 1; /* Set the new cursor position */ io_outb(0x3d4, 0x0f); io_outb(0x3d5, vidmem_off & 0x0ff); io_outw(0x3d4, 0x0e); io_outb(0x3d5, vidmem_off >> 8); }/* console_write */
static void flushdata(void) { while ((io_inb(REGISTERCONTROL) & STATUSOFULL)) io_inb(REGISTERDATA); }
/* * Read from a register of a channel. */ static uint8_t ata_reg_read(ata_driver_t *drv, uint8_t channel, uint8_t reg) { uint8_t result = 0; // Set high LBA flag if (reg > 0x07 && reg < 0x0C) { ata_reg_write(drv, channel, ATA_REG_CONTROL, 0x80 | drv->channels[channel].nIEN); } // If register is 0-7, read from base address if (reg < 0x08) { result = io_inb(drv->channels[channel].base + reg - 0x00); } // Is register SECCOUNT0, or LBA 3 through 5? else if (reg < 0x0C) { result = io_inb(drv->channels[channel].base + reg - 0x06); } // Is register DEVADDRESS? else if (reg < 0x0E) { result = io_inb(drv->channels[channel].ctrl + reg - 0x0A); } else if (reg < 0x16) { result = io_inb(drv->channels[channel].bmide + reg - 0x0E); } // Reset high LBA flag if (reg > 0x07 && reg < 0x0C) { ata_reg_write(drv, channel, ATA_REG_CONTROL, drv->channels[channel].nIEN); } return result; }
static unsigned char polldata(void) { while (!(io_inb(REGISTERCONTROL) & STATUSOFULL)); return io_inb(REGISTERDATA); }
void kkeyb_update_leds(uint8_t status) { while((io_inb(0x64)&2)!=0){} io_outb(0x60,0xED); while((io_inb(0x64)&2)!=0){} io_outb(0x60,status); }
/** * Aggiorna lo stato dei led della tastiera */ void keyboard_update_leds(uint8_t status) { uint8_t tmp; while((io_inb(0x64)&2)!=0){} io_outb(0x60,0xED); while((io_inb(0x64)&2)!=0){} io_outb(0x60,status); }
void setleds() { io_outb(0x60, 0xED); while(io_inb(0x64) & 2) /* wait. */; io_outb(0x60, led_status); while(io_inb(0x64) & 2) /* wait. */; }
/** * Unmasks the IRQ with the given index. * * @param index The index of the IRQ to unmask. */ void irq_pic_unmask(uint8_t index) { // IRQ 2 is always unmasked if (2 == index) return; // PIC 1 or PIC 2? if (index > 7 && index <= 15) io_outb(IO_PIC2_DATA, io_inb(IO_PIC2_DATA) & ~(1 << (index - 8))); else if (index <= 7) io_outb(IO_PIC1_DATA, io_inb(IO_PIC1_DATA) & ~(1 << index)); }
/** * Masks the IRQ with the given index. * * @param index The index of the IRQ to mask. */ void irq_pic_mask(uint8_t index) { // IRQ 2 cannot be masked if (UNLIKELY(2 == index)) return; // PIC 1 or PIC 2? if (index > 7 && index <= 15) io_outb(IO_PIC2_DATA, io_inb(IO_PIC2_DATA) | (1 << (index - 8))); else if (index <= 7) io_outb(IO_PIC1_DATA, io_inb(IO_PIC1_DATA) | (1 << index)); }
void __noreturn reboot(void) { uint8_t tmp; disable_interrupts(); do { tmp = io_inb(KEYBOARD_CMND); if (TEST_FLAG(tmp, KBD_KDATA_BIT) != 0) io_inb(KEYBOARD_DATA); } while (TEST_FLAG(tmp, KBD_UDATA_BIT) != 0); io_outb(KEYBOARD_CMND, KEYBOARD_RESET); printk(PRINTK_ERROR "Rebooting"); hang(); }
MouseDriver::MouseDriver() : Driver("Mouse", "ps") { uint8_t status; Wait(1); io_outb(0x64, 0xA8); Wait(1); io_outb(0x64, 0x20); Wait(0); status = (io_inb(0x60) | 2); Wait(1); io_outb(0x64, 0x60); Wait(1); io_outb(0x60, status); // Valori di default MouseWrite(0xF6); MouseRead(); // Abilita lo sacmbio dati MouseWrite(0xF4); MouseRead(); // Scaling 1:1 MouseWrite(0xE6); MouseRead(); // Imposta l'handler setHandler(MouseDriver::IRQ, &MouseCallback); }
/* * IRQ handler for the RTC (called twice a second) */ static void rtc_sys_tick(void* ctx) { // Read the RTC register so IRQ will happen again io_outb(0x70, 0x0C); io_inb(0x71); // Only increment time every second if(tick++ == 2) { tick = 0; } else { return; } // Increment seconds if(time.second++ == 59) { time.second = 0; // Increment minutes if(time.minute++ == 59) { time.minute = 0; // Resync with hardware every hour rtc_read(); } } // Reseed PRNG srand(irq_count()); // KDEBUG("%02u:%02u:%02u (%02u-%02u-%04u)", time.hour, time.minute, time.second, time.day, time.month, time.year); }
uint32_t PciBus::Read(uint32_t bus, uint32_t device, uint32_t function, uint32_t offset, uint8_t size) { uint32_t value; io_outd(0xCF8, 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | (offset & ~3)); switch (size) { case 1: value = io_inb(0xCFC + (offset & 3)); break; case 2: value = io_inw(0xCFC + (offset & 2)); break; case 4: value = io_ind(0xCFC); break; default: return 0xFF; } return value; }
int kb_handler(struct isr_regs *regs) { char scancode; scancode = io_inb(0x60); printk("\tKeyboard handler here! scancode is %x\n", scancode); }
BOOL harddisk_request(u32 lba, u32 sects_to_read) { u32 cylinder_no, head_no, sect_no, temp; cylinder_no = lba / (HD0_HEAD_PER_CYLINDER * HD0_SECT_PER_TRACK); temp = lba % (HD0_HEAD_PER_CYLINDER * HD0_SECT_PER_TRACK); head_no = temp / HD0_SECT_PER_TRACK; sect_no = temp % HD0_SECT_PER_TRACK + 1; /* check if harddisk is busy, if busy, wait */ while ((io_inb(HD_PORT_STATUS) & 0x80) != 0) ; /* set sect number and CHS */ io_outb(sects_to_read, HD_PORT_SECT_COUNT); io_outb(sect_no, HD_PORT_SECT_NO); io_outb(cylinder_no, HD_PORT_CYLINDER_LOW); cylinder_no >>= 8; io_outb((cylinder_no), HD_PORT_CYLINDER_HIGH); /* 0xa0 = 1010 0000, * when set head, bit5 and bit7 should be 1, * when bit6 == 0, bit0~bit3 is the head no, * bit4 is driver no, 0 is HD0 */ head_no |= 0xa0; io_outb((head_no), HD_PORT_DRIVE_HEAD); /* send read command */ io_outb(HD_CMD_READ, HD_PORT_COMMAND); return TRUE; }
static void setdata(unsigned char value) { while ((io_inb(REGISTERCONTROL) & STATUSIFULL)); io_outb(REGISTERDATA, value); }
static void setcommand(unsigned char value) { while ((io_inb(REGISTERCONTROL) & STATUSIFULL)); io_outb(REGISTERCONTROL, value); }
// Called by keyboard driver when Ctrl+Alt+Del is pressed void hid_keyboard_sas(void) { KWARNING("Ctrl+Alt+Del triggered"); uint8_t good = 0x02; while (good & 0x02) { good = io_inb(0x64); } io_outb(0x64, 0xFE); }
void do_keyboard() { u8 scan_code = io_inb(0x60); /* 读取扫描码 */ if (!is_queue_full(&kb_queue)) /* 若队列未满则入队,否则放弃该扫描码 */ { en_queue(&kb_queue, scan_code); } io_outb(0x20, 0x20); }
void Wait(uint8_t a_type) { uint32_t time_out = 100000; if(a_type == 0) { while(time_out--) if((io_inb(0x64) & 1) == 1) return; return; } else { while(time_out--) if((io_inb(0x64) & 2) == 0) return; return; } }
/** * Inizializza l'rtc */ void clock_init() { char prev; io_outb(0x70, 0x0B); prev = io_inb(0x71); io_outb(0x70, 0x0B); io_outb(0x71, prev | 0x40); handler_reg(8, &clock_callback); }
void irq_unmask(int irq_line) { uint16_t port; uint8_t mask; if (irq_line < 8) port = IO_PIC1_DATA; else { port = IO_PIC2_DATA; irq_line -= 8; } mask = io_inb(port); io_outb(port, mask & ~(1 << irq_line)); }
/** * Handler della tastiera */ static void keyboard_callback(regs_t *reg) { unsigned code = io_inb(0x60); // Tasto rilasciato if (code & 0x80) { code &= 0x7F; switch(code) { case SHIFT_LEFT: case SHIFT_RIGHT: shift = 0; break; } } // Tasto premuto else { switch(code) { case LOCK_CAPS: capslock = !capslock; keyboard_update_leds(LED_CAPS | LED_NUM); break; case LOCK_NUM: numlock = !numlock; keyboard_update_leds(LED_CAPS | LED_NUM); break; case SHIFT_LEFT: case SHIFT_RIGHT: shift = 1; break; default: if((shift && !capslock) || (!shift && capslock)) buf[bufpoint] = keyboard_standard_charset_shifted[code]; else buf[bufpoint] = keyboard_standard_charset[code]; bufsize++; bufpoint++; break; } } }
void pit_wait(unsigned int ms) { unsigned short x = 1193 * ms; io_outb(io + REGISTERCOMMAND, COMMANDCHANNEL0 | COMMANDBOTH | COMMANDMODE0); io_outb(io + REGISTERCHANNEL0, x >> 8); io_outb(io + REGISTERCHANNEL0, x); io_outb(io + REGISTERCOMMAND, 0xE2); while (!(io_inb(io + REGISTERCHANNEL0) & (1 << 7))); /* Return old values */ io_outb(io + REGISTERCOMMAND, COMMANDCHANNEL0 | COMMANDBOTH | COMMANDMODE3); io_outb(io + REGISTERCHANNEL0, divisor); io_outb(io + REGISTERCHANNEL0, divisor >> 8); }
/* Taken from http://www.sci.muni.cz/docs/pc/serport.txt */ static int serial_detect(const u16 addr) { u8 od; /* Check for UART presence */ od = io_inb(addr + 4); io_outb(addr + 4, 0x10); if (io_inb(addr + 6) & 0xF0) return 0; io_outb(addr + 4, 0x1F); if ((io_inb(addr + 6) & 0xF0) != 0xF0) return 0; io_outb(addr + 4, od); /* Check if 8250 */ od = io_inb(addr + 7); io_outb(addr + 7, 0x55); if (io_inb(addr + 7) != 0x55) return 1; io_outb(addr + 7, 0xAA); if (io_inb(addr + 7) != 0xAA) return 1; io_outb(addr + 7, od); /* Check for FIFO */ io_outb(addr + 2, 0x01); od = io_inb(addr + 2); io_outb(addr + 2, 0x00); /* Check if 8250 or 16450 with scratch regs */ if (!(od & 0x80)) return 2; /* Check if 16450 */ if (!(od & 0x40)) return 3; /* Then it's a 16550A */ return 4; }
unsigned int ps2_checkdata(unsigned int id) { unsigned char control = io_inb(REGISTERCONTROL); if (!(control & 0x01)) return 0; switch (id) { case PS2_KEYBOARD: return !(control & 0x20); case PS2_MOUSE: return (control & 0x20); } return 0; }
static void MouseCallback(regs_t *reg) { switch(Cycle) { case 0: Byte[0] = io_inb(0x60); Cycle++; break; case 1: Byte[1] = io_inw(0x60); Cycle++; break; case 2: Byte[2] = io_inw(0x60); Cycle = 0; //printf("%d %d\n", Byte[1], Byte[2]); break; } }