int32_t ide_wait(uint8_t channel, int advanced) { uint8_t status = 0; /* Do the delay first */ ide_delay(channel); /* Now we wait for it to clear BUSY */ while((status = _inb(ide_channels[channel].base + IDE_REGISTER_STATUS)) & IDE_ATA_BUSY); /* Do error check aswell? */ if(advanced) { status = _inb(ide_channels[channel].base + IDE_REGISTER_STATUS); if(status & IDE_ERROR_FAULT) return -1; if(status & IDE_ERROR_GENERIC) return -2; if(!(status & IDE_ERROR_DRQ)) return -3; } return 0; }
char keydown() { if( ! _test_bit(_inb(PORTB),ucKEY)) { _delay_ms(7); if(! _test_bit(_inb(PORTB),ucKEY )) return 1; } return 0 ; }
/*key detect routine*/ char press(char n) { if( ! _test_bit(_inb(PORTB), n) ){ _delay_ms(7); if(! _test_bit(_inb(PORTB), n) ){ while( ! _test_bit(_inb(PORTB), n) ); return 1; } } return 0; }
unsigned char wait_ec(unsigned char rw) { unsigned int l = 0; if( rw == _READ ) { while( !( _inb(0x66) & _READ) && ( l < 10000 ) ) { usleep(10000); l++; } } else { while( ( _inb(0x66) & _WRITE) && ( l < 10000 ) ) { usleep(10000); l++; } } return -(l == 10000); }
unsigned int _dense_inb(unsigned long port) { if ((port & ~0xffff) == 0) return _inb(port); mem_barrier(); return *(volatile CARD8 *)port; }
unsigned char read_temperature() { if( !wait_ec(_WRITE) ) _outb(0x66, 0x80); if( !wait_ec(_WRITE) ) _outb(0x62, TEMPERATURE); if( !wait_ec(_READ) ) return(_inb(0x62)); }
void keyboard_handler(void) { unsigned int scancode = _inb(0x60); char key = 0; kbd_status[scancode & ~SCANCODE_EXT] = !(scancode & SCANCODE_EXT); if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_LSHIFT) { lshift = !(scancode & SCANCODE_EXT); return; } if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_RSHIFT) { rshift = !(scancode & SCANCODE_EXT); return; } if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_CAPSLOCK) { if (!(scancode & SCANCODE_EXT)) { capslock = !capslock; } return; } if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_LCTRL) { lctrl = !(scancode & SCANCODE_EXT); return; } if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_RCTRL) { rctrl = !(scancode & SCANCODE_EXT); return; } if ((scancode & ~SCANCODE_EXT) == SCANCODE_CHAR_APOSTROPHE && !acute) { if (!(scancode & SCANCODE_EXT)) { acute = true; } return; } /* Mask arrows */ if ((scancode & ~SCANCODE_EXT) == 0x48 || (scancode & ~SCANCODE_EXT) == 0x4d || (scancode & ~SCANCODE_EXT) == 0x50 || (scancode & ~SCANCODE_EXT) == 0x4b) { return; } if (!(scancode & 0x80)) { key = kbd_keymap_get(scancode); } _event_callback(key, kbd_status); }
/************************************************************* *initialize_pics * Inicializa los PICS, el 1 como Master el 2 como slave * y les coloca los offset enviados * Recibe: Offset1 para el PIC1 * Offset2 para el PIC2 **************************************************************/ void initialize_pics(int offset_pic1, int offset_pic2){ unsigned char mask1 = _inb(PIC1_DATA); unsigned char mask2 = _inb(PIC2_DATA); _outb(PIC1_COMMAND, ICW1); _outb(PIC2_COMMAND, ICW1); _outb(PIC1_DATA, offset_pic1); _outb(PIC2_DATA, offset_pic2); _outb(PIC1_DATA, 4); _outb(PIC2_DATA, 2); _outb(PIC1_DATA, ICW4_8086); _outb(PIC2_DATA, ICW4_8086); _outb(PIC1_DATA, mask1); _outb(PIC2_DATA, mask2); }
unsigned short read_011() { unsigned short add=0; unsigned char i=0; _clear_bit(REF165_PORT,SH_REF165); //recept parallen load data, lockit _delay_us(7); _set_bit(REF165_PORT,SH_REF165); //lock it _delay_ms(1); _clear_bit(REF165_PORT,CLK_REF165); for (i=0;i<8;i++) { if(_test_bit(_inb(REF165_PORT),QH_REF165)) _set_bit(add,7-i); //上电后QH的值即是165的第8位值,可以直接赋值完后,给165上升沿读取下个数据 _clear_bit(REF165_PORT,CLK_REF165); _delay_us(7); _set_bit(REF165_PORT,CLK_REF165); _delay_us(7); } for (i=0;i<8;i++) { if(_test_bit(_inb(REF165_PORT),QH_REF165)) _set_bit(add,15-i); //上电后QH的值即是165的第8位值,可以直接赋值完后,给165上升沿读取下个数据 _clear_bit(REF165_PORT,CLK_REF165); _delay_us(7); _set_bit(REF165_PORT,CLK_REF165); _delay_us(7); } return add; }
uint8_t ide_read(uint8_t channel, uint8_t reg) { /* */ uint8_t data = 0;; if(reg > 0x07 && reg < 0x0C) ide_write(channel, IDE_REGISTER_CTRL, 0x80 | ide_channels[channel].irq); /* */ if(reg < 0x08) data = _inb((uint16_t)(ide_channels[channel].base + reg)); else if(reg < 0x0C) data = _inb((uint16_t)(ide_channels[channel].base + reg - 0x06)); else if(reg < 0x0E) data = _inb((uint16_t)(ide_channels[channel].ctrl + reg - 0x0A)); else if(reg < 0x16) data = _inb((uint16_t)(ide_channels[channel].busm + reg - 0x0E)); if(reg > 0x07 && reg < 0x0C) ide_write(channel, IDE_REGISTER_CTRL, ide_channels[channel].irq); return data; }
int play_speaker(uint16_t f) { int freq = 1193182 / f; _outb(0xb6, 0x43); /* sets the mode of the PIT. 0xb6 = 10/11/011/0 */ _outb((short int)freq, 0x42); /* sets frec on channel 2 of the PIT */ _outb((short int)(freq >> 8), 0x42); uint8_t tmp = _inb(0x61); tmp = tmp | 3; _outb(tmp, 0x61); return 1; }
unsigned int inb(unsigned long port) { int fd = ia64_port_to_fd(port); unsigned char val; if (!fd) return _inb(port & 0xffff); if (lseek(fd, port & 0xffff, SEEK_SET) == -1) { ErrorF("I/O lseek failed\n"); val = -1; goto out; } if (read(fd, &val, 1) != 1) { ErrorF("I/O read failed\n"); val = -1; goto out; } out: return val; }
/********************************************** kmain() Punto de entrada de código C. *************************************************/ kmain() { int i, num; // Paging.start(0x200000); // init_malloc(); initialize_pics(0x20,0x70); setup_IDT_entry(&idt[0x70], 0x08, (dword) & _rtc, ACS_INT, 0); _cache_init(); hdd_init(); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE IRQ0 */ setup_IDT_entry (&idt[0x00], 0x08, (dword)&_int_00_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x01], 0x08, (dword)&_int_01_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x02], 0x08, (dword)&_int_02_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x03], 0x08, (dword)&_int_03_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x04], 0x08, (dword)&_int_04_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x05], 0x08, (dword)&_int_05_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x06], 0x08, (dword)&_int_06_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x07], 0x08, (dword)&_int_07_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x08], 0x08, (dword)&_int_08_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x09], 0x08, (dword)&_int_09_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0A], 0x08, (dword)&_int_0A_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0B], 0x08, (dword)&_int_0B_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0C], 0x08, (dword)&_int_0C_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0D], 0x08, (dword)&_int_0D_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0E], 0x08, (dword)&_int_0E_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x0F], 0x08, (dword)&_int_0F_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x10], 0x08, (dword)&_int_10_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x11], 0x08, (dword)&_int_11_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x12], 0x08, (dword)&_int_12_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x13], 0x08, (dword)&_int_13_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x14], 0x08, (dword)&_int_14_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x15], 0x08, (dword)&_int_15_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x16], 0x08, (dword)&_int_16_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x17], 0x08, (dword)&_int_17_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x18], 0x08, (dword)&_int_18_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x19], 0x08, (dword)&_int_19_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1A], 0x08, (dword)&_int_1A_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1B], 0x08, (dword)&_int_1B_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1C], 0x08, (dword)&_int_1C_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1D], 0x08, (dword)&_int_1D_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1E], 0x08, (dword)&_int_1E_hand, ACS_INT, 0); setup_IDT_entry (&idt[0x1F], 0x08, (dword)&_int_1F_hand, ACS_INT, 0); // setup_IDT_entry (&idt[0x20], 0x08, (dword)&_int_20_hand, ACS_INT, 0); // setup_IDT_entry (&idt[0x21], 0x08, (dword)&_int_21_hand, ACS_INT, 0); setup_IDT_entry(&idt[0x20], 0x08, (dword) & _timer_tick_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE IRQ1 */ setup_IDT_entry(&idt[0x21], 0x08, (dword) & _KB_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE int80h */ setup_IDT_entry(&idt[0x80], 0x08, (dword) & _int_80_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE int79h */ setup_IDT_entry(&idt[0x79], 0x08, (dword) & _int_79_hand, ACS_INT, 0); /* Carga de IDTR */ idtr.base = 0; idtr.base += (dword) & idt; idtr.limit = sizeof(idt) - 1; _lidt(&idtr); Cli(); int rate = 0x06; _outb(0x70, 0x0A); //set index to register A char prev=_inb(0x71); //get initial value of register A _outb(0x70, 0x0A); //reset index to A _outb(0x71, (prev & 0xF0) | rate); //write only our rate to A. Note, rate is the bottom 4 bits. init_paging(); scheduler_init(); /* Habilito interrupcion de timer tick*/ _mascaraPIC1(0xFC); _mascaraPIC2(0xFE); _outb(0x70, 0x0B); //set the index to register B prev= _inb(0x71); //read the current value of register B _outb(0x70, 0x0B); //set the index again(a read will reset the index to register D) _outb(0x71, prev | 0x40); //write the previous value or'd with 0x40. This turns on bit 6 of register B Sti(); idle = create_process("idle", idle_main, 0, 0, 0, 0, 0, 0, 0, NULL, 0); // We soon exit out of here :) while (1); }
/********************************************** kmain() Punto de entrada de código C. *************************************************/ kmain() { int i, num; setup_IDT_entry(&idt[0x70], 0x08, (dword) & _rtc, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE IRQ0 */ setup_IDT_entry(&idt[0x08], 0x08, (dword) & _int_08_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE IRQ1 */ setup_IDT_entry(&idt[0x09], 0x08, (dword) & _int_09_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE int80h */ setup_IDT_entry(&idt[0x80], 0x08, (dword) & _int_80_hand, ACS_INT, 0); /* CARGA DE IDT CON LA RUTINA DE ATENCION DE int79h */ setup_IDT_entry(&idt[0x79], 0x08, (dword) & _int_79_hand, ACS_INT, 0); /* Carga de IDTR */ idtr.base = 0; idtr.base += (dword) & idt; idtr.limit = sizeof(idt) - 1; _lidt(&idtr); Cli(); int rate = 0x06; _outb(0x70, 0x0A); //set index to register A char prev=_inb(0x71); //get initial value of register A _outb(0x70, 0x0A); //reset index to A _outb(0x71, (prev & 0xF0) | rate); //write only our rate to A. Note, rate is the bottom 4 bits. scheduler_init(); /* Habilito interrupcion de timer tick*/ _mascaraPIC1(0x00); _mascaraPIC2(0x00); _outb(0x70, 0x0B); //set the index to register B prev= _inb(0x71); //read the current value of register B _outb(0x70, 0x0B); //set the index again(a read will reset the index to register D) _outb(0x71, prev | 0x40); //write the previous value or'd with 0x40. This turns on bit 6 of register B Sti(); idle = create_process("idle", idle_main, 0, 0, 0, 0, 0, 0, 0, NULL, 0); // We soon exit out of here :) while (1); }
void stop_speaker() { uint8_t tmp = _inb(0x61); tmp = tmp | 252; _outb(tmp, 0x61); }
/** * Initialize disk device driver. Reserves memory for data structures * and register driver to the interrupt handler. * * @param desc Pointer to the PCI IO device descriptor of the controller * * @return Pointer to the device structure of the controller */ int disk_init(io_descriptor_t *desc) { /* Cast it */ pci_conf_t *pci = (pci_conf_t*)(uint64_t*) desc; /* Set bases to default values */ uint16_t iobase1 = IDE_PRIMARY_CMD_BASE; uint16_t iobase2 = IDE_SECONDARY_CMD_BASE; uint16_t ctrlbase1 = IDE_PRIMARY_CTRL_BASE; uint16_t ctrlbase2 = IDE_SECONDARY_CTRL_BASE; uint16_t busmaster = pci->bar4; uint32_t i, j, count = 0; uint16_t buf[256]; /* Check for compatability mode */ if(pci->prog_if & 0x1) { /* Native mode for channel 1 */ iobase1 = (uint16_t)pci->bar0; ctrlbase1 = (uint16_t)pci->bar1; /* Check if they can be relocated */ if(iobase1 & 0x1) iobase1--; if(ctrlbase1 & 0x1) ctrlbase1--; } if(pci->prog_if & 0x4) { /* Native mode for channel 2 */ iobase2 = (uint16_t)pci->bar2; ctrlbase2 = (uint16_t)pci->bar3; /* Check if they can be relocated */ if(iobase2 & 0x1) iobase2--; if(ctrlbase2 & 0x1) ctrlbase2--; } /* Setup Channels */ ide_channels[IDE_PRIMARY].busm = busmaster; ide_channels[IDE_PRIMARY].base = iobase1; ide_channels[IDE_PRIMARY].ctrl = ctrlbase1; ide_channels[IDE_PRIMARY].irq = IDE_PRIMARY_IRQ; ide_channels[IDE_PRIMARY].irq_wait = 0; ide_channels[IDE_PRIMARY].dma_phys = 0; ide_channels[IDE_PRIMARY].dma_virt = 0; ide_channels[IDE_PRIMARY].dma_buf_phys = 0; ide_channels[IDE_PRIMARY].dma_buf_virt = 0; ide_channels[IDE_SECONDARY].busm = busmaster; ide_channels[IDE_SECONDARY].base = iobase2; ide_channels[IDE_SECONDARY].ctrl = ctrlbase2; ide_channels[IDE_SECONDARY].irq = IDE_SECONDARY_IRQ; ide_channels[IDE_SECONDARY].irq_wait = 0; ide_channels[IDE_SECONDARY].dma_phys = 0; ide_channels[IDE_SECONDARY].dma_virt = 0; ide_channels[IDE_SECONDARY].dma_buf_phys = 0; ide_channels[IDE_SECONDARY].dma_buf_virt = 0; /* Install interrupts */ interrupt_register(IDE_PRIMARY_IRQ, (int_handler_t)ide_irq_handler0, 0); interrupt_register(IDE_SECONDARY_IRQ, (int_handler_t)ide_irq_handler1, 0); /* Disable Irqs, we use polling mode */ ide_write(IDE_PRIMARY, IDE_REGISTER_CTRL, 2); ide_write(IDE_SECONDARY, IDE_REGISTER_CTRL, 2); /* Enumerate devices */ /* We send an IDE_IDENTIFY command to each device, on * each channel, and see if it responds */ for(i = 0; i < IDE_CHANNELS_PER_CTRL; i++) { for(j = 0; j < IDE_DEVICES_PER_CHANNEL; j++) { /* Variables */ uint8_t error = 0, type = 0, status = 0; uint32_t lba28 = 0; uint64_t lba48 = 0; ide_devices[count].present = 0; //assume no drive /* Step 1. Select drive */ ide_write(i, IDE_REGISTER_HDDSEL, 0xA0 | (j << 4)); ide_delay(i); /* Step 2. Send IDE_IDENTIFY */ ide_write(i, IDE_REGISTER_SECCOUNT0, 0); ide_write(i, IDE_REGISTER_LBA0, 0); ide_write(i, IDE_REGISTER_LBA1, 0); ide_write(i, IDE_REGISTER_LBA2, 0); ide_write(i, IDE_REGISTER_LBA2, 0); ide_write(i, IDE_REGISTER_COMMAND, IDE_COMMAND_IDENTIFY); ide_delay(i); /* Step 3. Poll */ status = _inb(ide_channels[i].base + IDE_REGISTER_STATUS); if(status == 0 || status == 0x7F || status == 0xFF) { count++; continue; } /* Wuhuu! device is here */ while(1) { status = _inb(ide_channels[i].base + IDE_REGISTER_STATUS); if(status & 0x1) { error = 1; break; } if(!(status & IDE_ATA_BUSY) && (status & IDE_ATA_DRQ)) { break; } } /* Step 4. Probe for ATAPI */ if(error != 0) { /* Get type */ uint8_t cl = _inb(ide_channels[i].base + IDE_REGISTER_LBA1); uint8_t ch = _inb(ide_channels[i].base + IDE_REGISTER_LBA2); if(cl == 0x14 && ch == 0xEB) /* PATAPI */ type = 1; else if(cl == 0x69 && ch == 0x96) /* SATAPI */ type = 1; else { /* Unknown Type */ count++; continue; } /* Identify */ ide_write(i, IDE_REGISTER_COMMAND, IDE_COMMAND_PACKET); ide_delay(i); } /* Step 5. Read identification space */ _insw(ide_channels[i].base + IDE_REGISTER_DATA, 256, (uint8_t*)buf); /* Step 6. Read device parameters */ ide_devices[count].present = 1; ide_devices[count].type = type; ide_devices[count].channel = i; ide_devices[count].drive = j; ide_devices[count].signature = (*(uint16_t*)(buf)); ide_devices[count].capabilities = (*(uint16_t*)(buf + 49)); ide_devices[count].commandset = (*(uint32_t*)(buf + 82)); /* Step 7. Get geometry */ lba28 = (*(uint32_t*)(buf + 60)); lba48 = (*(uint64_t*)(buf + 100)); if(lba48) { ide_devices[count].totalsectors = lba48; ide_devices[count].cylinders = (*(uint16_t*)(buf + 1)); ide_devices[count].headspercylinder = (*(uint16_t*)(buf + 3)); ide_devices[count].secsperhead = (*(uint64_t*)(buf + 6)); ide_devices[count].flags |= 0x1; } else if(lba28 && !lba48) { ide_devices[count].totalsectors = lba28; ide_devices[count].cylinders = (*(uint16_t*)(buf + 1)); ide_devices[count].headspercylinder = (*(uint16_t*)(buf + 3)); ide_devices[count].secsperhead = (*(uint64_t*)(buf + 6)); } else { ide_devices[count].totalsectors = 0; ide_devices[count].cylinders = 0; ide_devices[count].headspercylinder = 0; ide_devices[count].secsperhead = 0; } /* Register filesystem */ ide_dev[count].real_device = &(ide_channels[0]); ide_dev[count].type = TYPECODE_DISK; ide_dev[count].generic_device = &ide_gbd[count]; ide_dev[count].io_address = count; /* Setup ide device */ ide_gbd[count].device = &ide_dev[count]; ide_gbd[count].write_block = ide_write_block; ide_gbd[count].read_block = ide_read_block; ide_gbd[count].block_size = ide_get_sectorsize; ide_gbd[count].total_blocks = ide_get_sectorcount; device_register(&ide_dev[count]); /* Increase count */ count++; } } return 0; }
int is_transmit_empty() { return _inb(SERIAL_PORT + 5) & 0x20; }
char read_serial() { return _inb(SERIAL_PORT); }
int serial_received() { return _inb(SERIAL_PORT + 5) & 1; }