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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [vendor/] [altera-jtag/] [jtag-virtual.c] - Rev 2

Compare with Previous | Blame | View Log

/* Copyright 2012 Brian Swetland <swetland@frotz.net>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#include <stdio.h>
#include <stdlib.h>
 
#include "jtag.h"
 
int jtag_dr_8x4(unsigned *out) {
	unsigned bits = 0;
	unsigned tmp;
	int n, r;
 
	for (n = 0; n < 8; n++) {
		if ((r = jtag_dr(4, 0, &tmp)) < 0) return r;
		bits |= (tmp <<= (n * 4));
	}
	*out = bits;
	return 0;
}
 
/* number of bits needed given a max value 1-255 */
unsigned needbits(unsigned max) {
	if (max > 127) return 8;
	if (max > 63) return 7;
	if (max > 31) return 6;
	if (max > 15) return 5;
	if (max > 7) return 4;
	if (max > 3) return 3;
	if (max > 1) return 2;
	return 1;
}
 
static unsigned ir_width = 10;
 
static unsigned hub_version = 0;
static unsigned hub_nodecount = 0;
static unsigned hub_mfg = 0;
 
static unsigned vir_width = 0;
static unsigned vir_width_addr = 0;
static unsigned vir_width_ir = 0;
static unsigned vir_addr = 0;
 
 
int jtag_vir(unsigned vir) {
	int r;
	if ((r = jtag_ir(ir_width, 14)) < 0) return r;
	if ((r = jtag_dr(vir_width, vir_addr | vir, 0)) < 0) return r;
	return 0;
}
 
int jtag_vdr(unsigned sz, unsigned bits, unsigned *out) {
	int r;
	if ((r = jtag_ir(ir_width, 12)) < 0) return r;
	if ((r = jtag_dr(sz, bits, out)) < 0) return r;
	return 0;
}
 
int jtag_open_virtual_device(unsigned iid) {
	unsigned n, bits;
	int r;
 
	if ((r = jtag_open()) < 0) return r;
 
	if ((r = jtag_reset()) < 0) return r;
 
	/* select empty node_addr + node_vir -- all zeros */
	if ((r = jtag_ir(ir_width, 14)) < 0) return r;
	if ((r = jtag_dr(32, 0, 0)) < 0) return r;
 
	/* select vdr - this will be the hub info (addr=0,vir=0) */
	if ((r = jtag_ir(ir_width, 12)) < 0) return r;
 
	/* read hub info */
	if ((r = jtag_dr_8x4(&bits)) < 0) return r;
	hub_version = (bits >> 27) & 0x1F;
	hub_nodecount = (bits >> 19) & 0xFF;
	hub_mfg = (bits >> 8) & 0x7FF;
 
	if (hub_mfg != 0x06e) {
		fprintf(stderr,"HUB:    Cannot Find Virtual JTAG HUB\n");
		return -1;
	}
 
	/* altera docs claim this field is the sum of M bits (VIR field) and
	 * N bits (ADDR field), but empirical evidence suggests it is actually
	 * just the width of the ADDR field and the docs are wrong...
	 */
	vir_width_ir = bits & 0xFF;
	vir_width_addr = needbits(hub_nodecount);
	vir_width = vir_width_ir + vir_width_addr;
 
	for (n = 0; n < hub_nodecount; n++) {
		unsigned node_ver, node_id, node_mfg, node_iid;
		if ((r = jtag_dr_8x4(&bits)) < 0) return r;
		node_ver = (bits >> 27) & 0x1F;
		node_id = (bits >> 19) & 0xFF;
		node_mfg = (bits >> 8) & 0x7FF;
		node_iid = bits & 0xFF;
 
		if ((node_id == 0x08) && (node_iid) == iid) {
			vir_addr = (n + 1) << vir_width_ir;
		}
	}
 
	if ((vir_addr == 0) && (iid < 256)) {
		fprintf(stderr,"ERROR: IID 0x%02x not found\n", iid);
		return -1;
	}
	return 0;
}
 
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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