/** Enable PIO for specified I/O range. * * @param pio_addr I/O start address. * @param size Size of the I/O region. * @param virt Virtual address for application's * PIO operations. Can be NULL for PMIO. * * @return EOK on success. * @return Negative error code on failure. * */ int pio_enable(void *pio_addr, size_t size, void **virt) { #ifdef IO_SPACE_BOUNDARY if (pio_addr < IO_SPACE_BOUNDARY) { if (virt) *virt = pio_addr; return iospace_enable(task_get_id(), pio_addr, size); } #else (void) iospace_enable; #endif if (!virt) return EINVAL; void *phys_frame = (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); size_t offset = pio_addr - phys_frame; size_t pages = SIZE2PAGES(offset + size); void *virt_page; int rc = physmem_map(phys_frame, pages, AS_AREA_READ | AS_AREA_WRITE, &virt_page); if (rc != EOK) return rc; *virt = virt_page + offset; return EOK; }
int ega_init(void) { sysarg_t present; int rc = sysinfo_get_value("fb", &present); if (rc != EOK) present = false; if (!present) return ENOENT; sysarg_t kind; rc = sysinfo_get_value("fb.kind", &kind); if (rc != EOK) kind = (sysarg_t) -1; if (kind != 2) return EINVAL; sysarg_t paddr; rc = sysinfo_get_value("fb.address.physical", &paddr); if (rc != EOK) return rc; sysarg_t width; rc = sysinfo_get_value("fb.width", &width); if (rc != EOK) return rc; sysarg_t height; rc = sysinfo_get_value("fb.height", &height); if (rc != EOK) return rc; rc = iospace_enable(task_get_id(), (void *) EGA_IO_BASE, EGA_IO_SIZE); if (rc != EOK) return rc; ega.width = width; ega.height = height; ega.size = (width * height) << 1; rc = physmem_map((void *) paddr, ALIGN_UP(ega.size, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE, (void *) &ega.addr); if (rc != EOK) return rc; sysarg_t blinking; rc = sysinfo_get_value("fb.blinking", &blinking); if (rc != EOK) blinking = false; ega.style_normal = 0xf0; ega.style_inverted = 0x0f; if (blinking) { ega.style_normal &= 0x77; ega.style_inverted &= 0x77; } ega.backbuf = NULL; fbdev_t *dev = fbdev_register(&ega_ops, (void *) &ega); if (dev == NULL) { as_area_destroy(ega.addr); return EINVAL; } return EOK; }