/*
 * DF-5084 impact arithmetic (run on the DragonFly guest; no hardware needed).
 *
 * Reproduces, in userland, exactly what sys/dev/drm/radeon/radeon_agp.c
 * computes at :245-247 when it IS compiled (i.e. if CONFIG_AGP is ever
 * defined in sys/dev/drm/kconfig.h):
 *
 *   gtt_size = ai_aperture_size << 20;   // ai_aperture_size is in BYTES
 *   gtt_start = ai_aperture_base;
 *   gtt_end   = gtt_start + gtt_size - 1;
 *
 * and what the downstream consumers would program into 32-bit GPU registers:
 *   r100.c:663     WREG32(RADEON_AIC_HI_ADDR, gtt_end)          -> truncated
 *   r100.c:3865    WREG32(MC_AGP_TOP, gtt_end >> 16)            -> truncated
 *
 * Every realistic AGP aperture yields a 2^20x-inflated GTT and an
 * AIC_HI_ADDR that INVERTS the DMA window (hi < lo).
 */
#include <stdint.h>
#include <stdio.h>

int main(void)
{
	unsigned long bases[] = { 0xd0000000UL, 0xe0000000UL, 0xc0000000UL };
	unsigned long aper_mb[] = { 32, 64, 128, 256 };

	for (int b = 0; b < 3; b++) {
		for (int i = 0; i < 4; i++) {
			unsigned long aper_bytes = aper_mb[i] << 20;
			unsigned long gtt_size = aper_bytes << 20;	/* as written */
			unsigned long gtt_start = bases[b];
			unsigned long gtt_end = gtt_start + gtt_size - 1;
			uint32_t aic_hi = (uint32_t)gtt_end;
			uint32_t mc_top = (uint32_t)(gtt_end >> 16);

			printf("aper=%3luM base=0x%08lx -> "
			       "gtt_size=0x%016lx (%lu TB) gtt_end=0x%016lx | "
			       "AIC_HI_ADDR=0x%08x MC_AGP_TOP=0x%08x (START=0x%08x)\n",
			       aper_mb[i], bases[b], gtt_size, gtt_size >> 40,
			       gtt_end, aic_hi, mc_top,
			       (uint32_t)(gtt_start >> 16));
		}
	}
	return 0;
}
