Merge into main the new state of the operating system/kernel #1
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								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
 | 
			
		||||
 | 
			
		||||
@ -52,10 +52,6 @@ void initGDT(){
 | 
			
		||||
 | 
			
		||||
      LoadGlobalDescriptorTable();
 | 
			
		||||
 | 
			
		||||
      while (true)
 | 
			
		||||
         asm volatile("hlt");
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 ){
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
@ -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; }
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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 );
 | 
			
		||||
inline uint16_t getDeviceID(uint8_t bus, uint8_t device, uint8_t function ){
 | 
			
		||||
    return ConfigReadWord(bus, device, function , 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user