diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cons/cons.c | 28 | ||||
-rw-r--r-- | sys/dev/cons/cons_ansi.c | 3 | ||||
-rw-r--r-- | sys/dev/ic/ahci.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 77 |
4 files changed, 88 insertions, 23 deletions
diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index ce2b154..0735f11 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -65,7 +65,6 @@ static struct cdevsw cons_cdevsw; static void cons_draw_cursor(struct cons_screen *scr, uint32_t color); static int cons_handle_special(struct cons_screen *scr, char c); -static void cons_clear_scr(struct cons_screen *scr, uint32_t bg); static uint32_t rgb_invert(uint32_t rgb) @@ -191,22 +190,14 @@ cons_handle_special(struct cons_screen *scr, char c) SHOW_CURSOR(scr); return 0; case ASCII_LF: - HIDE_CURSOR(scr); - /* Are we past screen width? */ if (scr->ch_row >= scr->nrows - 1) { cons_clear_scr(scr, scr->bg); - cons_flush(scr); - scr->ch_col = 0; - scr->ch_row = 0; - - /* Update cursor */ - scr->curs_row = 0; - scr->curs_col = 0; - SHOW_CURSOR(scr); return 0; } + HIDE_CURSOR(scr); + /* Make a newline */ cons_flush(scr); ++scr->ch_row; @@ -255,18 +246,25 @@ cons_draw_cursor(struct cons_screen *scr, uint32_t color) * @scr: Screen to clear. * @bg: Color to clear it to. */ -static void +void cons_clear_scr(struct cons_screen *scr, uint32_t bg) { struct fbdev fbdev = scr->fbdev; - struct cons_buf *bp; + + cons_flush(scr); + HIDE_CURSOR(scr); + + scr->ch_col = 0; + scr->ch_row = 0; + scr->curs_col = 0; + scr->curs_row = 0; for (size_t i = 0; i < fbdev.height * fbdev.pitch; ++i) { scr->fb_mem[i] = bg; } - bp = scr->ob[scr->nrows - 1]; - bp->flags |= CONS_BUF_CLEAN; + SHOW_CURSOR(scr); + } /* diff --git a/sys/dev/cons/cons_ansi.c b/sys/dev/cons/cons_ansi.c index 4403f9c..ab1f22a 100644 --- a/sys/dev/cons/cons_ansi.c +++ b/sys/dev/cons/cons_ansi.c @@ -90,8 +90,7 @@ ansi_feed(struct ansi_state *statep, char c) return c; case 2: if (c == 'H') { - cons_reset_cursor(&g_root_scr); - ansi_reset(statep); + cons_clear_scr(&g_root_scr, g_root_scr.bg); return ANSI_UPDATE_CURSOR; } break; diff --git a/sys/dev/ic/ahci.c b/sys/dev/ic/ahci.c index 7d89dd3..d8d4a6f 100644 --- a/sys/dev/ic/ahci.c +++ b/sys/dev/ic/ahci.c @@ -806,8 +806,6 @@ ahci_init_port(struct ahci_hba *hba, uint32_t portno) } dp->fra = PHYS_TO_VIRT(fra); - memset(dp->cmdlist, 0, clen * pagesz); - memset(dp->fra, 0, pagesz); /* Write the command list */ lo = cmdlist & 0xFFFFFFFF; @@ -826,7 +824,6 @@ ahci_init_port(struct ahci_hba *hba, uint32_t portno) tmp = vm_alloc_frame(1); dp->cmdlist[i].prdtl = 1; dp->cmdlist[i].ctba = tmp; - memset(PHYS_TO_VIRT(tmp), 0, pagesz); } mmio_write32(&port->serr, 0xFFFFFFFF); diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 95fc5e2..9dfb90e 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -32,20 +32,31 @@ #include <sys/syslog.h> #include <sys/errno.h> #include <sys/spinlock.h> +#include <sys/mmio.h> #include <dev/pci/pci.h> #include <dev/pci/pciregs.h> +#include <dev/acpi/acpi.h> +#include <dev/acpi/tables.h> #include <machine/pci/pci.h> #include <vm/dynalloc.h> +#include <vm/vm.h> #include <lib/assert.h> #define pr_trace(fmt, ...) kprintf("pci: " fmt, ##__VA_ARGS__) static TAILQ_HEAD(, pci_device) device_list; static struct spinlock devlist_lock = {0}; +static struct acpi_mcfg *mcfg; struct cam_hook { + /* PCI CAM */ pcireg_t(*cam_readl)(struct pci_device *dev, uint32_t off); void(*cam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val); + + /* PCIe ECAM */ + pcireg_t(*ecam_readl)(struct pci_device *dev, uint32_t off); + void(*ecam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val); + void *ecam_base[1]; } cam_hook = { NULL }; static bool @@ -129,6 +140,9 @@ pci_set_device_info(struct pci_device *dev) dev->prog_if = PCIREG_PROGIF(classrev); dev->hdr_type = (uint8_t)pci_readl(dev, PCIREG_HDRTYPE); + /* This is a PCIe device if it has CAP ID of 0x10 */ + dev->pci_express = pci_get_cap(dev, 0x10) != 0; + /* Set type-specific data */ switch (dev->hdr_type & ~BIT(7)) { case PCI_HDRTYPE_NORMAL: @@ -157,6 +171,53 @@ pci_set_device_info(struct pci_device *dev) static void pci_scan_bus(uint8_t bus); +static inline vaddr_t +pcie_ecam_addr(struct pci_device *dev) +{ + vaddr_t base = (vaddr_t)cam_hook.ecam_base[0]; + + base += dev->bus << 20 | + dev->slot << 15 | + dev->func << 12; + return base; +} + +static pcireg_t +pcie_ecam_readl(struct pci_device *dev, uint32_t offset) +{ + vaddr_t address; + + address = pcie_ecam_addr(dev); + address += (offset & ~3); + return mmio_read32((void *)address); +} + +static void +pcie_ecam_writel(struct pci_device *dev, uint32_t offset, pcireg_t val) +{ + vaddr_t address; + + address = pcie_ecam_addr(dev); + address += (offset & ~3); + mmio_write32((void *)address, val); +} + +static int +pcie_init(struct acpi_mcfg_base *base) +{ + void *iobase; + + pr_trace("[group %02d] @ bus [%02d - %02d]\n", base->seg_grpno, + base->bus_start, base->bus_end); + pr_trace("ecam @ %p\n", base->base_pa); + + iobase = PHYS_TO_VIRT(base->base_pa); + cam_hook.ecam_base[0] = iobase; + cam_hook.ecam_writel = pcie_ecam_writel; + cam_hook.ecam_readl = pcie_ecam_readl; + return 0; +} + /* * Attempt to register a device. * @@ -283,8 +344,10 @@ pci_add_device(struct pci_device *dev) pcireg_t pci_readl(struct pci_device *dev, uint32_t offset) { - if (cam_hook.cam_readl == NULL) { - return (pcireg_t)-1; + bool have_ecam = cam_hook.ecam_readl != NULL; + + if (dev->pci_express && have_ecam) { + return cam_hook.ecam_readl(dev, offset); } return cam_hook.cam_readl(dev, offset); @@ -293,7 +356,10 @@ pci_readl(struct pci_device *dev, uint32_t offset) void pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val) { - if (cam_hook.cam_writel == NULL) { + bool have_ecam = cam_hook.ecam_writel != NULL; + + if (dev->pci_express && have_ecam) { + cam_hook.ecam_writel(dev, offset, val); return; } @@ -306,6 +372,11 @@ pci_init(void) size_t ndev; TAILQ_INIT(&device_list); + mcfg = acpi_query("MCFG"); + if (mcfg != NULL) { + pcie_init(&mcfg->base[0]); + } + cam_hook.cam_readl = md_pci_readl; cam_hook.cam_writel = md_pci_writel; |