OpenCores
URL https://opencores.org/ocsvn/s80186/s80186/trunk

Subversion Repositories s80186

[/] [s80186/] [trunk/] [vendor/] [altera-jtag/] [jtag-virtual.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
/* Copyright 2012 Brian Swetland <swetland@frotz.net>
2
 *
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 *     http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15
 
16
#include <stdio.h>
17
#include <stdlib.h>
18
 
19
#include "jtag.h"
20
 
21
int jtag_dr_8x4(unsigned *out) {
22
        unsigned bits = 0;
23
        unsigned tmp;
24
        int n, r;
25
 
26
        for (n = 0; n < 8; n++) {
27
                if ((r = jtag_dr(4, 0, &tmp)) < 0) return r;
28
                bits |= (tmp <<= (n * 4));
29
        }
30
        *out = bits;
31
        return 0;
32
}
33
 
34
/* number of bits needed given a max value 1-255 */
35
unsigned needbits(unsigned max) {
36
        if (max > 127) return 8;
37
        if (max > 63) return 7;
38
        if (max > 31) return 6;
39
        if (max > 15) return 5;
40
        if (max > 7) return 4;
41
        if (max > 3) return 3;
42
        if (max > 1) return 2;
43
        return 1;
44
}
45
 
46
static unsigned ir_width = 10;
47
 
48
static unsigned hub_version = 0;
49
static unsigned hub_nodecount = 0;
50
static unsigned hub_mfg = 0;
51
 
52
static unsigned vir_width = 0;
53
static unsigned vir_width_addr = 0;
54
static unsigned vir_width_ir = 0;
55
static unsigned vir_addr = 0;
56
 
57
 
58
int jtag_vir(unsigned vir) {
59
        int r;
60
        if ((r = jtag_ir(ir_width, 14)) < 0) return r;
61
        if ((r = jtag_dr(vir_width, vir_addr | vir, 0)) < 0) return r;
62
        return 0;
63
}
64
 
65
int jtag_vdr(unsigned sz, unsigned bits, unsigned *out) {
66
        int r;
67
        if ((r = jtag_ir(ir_width, 12)) < 0) return r;
68
        if ((r = jtag_dr(sz, bits, out)) < 0) return r;
69
        return 0;
70
}
71
 
72
int jtag_open_virtual_device(unsigned iid) {
73
        unsigned n, bits;
74
        int r;
75
 
76
        if ((r = jtag_open()) < 0) return r;
77
 
78
        if ((r = jtag_reset()) < 0) return r;
79
 
80
        /* select empty node_addr + node_vir -- all zeros */
81
        if ((r = jtag_ir(ir_width, 14)) < 0) return r;
82
        if ((r = jtag_dr(32, 0, 0)) < 0) return r;
83
 
84
        /* select vdr - this will be the hub info (addr=0,vir=0) */
85
        if ((r = jtag_ir(ir_width, 12)) < 0) return r;
86
 
87
        /* read hub info */
88
        if ((r = jtag_dr_8x4(&bits)) < 0) return r;
89
        hub_version = (bits >> 27) & 0x1F;
90
        hub_nodecount = (bits >> 19) & 0xFF;
91
        hub_mfg = (bits >> 8) & 0x7FF;
92
 
93
        if (hub_mfg != 0x06e) {
94
                fprintf(stderr,"HUB:    Cannot Find Virtual JTAG HUB\n");
95
                return -1;
96
        }
97
 
98
        /* altera docs claim this field is the sum of M bits (VIR field) and
99
         * N bits (ADDR field), but empirical evidence suggests it is actually
100
         * just the width of the ADDR field and the docs are wrong...
101
         */
102
        vir_width_ir = bits & 0xFF;
103
        vir_width_addr = needbits(hub_nodecount);
104
        vir_width = vir_width_ir + vir_width_addr;
105
 
106
        for (n = 0; n < hub_nodecount; n++) {
107
                unsigned node_ver, node_id, node_mfg, node_iid;
108
                if ((r = jtag_dr_8x4(&bits)) < 0) return r;
109
                node_ver = (bits >> 27) & 0x1F;
110
                node_id = (bits >> 19) & 0xFF;
111
                node_mfg = (bits >> 8) & 0x7FF;
112
                node_iid = bits & 0xFF;
113
 
114
                if ((node_id == 0x08) && (node_iid) == iid) {
115
                        vir_addr = (n + 1) << vir_width_ir;
116
                }
117
        }
118
 
119
        if ((vir_addr == 0) && (iid < 256)) {
120
                fprintf(stderr,"ERROR: IID 0x%02x not found\n", iid);
121
                return -1;
122
        }
123
        return 0;
124
}
125
 
126
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.