summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-10 18:25:07 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-10 18:25:07 +0200
commitdaa69726b2f3c9d4256a8a3591364419039f772e (patch)
treeea9c04d204bf2f3a10dbc3e86bc17afe42c762fd
parent82b2c8ddb429903da774b1a70585e6b47d60a2f4 (diff)
downloadabaos-daa69726b2f3c9d4256a8a3591364419039f772e.tar.gz
abaos-daa69726b2f3c9d4256a8a3591364419039f772e.tar.bz2
preparations for driver loading with PCI (BARs for I/O)
-rw-r--r--src/Makefile4
-rw-r--r--src/pci.c101
-rw-r--r--src/pci.h5
-rw-r--r--src/stage2_real_functions.asm2
4 files changed, 102 insertions, 10 deletions
diff --git a/src/Makefile b/src/Makefile
index 1609299..c7925bf 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -14,13 +14,13 @@ all: image.bin kernel.sym
# + 1 * 512 = 512 for magic.bin
# (M + N + 1 is the number of sectors to be read in stage 2, as stage 1
# loads only the first sector, and stage 1 loads 3 sectors of stage 2,
-# adapt NOF_LOAD_SECTORS to 36)
+# adapt NOF_LOAD_SECTORS to 37)
# then we make sure the image has the size of a 1.44 MB floppy
# (emulators like qemu do some guess work for CHS resolution based
# on the size of the image)
image.bin: boot.bin kernel.bin magic.bin
cat boot.bin kernel.bin > image.tmp
- truncate -s 19968 image.tmp
+ truncate -s 20480 image.tmp
cat image.tmp magic.bin > image.bin
truncate -s 1474560 image.bin
diff --git a/src/pci.c b/src/pci.c
index 58d651a..6b124b2 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -6,6 +6,16 @@
#define NOF_BUSES 8
#define NOF_DEVICES_PER_BUS 32
#define NOF_FUNCTIONS_PER_DEVICE 8
+#define NOF_BARS 6
+
+#define PCI_VENDOR_ID 0x00
+#define PCI_DEVICE_ID 0x02
+#define PCI_REVISION 0x08
+#define PCI_INTERFACE 0x09
+#define PCI_SUBCLASS 0x0A
+#define PCI_CLASS 0x0B
+#define PCI_HEADER_TYPE 0x0E
+#define PCI_BAR_BASE 0x10
void pci_controller_init( pci_controller_t *controller )
{
@@ -74,6 +84,25 @@ void pci_controller_scan_and_register( pci_controller_t *controller, driver_mana
device_descriptor.class_id,
device_descriptor.subclass_id,
device_descriptor.revision_id );
+
+ uint8_t header_type = pci_controller_read( controller, bus, device, function, PCI_HEADER_TYPE ) & 0x7F;
+ int max_nof_bars = NOF_BARS;
+ if( header_type & 0x01 ) {
+ max_nof_bars = 2;
+ }
+
+ for( int bar_number = 0; bar_number < max_nof_bars; bar_number++ ) {
+ pci_base_address_register_t bar;
+ pci_base_address_register_init( &bar, controller, bus, device, function, bar_number );
+ if( bar.type == BASE_ADDRESS_REGISTER_TYPE_IO && bar.addr ) {
+ device_descriptor.port_base = (uint32_t)bar.addr;
+ }
+
+ driver_t *driver = pci_device_get_driver( &device_descriptor, interrupt );
+ if( driver ) {
+ driver_manager_add_driver( driver_manager, driver );
+ }
+ }
}
}
}
@@ -83,16 +112,76 @@ void pci_device_descriptor_init( pci_device_descriptor_t *descriptor, pci_contro
{
memset( descriptor, 0, sizeof( pci_device_descriptor_t ) );
- descriptor->vendor_id = pci_controller_read( controller, bus, device, function, 0x00 );
- descriptor->device_id = pci_controller_read( controller, bus, device, function, 0x02 );
- descriptor->class_id = pci_controller_read( controller, bus, device, function, 0x0B );
- descriptor->subclass_id = pci_controller_read( controller, bus, device, function, 0x0A );
- descriptor->interface_id = pci_controller_read( controller, bus, device, function, 0x09 );
- descriptor->revision_id = pci_controller_read( controller, bus, device, function, 0x08 );
+ descriptor->vendor_id = pci_controller_read( controller, bus, device, function, PCI_VENDOR_ID );
+ descriptor->device_id = pci_controller_read( controller, bus, device, function, PCI_DEVICE_ID );
+ descriptor->class_id = pci_controller_read( controller, bus, device, function, PCI_CLASS );
+ descriptor->subclass_id = pci_controller_read( controller, bus, device, function, PCI_SUBCLASS );
+ descriptor->interface_id = pci_controller_read( controller, bus, device, function, PCI_INTERFACE );
+ descriptor->revision_id = pci_controller_read( controller, bus, device, function, PCI_REVISION );
}
void pci_base_address_register_init( pci_base_address_register_t *base_address_register, pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint16_t bar )
{
memset( base_address_register, 0, sizeof( pci_base_address_register_t ) );
+
+ uint32_t val = pci_controller_read( controller, bus, device, function, PCI_BAR_BASE + sizeof( uint32_t ) * bar );
+
+ // bit 0 indicates whether we are I/O or memory mapped
+ base_address_register->type = ( val & 0x01 ) ? BASE_ADDRESS_REGISTER_TYPE_IO : BASE_ADDRESS_REGISTER_TYPE_MEMORY_MAPPED;
+
+ switch( base_address_register->type ) {
+ case BASE_ADDRESS_REGISTER_TYPE_IO:
+ base_address_register->addr = (uint8_t *)( val & 0xFFFC );
+ base_address_register->prefetchable = false;
+ break;
+
+ case BASE_ADDRESS_REGISTER_TYPE_MEMORY_MAPPED:
+ switch( val << 1 & 0x03 ) {
+ case 0x00:
+ // 32-bit mode
+ break;
+
+ case 0x01:
+ // 20-bit mode
+ break;
+
+ case 0x02:
+ // 64-bit mode
+ break;
+ }
+ break;
+ }
}
+driver_t *pci_device_get_driver( pci_device_descriptor_t *descriptor, interrupt_t *interrupt )
+{
+ // find a specific device
+ switch( descriptor->vendor_id ) {
+ case 0x10ec: // Realtek Semiconductor
+ switch( descriptor->device_id ) {
+ case 0x8029: // RTL-8029
+ break;
+ }
+ break;
+
+ case 0x8086: // Intel
+ break;
+
+ default:
+ break;
+ }
+
+ // find a generic driver
+ switch( descriptor->class_id ) {
+ case 0x03: // graphics
+ switch( descriptor->subclass_id ) {
+ case 0x00: // VGA
+ break;
+ }
+ break;
+
+ default: // no driver found
+ break;
+ }
+ return NULL;
+}
diff --git a/src/pci.h b/src/pci.h
index 9d4fc67..ddbc990 100644
--- a/src/pci.h
+++ b/src/pci.h
@@ -14,6 +14,7 @@ typedef struct {
uint8_t subclass_id;
uint8_t interface_id;
uint8_t revision_id;
+ uint32_t port_base;
} pci_device_descriptor_t;
typedef struct {
@@ -28,7 +29,7 @@ typedef enum {
typedef struct {
pci_base_address_register_type_t type;
- bool prefechable;
+ bool prefetchable;
uint8_t *addr;
uint32_t *size;
} pci_base_address_register_t;
@@ -43,4 +44,6 @@ void pci_device_descriptor_init( pci_device_descriptor_t *descriptor, pci_contro
void pci_base_address_register_init( pci_base_address_register_t *base_address_register, pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint16_t bar );
+driver_t *pci_device_get_driver( pci_device_descriptor_t *descriptor, interrupt_t *interrupt );
+
#endif // PCI_H
diff --git a/src/stage2_real_functions.asm b/src/stage2_real_functions.asm
index 1728b1a..d49bfce 100644
--- a/src/stage2_real_functions.asm
+++ b/src/stage2_real_functions.asm
@@ -2,7 +2,7 @@
; (note: the first sector gets loaded by the BIOS, the
; next 3 sectors are read by the simple stage 1 loader,
; so subtract 3 here!)
-NOF_LOAD_SECTORS equ 36
+NOF_LOAD_SECTORS equ 37
; data sections used for reading the kernel from disk
SECTORS_PER_CYLINDER: