Commit cc18f318 by malcolm

Merge branch 'pci_enum' into 'master'

Pci enum

Just writes all the PCI devices to serial

See merge request !16
parents 4d9fc048 47aabae5
...@@ -2,24 +2,39 @@ ...@@ -2,24 +2,39 @@
asm.h contains x86 specific functions for executing low level code asm.h contains x86 specific functions for executing low level code
*/ */
#pragma once #ifndef _ASM_INC
#define _ASM_INC
#include <stdint.h> #include <stdint.h>
// Wrapper for outb // Wrapper for outb
// Stolen from http://wiki.osdev.org/Inline_Assembly/Examples // Stolen from http://wiki.osdev.org/Inline_Assembly/Examples
inline void outb(uint16_t port, uint8_t val) inline void outb(uint16_t port, uint8_t val)
{ {
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port)); asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
} }
// Wrapper for inb // Wrapper for inb
inline uint8_t inb(uint16_t port) inline uint8_t inb(uint16_t port)
{ {
uint8_t ret; uint8_t ret;
asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret; return ret;
} }
// Wrapper for outl
inline void outl(uint16_t port, uint32_t val)
{
asm volatile("outl %0, %1" : : "a"(val), "Nd"(port));
}
// Wrapper for inl
inline uint32_t inl(uint16_t port)
{
uint32_t ret;
asm volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
inline void disable_int() inline void disable_int()
{ {
asm volatile ("cli"); asm volatile ("cli");
...@@ -29,3 +44,5 @@ inline void enable_int() ...@@ -29,3 +44,5 @@ inline void enable_int()
{ {
asm volatile ("sti"); asm volatile ("sti");
} }
#endif
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "gdt.h" #include "gdt.h"
#include "idt.h" #include "idt.h"
#include "test.h" #include "test.h"
#include "pci.h"
#include "multiboot.h" #include "multiboot.h"
#include "pic.h" #include "pic.h"
#include "pit.h" #include "pit.h"
...@@ -34,12 +35,12 @@ void kernel_main(multiboot_info* mbt, uint32_t magic) ...@@ -34,12 +35,12 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
io_init(); io_init();
pit_start_counter(100, PIT_OCW_CONT_0, PIT_OCW_MODE_SQWVGEN); pit_start_counter(100, PIT_OCW_CONT_0, PIT_OCW_MODE_SQWVGEN);
enable_int(); enable_int();
/* Since there is no support for newlines in terminal_putchar /* Since there is no support for newlines in terminal_putchar
* yet, '\n' will produce some VGA specific character instead. * yet, '\n' will produce some VGA specific character instead.
* This is normal. * This is normal.
*/ */
serial_writestring("Hello, kernel World!\n"); serial_writestring("Hello, kernel World!\n");
terminal_writestring("Hello, kernel World!\n"); terminal_writestring("Hello, kernel World!\n");
terminal_writestring("> "); terminal_writestring("> ");
...@@ -60,8 +61,13 @@ void kernel_main(multiboot_info* mbt, uint32_t magic) ...@@ -60,8 +61,13 @@ void kernel_main(multiboot_info* mbt, uint32_t magic)
serial_writestring("Finished Initilizing memory\n"); serial_writestring("Finished Initilizing memory\n");
int o=0; int o=0;
int j=5/o; int j=5/o;
serial_hexword(j); serial_hexword(j);
test_mem(); //test_mem();
serial_writechar('\n');
// PCI
checkAllBuses();
test_idt(); test_idt();
while(true) while(true)
{ {
......
...@@ -9,3 +9,8 @@ all: ...@@ -9,3 +9,8 @@ all:
clean: clean:
rm *.o *.bin rm *.o *.bin
run:
qemu-system-i386 -kernel myos.bin -serial file:serial.log -hda /dev/null \
-drive file=/dev/null,if=none,id=drive-sata0-0-0 \
-device ich9-ahci,id=ahci \
-device ide-drive,drive=drive-sata0-0-0,bus=ahci.0 \
// pci.c
//
// Contains implementations of the functions for dealing with PCI
// defined in pci.h
#include "pci.h"
#include "serial.h"
void pciSerialInfo(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset)
{
uint32_t address;
uint32_t lbus = (uint32_t)bus;
uint32_t lslot = (uint32_t)device;
uint32_t lfunc = (uint32_t)function;
address = (uint32_t)((lbus << 16) |
(lslot << 11) |
(lfunc << 8) |
(offset & 0xfc) |
((uint32_t)0x80000000));
outl(PCI_CONFIG_ACCESS, address);
uint32_t data = inl(PCI_CONFIG_DATA);
serial_writestring("address 0x");
serial_hexword(address);
serial_writestring(" returned 0x");
serial_hexword(data);
serial_writestring(" on bus ");
serial_hexbyte(bus);
serial_writestring(" device ");
serial_hexbyte(device);
serial_writestring(" function ");
serial_hexbyte(function);
serial_writestring(" with offset ");
serial_hexbyte(offset);
serial_writechar('\n');
}
// reads a word from the io port using the pci addressing scheme
uint32_t pciConfigReadWord(uint8_t bus, uint8_t device, uint8_t func, uint8_t offset)
{
uint32_t address;
uint32_t lbus = (uint32_t)bus;
uint32_t ldev = (uint32_t)device;
uint32_t lfunc = (uint32_t)func;
address = (uint32_t)((lbus << 16) |
(ldev << 11) |
(lfunc << 8) |
(offset & 0xfc) |
((uint32_t)0x80000000));
outl(PCI_CONFIG_ACCESS, address);
// return the contents of the address clipped
uint32_t data = inl(PCI_CONFIG_DATA);
return data;
}
void checkAllBuses(void)
{
serial_writestring("Enumerating PCI busses\n");
uint8_t bus;
uint8_t device;
uint8_t function;
for (bus = 0; bus < 255; bus++)
{
for (device = 0; device < 32; device++)
{
for (function = 0; function < 8; function++)
{
if (pciConfigReadWord(bus, device, function, 0) != 0xffffffff)
{
pciSerialInfo(bus, device, function, 0);
serial_writestring("- - - - - - - - - - - - - - - - - - - -\n");
pciSerialInfo(bus, device, function, 8);
serial_writestring("=======================================\n");
}
}
}
}
}
// pci.h
//
// Contains headers for functions related to dealivg with PCI
#ifndef _PCI_INC
#define _PCI_INC
#include <stdint.h>
#include "asm.h"
#define PCI_CONFIG_ACCESS 0xCF8
#define PCI_CONFIG_DATA 0xCFC
uint32_t pciConfigReadWord(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset);
void checkAllBuses();
#endif
...@@ -39,6 +39,22 @@ void serial_writestring(char* s) ...@@ -39,6 +39,22 @@ void serial_writestring(char* s)
} }
const char* hexchars = "0123456789abcdef"; const char* hexchars = "0123456789abcdef";
void serial_hexbyte(uint8_t x)
{
for (int i = 1; i >= 0; i--)
{
serial_writechar(hexchars[x>>i*4&0xf]);
}
}
void serial_hexhword(uint16_t x)
{
for (int i = 3; i >= 0; i--)
{
serial_writechar(hexchars[x>>i*4&0xf]);
}
}
void serial_hexword(uint32_t x) void serial_hexword(uint32_t x)
{ {
for (int i = 7; i >= 0; i--) for (int i = 7; i >= 0; i--)
......
...@@ -21,8 +21,12 @@ void serial_writechar(char a); ...@@ -21,8 +21,12 @@ void serial_writechar(char a);
void serial_writestring(char* s); void serial_writestring(char* s);
// Function to write a 4 byte word toserial in hex // Function to write a 4 byte word toserial in hex
void serial_hexbyte(uint8_t x);
void serial_hexhword(uint16_t x);
void serial_hexword(uint32_t x); void serial_hexword(uint32_t x);
void serial_hexqword(uint64_t x); void serial_hexqword(uint64_t x);
// Writes an arbitrary amount memory to serial
void serial_hexstring(void* s, uint32_t n); void serial_hexstring(void* s, uint32_t n);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment