diff --git a/Makefile b/Makefile index afa65c7..c553ba1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o SRC_DIR = src BUILD_DIR = build @@ -36,7 +36,7 @@ iso: clean_iso clean build grub-mkrescue -o build/barinkOS.iso root test: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -monitor stdio -display gtk -m 2G -cpu core2duo + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo build_kernel: $(OBJ_LINK_LIST) $(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \ @@ -85,3 +85,6 @@ $(BUILD_DIR)/string.o: $(BUILD_DIR)/PhysicalMemoryManager.o: $(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/pci.o: + $(CPP) -c $(SRC_DIR)/kernel/pci.cpp -o $(BUILD_DIR)/pci.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index f2624bf..d02d0fd 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -52,10 +52,6 @@ void initGDT(){ LoadGlobalDescriptorTable(); - while (true) - asm volatile("hlt"); - - } diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index 8a0861c..80e16d3 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -12,9 +12,10 @@ unsigned short inw_p(unsigned short ){ // TODO: implement me! return 0; } -unsigned int inl(unsigned short ){ -// TODO: implement me! - return 0; +uint32_t inl( int port ){ + unsigned int data; + asm volatile ("inl %w1, %0": "=a" (data): "d" (port)); + return data; } unsigned int inl_p(unsigned short ){ // TODO: implement me! @@ -31,9 +32,12 @@ void outw(unsigned short , unsigned short ){ void outw_p(unsigned short , unsigned short ){ } -void outl(unsigned int , unsigned short ){ +void outl( int port , uint32_t data ){ + asm volatile ("outl %0, %1" :: "a" (data), "dn"(port)); } + + void outl_p(unsigned int , unsigned short ){ } diff --git a/src/kernel/io.h b/src/kernel/io.h index c7fd561..094d595 100644 --- a/src/kernel/io.h +++ b/src/kernel/io.h @@ -12,21 +12,17 @@ static inline uint8_t inb(uint16_t port) unsigned char inb_p(unsigned short port); unsigned short inw(unsigned short port); unsigned short inw_p(unsigned short port); -unsigned int inl(unsigned short port); +uint32_t inl( int port ); unsigned int inl_p(unsigned short port); static inline void outb(uint16_t port, uint8_t val) { asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); - /* There's an outb %al, $imm8 encoding, for compile-time constant port numbers that fit in 8b. (N constraint). - * Wider immediate constants would be truncated at assemble-time (e.g. "i" constraint). - * The outb %al, %dx encoding is the only option for all other cases. - * %1 expands to %dx because port is a uint16_t. %w1 could be used if we had the port number a wider C type */ } void outb_p(unsigned char value, unsigned short port); void outw(unsigned short value, unsigned short port); void outw_p(unsigned short value, unsigned short port); -void outl(unsigned int value, unsigned short port); +void outl( int port , uint32_t data ); void outl_p(unsigned int value, unsigned short port); void insb(unsigned short port, void *addr, diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index d30350d..03654bf 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,15 +1,20 @@ #include "kernel.h" #define GB4 524288 #define GB2 262144 + +int memcmp( const void* ptr1, const void* ptr2, size_t num); + +extern "C" void kernel_main (void); + extern "C" void early_main(unsigned long magic, unsigned long addr){ - /** initialize terminal interface */ + /** initialize terminal interface */ kterm_init(); - + if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ printf("Invalid magic number: 0x%x\n", magic); return; } - + CheckMBT( (multiboot_info_t *) addr); multiboot_info_t* mbt = (multiboot_info_t*) addr; @@ -27,19 +32,83 @@ } initGDT(); + + + + kernel_main(); + } + + int memcmp( const void* ptr1, const void* ptr2, size_t num) + { + const unsigned char * cs = (const unsigned char*) ptr1; + const unsigned char * ct = (const unsigned char*) ptr2; + + + for (int i = 0 ; i < num ; i++, cs++, ct++ ){ + if( *cs < *ct){ + return -1; + } else if( *cs > *ct){ + return 1; + } + } + + return 0; - } extern "C" void kernel_main (void) { printf("call to init serial\n"); init_serial(); + print_serial("Serial port initialized!"); + + // Enumerate the PCI bus + + int devicesFound = 0; + // loop through all possible busses, devices and their functions; + for( int bus = 0 ; bus < 256 ; bus++) + { + + for(int device = 0; device < 32 ; device ++) + { + for ( int function = 0; function < 8; function++) + { + + uint64_t DeviceIdentify = ConfigReadWord(bus, device, function,0x0); + uint32_t VendorID = DeviceIdentify & 0xFFFF; + uint32_t DeviceID = DeviceIdentify >> 16; + + + + if( DeviceID != 0xFFFF){ + printf("bus: %d, device: %d, function %d \n"); + printf("Device found!\n"); + printf("DeviceID: 0x%x, VendorID: 0x%x\n", DeviceID, VendorID); + + uint32_t classcodes = ConfigReadWord(bus, device, function, 0x8); + uint32_t classData = classcodes >> 16; // We only care for the last 2 bytes! + uint32_t deviceClass = classData >> 8; + uint32_t subclass = classData & 0xFF; + + printf(" class: %d, subClass: %d\n\n", deviceClass, subclass); + devicesFound++; + + } + + + + } + + } + + } + + printf("Found %d devices!", devicesFound); while (true){ //Read time indefinetely - read_rtc(); - printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); + //read_rtc(); + //printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); delay(1000); } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index f82f5da..ff76ffa 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -16,6 +16,8 @@ extern "C"{ #include "time.h" #include "cpu.h" #include "serial.h" +#include "pci.h" + #define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) #define PANIC(message) { return; } diff --git a/src/kernel/pci.cpp b/src/kernel/pci.cpp index 3f81c29..a579fbd 100644 --- a/src/kernel/pci.cpp +++ b/src/kernel/pci.cpp @@ -1,108 +1,28 @@ #include "pci.h" +#include "tty/kterm.h" +#define PCI_BUS_ADDR_SHIFT 16 +#define PCI_DEVICE_ADDR_SHIFT 11 +#define PCI_FUNCTION_ADDR_SHIFT 8 +#define PCI_ENABLE_ADDR_SHIFT 31 -uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){ + + +uint32_t ConfigReadWord (uint8_t bus, uint8_t device, 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 */ + address = (uint32_t) ( + ((uint32_t) 1 << PCI_ENABLE_ADDR_SHIFT) | + ((uint32_t)bus << PCI_BUS_ADDR_SHIFT) | + ((uint32_t)device << PCI_DEVICE_ADDR_SHIFT) | + ((uint32_t)func << PCI_FUNCTION_ADDR_SHIFT) | + offset ); + // printf("PCI address read 0x%x", address); + + + outl(CONFIG_ADDRESS, address); - /* read in the data */ - /* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/ - tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF); - return (tmp); + + + return inl(CONFIG_DATA); } -uint16_t CheckVendor (uint8_t bus, uint8_t slot) { - uint16_t vendor, device; - /* - Try and read the first configuration register. Since there ar no - vendors that == 0xFFFF, it must be a non-existent device. - */ - if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) { - device = ConfigReadWord(bus, slot, 0,2); - // Possible read more config values ... - } return (vendor); -} - -void checkDevice (uint8_t bus, uint8_t device ) { - uint8_t function = 0; - - uint16_t vendorID = CheckVendor(bus, device); - if (vendorID == 0xFFFF) { - return; - } - - checkFunction (bus, device, function ); - headerType = getHeaderType(bus, device, function ); - if( (headerType & 0x80) != 0) { - /* It is a multi-function device, so check remaining functions */ - for (function = 1; function < 8; function++){ - if (CheckVendor(bus, device)!= 0xFFFF){ - checkFunction(bus, device, function ); - } - } - } - -} - - -void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){ - uint8_t baseClass; - uint8_t subClass; - uint8_t secondaryBus; - - baseClass = getBaseClass(bus, device, function); - subClass = getSubClass (bus, device, function ); - if ( (baseClass == 0x06) && (subClass == 0x04)){ - secondaryBus = getSecondaryBus(bus,device, function); - checkBus(secondaryBus); - } -} - - -// Brute-force scan -void checkAllBuses (){ - uint16_t bus; - uint8_t device; - - for(bus = 0; bus < 256; bus++){ - for(device = 0; device < 32; device++){ - checkDevice(bus,device); - } - } -} - -// Recursive scan -void checkBus (uint8_t bus){ - uint8_t device; - - for(device = 0; device < 32; device ++){ - checkDevice(bus,device); - } -} - -void checkAllBuses(){ - uint8_t function; - uint8_t bus; - - headerType = getHeaderType(0,0,0); - if ( (headerType & 0x80) == 0 ){ - /* Single PCI host controller */ - checkBus(0); - } else{ - /* Multiple PCI host controllers */ - for (function = 0; function < 8; function++){ - if( CheckVendor(0,0) != 0xFFFF) { - break; - } - bus = function; - checkBus(bus); - } - } - -} \ No newline at end of file diff --git a/src/kernel/pci.h b/src/kernel/pci.h index 93b15ce..7f5ed47 100644 --- a/src/kernel/pci.h +++ b/src/kernel/pci.h @@ -5,54 +5,13 @@ #define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed #define CONFIG_DATA 0xCFC // Will do the actual configuration operation -/* -CONFIG_ADDRESS - -32 bit register - -bit 31 Enable bit (Should CONFIG_DATA be translatedc to configuration cycles) -bit 30 - 24 Reserved -bit 23 - 16 Bus Number (Choose a specific PCI BUS) -bit 15 - 11 Device Number (Selects specific device one the pci bus) -bit 10 - 8 Function Number (Selects a specific function in a device) -bit 7 - 0 Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero - -*/ +uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset); -/* -PCI Device structure +inline uint16_t getVendorID(uint8_t bus, uint8_t device, uint8_t function ){ + return ConfigReadWord ( bus , device, function, 0); +} -Register offset bits 31-24 bits 23-16 bits 15-8 bits 7-0 -00 00 Device ID <---- Vendor ID <------- -01 04 Status <---- Command <------- -02 08 Class code Sub class Prog IF Revision ID -03 0C BIST Header Type Ltncy Timer Cache line Size -04 10 Base address #0 (BAR0) -05 14 Base address #1 (BAR1) -06 18 Base address #2 (BAR2) -07 1C Base address #3 (BAR3) -08 20 Base address #4 (BAR4) -09 24 Base address #5 (BAR5) -0A 28 Cardbus CIS Pointer -0B 2C Subsystem ID <------ Subsystem Vendor ID <------- -0C 30 Expansion ROM base address -0D 34 Reserved <------- Capabilities Pointer <------ -0E 38 Reserved <------- <-------- <-------- -0F 3C Max ltncy Min Grant Interrupt PIN Interrupt Line - -*/ - - -/* -The idea for now is to support the minimal things necessary to find ATA supported drives - */ - - -// Lets write some boiler plate configuration code - -uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); - -uint16_t CheckVendor (uint8_t bus, uint8_t slot); - -void checkDevice (uint8_t bus, uint8_t device ); \ No newline at end of file +inline uint16_t getDeviceID(uint8_t bus, uint8_t device, uint8_t function ){ + return ConfigReadWord(bus, device, function , 16); +}