diff options
| author | Miguel <m.i@gmx.at> | 2018-08-18 16:20:26 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-08-18 16:20:26 +0200 |
| commit | 639c3d47b09114628f8e1f8817c27c10bf1fb28c (patch) | |
| tree | f0381de25cc8f2de96a87b47cc76f7d09548bf7e /driver | |
| parent | 7b0d88b2dff9b635d9ff69f6d51b6832c1ca4c40 (diff) | |
reviving old drivers: mouse, pci, e1000
Diffstat (limited to 'driver')
| -rw-r--r-- | driver/e1000.c | 4 | ||||
| -rw-r--r-- | driver/e1000.h | 1 | ||||
| -rw-r--r-- | driver/keyboard.c | 2 | ||||
| -rw-r--r-- | driver/mouse.c | 166 | ||||
| -rw-r--r-- | driver/pci.c | 134 | ||||
| -rw-r--r-- | driver/serial.c | 37 | ||||
| -rw-r--r-- | driver/serial.h | 11 |
7 files changed, 355 insertions, 0 deletions
diff --git a/driver/e1000.c b/driver/e1000.c new file mode 100644 index 0000000..99194be --- /dev/null +++ b/driver/e1000.c @@ -0,0 +1,4 @@ + +void init_e1000() +{ +} diff --git a/driver/e1000.h b/driver/e1000.h new file mode 100644 index 0000000..5413fe1 --- /dev/null +++ b/driver/e1000.h @@ -0,0 +1 @@ +void init_e1000(); diff --git a/driver/keyboard.c b/driver/keyboard.c index 8d7c8aa..55e3c41 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -4,6 +4,7 @@ #define FOOLOS_MODULE_NAME "keyboard" #include <stdbool.h> #include "kernel/x86.h" +#include "lib/logger/log.h" static bool ctrl_l=false; static bool shift_l=false; @@ -20,6 +21,7 @@ static void put(uint8_t c) void keyboard_init(uint32_t s) { kb_stream=s; + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Keyboard Initialized"); } void keyboard_handle(uint8_t in) diff --git a/driver/mouse.c b/driver/mouse.c new file mode 100644 index 0000000..d676f45 --- /dev/null +++ b/driver/mouse.c @@ -0,0 +1,166 @@ +#define FOOLOS_MODULE_NAME "mouse" + +//http://forum.osdev.org/viewtopic.php?t=10247 +//based on Mouse.inc by SANiK +//License: Use as you wish, except to cause damage + +#include "lib/logger/log.h" +#include <stdint.h> + +#include "kernel/x86.h" + +static volatile uint8_t mouse_cycle; +static volatile uint8_t mouse_byte[3]; +volatile int16_t mouse_x; +volatile int16_t mouse_y; +static volatile uint8_t mouse_a; + +uint8_t mouse_read(); + +void mouse_wait(uint8_t a_type) //unsigned char +{ + uint32_t _time_out=100000; //unsigned int + if(a_type==0) + { + while(_time_out--) //Data + { + if((x86_inb(0x64) & 1)==1) + { + return; + } + } + return; + } + else + { + while(_time_out--) //Signal + { + if((x86_inb(0x64) & 2)==0) + { + return; + } + } + return; + } +} + +void mouse_write(uint8_t a_write) +{ + //Wait to be able to send a command + mouse_wait(1); + //Tell the mouse we are sending a command + x86_outb(0x64, 0xD4); + //Wait for the final part + mouse_wait(1); + //Finally write + x86_outb(0x60, a_write); +} + +int8_t mouse_get_x() +{ + return mouse_x; +} +int8_t mouse_get_y() +{ + return mouse_y; +} + +void mouse_init() +{ + mouse_x=mouse_y=0; + mouse_cycle=0; + + uint8_t _status; //unsigned char + + //Enable the auxiliary mouse device + mouse_wait(1); + x86_outb(0x64, 0xA8); + + //Enable the interrupts + mouse_wait(1); + x86_outb(0x64, 0x20); + mouse_wait(0); + _status=(x86_inb(0x60) | 2); + mouse_wait(1); + x86_outb(0x64, 0x60); + mouse_wait(1); + x86_outb(0x60, _status); + + //Tell the mouse to use default settings + mouse_write(0xF6); + mouse_read(); //Acknowledge + + //Enable the mouse + mouse_write(0xF4); + mouse_read(); //Acknowledge + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Mouse Initialized"); +} + +void mouse_log() +{ + //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%02x / %02x / %02x ",mouse_byte[0], mouse_byte[1],mouse_byte[2]); + + if(mouse_byte[0]&0x80||mouse_byte[0]&0x40)return; //skip packet on overflow + if(!(mouse_byte[0]&0x8))panic(FOOLOS_MODULE_NAME,"mouse packets out of sync!?"); // this bit is always 1, otherwise panic! + + // + if(mouse_byte[1]>127){ + mouse_x-=256; + mouse_x+=mouse_byte[1]; + } + else + { + mouse_x+=mouse_byte[1]; + } + if(mouse_byte[2]>127){ + mouse_y-=256; + mouse_y+=mouse_byte[2]; + } + else + { + mouse_y+=mouse_byte[2]; + } + + if(mouse_x<0)mouse_x=0; + if(mouse_y<0)mouse_y=0; + if(mouse_x>800)mouse_x=800; + if(mouse_y>600)mouse_y=600; + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d / %d / %02x ",mouse_x, mouse_y,mouse_byte[2]); + //PutFont('X', mouse_x,600-mouse_y, 0xffffff); + +} + +//Mouse functions +void mouse_handler()//struct regs *a_r) //struct regs *a_r (not used but just there) +{ +// X86_IRQ_BEGIN + + switch(mouse_cycle) + { + case 0: + mouse_byte[0]=x86_inb(0x60); + mouse_cycle++; + break; + case 1: + mouse_byte[1]=x86_inb(0x60); + mouse_cycle++; + break; + case 2: + mouse_byte[2]=x86_inb(0x60); + mouse_cycle=0; + mouse_log(); + break; + } + +// X86_IRQ_END +} + +uint8_t mouse_read() +{ + //Get's response from mouse + mouse_wait(0); + return x86_inb(0x60); +} + diff --git a/driver/pci.c b/driver/pci.c new file mode 100644 index 0000000..677f445 --- /dev/null +++ b/driver/pci.c @@ -0,0 +1,134 @@ +#define FOOLOS_MODULE_NAME "pci" + +#include "kernel/kernel.h" +#include "kernel/x86.h" +#include "e1000.h" +#include "lib/logger/log.h" // logger facilities + +#define PCI_CONFIG_DATA 0xCFC +#define PCI_CONFIG_ADDRESS 0xCF8 + + void pciConfigSet (uint8_t bus, uint8_t slot, + uint8_t func, uint8_t offset, uint32_t data) + { + uint32_t address; + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + x86_outl (0xCF8, address); + x86_outl (0xCFC,data); + + } + uint16_t pciConfigReadWord (uint8_t bus, uint8_t slot, + uint8_t func, uint8_t offset) + { + uint32_t address; + uint32_t lbus = (uint32_t)bus; + uint32_t lslot = (uint32_t)slot; + uint32_t lfunc = (uint32_t)func; + uint16_t tmp = 0; + + /* create configuration address as per Figure 1 */ + address = (uint32_t)((lbus << 16) | (lslot << 11) | + (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); + + /* write out the address */ + x86_outl (0xCF8, address); + /* read in the data */ + /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits register */ + tmp = (uint16_t)((x86_inl (0xCFC) >> ((offset & 2) * 8)) & 0xffff); + return (tmp); + } + +void test_bar(uint8_t bus, uint8_t slot, uint8_t offset) +{ + + uint16_t bar_low=pciConfigReadWord(bus,slot,0,offset); + uint16_t bar_high=pciConfigReadWord(bus,slot,0,offset+2); + + // check size + pciConfigSet(bus,slot,0,offset,0xffffffff); + uint16_t size_low=pciConfigReadWord(bus,slot,0,offset); + uint16_t size_high=pciConfigReadWord(bus,slot,0,offset+2); + uint32_t size=(size_high<<16)+size_low; + size=~size; + size++; + // + + // restore original values + pciConfigSet(bus,slot,0,offset,(bar_high<<16)+bar_low); + + + log("e1000",FOOLOS_LOG_INFO,"%s bar: (0x%x 0x%x) size: 0x%x" ,bar_low&1?"i/o":"mem",bar_high, bar_low, size); + +} + +uint16_t pciCheck(uint8_t bus, uint8_t slot) +{ + + uint16_t vendor, device; + + /* try and read the first configuration register. Since there are no */ + /* vendors that == 0xFFFF, it must be a non-existent device. */ + if ((vendor = pciConfigReadWord(bus,slot,0,0)) != 0xFFFF) + { + device = pciConfigReadWord(bus,slot,0,2); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"[%d,%d]: vendor: 0x%x / device: 0x%x",bus,slot,vendor,device); + + // check for: E1000 (82540EM). PCI Ethernet Controller + if(vendor==0x8086&&device==0x100e) + { + // uint16_t irq=pciConfigReadWord(bus,slot,0,0x3C); + // uint16_t irq2=pciConfigReadWord(bus,slot,0,0x3E); + // + init_e1000(); + + test_bar(bus,slot,0x10); + test_bar(bus,slot,0x14); + test_bar(bus,slot,0x18); + + // scr_put_hex(irq); + // scr_put_hex(irq2); + // scr_put_string_nl(";"); + + + } + + + + + } + + return (vendor); + +} + +void pci_init() +{ + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"scanning bus"); + // todo: recurse on pci to pci bridges! + // todo: support multiple pci host controllers! + // (check more funcitons of device 0:0) + + uint16_t bus; + uint8_t device; + + for(bus = 0; bus < 256; bus++) + { + for(device = 0; device < 32; device++) + { + + pciCheck(bus, device); + + } + + } + +} diff --git a/driver/serial.c b/driver/serial.c new file mode 100644 index 0000000..f402d0c --- /dev/null +++ b/driver/serial.c @@ -0,0 +1,37 @@ +#define FOOLOS_MODULE_NAME "serial" +// https://wiki.osdev.org/Serial_Ports + +#define PORT 0x3f8 /* COM1 */ + +#include "lib/logger/log.h" + +void serial_init() { + + x86_outb(PORT + 1, 0x00); // Disable all interrupts + x86_outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + x86_outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + x86_outb(PORT + 1, 0x00); // (hi byte) + x86_outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + x86_outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + x86_outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"COM 1 - initialized"); +} + +int serial_received() { + return x86_inb(PORT + 5) & 1; +} + +char serial_read() { + while (serial_received() == 0); + return x86_inb(PORT); +} + +int is_transmit_empty() { + return x86_inb(PORT + 5) & 0x20; +} + +void serial_write(char a) { + while (is_transmit_empty() == 0); + x86_outb(PORT,a); +} diff --git a/driver/serial.h b/driver/serial.h new file mode 100644 index 0000000..2f287e6 --- /dev/null +++ b/driver/serial.h @@ -0,0 +1,11 @@ +void serial_init() + +char serial_read() { +int is_transmit_empty() { + return x86_inb(PORT + 5) & 0x20; +} + +void serial_write(char a) { + while (is_transmit_empty() == 0); + x86_outb(PORT,a); +} |
