Files
86Box/src/video/agpgart.c

175 lines
4.4 KiB
C
Raw Normal View History

2021-11-10 21:14:54 -03:00
/*
2023-01-06 15:36:05 -05:00
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
2021-11-10 21:14:54 -03:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86Box distribution.
2021-11-10 21:14:54 -03:00
*
2023-01-06 15:36:05 -05:00
* AGP Graphics Address Remapping Table remapping emulation.
2021-11-10 21:14:54 -03:00
*
*
*
2023-01-06 15:36:05 -05:00
* Authors: RichardG, <richardg867@gmail.com>
2021-11-10 21:14:54 -03:00
*
2023-01-06 15:36:05 -05:00
* Copyright 2021 RichardG.
2021-11-10 21:14:54 -03:00
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/mem.h>
2022-08-31 18:23:38 -04:00
#include <86box/agpgart.h>
2023-06-09 23:46:54 -04:00
#include <86box/plat_unused.h>
2021-11-10 21:14:54 -03:00
#ifdef ENABLE_AGPGART_LOG
int agpgart_do_log = ENABLE_AGPGART_LOG;
static void
agpgart_log(const char *fmt, ...)
{
va_list ap;
if (agpgart_do_log) {
2022-08-31 19:19:29 -04:00
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
2021-11-10 21:14:54 -03:00
}
}
#else
2022-08-31 19:19:29 -04:00
# define agpgart_log(fmt, ...)
2021-11-10 21:14:54 -03:00
#endif
void
2022-08-31 18:23:38 -04:00
agpgart_set_aperture(agpgart_t *dev, uint32_t base, uint32_t size, int enable)
2021-11-10 21:14:54 -03:00
{
agpgart_log("AGP GART: set_aperture(%08X, %d, %d)\n", base, size, enable);
/* Disable old aperture mapping. */
mem_mapping_disable(&dev->aperture_mapping);
/* Set new aperture base address, size, mask and enable. */
2022-09-18 17:17:41 -04:00
dev->aperture_base = base;
dev->aperture_size = size;
dev->aperture_mask = size - 1;
dev->aperture_enable = enable;
2021-11-10 21:14:54 -03:00
/* Enable new aperture mapping if requested. */
if (dev->aperture_base && dev->aperture_size && dev->aperture_enable) {
2022-08-31 19:19:29 -04:00
mem_mapping_set_addr(&dev->aperture_mapping, dev->aperture_base, dev->aperture_size);
mem_mapping_enable(&dev->aperture_mapping);
2021-11-10 21:14:54 -03:00
}
}
void
2022-08-31 18:23:38 -04:00
agpgart_set_gart(agpgart_t *dev, uint32_t base)
2021-11-10 21:14:54 -03:00
{
agpgart_log("AGP GART: set_gart(%08X)\n", base);
/* Set GART base address. */
dev->gart_base = base;
}
static uint32_t
agpgart_translate(uint32_t addr, agpgart_t *dev)
{
/* Extract the bits we care about. */
addr &= dev->aperture_mask;
/* Get the GART pointer for this page. */
register uint32_t gart_ptr = mem_readl_phys(dev->gart_base + ((addr >> 10) & 0xfffffffc)) & 0xfffff000;
/* Return remapped address with the page offset. */
2021-11-11 22:48:21 -03:00
return gart_ptr | (addr & 0x00000fff);
2021-11-10 21:14:54 -03:00
}
static uint8_t
agpgart_aperture_readb(uint32_t addr, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
return mem_readb_phys(agpgart_translate(addr, dev));
}
static uint16_t
agpgart_aperture_readw(uint32_t addr, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
return mem_readw_phys(agpgart_translate(addr, dev));
}
static uint32_t
agpgart_aperture_readl(uint32_t addr, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
return mem_readl_phys(agpgart_translate(addr, dev));
}
static void
agpgart_aperture_writeb(uint32_t addr, uint8_t val, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
mem_writeb_phys(agpgart_translate(addr, dev), val);
}
static void
agpgart_aperture_writew(uint32_t addr, uint16_t val, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
mem_writew_phys(agpgart_translate(addr, dev), val);
}
static void
agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
mem_writel_phys(agpgart_translate(addr, dev), val);
}
static void *
2023-06-09 23:46:54 -04:00
agpgart_init(UNUSED(const device_t *info))
2021-11-10 21:14:54 -03:00
{
agpgart_t *dev = malloc(sizeof(agpgart_t));
memset(dev, 0, sizeof(agpgart_t));
agpgart_log("AGP GART: init()\n");
/* Create aperture mapping. */
mem_mapping_add(&dev->aperture_mapping, 0, 0,
2022-08-31 19:19:29 -04:00
agpgart_aperture_readb, agpgart_aperture_readw, agpgart_aperture_readl,
agpgart_aperture_writeb, agpgart_aperture_writew, agpgart_aperture_writel,
NULL, MEM_MAPPING_EXTERNAL, dev);
2021-11-10 21:14:54 -03:00
return dev;
}
static void
agpgart_close(void *priv)
{
agpgart_t *dev = (agpgart_t *) priv;
agpgart_log("AGP GART: close()\n");
/* Disable aperture. */
mem_mapping_disable(&dev->aperture_mapping);
free(dev);
}
2022-03-13 21:43:45 -04:00
const device_t agpgart_device = {
2022-08-31 19:19:29 -04:00
.name = "AGP Graphics Address Remapping Table",
2022-03-13 21:43:45 -04:00
.internal_name = "agpgart",
2022-08-31 19:19:29 -04:00
.flags = DEVICE_PCI,
.local = 0,
.init = agpgart_init,
.close = agpgart_close,
.reset = NULL,
2022-03-13 21:43:45 -04:00
{ .available = NULL },
.speed_changed = NULL,
2022-08-31 19:19:29 -04:00
.force_redraw = NULL,
.config = NULL
2021-11-10 21:14:54 -03:00
};