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

gus_dram.c (2296B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
      4 *  DRAM access routines
      5 */
      6
      7#include <linux/time.h>
      8#include <sound/core.h>
      9#include <sound/gus.h>
     10#include <sound/info.h>
     11
     12
     13static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer,
     14			     unsigned int address, unsigned int size)
     15{
     16	unsigned long flags;
     17	unsigned int size1, size2;
     18	char buffer[256], *pbuffer;
     19
     20	while (size > 0) {
     21		size1 = size > sizeof(buffer) ? sizeof(buffer) : size;
     22		if (copy_from_user(buffer, _buffer, size1))
     23			return -EFAULT;
     24		if (gus->interwave) {
     25			spin_lock_irqsave(&gus->reg_lock, flags);
     26			snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
     27			snd_gf1_dram_addr(gus, address);
     28			outsb(GUSP(gus, DRAM), buffer, size1);
     29			spin_unlock_irqrestore(&gus->reg_lock, flags);
     30			address += size1;
     31		} else {
     32			pbuffer = buffer;
     33			size2 = size1;
     34			while (size2--)
     35				snd_gf1_poke(gus, address++, *pbuffer++);
     36		}
     37		size -= size1;
     38		_buffer += size1;
     39	}
     40	return 0;
     41}
     42
     43
     44int snd_gus_dram_write(struct snd_gus_card *gus, char __user *buffer,
     45		       unsigned int address, unsigned int size)
     46{
     47	return snd_gus_dram_poke(gus, buffer, address, size);
     48}
     49
     50static int snd_gus_dram_peek(struct snd_gus_card *gus, char __user *_buffer,
     51			     unsigned int address, unsigned int size,
     52			     int rom)
     53{
     54	unsigned long flags;
     55	unsigned int size1, size2;
     56	char buffer[256], *pbuffer;
     57
     58	while (size > 0) {
     59		size1 = size > sizeof(buffer) ? sizeof(buffer) : size;
     60		if (gus->interwave) {
     61			spin_lock_irqsave(&gus->reg_lock, flags);
     62			snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, rom ? 0x03 : 0x01);
     63			snd_gf1_dram_addr(gus, address);
     64			insb(GUSP(gus, DRAM), buffer, size1);
     65			snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);
     66			spin_unlock_irqrestore(&gus->reg_lock, flags);
     67			address += size1;
     68		} else {
     69			pbuffer = buffer;
     70			size2 = size1;
     71			while (size2--)
     72				*pbuffer++ = snd_gf1_peek(gus, address++);
     73		}
     74		if (copy_to_user(_buffer, buffer, size1))
     75			return -EFAULT;
     76		size -= size1;
     77		_buffer += size1;
     78	}
     79	return 0;
     80}
     81
     82int snd_gus_dram_read(struct snd_gus_card *gus, char __user *buffer,
     83		      unsigned int address, unsigned int size,
     84		      int rom)
     85{
     86	return snd_gus_dram_peek(gus, buffer, address, size, rom);
     87}