diff --git a/kernel/Makefile b/kernel/Makefile index 789aea0..a01c8de 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -70,6 +70,7 @@ SRCFILES += $(call GRABSRC, \ vmm \ pci \ pci/ata \ + pci/qemu_pci_serial \ ) CFILES := $(call GET_CFILES, $(SRCFILES)) diff --git a/kernel/dev/dev.c b/kernel/dev/dev.c index 0dfa6ae..c5f89fe 100644 --- a/kernel/dev/dev.c +++ b/kernel/dev/dev.c @@ -4,7 +4,6 @@ #include "std/string.h" #include "dev/dev.h" #include "dev/ps2kbdev.h" -#include "dev/serialdev.h" #include "hshtb.h" DevTable DEVTABLE; @@ -14,5 +13,4 @@ void dev_init(void) { spinlock_init(&DEVTABLE.spinlock); ps2kbdev_init(); - serialdev_init(); } diff --git a/kernel/dev/serialdev.c b/kernel/dev/serialdev.c deleted file mode 100644 index d567331..0000000 --- a/kernel/dev/serialdev.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include "dev/dev.h" -#include "dev/serialdev.h" -#include "util/util.h" -#include "sysdefs/dev.h" -#include "io/io.h" -#include "errors.h" -#include "hshtb.h" -#include "kprintf.h" - -// https://wiki.osdev.org/Serial_Ports - -#define PORT 0x3f8 - -void serial_init(void) { - io_out8(PORT+1, 0x00); - io_out8(PORT+3, 0x80); - io_out8(PORT+0, 0x03); - io_out8(PORT+1, 0x00); - io_out8(PORT+3, 0x03); - io_out8(PORT+2, 0xC7); - io_out8(PORT+4, 0x0B); - io_out8(PORT+4, 0x1E); - io_out8(PORT+0, 0xAE); - - if (io_in8(PORT+0) != 0xAE) { - ERR("serial", "serial is faulty!\n"); - return; - } - - io_out8(PORT+4, 0x0F); -} - -int serial_recvready(void) { - return io_in8(PORT+5) & 1; -} - -uint8_t serial_recvb(void) { - return io_in8(PORT); -} - -int serial_sendready(void) { - return io_in8(PORT+5) & 0x20; -} - -void serial_sendb(uint8_t b) { - io_out8(PORT, b); -} - -int32_t serialdev_sendb(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { - (void)dev; (void)len; (void)pid; - serial_sendb(buffer[0]); - return E_OK; -} - -int32_t serialdev_sendready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { - (void)dev; (void)buffer; (void)len; (void)pid; - return serial_sendready(); -} - -int32_t serialdev_recvb(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { - (void)dev; (void)buffer; (void)len; (void)pid; - return serial_recvb(); -} - -int32_t serialdev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { - (void)dev; (void)buffer; (void)len; (void)pid; - return serial_recvready(); -} - -void serialdev_init(void) { - Dev *serialdev = NULL; - HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev); - serialdev->fns[DEV_SERIALDEV_SENDB] = &serialdev_sendb; - serialdev->fns[DEV_SERIALDEV_SENDREADY] = &serialdev_sendready; - serialdev->fns[DEV_SERIALDEV_RECVB] = &serialdev_recvb; - serialdev->fns[DEV_SERIALDEV_RECVREADY] = &serialdev_recvready; - spinlock_init(&serialdev->spinlock); - serial_init(); -} diff --git a/kernel/dev/serialdev.h b/kernel/dev/serialdev.h deleted file mode 100644 index df838b9..0000000 --- a/kernel/dev/serialdev.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef DEV_SERIALDEV_H_ -#define DEV_SERIALDEV_H_ - -void serialdev_init(void); - -#endif // DEV_SERIALDEV_H_ diff --git a/kernel/pci/pci.c b/kernel/pci/pci.c index 3998417..8cc16c2 100644 --- a/kernel/pci/pci.c +++ b/kernel/pci/pci.c @@ -2,6 +2,7 @@ #include #include "pci/pci.h" #include "pci/ata/ata.h" +#include "pci/qemu_pci_serial/qemu_pci_serial.h" #include "io/io.h" #include "std/string.h" #include "util/util.h" @@ -123,7 +124,8 @@ PciDev pci_getdev(uint16_t vendorid, uint16_t deviceid, int devtype) { } if (pci_isend(PCI_DEV_ZERO)) { - ERR("pci", "pci_getdev() failed\n"); + ERR("pci", "pci_getdev() failed for 0x%04x/0x%04x,%d\n", vendorid, deviceid, devtype); + return PCI_DEV_ZERO; } for (uint32_t fn = 1; fn < PCI_FN_PER_DEV; fn++) { @@ -167,6 +169,7 @@ void pci_init_size_map(void) { PciInitFn PCI_INIT_ARRAY[PCI_INIT_ARRAY_MAX] = { &pci_ata_init, + &pci_qemu_pci_serial_init, }; void pci_init_devs(void) { diff --git a/kernel/pci/qemu_pci_serial/qemu_pci_serial.c b/kernel/pci/qemu_pci_serial/qemu_pci_serial.c new file mode 100644 index 0000000..e33f651 --- /dev/null +++ b/kernel/pci/qemu_pci_serial/qemu_pci_serial.c @@ -0,0 +1,111 @@ +#include +#include +#include "pci/pci.h" +#include "pci/qemu_pci_serial/qemu_pci_serial.h" +#include "io/io.h" +#include "sysdefs/dev.h" +#include "util/util.h" +#include "dev/dev.h" +#include "errors.h" +#include "hshtb.h" +#include "kprintf.h" + +static QemuPciSerialDev QEMU_PCI_SERIAL_DEV; + +// https://wiki.osdev.org/Serial_Ports + +void _serial_init(uint16_t iobase) { + io_out8(iobase+1, 0x00); + io_out8(iobase+3, 0x80); + io_out8(iobase+0, 0x03); + io_out8(iobase+1, 0x00); + io_out8(iobase+3, 0x03); + io_out8(iobase+2, 0xC7); + io_out8(iobase+4, 0x0B); + io_out8(iobase+4, 0x1E); + io_out8(iobase+0, 0xAE); + + if (io_in8(iobase+0) != 0xAE) { + ERR("pci", "QEMU_PCI_SERIAL serial is faulty!\n"); + return; + } + + io_out8(iobase+4, 0x0F); +} + +int _serial_recvready(uint16_t iobase) { + return io_in8(iobase+5) & 1; +} + +uint8_t _serial_recvb(uint16_t iobase) { + return io_in8(iobase); +} + +int _serial_sendready(uint16_t iobase) { + return io_in8(iobase+5) & 0x20; +} + +void _serial_sendb(uint16_t iobase, uint8_t b) { + io_out8(iobase, b); +} + +int32_t qemu_pci_serial_dev_sendb(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { + (void)len; (void)pid; + + QemuPciSerialDev *qpsd = dev->extra; + _serial_sendb(qpsd->iobase, buffer[0]); + + return E_OK; +} + +int32_t qemu_pci_serial_dev_sendready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { + (void)buffer; (void)len; (void)pid; + + QemuPciSerialDev *qpsd = dev->extra; + + return _serial_sendready(qpsd->iobase); +} + +int32_t qemu_pci_serial_dev_recvb(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { + (void)buffer; (void)len; (void)pid; + + QemuPciSerialDev *qpsd = dev->extra; + + return _serial_recvb(qpsd->iobase); +} + +int32_t qemu_pci_serial_dev_recvready(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { + (void)dev; (void)buffer; (void)len; (void)pid; + + QemuPciSerialDev *qpsd = dev->extra; + + return _serial_recvready(qpsd->iobase); +} + +void pci_qemu_pci_serial_init(void) { + PciDev dev = pci_getdev(0x1B36, 0x0002, -1); + if (!dev.bits) { + return; + } + + uint32_t bar0 = pci_read(dev, PCI_BAR0); + + LOG("pci", "QEMU_PCI_SERIAL bar0=0x%x\n", bar0); + + uint16_t iobase = bar0 & 0xFFFFFFFC; + LOG("pci", "QEMU_PCI_SERIAL iobase=0x%x\n", iobase); + + QEMU_PCI_SERIAL_DEV._magic = QEMU_PCI_SERIAL_MAGIC; + QEMU_PCI_SERIAL_DEV.iobase = iobase; + + Dev *serialdev = NULL; + HSHTB_ALLOC(DEVTABLE.devs, ident, "serialdev", serialdev); + serialdev->fns[0] = &qemu_pci_serial_dev_sendb; + serialdev->fns[1] = &qemu_pci_serial_dev_sendready; + serialdev->fns[2] = &qemu_pci_serial_dev_recvb; + serialdev->fns[3] = &qemu_pci_serial_dev_recvready; + spinlock_init(&serialdev->spinlock); + serialdev->extra = &QEMU_PCI_SERIAL_DEV; + _serial_init(QEMU_PCI_SERIAL_DEV.iobase); +} + diff --git a/kernel/pci/qemu_pci_serial/qemu_pci_serial.h b/kernel/pci/qemu_pci_serial/qemu_pci_serial.h new file mode 100644 index 0000000..1dcb872 --- /dev/null +++ b/kernel/pci/qemu_pci_serial/qemu_pci_serial.h @@ -0,0 +1,16 @@ +#ifndef PCI_QEMU_PCI_SERIAL_QEMU_PCI_SERIAL_H_ +#define PCI_QEMU_PCI_SERIAL_QEMU_PCI_SERIAL_H_ + +#include +#include + +#define QEMU_PCI_SERIAL_MAGIC 0x1234 + +typedef struct { + uint32_t _magic; + uint16_t iobase; +} QemuPciSerialDev; + +void pci_qemu_pci_serial_init(void); + +#endif // PCI_QEMU_PCI_SERIAL_QEMU_PCI_SERIAL_H_ diff --git a/run/qemu-x86_64-hdd.sh b/run/qemu-x86_64-hdd.sh index 3dbd4b6..79c0255 100755 --- a/run/qemu-x86_64-hdd.sh +++ b/run/qemu-x86_64-hdd.sh @@ -6,6 +6,6 @@ qemu-system-x86_64 \ -machine pc \ -m 4G \ -boot d \ - -serial stdio \ - -hda disk.hdd + -hda disk.hdd \ + -device pci-serial,chardev=char0 -chardev stdio,id=char0 \ $@ diff --git a/share/sysdefs/dev.h b/share/sysdefs/dev.h index f94031d..f140202 100644 --- a/share/sysdefs/dev.h +++ b/share/sysdefs/dev.h @@ -4,11 +4,6 @@ #include #include -#define DEV_SERIALDEV_SENDB 0 -#define DEV_SERIALDEV_SENDREADY 1 -#define DEV_SERIALDEV_RECVB 2 -#define DEV_SERIALDEV_RECVREADY 3 - #define DEV_STOREDEV_READ 0 #define DEV_STOREDEV_WRITE 1 #define DEV_STOREDEV_SECCOUNT 2 diff --git a/user/diagdummy/serial.c b/user/diagdummy/serial.c index df9288f..04e9848 100644 --- a/user/diagdummy/serial.c +++ b/user/diagdummy/serial.c @@ -2,6 +2,11 @@ #include #include +#define SENDB 0 +#define SENDREADY 1 +#define RECVB 2 +#define RECVREADY 3 + void diagdummy_serialprint(void) { char *str = "Hello world\n"; @@ -14,8 +19,8 @@ void diagdummy_serialprint(void) { char *s = str; while (*s) { - while(!dev_cmd(&serialdev, DEV_SERIALDEV_SENDREADY, NULL, 0)); - dev_cmd(&serialdev, DEV_SERIALDEV_SENDB, s, 1); + while(!dev_cmd(&serialdev, SENDREADY, NULL, 0)); + dev_cmd(&serialdev, SENDB, s, 1); s++; } }