summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cons/cons.c28
-rw-r--r--sys/dev/cons/cons_ansi.c3
-rw-r--r--sys/dev/ic/ahci.c3
-rw-r--r--sys/dev/pci/pci.c77
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;