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

kbic.c (7003B)


      1/*
      2        kbic.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
      3                              Under the terms of the GNU General Public License.
      4
      5        This is a low-level driver for the KBIC-951A and KBIC-971A
      6        parallel to IDE adapter chips from KingByte Information Systems.
      7
      8	The chips are almost identical, however, the wakeup code 
      9	required for the 971A interferes with the correct operation of
     10        the 951A, so this driver registers itself twice, once for
     11	each chip.
     12
     13*/
     14
     15/* Changes:
     16
     17        1.01    GRG 1998.05.06 init_proto, release_proto
     18
     19*/
     20
     21#define KBIC_VERSION      "1.01"
     22
     23#include <linux/module.h>
     24#include <linux/init.h>
     25#include <linux/delay.h>
     26#include <linux/kernel.h>
     27#include <linux/types.h>
     28#include <linux/wait.h>
     29#include <asm/io.h>
     30
     31#include "paride.h"
     32
     33#define r12w()			(delay_p,inw(pi->port+1)&0xffff) 
     34
     35#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
     36#define j53(w)                  (((w>>3)&0x1f)|((w>>4)&0xe0))
     37
     38
     39/* cont = 0 - access the IDE register file 
     40   cont = 1 - access the IDE command set 
     41*/
     42
     43static int  cont_map[2] = { 0x80, 0x40 };
     44
     45static int kbic_read_regr( PIA *pi, int cont, int regr )
     46
     47{       int     a, b, s;
     48
     49        s = cont_map[cont];
     50
     51	switch (pi->mode) {
     52
     53	case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8);
     54	        a = r1(); w0(0x28); b = r1(); w2(4);
     55		return j44(a,b);
     56
     57	case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8);
     58		a = r12w(); w2(4);
     59		return j53(a);
     60
     61	case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);
     62		a = r0(); w2(4);
     63       		return a;
     64
     65	case 3:
     66	case 4:
     67	case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
     68		a = r4(); b = r4(); w2(4); w2(0); w2(4);
     69		return a;
     70
     71	}
     72	return -1;
     73}       
     74
     75static void  kbic_write_regr( PIA *pi, int cont, int regr, int val)
     76
     77{       int  s;
     78
     79        s = cont_map[cont];
     80
     81        switch (pi->mode) {
     82
     83	case 0: 
     84        case 1:
     85	case 2:	w0(regr|0x10|s); w2(4); w2(6); w2(4); 
     86		w0(val); w2(5); w2(4);
     87		break;
     88
     89	case 3:
     90	case 4:
     91	case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr);
     92		w4(val); w4(val);
     93		w2(4); w2(0); w2(4);
     94                break;
     95
     96	}
     97}
     98
     99static void k951_connect ( PIA *pi  )
    100
    101{ 	pi->saved_r0 = r0();
    102        pi->saved_r2 = r2();
    103        w2(4); 
    104}
    105
    106static void k951_disconnect ( PIA *pi )
    107
    108{      	w0(pi->saved_r0);
    109        w2(pi->saved_r2);
    110}
    111
    112#define	CCP(x)	w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\
    113		w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff);
    114
    115static void k971_connect ( PIA *pi  )
    116
    117{ 	pi->saved_r0 = r0();
    118        pi->saved_r2 = r2();
    119	CCP(0x20);
    120        w2(4); 
    121}
    122
    123static void k971_disconnect ( PIA *pi )
    124
    125{       CCP(0x30);
    126	w0(pi->saved_r0);
    127        w2(pi->saved_r2);
    128}
    129
    130/* counts must be congruent to 0 MOD 4, but all known applications
    131   have this property.
    132*/
    133
    134static void kbic_read_block( PIA *pi, char * buf, int count )
    135
    136{       int     k, a, b;
    137
    138        switch (pi->mode) {
    139
    140        case 0: w0(0x98); w2(4); w2(6); w2(4);
    141                for (k=0;k<count/2;k++) {
    142			w2(1); w0(8);    a = r1();
    143			       w0(0x28); b = r1();
    144			buf[2*k]   = j44(a,b);
    145			w2(5);           b = r1();
    146			       w0(8);    a = r1();
    147			buf[2*k+1] = j44(a,b);
    148			w2(4);
    149                } 
    150                break;
    151
    152        case 1: w0(0xb8); w2(4); w2(6); w2(4); 
    153                for (k=0;k<count/4;k++) {
    154                        w0(0xb8); 
    155			w2(4); w2(5); 
    156                        w0(8);    buf[4*k]   = j53(r12w());
    157			w0(0xb8); buf[4*k+1] = j53(r12w());
    158			w2(4); w2(5);
    159			          buf[4*k+3] = j53(r12w());
    160			w0(8);    buf[4*k+2] = j53(r12w());
    161                }
    162                w2(4);
    163                break;
    164
    165        case 2: w0(0x88); w2(4); w2(6); w2(4);
    166                for (k=0;k<count/2;k++) {
    167                        w2(0xa0); w2(0xa1); buf[2*k] = r0();
    168                        w2(0xa5); buf[2*k+1] = r0();
    169                }
    170                w2(4);
    171                break;
    172
    173        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    174                for (k=0;k<count;k++) buf[k] = r4();
    175                w2(4); w2(0); w2(4);
    176                break;
    177
    178	case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    179                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
    180                w2(4); w2(0); w2(4);
    181                break;
    182
    183        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    184                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
    185                w2(4); w2(0); w2(4);
    186                break;
    187
    188
    189        }
    190}
    191
    192static void kbic_write_block( PIA *pi, char * buf, int count )
    193
    194{       int     k;
    195
    196        switch (pi->mode) {
    197
    198        case 0:
    199        case 1:
    200        case 2: w0(0x90); w2(4); w2(6); w2(4); 
    201		for(k=0;k<count/2;k++) {
    202			w0(buf[2*k+1]); w2(0); w2(4); 
    203			w0(buf[2*k]);   w2(5); w2(4); 
    204		}
    205		break;
    206
    207        case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    208		for(k=0;k<count/2;k++) {
    209			w4(buf[2*k+1]); 
    210                        w4(buf[2*k]);
    211                }
    212		w2(4); w2(0); w2(4);
    213		break;
    214
    215	case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    216                for(k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
    217                w2(4); w2(0); w2(4);
    218                break;
    219
    220        case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0);
    221                for(k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
    222                w2(4); w2(0); w2(4);
    223                break;
    224
    225        }
    226
    227}
    228
    229static void kbic_log_adapter( PIA *pi, char * scratch, 
    230			      int verbose, char * chip )
    231
    232{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
    233				   "EPP-8","EPP_16","EPP-32"};
    234
    235        printk("%s: kbic %s, KingByte %s at 0x%x, ",
    236                pi->device,KBIC_VERSION,chip,pi->port);
    237        printk("mode %d (%s), delay %d\n",pi->mode,
    238		mode_string[pi->mode],pi->delay);
    239
    240}
    241
    242static void k951_log_adapter( PIA *pi, char * scratch, int verbose )
    243
    244{	kbic_log_adapter(pi,scratch,verbose,"KBIC-951A");
    245}
    246
    247static void k971_log_adapter( PIA *pi, char * scratch, int verbose )
    248
    249{       kbic_log_adapter(pi,scratch,verbose,"KBIC-971A");
    250}
    251
    252static struct pi_protocol k951 = {
    253	.owner		= THIS_MODULE,
    254	.name		= "k951",
    255	.max_mode	= 6,
    256	.epp_first	= 3,
    257	.default_delay	= 1,
    258	.max_units	= 1,
    259	.write_regr	= kbic_write_regr,
    260	.read_regr	= kbic_read_regr,
    261	.write_block	= kbic_write_block,
    262	.read_block	= kbic_read_block,
    263	.connect	= k951_connect,
    264	.disconnect	= k951_disconnect,
    265	.log_adapter	= k951_log_adapter,
    266};
    267
    268static struct pi_protocol k971 = {
    269	.owner		= THIS_MODULE,
    270	.name		= "k971",
    271	.max_mode	= 6,
    272	.epp_first	= 3,
    273	.default_delay	= 1,
    274	.max_units	= 1,
    275	.write_regr	= kbic_write_regr,
    276	.read_regr	= kbic_read_regr,
    277	.write_block	= kbic_write_block,
    278	.read_block	= kbic_read_block,
    279	.connect	= k971_connect,
    280	.disconnect	= k971_disconnect,
    281	.log_adapter	= k971_log_adapter,
    282};
    283
    284static int __init kbic_init(void)
    285{
    286	int rv;
    287
    288	rv = paride_register(&k951);
    289	if (rv < 0)
    290		return rv;
    291	rv = paride_register(&k971);
    292	if (rv < 0)
    293		paride_unregister(&k951);
    294	return rv;
    295}
    296
    297static void __exit kbic_exit(void)
    298{
    299	paride_unregister(&k951);
    300	paride_unregister(&k971);
    301}
    302
    303MODULE_LICENSE("GPL");
    304module_init(kbic_init)
    305module_exit(kbic_exit)