summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-07 11:57:16 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-07 11:57:16 +0200
commit03b54c5ab504e8a9abafaf60c7b4fed4f8629ea6 (patch)
treed79fab50d5f5aeeed5f50c57a65a6d297ede3fec
parentaa85f2aaf27d79af277867fc7ca4168f1bb117c0 (diff)
downloadabaos-03b54c5ab504e8a9abafaf60c7b4fed4f8629ea6.tar.gz
abaos-03b54c5ab504e8a9abafaf60c7b4fed4f8629ea6.tar.bz2
added 32-bit port functions
started to add PCI functions (for now read/write only) added help menu in boot kernel input mode
-rw-r--r--doc/LINKS.TODO9
-rw-r--r--src/Makefile7
-rw-r--r--src/kernel.c18
-rw-r--r--src/pci.c48
-rw-r--r--src/pci.h16
-rw-r--r--src/port.asm24
-rw-r--r--src/port.c7
-rw-r--r--src/port.h11
8 files changed, 135 insertions, 5 deletions
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index b61fd98..66aa777 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -50,3 +50,12 @@ https://www.lowlevel.eu/wiki/Keyboard_Controller
PIT:
http://wiki.osdev.org/Programmable_Interval_Timer
+
+PCI:
+http://wiki.osdev.org/PCI
+https://www.lowlevel.eu/wiki/Peripheral_Component_Interconnect
+http://www.ics.uci.edu/~harris/ics216/pci/PCI_22.pdf
+
+assembly:
+NASM
+FASM
diff --git a/src/Makefile b/src/Makefile
index 6e52754..9c793df 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -28,10 +28,10 @@ kernel.bin: kernel.elf
kernel.sym: kernel.elf
$(OBJCOPY) --only-keep-debug kernel.elf kernel.sym
-kernel.elf: kernel.o kernel_asm.o console.o vga.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o keyboard.o mouse.o string.o stdlib.o stdio.o setjmp.o
+kernel.elf: kernel.o kernel_asm.o console.o vga.o serial.o port.o port_asm.o interrupts.o interrupts_asm.o pci.o keyboard.o mouse.o string.o stdlib.o stdio.o setjmp.o
$(LD) -o kernel.elf -N -n -Ttext 0x8400 --oformat elf32-i386 \
kernel.o kernel_asm.o console.o vga.o serial.o \
- port.o port_asm.o interrupts.o interrupts_asm.o \
+ port.o port_asm.o interrupts.o interrupts_asm.o pci.o \
keyboard.o mouse.o \
string.o stdlib.o stdio.o setjmp.o
@@ -65,6 +65,9 @@ interrupts.o: interrupts.c interrupts.h
interrupts_asm.o: interrupts.asm
$(NASM) interrupts.asm $(NASMFLAGS) -o interrupts_asm.o
+pci.o: pci.c pci.h
+ $(CC) $(CFLAGS) -c -o pci.o pci.c
+
keyboard.o: keyboard.c keyboard.h
$(CC) $(CFLAGS) -c -o keyboard.o keyboard.c
diff --git a/src/kernel.c b/src/kernel.c
index e8cfc88..c84d28c 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -11,6 +11,7 @@
#include "interrupts.h"
#include "keyboard.h"
#include "mouse.h"
+#include "pci.h"
#include "setjmp.h"
#include "kernel.h"
@@ -72,7 +73,11 @@ void entry( void )
puts( "Enabling interrupt handing now.." );
interrupts_enable( );
-
+
+ puts( "Detecting devices via PCI.." );
+ pci_controller_t pci_controller;
+ pci_controller_init( &pci_controller );
+
puts( "Running.." );
// endless loop doing nothing, later we have to get events
@@ -118,12 +123,21 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
buf[pos] = '\0';
pos = 0;
puts( "" );
- if( strcmp( buf, "quit" ) == 0 ) {
+ if( strcmp( buf, "help" ) == 0 ) {
+ puts( "quit - terminate os" );
+ puts( "mem - show memory usage" );
+ puts( "driver - show status of drivers" );
+ puts( "proc - show process status" );
+ } else if( strcmp( buf, "quit" ) == 0 ) {
terminate = true;
} else if( strcmp( buf, "mem" ) == 0 ) {
// TODO: print memory usage
} else if( strcmp( buf, "proc" ) == 0 ) {
// TODO: print scheduler status
+ } else if( strcmp( buf, "driver" ) == 0 ) {
+ // TODO: print driver information
+ } else {
+ printf( "ERR: Unknown pre-boot command '%s'\n", buf );
}
} else {
printf( "%c", event->ascii_key );
diff --git a/src/pci.c b/src/pci.c
new file mode 100644
index 0000000..fce20df
--- /dev/null
+++ b/src/pci.c
@@ -0,0 +1,48 @@
+#include "pci.h"
+
+#include "string.h"
+
+void pci_controller_init( pci_controller_t *controller )
+{
+ memset( controller, 0, sizeof( pci_controller_t ) );
+
+ port32_init( &controller->command_port, 0xCF8 );
+ port32_init( &controller->data_port, 0xCFC );
+}
+
+static uint32_t compute_id( uint16_t bus, uint16_t device, uint16_t function, uint32_t offset )
+{
+ uint32_t id;
+
+ id = ( 0x01 << 31 )
+ | ( ( bus & 0xFF ) << 16 )
+ | ( ( device & 0x1F ) << 11 )
+ | ( ( function & 0x07 ) << 8 )
+ | ( offset & 0xFC );
+
+ return id;
+}
+
+uint16_t pci_controller_read( pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint32_t offset )
+{
+ uint32_t id = compute_id( bus, device, function, offset );
+
+ port32_write( &controller->command_port, id );
+
+ uint32_t data = port32_read( &controller->data_port );
+
+ // we get 256 byte data blocks aligned to 32-bit addresses
+ // for each offset
+ data = data >> ( ( 8 * ( offset % 4 ) ) & 0xFFFF );
+
+ return data;
+}
+
+void pci_controller_write( pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint32_t offset, uint32_t data )
+{
+ uint32_t id = compute_id( bus, device, function, offset );
+
+ port32_write( &controller->command_port, id );
+ port32_write( &controller->data_port, data );
+}
+
diff --git a/src/pci.h b/src/pci.h
new file mode 100644
index 0000000..2381fc3
--- /dev/null
+++ b/src/pci.h
@@ -0,0 +1,16 @@
+#ifndef PCI_H
+#define PCI_H
+
+#include "port.h"
+
+typedef struct {
+ port32_t command_port;
+ port32_t data_port;
+} pci_controller_t;
+
+void pci_controller_init( pci_controller_t *controller );
+
+uint16_t pci_controller_read( pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint32_t offset );
+void pci_controller_write( pci_controller_t *controller, uint16_t bus, uint16_t device, uint16_t function, uint32_t offset, uint32_t data );
+
+#endif // PCI_H
diff --git a/src/port.asm b/src/port.asm
index 4f2b646..555a4e8 100644
--- a/src/port.asm
+++ b/src/port.asm
@@ -23,3 +23,27 @@ port8_read:
in al, dx
leave
ret
+
+global port32_write
+global port32_read
+
+; void port32_write( port32_t *port, uint32_t data );
+port32_write:
+ push ebp
+ mov ebp, esp
+ mov ecx, [ebp+8]
+ mov edx, DWORD [ecx]
+ mov eax, DWORD [ebp+12]
+ out dx, eax
+ leave
+ ret
+
+; uint32_t port32_read( port32_t *port )
+port32_read:
+ push ebp
+ mov ebp, esp
+ mov ecx, DWORD [ebp+8]
+ mov edx, [ecx]
+ in eax, dx
+ leave
+ ret
diff --git a/src/port.c b/src/port.c
index 3eae387..46e7f37 100644
--- a/src/port.c
+++ b/src/port.c
@@ -8,3 +8,10 @@ void port8_init( port8_t *port, uint16_t number )
port->number = number;
}
+
+void port32_init( port32_t *port, uint16_t number )
+{
+ memset( port, 0, sizeof( port32_t ) );
+
+ port->number = number;
+}
diff --git a/src/port.h b/src/port.h
index 32679ee..ec96d09 100644
--- a/src/port.h
+++ b/src/port.h
@@ -11,4 +11,13 @@ void port8_init( port8_t *port, uint16_t number );
void port8_write( port8_t *port, uint8_t data );
uint8_t port8_read( port8_t *port );
-#endif //
+typedef struct {
+ uint16_t number; // port number, e.g. 0x3d4 VGA index register
+} port32_t;
+
+void port32_init( port32_t *port, uint16_t number );
+void port32_write( port32_t *port, uint32_t data );
+uint32_t port32_read( port32_t *port );
+
+#endif // PORT_H
+