cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mgag200_mm.c (3105B)


      1/*
      2 * Copyright 2012 Red Hat Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the
      6 * "Software"), to deal in the Software without restriction, including
      7 * without limitation the rights to use, copy, modify, merge, publish,
      8 * distribute, sub license, and/or sell copies of the Software, and to
      9 * permit persons to whom the Software is furnished to do so, subject to
     10 * the following conditions:
     11 *
     12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
     19 *
     20 * The above copyright notice and this permission notice (including the
     21 * next paragraph) shall be included in all copies or substantial portions
     22 * of the Software.
     23 *
     24 */
     25/*
     26 * Authors: Dave Airlie <airlied@redhat.com>
     27 */
     28
     29#include <linux/pci.h>
     30
     31#include <drm/drm_managed.h>
     32
     33#include "mgag200_drv.h"
     34
     35static size_t mgag200_probe_vram(struct mga_device *mdev, void __iomem *mem,
     36				 size_t size)
     37{
     38	int offset;
     39	int orig;
     40	int test1, test2;
     41	int orig1, orig2;
     42	size_t vram_size;
     43
     44	/* Probe */
     45	orig = ioread16(mem);
     46	iowrite16(0, mem);
     47
     48	vram_size = size;
     49
     50	if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000))
     51		vram_size = vram_size - 0x400000;
     52
     53	for (offset = 0x100000; offset < vram_size; offset += 0x4000) {
     54		orig1 = ioread8(mem + offset);
     55		orig2 = ioread8(mem + offset + 0x100);
     56
     57		iowrite16(0xaa55, mem + offset);
     58		iowrite16(0xaa55, mem + offset + 0x100);
     59
     60		test1 = ioread16(mem + offset);
     61		test2 = ioread16(mem);
     62
     63		iowrite16(orig1, mem + offset);
     64		iowrite16(orig2, mem + offset + 0x100);
     65
     66		if (test1 != 0xaa55)
     67			break;
     68
     69		if (test2)
     70			break;
     71	}
     72
     73	iowrite16(orig, mem);
     74
     75	return offset - 65536;
     76}
     77
     78int mgag200_mm_init(struct mga_device *mdev)
     79{
     80	struct drm_device *dev = &mdev->base;
     81	struct pci_dev *pdev = to_pci_dev(dev->dev);
     82	u8 misc;
     83	resource_size_t start, len;
     84
     85	WREG_ECRT(0x04, 0x00);
     86
     87	misc = RREG8(MGA_MISC_IN);
     88	misc |= MGAREG_MISC_RAMMAPEN |
     89		MGAREG_MISC_HIGH_PG_SEL;
     90	WREG8(MGA_MISC_OUT, misc);
     91
     92	/* BAR 0 is VRAM */
     93	start = pci_resource_start(pdev, 0);
     94	len = pci_resource_len(pdev, 0);
     95
     96	if (!devm_request_mem_region(dev->dev, start, len, "mgadrmfb_vram")) {
     97		drm_err(dev, "can't reserve VRAM\n");
     98		return -ENXIO;
     99	}
    100
    101	/* Don't fail on errors, but performance might be reduced. */
    102	devm_arch_io_reserve_memtype_wc(dev->dev, start, len);
    103	devm_arch_phys_wc_add(dev->dev, start, len);
    104
    105	mdev->vram = devm_ioremap(dev->dev, start, len);
    106	if (!mdev->vram)
    107		return -ENOMEM;
    108
    109	mdev->mc.vram_size = mgag200_probe_vram(mdev, mdev->vram, len);
    110	mdev->mc.vram_base = start;
    111	mdev->mc.vram_window = len;
    112
    113	mdev->vram_fb_available = mdev->mc.vram_size;
    114
    115	return 0;
    116}