initial push
This commit is contained in:
33
m683xx/bdm-load/Makefile
Normal file
33
m683xx/bdm-load/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
#TARGET_ARCH = -bi586-pc-linux-gnulibc1
|
||||
#CC = egcc
|
||||
|
||||
CFLAGS += -Wall -ggdb -O2
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
CFLAGS += ${TARGET_ARCH}
|
||||
|
||||
#/* Select right place or libraries with configured m68k-coff support */
|
||||
LDLIBS += -lbfd
|
||||
#CFLAGS += -I ./gdblibs
|
||||
#LOCLIBS += ./gdblibs/libbfd.a ./gdblibs/libiberty.a
|
||||
#LDFLAGS += -lintl
|
||||
LDLIBS += -liberty
|
||||
LDFLAGS += ${TARGET_ARCH}
|
||||
|
||||
all : bdm-load bdm_test tpudb
|
||||
|
||||
dep:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M *.c $(MORE_C_FILES) > depend
|
||||
|
||||
depend:
|
||||
@touch depend
|
||||
|
||||
clean :
|
||||
rm -f *.o *.lo *~ *.a *.so *.so.* depend
|
||||
|
||||
bdm-load : bdm-load.o bdmlib.o bdmflash.o ${LOCLIBS}
|
||||
|
||||
bdm_test : bdm_test.o bdmlib.o ${LOCLIBS}
|
||||
|
||||
tpudb : tpudb.o bdmlib.o tpudis.o ${LOCLIBS}
|
||||
|
||||
-include depend
|
||||
188
m683xx/bdm-load/README
Normal file
188
m683xx/bdm-load/README
Normal file
@@ -0,0 +1,188 @@
|
||||
BDM-LOAD snapshot 2003-08-15
|
||||
|
||||
This is attempt to rewrite bdm-load utility for 683xx based
|
||||
embedded systems.
|
||||
|
||||
This code is in experimental and rewrite phase, it works for me,
|
||||
but there is no warranty that it is useful or safe for others.
|
||||
|
||||
Except "bdm-load" program, two test utilities are build.
|
||||
It is "bdm_test" program. It was my first experiment with
|
||||
interfacing BDM library with stand-alone program.
|
||||
The second project is to write free TPU debugger, but this
|
||||
code does not do anything useful yet.
|
||||
|
||||
INSTALL
|
||||
|
||||
To compile and install "bdm-load" you need:
|
||||
- mc683xx target system with BDM interface
|
||||
- GCC compiler for your Linux system.
|
||||
- BDM driver - latest version is attached into "bdm-load" archive
|
||||
- BFD object file handling library
|
||||
- some time and experience with Linux system and make utility
|
||||
|
||||
To be able load other formats than S-record and IntelHEX, you
|
||||
need to link with BFD library with m68kcoff and/or m68kelf
|
||||
targets. I have system wide BFD with all targets I use.
|
||||
I build my Linux binutils configured by next line in created
|
||||
source tree subdirectory i586-linux
|
||||
|
||||
---System wide multi binutils configuration-----------------------
|
||||
../configure \
|
||||
--with-ld --exec-prefix=/usr --prefix=/usr \
|
||||
--enable-shared --enable-commonbfdlib --verbose --with-mmap \
|
||||
--enable-targets=i586-pc-linux-gnulibc1,i386-a.out-linux,i386-coff,\
|
||||
m68k-linux-elf,m68k-coff,m68k-a.out-linux,h8300-hitachi-coff,\
|
||||
sparc-linux-elf,i586-win-pe,tic30-ti-coff,tic30-ti-aout
|
||||
------------------------------------------------------------------
|
||||
|
||||
You need not to rebuild your system wide BFD. You can statically link
|
||||
with "libbfd.a", "libiberty.a" and "bfd.h" taken, for example,
|
||||
from GDB build tree configured for m68k-coff. Configuration of GDB
|
||||
is bellow
|
||||
|
||||
---GDB for m683xx with BDM configuration--------------------------
|
||||
../configure --target=m68k-bdm-coff --enable-gdbtk --with-x --verbose \
|
||||
--enable-targets=m68k-linux-elf,m68k-coff,m68k-a.out-linux
|
||||
------------------------------------------------------------------
|
||||
|
||||
To compile statically copy three needed files to gdblibs subdirectory
|
||||
and change next lines in "Makefile" to form
|
||||
|
||||
CFLAGS += -I ./gdblibs
|
||||
#LDFLAGS += -lbfd -liberty
|
||||
LOCLIBS += ./gdblibs/libbfd.a ./gdblibs/libiberty.a
|
||||
|
||||
Prebuild version of "bdm-load" is attached to archive under name
|
||||
"bdm-load-i586-linux-static".
|
||||
|
||||
PROGRAMMERS NOTES
|
||||
|
||||
Sources of "bdm-load" are in next files
|
||||
|
||||
bdmlib.c,bdmlib.h library for communication with CPU32
|
||||
through BDM
|
||||
|
||||
bdmflash.c,bdmflash.h flash write and erase algorithms and
|
||||
flash areas write filter routines
|
||||
|
||||
bdm-load.c loader command line and interactive
|
||||
interface
|
||||
|
||||
It is necessary to add new entries into array flash_alg_infos_def
|
||||
in "bdmflash.c" file for every new flash programming algorithm.
|
||||
Flash types should be sorted from smallest to biggest.
|
||||
|
||||
RUNNING BDM-LOAD
|
||||
|
||||
Command line interface
|
||||
|
||||
Usage bdm-load [OPTIONS] file1 ...
|
||||
-h --help - this help information!
|
||||
-i --init-file=FILE - object file to initialize processor
|
||||
-r --reset - reset target CPU before other operations
|
||||
-c --check - check flash setup (needed for auto)
|
||||
-e --erase - erase flash
|
||||
-b --blankck - blank check of flash
|
||||
-l --load - download listed filenames
|
||||
--go[=address] - run target CPU from entry address
|
||||
-M --mbar=val - setup 68360 MBAR register
|
||||
-s --script - do actions and return
|
||||
-d --bdm-delay=d - sets BDM driver speed/delay
|
||||
-D --bdm-device - sets BDM device file
|
||||
-f --flash=TYPE@ADR - select flash
|
||||
For flash TYPE@ADR can be
|
||||
{<TYPE>|auto}[@{csboot|cs<x>|<start>{+<size>|-<end>}}]
|
||||
Examples
|
||||
auto@csboot amd29f400@0x800000-0x87ffff auto@0+0x80000
|
||||
If auto type or cs address is used, check must be
|
||||
specified to take effect.
|
||||
Known flash types/algorithms :
|
||||
amd29f010x2 amd29f040 amd29f400 amd29f800 at49f040x2 amd29f080x4
|
||||
|
||||
Possible commands in interactive mode :
|
||||
- run
|
||||
starts CPU32 execution at address taken from last downloaded
|
||||
object file. If no file is loaded, it starts at address
|
||||
fetched during last reset command.
|
||||
|
||||
- reset
|
||||
resets CPU32 and if no entry address is defined, PC address is
|
||||
remembered
|
||||
|
||||
- erase
|
||||
sets erase request and starts erase procedure
|
||||
|
||||
-load [<object-file>]
|
||||
sets load request and starts download of files from
|
||||
object file list.
|
||||
if <object-file> is specified, object file list is cleared
|
||||
and specified file is added on-to list
|
||||
|
||||
- exit/quit
|
||||
exit interactive mode and return to shell
|
||||
|
||||
- dump <address> <bytes>
|
||||
dumps memory contents from specified address.
|
||||
bytes specifies number of bytes to print.
|
||||
|
||||
- stat
|
||||
shows CPU32 state, does not require CPU32 to stop
|
||||
|
||||
- check
|
||||
checks flash memories at specified ranges,
|
||||
if auto type or "cs" address is specified for some
|
||||
flash, CS address is fetched and flash autodetection
|
||||
is run
|
||||
|
||||
- autoset
|
||||
same as check, but all flash types are revalidated
|
||||
|
||||
- stop
|
||||
stops CPU32 and clears all reset, erase, load and run
|
||||
requests
|
||||
|
||||
- make
|
||||
make in current directory is called
|
||||
|
||||
|
||||
The simplest way to initialize CPU32 chipselect subsystem
|
||||
and other SIM parameters is to provide "cpu32init" file
|
||||
in same directory as "bdm-load" is started from.
|
||||
The "cpu32init" file is processed at every reset of target.
|
||||
The syntax of the macro file is:
|
||||
|
||||
<cmd-letter> <num1> <num2> <num3>
|
||||
|
||||
The nums are either in hex (form 0x), in decimal (form 123) or in octal
|
||||
(form 0234)
|
||||
|
||||
The meaning of the nums depends on the command letter:
|
||||
|
||||
w or W means: (write)
|
||||
|
||||
write to address (num1) contents (num2) length is (num3) bytes. Only
|
||||
1, 2, 4 bytes are permitted.
|
||||
|
||||
z or Z means: (zap, zero)
|
||||
|
||||
fill memory area beginning at (num1) with byte value (num2) length
|
||||
(num3) bytes.
|
||||
|
||||
c or C means: (copy)
|
||||
|
||||
copy memory area from (num1) to (num2) with length (num3) bytes.
|
||||
|
||||
m or M is new command to set 68360 MBAR register.
|
||||
|
||||
the MBAR register is set to value of (num3)
|
||||
|
||||
Empty lines and lines with a leading '#' are ignored. See GDB-BDM
|
||||
patches for more information.
|
||||
|
||||
|
||||
For more questions contact
|
||||
|
||||
Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
|
||||
|
||||
903
m683xx/bdm-load/bdm-load.c
Normal file
903
m683xx/bdm-load/bdm-load.c
Normal file
@@ -0,0 +1,903 @@
|
||||
/*
|
||||
* Adapted from....
|
||||
*
|
||||
* Remote debugging interface for 683xx via Background Debug Mode
|
||||
* needs a driver, which controls the BDM interface.
|
||||
* written by G.Magin
|
||||
* (C) 1995 Technische Universitaet Muenchen, Lehrstuhl fuer Prozessrechner
|
||||
*
|
||||
* D.Jeff Dionne
|
||||
* (C) 1995, Dionne & Associates
|
||||
*
|
||||
* V0.2 Enhancements:
|
||||
* Added command line arguments
|
||||
* Rewritten flash programming functions for more flexability
|
||||
*
|
||||
* Andrew Dennison <adennison@swin.edu.au>
|
||||
* December 1995
|
||||
*
|
||||
* Modified by Pavel Pisa pisa@cmp.felk.cvut.cz 2000
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* This file is assumed to be runnable only on Linux/i386 because of
|
||||
* HW-restrictions: the driver is currently only available on i386-Linux
|
||||
* So byte-swapping and alignment is handled directly, violating the
|
||||
* GNU-coding standards. However, the "dirty spots" are restricted in this
|
||||
* file.
|
||||
*
|
||||
* If anybody wants to port to e.g. Sparc, byte-sex has to be handled in
|
||||
* a more general way.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <bfd.h>
|
||||
#include "bdm.h"
|
||||
#include "bdmlib.h"
|
||||
#include "bdmflash.h"
|
||||
|
||||
/*
|
||||
* Global Types
|
||||
**************
|
||||
*/
|
||||
typedef caddr_t CORE_ADDR;
|
||||
|
||||
#define END_MACRO 0
|
||||
#define BEGIN_MACRO 1
|
||||
#define NO_SUFFIX_MACRO 2
|
||||
#define DEBUG_MESSAGES
|
||||
|
||||
#define swap_l(x) (x>>24) | ((x>>8)&0xff00) | ((x<<8)&0xff0000) | ((x&0xff)<<24)
|
||||
|
||||
#define AUTO_ADR_CSBOOT ((caddr_t)-100)
|
||||
#define AUTO_ADR_CSX ((caddr_t)-100+1)
|
||||
|
||||
typedef struct str_list_t{
|
||||
char **items;
|
||||
int count;
|
||||
int alloccnt;
|
||||
}str_list_t; /* to store list of filenames */
|
||||
|
||||
/*
|
||||
* Global Variables
|
||||
******************
|
||||
*/
|
||||
|
||||
char hashmark = 0; /* flag set by "set hash" */
|
||||
int bdm_autoreset = 0; /* automatic reset before load */
|
||||
int bdm_ttcu = 0; /* time to come up for init by rom */
|
||||
char *initname; /* need reimplement !!!!!!!!! */
|
||||
char *bdm_dev_name; /* device name */
|
||||
static char *entry_name=NULL;
|
||||
|
||||
int
|
||||
mem_dump (char *buf)
|
||||
{
|
||||
caddr_t adr;
|
||||
long len, l;
|
||||
int i, ret;
|
||||
u_char mem[16];
|
||||
char *dump_fname = NULL;
|
||||
FILE *dump_file = NULL;
|
||||
i = sscanf (buf, " %li %li %as", &l, &len, &dump_fname);
|
||||
if (i < 2)
|
||||
{
|
||||
printf ("use : dump address len [file]\n");
|
||||
return -1;
|
||||
}
|
||||
if(dump_fname && *dump_fname)
|
||||
{ dump_file=fopen(dump_fname,"wb");
|
||||
if(dump_file==NULL)
|
||||
{
|
||||
printf ("mem_dump : file \"%s\" open for write error\n", dump_fname);
|
||||
free(dump_fname);
|
||||
return -1;
|
||||
}
|
||||
free(dump_fname);
|
||||
}
|
||||
|
||||
adr = (caddr_t) l;
|
||||
while (len)
|
||||
{
|
||||
l = len > 16 ? 16 : len;
|
||||
ret = bdmlib_read_block (adr, l, mem);
|
||||
if (ret != l)
|
||||
{
|
||||
printf ("error to read 0x%lx len 0x%lx ret %d\n",
|
||||
(u_long) adr, l, ret);
|
||||
if(dump_file!=NULL)
|
||||
fclose(dump_file);
|
||||
return -2;
|
||||
}
|
||||
printf ("%06lx:", (u_long) adr);
|
||||
for (i = 0; i < l; i++)
|
||||
printf (" %02x", mem[i]);
|
||||
printf ("\n");
|
||||
if(dump_file!=NULL)
|
||||
fwrite(mem, l, 1, dump_file);
|
||||
len -= l;
|
||||
adr += l;
|
||||
}
|
||||
if(dump_file!=NULL)
|
||||
fclose(dump_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mem_modify (char *buf)
|
||||
{
|
||||
int ret;
|
||||
char *p;
|
||||
long addr;
|
||||
long count=0;
|
||||
long capacity=0;
|
||||
u_char *data=NULL;
|
||||
u_char val;
|
||||
|
||||
while(*buf&&!isblank(*buf)) buf++;
|
||||
while(*buf&&isblank(*buf)) buf++;
|
||||
if(!*buf)
|
||||
{ usage_error:
|
||||
if(data) free(data);
|
||||
printf ("use : modify address byte1 byte2 ...\n");
|
||||
return -1;
|
||||
}
|
||||
addr=strtol(buf,&p,0);
|
||||
if(p==buf) goto usage_error;
|
||||
buf=p;
|
||||
capacity=128;
|
||||
data=malloc(capacity);
|
||||
while(*buf&&isblank(*buf)) buf++;
|
||||
while(*buf){
|
||||
val=strtol(buf,&p,0);
|
||||
if(p==buf) goto usage_error;
|
||||
buf=p;
|
||||
if(count>=capacity){
|
||||
capacity*=2;
|
||||
data=realloc(data,capacity);
|
||||
if(!data) goto usage_error;
|
||||
}
|
||||
data[count++]=val;
|
||||
while(*buf&&isblank(*buf)) buf++;
|
||||
}
|
||||
|
||||
ret=bdmlib_wrb_filt(bdmlib_bfilt, (caddr_t)addr, count, data);
|
||||
//if(ret!=count)
|
||||
printf("bdmlib_wrb_filt: addr=0x%08lx count=%ld return=%ld\n",
|
||||
(long)addr,(long)count,(long)ret);
|
||||
|
||||
if(data) free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
cpu_get_rpc(u_int32_t *val)
|
||||
{
|
||||
int ret;
|
||||
u_int32_t rpc;
|
||||
if ((ret = bdmlib_get_sys_reg (BDM_REG_RPC, &rpc)) < 0)
|
||||
return ret;
|
||||
*val=swap_l(rpc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cpu_stat (char *buf)
|
||||
{
|
||||
int ret;
|
||||
u_int32_t rpc;
|
||||
ret = bdmlib_getstatus ();
|
||||
printf ("MCU ");
|
||||
if (ret & BDM_TARGETRESET)
|
||||
printf ("Reset ");
|
||||
if (ret & BDM_TARGETSTOPPED)
|
||||
printf ("Stopped ");
|
||||
if (ret & BDM_TARGETPOWER)
|
||||
printf ("NoPower ");
|
||||
if (ret & BDM_TARGETNC)
|
||||
printf ("NoConnect ");
|
||||
printf ("\n");
|
||||
if (ret & BDM_TARGETSTOPPED)
|
||||
{
|
||||
if ((ret = cpu_get_rpc (&rpc)) < 0)
|
||||
return ret;
|
||||
printf ("RPC=%x\n",rpc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
flash_check_one (bdmlib_bfilt_t *filt, int autoset)
|
||||
{
|
||||
flash_alg_info_t const *alg;
|
||||
caddr_t adr;
|
||||
flash_d_t readid[2];
|
||||
int ret;
|
||||
|
||||
alg = (flash_alg_info_t *) filt->info;
|
||||
adr = filt->begin_adr;
|
||||
|
||||
if(filt->flags&BDMLIB_FILT_AUTO)
|
||||
{
|
||||
autoset|=2;
|
||||
if(adr==filt->end_adr)
|
||||
autoset|=4;
|
||||
}
|
||||
|
||||
if ((autoset & 4)&&(adr>=AUTO_ADR_CSBOOT)&&(adr<=AUTO_ADR_CSBOOT+12))
|
||||
{
|
||||
u_int32_t csx_opt, csx_base, csx_size;
|
||||
caddr_t cpu32csopt_adr;
|
||||
cpu32csopt_adr=(caddr_t)0xfffa48+(adr-AUTO_ADR_CSBOOT)*4;
|
||||
if (bdmlib_read_var (cpu32csopt_adr, BDM_SIZE_LONG, &csx_opt) >= 0)
|
||||
{
|
||||
static u_int32_t csx_sizes[]={1<<11,1<<13,1<<14,1<<16,
|
||||
1<<17,1<<18,1<<19,1<<20};
|
||||
csx_base = (csx_opt >> 8) & 0xfff800;
|
||||
filt->begin_adr = (caddr_t) csx_base;
|
||||
csx_size = csx_sizes[(csx_opt >> 16) & 0x7];
|
||||
filt->end_adr = (caddr_t) (csx_base + csx_size - 1);
|
||||
if(adr==AUTO_ADR_CSBOOT)
|
||||
printf ("Flash addresses taken from CSBOOT\n");
|
||||
else
|
||||
printf ("Flash addresses taken from CS%d\n",
|
||||
(int)(adr-AUTO_ADR_CSX));
|
||||
printf ("Start %06lX End %06lX\n",
|
||||
(long) filt->begin_adr, (long) filt->end_adr);
|
||||
}
|
||||
}
|
||||
|
||||
adr = filt->begin_adr;
|
||||
|
||||
ret = bdmflash_check_id (alg, adr, readid);
|
||||
if((ret >= 0)&&(autoset&4)&&(filt->begin_adr==filt->end_adr))
|
||||
filt->end_adr=filt->begin_adr+alg->addr_mask;
|
||||
printf ("Flash@%06lX-%06lX ManID %08X DevID %08X\n",
|
||||
(long) adr, (long) filt->end_adr,
|
||||
(unsigned) readid[0], (unsigned) readid[1]);
|
||||
if (ret >= 0)
|
||||
{
|
||||
printf ("Flash ID is OK\nUsed algorithm %s\n", alg->alg_name);
|
||||
return 1;
|
||||
}
|
||||
if (!autoset & 2)
|
||||
{
|
||||
printf ("Flash parameters are incorrect !!!\n");
|
||||
return -1;
|
||||
}
|
||||
alg = bdmflash_alg_probe (adr);
|
||||
if (alg == NULL)
|
||||
{
|
||||
printf ("Flash parameters cannot be probed\n");
|
||||
return -1;
|
||||
}
|
||||
ret = bdmflash_check_id (alg, adr, readid);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf ("Probed parameters are incorrect\n");
|
||||
return -1;
|
||||
}
|
||||
filt->info = (void *) alg;
|
||||
if(filt->begin_adr==filt->end_adr)
|
||||
filt->end_adr=filt->begin_adr+alg->addr_mask;
|
||||
printf ("Probed flash parameters\n");
|
||||
printf ("Flash@%06lX-%06lX ManID %04X DevID %04X\n",
|
||||
(long) filt->begin_adr, (long) filt->end_adr,
|
||||
(unsigned) readid[0], (unsigned) readid[1]);
|
||||
printf ("Used algorithm %s\n", alg->alg_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
flash_check(char *buf, int autoset)
|
||||
{
|
||||
int ret;
|
||||
bdmlib_bfilt_t *filt = bdmlib_bfilt;
|
||||
printf("\n");
|
||||
while(filt)
|
||||
{
|
||||
if(filt->flags&BDMLIB_FILT_FLASH)
|
||||
{
|
||||
ret=flash_check_one(filt,autoset);
|
||||
printf("\n");
|
||||
if(ret<0)
|
||||
return ret;
|
||||
}
|
||||
filt=filt->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
flash_erase(void)
|
||||
{
|
||||
int ret;
|
||||
bdmlib_bfilt_t *filt = bdmlib_bfilt;
|
||||
while(filt)
|
||||
{
|
||||
if(filt->flags&BDMLIB_FILT_FLASH)
|
||||
{
|
||||
ret=bdmflash_erase_filt (filt, (caddr_t) 0, 0);
|
||||
if(ret<0)
|
||||
return ret;
|
||||
}
|
||||
filt=filt->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
flash_blankck(void)
|
||||
{
|
||||
int ret,sum=0;
|
||||
bdmlib_bfilt_t *filt = bdmlib_bfilt;
|
||||
while(filt)
|
||||
{
|
||||
if(filt->flags&BDMLIB_FILT_FLASH)
|
||||
{
|
||||
ret=bdmflash_blankck_filt (filt, (caddr_t) 0, 0);
|
||||
if(ret<0)
|
||||
return ret;
|
||||
sum+=ret;
|
||||
}
|
||||
filt=filt->next;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* bdmlib_propeller(stdout); */
|
||||
|
||||
int
|
||||
flash_setup(char *buf)
|
||||
{
|
||||
char *p,*r;
|
||||
int i;
|
||||
caddr_t begin_adr=(caddr_t)(0);
|
||||
caddr_t end_adr=(caddr_t)(0);
|
||||
char alg_name[32];
|
||||
flash_alg_info_t const *alg=NULL;
|
||||
bdmlib_bfilt_t *filt;
|
||||
|
||||
while(*buf&&isblank(*buf)) buf++;
|
||||
if((p=strchr(buf,'@'))!=NULL){/* '@' character in specification */
|
||||
i=p-buf;
|
||||
if(i>=sizeof(alg_name)-1)
|
||||
i=sizeof(alg_name)-1;
|
||||
strncpy(alg_name,buf,i);
|
||||
alg_name[i]=0;
|
||||
p++;
|
||||
if(!strncmp(p,"csboot",6)){ /* take address from CSBOOT */
|
||||
p+=6;
|
||||
end_adr=begin_adr=AUTO_ADR_CSBOOT;
|
||||
}else if(!strncmp(p,"cs",2)){
|
||||
p+=2;
|
||||
end_adr=begin_adr=AUTO_ADR_CSX+strtoul(p,&r,0);
|
||||
if((p==r)||(begin_adr>AUTO_ADR_CSX+11)){
|
||||
fprintf(stderr,"%s : bad chipselect format\n",buf);
|
||||
return -1;
|
||||
}
|
||||
p=r;
|
||||
}else{ /* take begin address after '@' */
|
||||
end_adr=begin_adr=(caddr_t)strtoul(p,&r,0);
|
||||
if(p==r){
|
||||
fprintf(stderr,"%s : bad begin address format\n",buf);
|
||||
return -1;
|
||||
}
|
||||
p=r;
|
||||
if(*p=='+'){ /* take end address from size */
|
||||
end_adr=begin_adr+strtoul(++p,&r,0)-1;
|
||||
if(p==r){
|
||||
fprintf(stderr,"%s : bad size format\n",buf);
|
||||
return -1;
|
||||
}
|
||||
p=r;
|
||||
} else if(*p=='-') { /* take absolute end address */
|
||||
end_adr=(caddr_t)strtoul(++p,&r,0);
|
||||
if(p==r){
|
||||
fprintf(stderr,"%s : bad end address format\n",buf);
|
||||
return -1;
|
||||
}
|
||||
p=r;
|
||||
}
|
||||
}
|
||||
while(*buf&&isblank(*buf)) buf++;
|
||||
if(*p){
|
||||
fprintf(stderr,"%s : extra characters in specification %s\n",buf,p);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
end_adr=begin_adr=AUTO_ADR_CSBOOT;
|
||||
strncpy(alg_name,buf,sizeof(alg_name)-1);
|
||||
}
|
||||
|
||||
if(strcmp(alg_name,"auto")){
|
||||
int alg_indx=0;
|
||||
do{
|
||||
alg=flash_alg_infos[alg_indx++];
|
||||
if(alg==NULL){
|
||||
fprintf(stderr,"%s : unknown flash type or algorithm\n",alg_name);
|
||||
return -1;
|
||||
}
|
||||
}while(strcmp(alg_name,alg->alg_name));
|
||||
}
|
||||
|
||||
filt=(bdmlib_bfilt_t*)malloc(sizeof(bdmlib_bfilt_t));
|
||||
if(filt==NULL){
|
||||
fprintf(stderr,"No memory for flash_setup\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
filt->flags=BDMLIB_FILT_FLASH;
|
||||
if(alg==NULL){
|
||||
filt->flags|=BDMLIB_FILT_AUTO;
|
||||
filt->info=flash_alg_infos[0];
|
||||
} else filt->info=(void *)alg;
|
||||
filt->begin_adr=begin_adr;
|
||||
filt->end_adr=end_adr;
|
||||
if(begin_adr==end_adr){
|
||||
filt->flags|=BDMLIB_FILT_AUTO;
|
||||
};
|
||||
filt->filt_id=1;
|
||||
filt->wrb_filt=&bdmflash_wrb_filt;
|
||||
|
||||
filt->next=bdmlib_bfilt;
|
||||
bdmlib_bfilt=filt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
str_list_add(str_list_t *list, char *str)
|
||||
{
|
||||
char **p;
|
||||
int a;
|
||||
if(list->count>=list->alloccnt)
|
||||
{
|
||||
a=list->alloccnt+5;
|
||||
if(list->items==NULL)
|
||||
p=(char**)malloc(sizeof(char *)*a);
|
||||
else
|
||||
p=(char**)realloc(list->items,sizeof(char *)*a);
|
||||
if(p==NULL) return -1;
|
||||
list->items=p;
|
||||
list->alloccnt=a;
|
||||
}
|
||||
list->items[list->count++]=str;
|
||||
return list->count;
|
||||
}
|
||||
|
||||
void str_list_clear(str_list_t *list)
|
||||
{
|
||||
while(list->count--)
|
||||
{
|
||||
if(list->items[list->count]!=NULL)
|
||||
free(list->items[list->count]);
|
||||
}
|
||||
list->alloccnt=list->count=0;
|
||||
if(list->items!=NULL) free(list->items);
|
||||
list->items=NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Main Program
|
||||
**************
|
||||
*/
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int done;
|
||||
int error;
|
||||
int ret;
|
||||
static int print_help = 0; /* Help */
|
||||
static int reset = 0; /* Reset target */
|
||||
static int check = 0; /* Check flash configuration */
|
||||
static int erase = 0; /* Erase flash */
|
||||
static int blankck = 0; /* Check, that flash is blank */
|
||||
static int load = 0; /* Load files to flash */
|
||||
static int run = 0; /* Run target from entry point */
|
||||
static int script = 0; /* Batch mode */
|
||||
static int bdm_delay = 0; /* Delay/speed for BDM driver */
|
||||
static int set_mbar_fl = 0; /* Set MBAR requested */
|
||||
static u_long mbar_val = 0;
|
||||
static u_long entry_pt=0;
|
||||
str_list_t files2load={0,}; /* List of filenames to load */
|
||||
int cmd;
|
||||
char buf[255];
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
/* initialize global flash control variables */
|
||||
initname = strdup ("ram_init.srec"); /* default init file for EFI332 */
|
||||
|
||||
/* initialize name of bdm device */
|
||||
bdm_dev_name = strdup ("/dev/bdm");
|
||||
|
||||
/* start bdmlib debugging */
|
||||
bdmlib_setdebug (0);
|
||||
|
||||
/* Parse arguments and options. Taken from GDB. */
|
||||
{
|
||||
int c;
|
||||
/* When var field is 0, use flag field to record the equivalent
|
||||
short option (or arbitrary numbers starting at 10 for those
|
||||
with no equivalent). */
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, &print_help, 1},
|
||||
{"h", no_argument, &print_help, 1},
|
||||
{"flash", required_argument, 0, 'f'},
|
||||
{"f", required_argument, 0, 'f'},
|
||||
{"init-file", required_argument, 0, 'i'},
|
||||
{"i", required_argument, 0, 'i'},
|
||||
{"reset", no_argument, &reset, 1},
|
||||
{"r", no_argument, &reset, 1},
|
||||
{"check", no_argument, &check, 1},
|
||||
{"c", no_argument, &check, 1},
|
||||
{"erase", no_argument, &erase, 1},
|
||||
{"e", no_argument, &erase, 1},
|
||||
{"blankck", no_argument, &blankck, 1},
|
||||
{"b", no_argument, &blankck, 1},
|
||||
{"load", no_argument, &load, 1},
|
||||
{"l", no_argument, &load, 1},
|
||||
{"go", optional_argument, NULL, 'g'},
|
||||
{"g", no_argument, &run, 1},
|
||||
{"mbar", required_argument, NULL, 'M'},
|
||||
{"M", required_argument, NULL, 'M'},
|
||||
{"script", no_argument, &script, 1},
|
||||
{"s", no_argument, &script, 1},
|
||||
{"bdm-delay", required_argument, 0, 'd'},
|
||||
{"d", required_argument, 0, 'd'},
|
||||
{"bdm-device", required_argument, 0, 'D'},
|
||||
{"D", required_argument, 0, 'D'},
|
||||
{0, no_argument, 0, 0}
|
||||
};
|
||||
|
||||
while (1)
|
||||
{
|
||||
int option_index;
|
||||
|
||||
c = getopt_long_only (argc, argv, "",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
/* Long option that takes an argument. */
|
||||
if (c == 0 && long_options[option_index].flag == 0)
|
||||
c = long_options[option_index].val;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
/* Long option that just sets a flag. */
|
||||
break;
|
||||
case 'f':
|
||||
/* Setup flash region */
|
||||
if(flash_setup(optarg)<0)
|
||||
exit(1);
|
||||
break;
|
||||
case 'g':
|
||||
/* Run target from default or optional entry point */
|
||||
run=1;
|
||||
if (optarg) {
|
||||
if (entry_name) free (entry_name);
|
||||
entry_name = strdup (optarg);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
/* Set MBAR register */
|
||||
mbar_val=strtoul(optarg,&p,0);
|
||||
set_mbar_fl=1;
|
||||
if(optarg==p){
|
||||
fprintf(stderr,"%s: bad numeric format for MBAR\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
if (bdm_dev_name)
|
||||
free (bdm_dev_name);
|
||||
bdm_dev_name = strdup (optarg);
|
||||
break;
|
||||
case 'i':
|
||||
/* Init File */
|
||||
if(initname)
|
||||
free(initname);
|
||||
initname = strdup (optarg);
|
||||
break;
|
||||
case 'd':
|
||||
/* BDM driver delay */
|
||||
bdm_delay=strtol(optarg,&p,0);
|
||||
if(optarg==p){
|
||||
fprintf(stderr,"%s: bad numeric format for BDM delay\n",argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
fprintf(stderr,
|
||||
"Use `%s --help' for a complete list of options.\n",
|
||||
argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(print_help)
|
||||
{
|
||||
printf ("Usage bdm-load [OPTIONS] file1 ...\n"
|
||||
"\t-h --help - this help information!\n"
|
||||
"\t-i --init-file=FILE - object file to initialize processor\n"
|
||||
"\t-r --reset - reset target CPU before other operations\n"
|
||||
"\t-c --check - check flash setup (needed for auto)\n"
|
||||
"\t-e --erase - erase flash\n"
|
||||
"\t-b --blankck - blank check of flash\n"
|
||||
"\t-l --load - download listed filenames\n"
|
||||
"\t --go[=address] - run target CPU from entry address\n"
|
||||
"\t-M --mbar=val - setup 68360 MBAR register\n"
|
||||
"\t-s --script - do actions and return\n"
|
||||
"\t-d --bdm-delay=d - sets BDM driver speed/delay\n"
|
||||
"\t-D --bdm-device - sets BDM device file\n"
|
||||
"\t-f --flash=TYPE@ADR - select flash\n"
|
||||
"For flash TYPE@ADR can be\n"
|
||||
" {<TYPE>|auto}[@{csboot|cs<x>|<start>{+<size>|-<end>}}]\n"
|
||||
"Examples\n"
|
||||
" auto@csboot amd29f400@0x800000-0x87ffff auto@0+0x80000\n"
|
||||
"If auto type or cs address is used, check must be\n"
|
||||
"specified to take effect.\n"
|
||||
"Known flash types/algorithms :\n");
|
||||
for(i=0;flash_alg_infos[i]!=NULL;i++)
|
||||
printf(" %s",flash_alg_infos[i]->alg_name);
|
||||
printf("\n\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
while(optind<argc)
|
||||
str_list_add(&files2load,strdup(argv[optind++]));
|
||||
|
||||
#ifdef DEBUG_MESSAGES
|
||||
printf ("Init file is: %s\n", initname);
|
||||
for(i=0;i<files2load.count;i++){
|
||||
printf ("Object file : %s\n", files2load.items[i]);
|
||||
}
|
||||
printf ("Actions to do%s%s%s%s%s\n", (reset) ? " Reset" : "",
|
||||
(check) ? " Check" : "", (erase) ? " Erase" : "",
|
||||
(blankck) ? " Blankck" : "", (load) ? " Load" : "");
|
||||
#endif
|
||||
|
||||
|
||||
/* Connect to target */
|
||||
if((ret=bdmlib_open (bdm_dev_name)) != BDM_NO_ERROR) {
|
||||
printf("%s: Open \"%s\" reports %s\n",
|
||||
argv[0],bdm_dev_name,bdmlib_geterror_str(ret));
|
||||
exit(1);
|
||||
}
|
||||
if((ret=bdmlib_setioctl (BDM_SPEED, bdm_delay)) != BDM_NO_ERROR) {
|
||||
printf("%s: Set bdm_delay failed with error %s\n",
|
||||
argv[0],bdmlib_geterror_str(ret));
|
||||
exit(1);
|
||||
}
|
||||
hashmark = 1;
|
||||
if(set_mbar_fl) {
|
||||
printf ("MBAR setup to %08lX\n",mbar_val);
|
||||
if(bdmlib_set_mbar(mbar_val) != BDM_NO_ERROR) {
|
||||
printf("%s: MBAR setup failed with error %s\n",
|
||||
argv[0],bdmlib_geterror_str(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(files2load.count>0)
|
||||
bdmlib_do_load_macro (files2load.items[0], BEGIN_MACRO);
|
||||
|
||||
done = cmd = 0;
|
||||
|
||||
do
|
||||
{
|
||||
error = 0;
|
||||
if (reset)
|
||||
{
|
||||
/* bdmlib_init(); */
|
||||
if(bdmlib_reset()<0)
|
||||
{
|
||||
printf ("Reset Failed\n");
|
||||
error=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cpu_stat(NULL)<0)
|
||||
{
|
||||
printf ("CPU Stat Failed\n");
|
||||
error=4;
|
||||
}
|
||||
else
|
||||
{
|
||||
u_int32_t rpc;
|
||||
reset = 0;
|
||||
if(entry_pt==0)
|
||||
{
|
||||
cpu_get_rpc (&rpc);
|
||||
entry_pt=rpc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (check && !error)
|
||||
{
|
||||
if(flash_check(NULL,0)<0)
|
||||
{
|
||||
printf ("Flash Check Failed\n");
|
||||
error=3;
|
||||
}
|
||||
else
|
||||
check = 0;
|
||||
}
|
||||
|
||||
if (erase && !error)
|
||||
{
|
||||
printf ("Erasing Flash...");
|
||||
fflush (stdout);
|
||||
if (flash_erase() >= 0)
|
||||
{
|
||||
printf ("done.\n");
|
||||
erase = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Erase Failed\n");
|
||||
error = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (blankck && !error)
|
||||
{
|
||||
int res;
|
||||
printf ("Flash blank check ...\n");
|
||||
res=flash_blankck();
|
||||
if(!res){
|
||||
printf("Flash blank check OK\n");
|
||||
blankck = 0;
|
||||
}else{
|
||||
error = 5;
|
||||
if(res<0) printf("Flash blank check FAILED\n");
|
||||
else printf("Flash is NOT erased\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (load && !error)
|
||||
{
|
||||
bdmlib_load_use_lma = 1;
|
||||
for(i=0;i<files2load.count;i++){
|
||||
printf("Loading file : %s\n",files2load.items[i]);
|
||||
fflush(stdout);
|
||||
if((ret=bdmlib_load(files2load.items[i], entry_name, &entry_pt))<0)
|
||||
{
|
||||
printf ("Load Failed %d\n", ret);
|
||||
error = 1; //break;
|
||||
}
|
||||
}
|
||||
if(!error) load = 0;
|
||||
bdmlib_load_use_lma = 0;
|
||||
}
|
||||
|
||||
if (run && !error)
|
||||
{
|
||||
printf ("starting at 0x%lx\n", entry_pt);
|
||||
bdmlib_set_sys_reg (BDM_REG_RPC, entry_pt);
|
||||
bdmlib_go ();
|
||||
run=0;
|
||||
}
|
||||
|
||||
if(script)
|
||||
exit(0);
|
||||
|
||||
printf ("bdm-load %d> ", ++cmd);
|
||||
fgets (buf, 250, stdin);
|
||||
|
||||
if (!strncmp (buf, "run", 3))
|
||||
{
|
||||
run = 1;
|
||||
}
|
||||
|
||||
if (!strncmp (buf, "reset", 5))
|
||||
{
|
||||
reset = 1;
|
||||
}
|
||||
|
||||
if (!strncmp (buf, "erase", 5))
|
||||
erase = 1;
|
||||
|
||||
if (!strncmp (buf, "blankck", 5))
|
||||
blankck = 1;
|
||||
|
||||
if (!strncmp (buf, "load", 4))
|
||||
{
|
||||
load = 1;
|
||||
if ((strlen (buf) > 5))
|
||||
{
|
||||
str_list_clear(&files2load);
|
||||
str_list_add(&files2load,strdup(&buf[5]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp (buf, "exit", 4) || !strncmp (buf, "quit", 4))
|
||||
done = 1;
|
||||
|
||||
if (!strncmp (buf, "dump", 4))
|
||||
mem_dump (buf + 4);
|
||||
|
||||
if (!strncmp (buf, "modify", 3))
|
||||
mem_modify (buf + 3);
|
||||
|
||||
if (!strncmp (buf, "stat", 4))
|
||||
cpu_stat (buf + 4);
|
||||
|
||||
if (!strncmp (buf, "check", 5))
|
||||
flash_check (buf + 5, 0);
|
||||
|
||||
if (!strncmp (buf, "autoset", 5))
|
||||
flash_check (buf + 5, 0xff);
|
||||
|
||||
if (!strncmp (buf, "stop", 5))
|
||||
{
|
||||
bdmlib_ioctl(BDM_STOP_CHIP);
|
||||
reset=check=erase=blankck=load=run=0;
|
||||
}
|
||||
|
||||
if (!strncmp (buf, "make", 4))
|
||||
system (buf);
|
||||
|
||||
if (!strncmp (buf, "help", 4) || !strncmp (buf, "?", 1))
|
||||
{
|
||||
printf("Next commands are accepted :\n"\
|
||||
" run - enable full speed ran of target CPU\n"\
|
||||
" stop - stop target CPU\n"\
|
||||
" reset - reset target\n"\
|
||||
" erase - erase all configured FLASH chips\n"\
|
||||
" blankck - check blank state of chips\n"\
|
||||
" load - loand all object files specified\n"\
|
||||
" at command line to RAM or FLASH\n"\
|
||||
" using VMA addresses, name of file to\n"\
|
||||
" can be optionaly specified after \"load\"\n"\
|
||||
" dump <from> <len> - dump target memory\n"\
|
||||
" modify <from> <byte> ... - modify target memory (even flash)\n"\
|
||||
" state - print target status\n"\
|
||||
" check - check presence of configured chips\n"\
|
||||
" autoset - set FLASH chip types from their IDs\n"\
|
||||
" make <par> - call make command in current directory\n"\
|
||||
" quit - leave loader\n"\
|
||||
);
|
||||
}
|
||||
}
|
||||
while (!done);
|
||||
|
||||
str_list_clear(&files2load);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
25
m683xx/bdm-load/bdm-load.lsm
Normal file
25
m683xx/bdm-load/bdm-load.lsm
Normal file
@@ -0,0 +1,25 @@
|
||||
Begin4
|
||||
Title: bdm-load
|
||||
Version: 030815
|
||||
Entered-date: 2003-08-15
|
||||
Description: Flash writer utility for 683xx target systems through
|
||||
Background Debug Mode interface for Motorola CPU32 and Linux
|
||||
Both Public Domain and ICD interfaces are supported.
|
||||
Code contains first experimental tests of GPLed TPU debugger
|
||||
project.
|
||||
* More info about related software and BDM driver at
|
||||
http://cmp.felk.cvut.cz/~pisa
|
||||
http://cmp.felk.cvut.cz/~pisa/m683xx/bdm_driver.html
|
||||
Keywords: debugger GDB m68k 68332 683xx BDM flash embedded TPU
|
||||
Author: jeff@uclinux.org (D.Jeff Dionne)
|
||||
adennison@swin.edu.au (Andrew Dennison)
|
||||
pisa@cvlinux.felk.cvut.cz (Pavel Pisa)
|
||||
Maintained-by: pisa@cvlinux.felk.cvut.cz (Pavel Pisa)
|
||||
Primary-site: metalab.unc.edu /pub/Linux/devel/debuggers
|
||||
210 kB bdm-load-030519.tar.gz
|
||||
Alternate-site: ftp.cygnus.com /pub/embedded
|
||||
210 kB bdm-load-030519.tar.gz
|
||||
Original-site: freeware.aus.sps.mot.com
|
||||
Platforms: Linux 2.0.xx, 2.2.yy, 2.4.zz ( last tested 2.5.69 )
|
||||
Copying-policy: GPL
|
||||
End
|
||||
115
m683xx/bdm-load/bdm.h
Normal file
115
m683xx/bdm-load/bdm.h
Normal file
@@ -0,0 +1,115 @@
|
||||
#ifndef LINUX_BDM_H
|
||||
#define LINUX_BDM_H
|
||||
/*
|
||||
* $Id: bdm.h,v 1.1 2003/06/04 01:31:32 ppisa Exp $
|
||||
*
|
||||
* Linux Device Driver for Public Domain BDM Interface
|
||||
* based on the PD driver package by Scott Howard, Feb 93
|
||||
* ported to Linux by M.Schraut
|
||||
* tested for kernel version 1.2.4
|
||||
* (C) 1995 Technische Universitaet Muenchen, Lehrstuhl fuer Prozessrechner
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#define BDM_MAJOR_NUMBER 53
|
||||
|
||||
/* error codes */
|
||||
#define BDM_FAULT_UNKNOWN -610 /*Error-definitions*/
|
||||
#define BDM_FAULT_POWER -611
|
||||
#define BDM_FAULT_CABLE -612
|
||||
#define BDM_FAULT_RESPONSE -613 /*NOT Ready */
|
||||
#define BDM_FAULT_RESET -614
|
||||
#define BDM_FAULT_PORT -615
|
||||
#define BDM_FAULT_BERR -616
|
||||
#define BDM_FAULT_NVC -617 /*no valid command */
|
||||
|
||||
/* Debug Levels */
|
||||
#define BDM_DEBUG_NONE 0
|
||||
#define BDM_DEBUG_SOME 1
|
||||
#define BDM_DEBUG_ALL 2
|
||||
|
||||
/* supported ioctls */
|
||||
#define BDM_INIT 0 /* no argument */
|
||||
#define BDM_DEINIT 1 /* no argument */
|
||||
#define BDM_RESET_CHIP 2 /* no argument */
|
||||
#define BDM_RESTART_CHIP 3 /* no argument */
|
||||
#define BDM_STOP_CHIP 4 /* no argument */
|
||||
#define BDM_STEP_CHIP 5 /* no argument */
|
||||
#define BDM_GET_STATUS 6 /* no argument */
|
||||
#define BDM_SPEED 7 /* arg = speed */
|
||||
#define BDM_RELEASE_CHIP 8 /* no argument */
|
||||
#define BDM_DEBUG_LEVEL 9 /* arg = level */
|
||||
#define BDM_GET_VERSION 10 /* arg = &int */
|
||||
#define BDM_SENSECABLE 11 /* arg =on/off */
|
||||
|
||||
#define BDM_NORETURN 0 /* no error, no ret value */
|
||||
/* functional bits of ioctl BDM_GET_STATUS */
|
||||
#define BDM_TARGETRESET (1<<0) /* Target reset */
|
||||
#define BDM_TARGETSTOPPED (1<<2) /* Target (was already) stopped */
|
||||
#define BDM_TARGETPOWER (1<<3) /* Power failed */
|
||||
#define BDM_TARGETNC (1<<4) /* Target not Connected */
|
||||
|
||||
/* command codes for bdm interface */
|
||||
#define BDM_RREG_CMD 0x2180
|
||||
#define BDM_WREG_CMD 0x2080
|
||||
#define BDM_RSREG_CMD 0x2580
|
||||
#define BDM_WSREG_CMD 0x2480
|
||||
#define BDM_READ_CMD 0x1900
|
||||
#define BDM_WRITE_CMD 0x1800
|
||||
#define BDM_DUMP_CMD 0x1d00
|
||||
#define BDM_FILL_CMD 0x1c00
|
||||
#define BDM_GO_CMD 0x0c00
|
||||
#define BDM_CALL_CMD 0x0800
|
||||
#define BDM_RST_CMD 0x0400
|
||||
#define BDM_NOP_CMD 0x0000
|
||||
|
||||
/* system register for RSREG/WSREG */
|
||||
#define BDM_REG_RPC 0x0
|
||||
#define BDM_REG_PCC 0x1
|
||||
#define BDM_REG_SR 0xb
|
||||
#define BDM_REG_USP 0xc
|
||||
#define BDM_REG_SSP 0xd
|
||||
#define BDM_REG_SFC 0xe
|
||||
#define BDM_REG_DFC 0xf
|
||||
#define BDM_REG_ATEMP 0x8
|
||||
#define BDM_REG_FAR 0x9
|
||||
#define BDM_REG_VBR 0xa
|
||||
|
||||
/* system register for RREG/WREG */
|
||||
#define BDM_REG_D0 0x0
|
||||
#define BDM_REG_D1 0x1
|
||||
#define BDM_REG_D2 0x2
|
||||
#define BDM_REG_D3 0x3
|
||||
#define BDM_REG_D4 0x4
|
||||
#define BDM_REG_D5 0x5
|
||||
#define BDM_REG_D6 0x6
|
||||
#define BDM_REG_D7 0x7
|
||||
#define BDM_REG_A0 0x8
|
||||
#define BDM_REG_A1 0x9
|
||||
#define BDM_REG_A2 0xa
|
||||
#define BDM_REG_A3 0xb
|
||||
#define BDM_REG_A4 0xc
|
||||
#define BDM_REG_A5 0xd
|
||||
#define BDM_REG_A6 0xe
|
||||
#define BDM_REG_A7 0xf
|
||||
|
||||
/* op size for READ/WRITE */
|
||||
#define BDM_SIZE_BYTE 0x0000
|
||||
#define BDM_SIZE_WORD 0x0040
|
||||
#define BDM_SIZE_LONG 0x0080
|
||||
|
||||
#endif
|
||||
272
m683xx/bdm-load/bdm_test.c
Normal file
272
m683xx/bdm-load/bdm_test.c
Normal file
@@ -0,0 +1,272 @@
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "bdm.h"
|
||||
#include "bdmlib.h"
|
||||
|
||||
char* TestSW(int argc,char *argv[],char swch);
|
||||
|
||||
#define swap_l(x) (x>>24) | ((x>>8)&0xff00) | ((x<<8)&0xff0000) | ((x&0xff)<<24)
|
||||
|
||||
/* for BDMLIB to work */
|
||||
char hashmark;
|
||||
int bdm_autoreset;
|
||||
int bdm_ttcu;
|
||||
|
||||
int bdm_step_chip()
|
||||
{
|
||||
int ret;
|
||||
u_int32_t rpc;
|
||||
|
||||
if (!bdmlib_isopen())
|
||||
return BDM_ERR_NOT_OPEN;
|
||||
|
||||
if (!(bdmlib_getstatus()&BDM_TARGETSTOPPED))
|
||||
if((ret=bdmlib_ioctl(BDM_STOP_CHIP)<0))
|
||||
{return ret;};
|
||||
|
||||
if((ret=bdmlib_get_sys_reg(BDM_REG_RPC, &rpc))<0) return ret;
|
||||
printf("RPC=%x\n",swap_l(rpc));
|
||||
ret=bdmlib_ioctl(BDM_STEP_CHIP);
|
||||
if((ret=bdmlib_get_sys_reg(BDM_REG_RPC, &rpc))<0) return ret;
|
||||
printf("RPC=%x\n",swap_l(rpc));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bdm_show_regs(void)
|
||||
{
|
||||
u_int reg;
|
||||
if (!bdmlib_isopen())
|
||||
return BDM_ERR_NOT_OPEN;
|
||||
|
||||
bdmlib_get_reg(BDM_REG_D0, ®);
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
int rd_test(void)
|
||||
{
|
||||
u_int16_t val;
|
||||
caddr_t adr=(caddr_t)0xFFAA;
|
||||
int counter=0;
|
||||
|
||||
if (!bdmlib_isopen())
|
||||
return BDM_ERR_NOT_OPEN;
|
||||
while(1){
|
||||
if(bdmlib_read_var(adr,BDM_SIZE_WORD,&val)<0)
|
||||
goto mem_op_error;
|
||||
//usleep(1);
|
||||
if(counter++>=10000){
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
counter=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
mem_op_error:
|
||||
printf("Memory read error\n");
|
||||
return -1;
|
||||
};
|
||||
|
||||
int wr_test(void)
|
||||
{
|
||||
u_int16_t val=0xAAAA;
|
||||
caddr_t adr=(caddr_t)0xFFAA;
|
||||
int counter=0;
|
||||
|
||||
if (!bdmlib_isopen())
|
||||
return BDM_ERR_NOT_OPEN;
|
||||
while(1){
|
||||
if(bdmlib_write_var(adr,BDM_SIZE_WORD,val)<0)
|
||||
goto mem_op_error;
|
||||
//usleep(1);
|
||||
if(counter++>=10000){
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
counter=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
mem_op_error:
|
||||
printf("Memory write error\n");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
int step_test(void)
|
||||
{
|
||||
int counter=0;
|
||||
|
||||
if (!bdmlib_isopen())
|
||||
return BDM_ERR_NOT_OPEN;
|
||||
while(1){
|
||||
if(bdmlib_ioctl(BDM_STEP_CHIP)<0)
|
||||
goto step_op_error;
|
||||
usleep(1);
|
||||
if(counter++>=10000){
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
counter=0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
step_op_error:
|
||||
printf("Stepping error\n");
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int quit_fl=0;
|
||||
int ret;
|
||||
char c;
|
||||
char *p;
|
||||
char file_name[100]="";
|
||||
char bdm_dev_name[100]="/dev/bdm";
|
||||
unsigned long entry_pt=0;
|
||||
|
||||
bdmlib_setdebug(1);
|
||||
if((p=TestSW(argc,argv,'D'))!=NULL)
|
||||
strncpy(bdm_dev_name,p,sizeof(bdm_dev_name));
|
||||
if((ret=bdmlib_open(bdm_dev_name))<0)
|
||||
{ printf("bdmlib_open : %s\n",bdmlib_geterror_str(ret)); return 1; };
|
||||
bdmlib_setioctl(BDM_SPEED,0);
|
||||
|
||||
if((p=TestSW(argc,argv,'F'))!=NULL)
|
||||
{
|
||||
strncpy(file_name,p,sizeof(file_name));
|
||||
bdmlib_setioctl(BDM_SPEED,100);
|
||||
bdmlib_reset();
|
||||
bdmlib_setioctl(BDM_SPEED,10);
|
||||
bdmlib_go();
|
||||
sleep(2);
|
||||
bdm_step_chip();
|
||||
ret=bdmlib_load(file_name, NULL, &entry_pt);
|
||||
if(ret<0) printf("bdmlib_load : %s\n",bdmlib_geterror_str(ret));
|
||||
bdmlib_set_sys_reg(BDM_REG_RPC, entry_pt);
|
||||
ret=bdmlib_go();
|
||||
};
|
||||
|
||||
do {
|
||||
c=getchar();
|
||||
|
||||
ret=bdmlib_getstatus();
|
||||
if(ret<0) printf("bdmlib_go : %s\n",bdmlib_geterror_str(ret));
|
||||
else {
|
||||
printf("MCU ");
|
||||
if(ret&BDM_TARGETRESET) printf("Reset ");
|
||||
if(ret&BDM_TARGETSTOPPED) printf("Stopped ");
|
||||
if(ret&BDM_TARGETPOWER) printf("NoPower ");
|
||||
if(ret&BDM_TARGETNC) printf("NoConnect ");
|
||||
printf("\n");
|
||||
};
|
||||
|
||||
c=toupper(c);
|
||||
|
||||
switch(c) {
|
||||
|
||||
case 'B':
|
||||
|
||||
case 'D':
|
||||
bdmlib_showpc();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
ret=bdm_step_chip();
|
||||
if(ret<0) printf("bdmlib_go : %s\n",bdmlib_geterror_str(ret));
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
ret=bdmlib_go();
|
||||
if(ret<0) printf("bdmlib_go : %s\n",bdmlib_geterror_str(ret));
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
bdmlib_setioctl(BDM_SPEED,100);
|
||||
ret=bdmlib_reset();
|
||||
bdmlib_setioctl(BDM_SPEED,0);
|
||||
if(ret<0) printf("bdmlib_reset : %s\n",bdmlib_geterror_str(ret));
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
quit_fl=1;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
wr_test();
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
rd_test();
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
step_test();
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
printf("Enter file name : ");
|
||||
scanf("%s",file_name);
|
||||
printf("\n");
|
||||
ret=bdmlib_load(file_name, NULL, &entry_pt);
|
||||
if(ret<0) printf("bdmlib_load : %s\n",bdmlib_geterror_str(ret));
|
||||
else
|
||||
{printf("loaded OK, entrypoint %lx\n",entry_pt);
|
||||
if((ret=bdmlib_set_sys_reg(BDM_REG_RPC, entry_pt))<0)
|
||||
printf("set PC error : %s\n",bdmlib_geterror_str(ret));
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("Help for BDM_TEST\n"
|
||||
"B: Begin Program Execution from Reset\n"
|
||||
"D: Dump Target MCU Registers\n"
|
||||
"H: Print This Help Summary\n"
|
||||
"L: Load S-Record or Object File into Target\n"
|
||||
"M: Memory Hex/ASCII Display\n"
|
||||
"R: Hardware Reset Target MCU\n"
|
||||
"S: Single Step Target MCU\n"
|
||||
"G: Go Full Speed Target MCU\n"
|
||||
"Q: Quit back to DOS\n");
|
||||
};
|
||||
|
||||
} while(!quit_fl);
|
||||
|
||||
bdmlib_close(1);
|
||||
|
||||
return(0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
char* TestSW(int argc,char *argv[],char swch)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
for(i=1;i<argc;i++)
|
||||
if((argv[i][0]=='-')&&(toupper(argv[i][1])==swch))
|
||||
{
|
||||
p=argv[i]+2;
|
||||
while(((*p==' ')||(*p=='\t'))&&(*p)) p++;
|
||||
if((!*p)&&(i<argc)) if(argv[++i][0]!='-')
|
||||
{
|
||||
p=argv[i];
|
||||
while(((*p==' ')||(*p=='\t'))&&(*p)) p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
945
m683xx/bdm-load/bdmflash.c
Normal file
945
m683xx/bdm-load/bdmflash.c
Normal file
@@ -0,0 +1,945 @@
|
||||
/*******************************************************************
|
||||
Flash programming algorithms for use with BDM flash utility
|
||||
|
||||
bdmflash.c - test driver implementation
|
||||
|
||||
(C) Copyright 2000 by Pavel Pisa <pisa@waltz.felk.cvut.cz>
|
||||
|
||||
This souce is distributed under the Gnu General Public Licence.
|
||||
See file COPYING for details.
|
||||
|
||||
Source could be used under any other license for embeded systems,
|
||||
but in such case enhancements must be sent to original author.
|
||||
If some of contributors does not agree with above two lines,
|
||||
he can delete them and only GPL will apply.
|
||||
*******************************************************************/
|
||||
/*
|
||||
Revision history
|
||||
|
||||
2001-01-16 Added experimental support of single 8 bit flash memory
|
||||
based on Avi Cohen Stuart <astuart@baan.nl> changes
|
||||
|
||||
2001-07-10 Added support for amd_29f010 with x8x2 configuration
|
||||
based on John S. Gwynne <jsg@jsgpc.mrcday.com> changes
|
||||
Trying to solve x8x2 race condition with shortest
|
||||
possible code - needs more tests
|
||||
|
||||
2001-08-30 Added alg-info for at_49f040 with x8x2 configuration
|
||||
x8x2 configuration needs more testing, may be broken
|
||||
|
||||
2003-05-19 Added initial support for x32 memory configurations.
|
||||
The x16x2 and x8x4 should work as well. Changes were
|
||||
motivated by Andrei Smirnov <andrei.s@myrealbox.com>
|
||||
code, but his small update results in deeper code redesign.
|
||||
This could enable to support page writes for modern versions
|
||||
of FLASH memories in future.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "bdm.h"
|
||||
#include "bdmlib.h"
|
||||
#include "bdmflash.h"
|
||||
|
||||
/* predefined flash algorithms metods */
|
||||
|
||||
int bdmflash_check_id_x32(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2]);
|
||||
int bdmflash_prog_x32(const flash_alg_info_t *alg, void *addr, const void *data, long count);
|
||||
int bdmflash_erase_x32(const flash_alg_info_t *alg, void *addr, long size);
|
||||
|
||||
int bdmflash_check_id_x16(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2]);
|
||||
int bdmflash_prog_x16(const flash_alg_info_t *alg, void *addr, const void *data, long count);
|
||||
int bdmflash_erase_x16(const flash_alg_info_t *alg, void *addr, long size);
|
||||
|
||||
int bdmflash_check_id_x8(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2]);
|
||||
int bdmflash_prog_x8(const flash_alg_info_t *alg, void *addr, const void *data, long count);
|
||||
int bdmflash_erase_x8(const flash_alg_info_t *alg, void *addr, long size);
|
||||
|
||||
/* predefined flash types */
|
||||
|
||||
flash_alg_info_t amd_29f800_x16={
|
||||
check_id: bdmflash_check_id_x16,
|
||||
prog: bdmflash_prog_x16,
|
||||
erase: bdmflash_erase_x16,
|
||||
addr_mask: 0xfffff, /* 1MB */
|
||||
reg1_addr: 0x555*2,
|
||||
reg2_addr: 0x2aa*2,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x16,
|
||||
cmd_unlock1:0xaa, /* reg1 */
|
||||
cmd_unlock2:0x55, /* reg2 */
|
||||
cmd_rdid: 0x90, /* reg1 */
|
||||
cmd_prog: 0xa0, /* reg1 */
|
||||
cmd_erase: 0x80, /* reg1 */
|
||||
cmd_reset: 0xf0, /* any */
|
||||
erase_all: 0x10, /* reg1 */
|
||||
erase_sec: 0x30, /* sector */
|
||||
fault_bit: 0x20,
|
||||
manid: 1,
|
||||
devid: 0x2258,
|
||||
alg_name: "amd29f800"
|
||||
};
|
||||
|
||||
flash_alg_info_t amd_29f400_x16={
|
||||
check_id: bdmflash_check_id_x16,
|
||||
prog: bdmflash_prog_x16,
|
||||
erase: bdmflash_erase_x16,
|
||||
addr_mask: 0x7ffff, /* 0.5MB */
|
||||
reg1_addr: 0x555*2,
|
||||
reg2_addr: 0x2aa*2,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x16,
|
||||
cmd_unlock1:0xaa, /* reg1 */
|
||||
cmd_unlock2:0x55, /* reg2 */
|
||||
cmd_rdid: 0x90, /* reg1 */
|
||||
cmd_prog: 0xa0, /* reg1 */
|
||||
cmd_erase: 0x80, /* reg1 */
|
||||
cmd_reset: 0xf0, /* any */
|
||||
erase_all: 0x10, /* reg1 */
|
||||
erase_sec: 0x30, /* sector */
|
||||
fault_bit: 0x20,
|
||||
manid: 1,
|
||||
devid: 0x22ab,
|
||||
alg_name: "amd29f400"
|
||||
};
|
||||
|
||||
flash_alg_info_t amd_29f040_x8={
|
||||
check_id: bdmflash_check_id_x8,
|
||||
prog: bdmflash_prog_x8,
|
||||
erase: bdmflash_erase_x8,
|
||||
addr_mask: 0x7ffff, /* 0.5MB */
|
||||
reg1_addr: 0x555,
|
||||
reg2_addr: 0x2aa,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x8,
|
||||
cmd_unlock1:0xaa, /* reg1 */
|
||||
cmd_unlock2:0x55, /* reg2 */
|
||||
cmd_rdid: 0x90, /* reg1 */
|
||||
cmd_prog: 0xa0, /* reg1 */
|
||||
cmd_erase: 0x80, /* reg1 */
|
||||
cmd_reset: 0xf0, /* any */
|
||||
erase_all: 0x10, /* reg1 */
|
||||
erase_sec: 0x30, /* sector */
|
||||
fault_bit: 0x20,
|
||||
manid: 1,
|
||||
devid: 0xa4,
|
||||
alg_name: "amd29f040"
|
||||
};
|
||||
|
||||
flash_alg_info_t amd_29f010_x8x2={
|
||||
check_id: bdmflash_check_id_x16,
|
||||
prog: bdmflash_prog_x16,
|
||||
erase: bdmflash_erase_x16,
|
||||
addr_mask: 0x3ffff, /* 2x128kB = 256kB */
|
||||
reg1_addr: 0x5555*2,
|
||||
reg2_addr: 0x2aaa*2,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x8x2,
|
||||
cmd_unlock1:0xaaaa, /* reg1 */
|
||||
cmd_unlock2:0x5555, /* reg2 */
|
||||
cmd_rdid: 0x9090, /* reg1 */
|
||||
cmd_prog: 0xa0a0, /* reg1 */
|
||||
cmd_erase: 0x8080, /* reg1 */
|
||||
cmd_reset: 0xf0f0, /* any */
|
||||
erase_all: 0x1010, /* reg1 */
|
||||
erase_sec: 0x3030, /* sector */
|
||||
fault_bit: 0x2020,
|
||||
manid: 0x0101,
|
||||
devid: 0x2020,
|
||||
alg_name: "amd29f010x2"
|
||||
};
|
||||
|
||||
flash_alg_info_t at_49f040_x8x2={
|
||||
check_id: bdmflash_check_id_x16,
|
||||
prog: bdmflash_prog_x16,
|
||||
erase: bdmflash_erase_x16,
|
||||
addr_mask: 0xfffff, /* 2x0.5MB = 1MB */
|
||||
reg1_addr: 0x5555*2,
|
||||
reg2_addr: 0x2aaa*2,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x8x2,
|
||||
cmd_unlock1:0xaaaa, /* reg1 */
|
||||
cmd_unlock2:0x5555, /* reg2 */
|
||||
cmd_rdid: 0x9090, /* reg1 */
|
||||
cmd_prog: 0xa0a0, /* reg1 */
|
||||
cmd_erase: 0x8080, /* reg1 */
|
||||
cmd_reset: 0xf0f0, /* any */
|
||||
erase_all: 0x1010, /* reg1 */
|
||||
erase_sec: 0x3030, /* sector */
|
||||
fault_bit: 0x2020,
|
||||
manid: 0x1F1F,
|
||||
devid: 0x1313,
|
||||
alg_name: "at49f040x2"
|
||||
};
|
||||
|
||||
#ifdef WITH_TARGET_BUS32
|
||||
|
||||
flash_alg_info_t amd_29f080_x8x4={
|
||||
check_id: bdmflash_check_id_x32,
|
||||
prog: bdmflash_prog_x32,
|
||||
erase: bdmflash_erase_x32,
|
||||
addr_mask: 0x3fffff, /* 4x1MB */
|
||||
reg1_addr: 0x555*4,
|
||||
reg2_addr: 0x2aa*4,
|
||||
sec_size: 0x10000,
|
||||
width: FLASH_ALG_BITS_x8x4,
|
||||
cmd_unlock1:0xaaaaaaaa, /* reg1 */
|
||||
cmd_unlock2:0x55555555, /* reg2 */
|
||||
cmd_rdid: 0x90909090, /* reg1 */
|
||||
cmd_prog: 0xa0a0a0a0, /* reg1 */
|
||||
cmd_erase: 0x80808080, /* reg1 */
|
||||
cmd_reset: 0xf0f0f0f0, /* any */
|
||||
erase_all: 0x10101010, /* reg1 */
|
||||
erase_sec: 0x30303030, /* sector */
|
||||
fault_bit: 0x20202020,
|
||||
manid: 0x01010101,
|
||||
devid: 0xd5d5d5d5,
|
||||
alg_name: "amd29f080x4"
|
||||
};
|
||||
|
||||
#endif /* WITH_TARGET_BUS32 */
|
||||
|
||||
/* please keep sorted by flash sizes, smallest first */
|
||||
flash_alg_info_t *flash_alg_infos_def[]={
|
||||
&amd_29f010_x8x2, /* 256 kB */
|
||||
&amd_29f040_x8, /* 512 kB */
|
||||
&amd_29f400_x16, /* 512 kB */
|
||||
&amd_29f800_x16, /* 1 MB */
|
||||
&at_49f040_x8x2, /* 1 MB */
|
||||
#ifdef WITH_TARGET_BUS32
|
||||
&amd_29f080_x8x4, /* 4 MB */
|
||||
#endif /* WITH_TARGET_BUS32 */
|
||||
NULL
|
||||
};
|
||||
|
||||
flash_alg_info_t **flash_alg_infos=flash_alg_infos_def;
|
||||
|
||||
#if 0
|
||||
#define FLASH_WR32(adr,val) (*(volatile u_int32_t*)(adr)=(val))
|
||||
#define FLASH_RD32(adr) (*(volatile u_int32_t*)(adr))
|
||||
#define FLASH_WR16(adr,val) (*(volatile u_int16_t*)(adr)=(val))
|
||||
#define FLASH_RD16(adr) (*(volatile u_int16_t*)(adr))
|
||||
#define FLASH_WR8(adr,val) (*(volatile u_int8_t*)(adr)=(val))
|
||||
#define FLASH_RD8(adr) (*(volatile u_int8_t*)(adr))
|
||||
#else
|
||||
#define FLASH_WR32(adr,val) \
|
||||
({ \
|
||||
if(bdmlib_write_var(adr,BDM_SIZE_LONG,val)<0) \
|
||||
goto mem_op_error; \
|
||||
val; \
|
||||
})
|
||||
#define FLASH_RD32(adr) \
|
||||
({ u_int32_t temp_val; \
|
||||
if(bdmlib_read_var(adr,BDM_SIZE_LONG,&temp_val)<0) \
|
||||
goto mem_op_error; \
|
||||
temp_val; \
|
||||
})
|
||||
#define FLASH_WR16(adr,val) \
|
||||
({ \
|
||||
if(bdmlib_write_var(adr,BDM_SIZE_WORD,val)<0) \
|
||||
goto mem_op_error; \
|
||||
val; \
|
||||
})
|
||||
#define FLASH_RD16(adr) \
|
||||
({ u_int16_t temp_val; \
|
||||
if(bdmlib_read_var(adr,BDM_SIZE_WORD,&temp_val)<0) \
|
||||
goto mem_op_error; \
|
||||
temp_val; \
|
||||
})
|
||||
#define FLASH_WR8(adr,val) \
|
||||
({ \
|
||||
if(bdmlib_write_var(adr,BDM_SIZE_BYTE,val)<0) \
|
||||
goto mem_op_error; \
|
||||
val; \
|
||||
})
|
||||
#define FLASH_RD8(adr) \
|
||||
({ u_int8_t temp_val; \
|
||||
if(bdmlib_read_var(adr,BDM_SIZE_BYTE,&temp_val)<0) \
|
||||
goto mem_op_error; \
|
||||
temp_val; \
|
||||
})
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static
|
||||
int bdmflash_prepval_x16(u_int16_t *pval, void *addr, const void *data, long count)
|
||||
{
|
||||
if(!((long)addr&1) && (count>=2)){
|
||||
*pval=(((u_char*)data)[0]<<8)|(((u_char*)data)[1]);
|
||||
return 2;
|
||||
}
|
||||
if(!count) return count;
|
||||
if(!((long)addr&1)){
|
||||
*pval=(((u_char*)data)[0]<<8) | FLASH_RD8((u_char*)addr+1);
|
||||
}else{
|
||||
*pval=(FLASH_RD8((u_char*)addr-1)<<8) | (((u_char*)data)[0]);
|
||||
}
|
||||
return 1;
|
||||
|
||||
mem_op_error:
|
||||
return -4;
|
||||
}
|
||||
|
||||
#ifdef WITH_TARGET_BUS32
|
||||
static
|
||||
int bdmflash_prepval_x32(u_int32_t *pval, void *addr, const void *data, long count)
|
||||
{
|
||||
int offs=(long)addr&3;
|
||||
int rest=4-offs;
|
||||
u_int32_t val=0;
|
||||
if(!offs && (count>=4)){
|
||||
*pval=((u_int32_t)((u_char*)data)[0]<<24)|((u_int32_t)((u_char*)data)[1]<<16)|
|
||||
(((u_char*)data)[2]<<8)|(((u_char*)data)[3]);
|
||||
return 4;
|
||||
}
|
||||
if(!count) return count;
|
||||
if(count>rest) count=rest;
|
||||
while(offs){
|
||||
val<<=8;
|
||||
val|=FLASH_RD8((u_char*)addr-offs);
|
||||
offs--;
|
||||
}
|
||||
while(offs<count){
|
||||
val<<=8;
|
||||
val|=((u_char*)data)[offs];
|
||||
offs++;
|
||||
}
|
||||
while(offs<rest){
|
||||
val<<=8;
|
||||
val|=FLASH_RD8((u_char*)addr+offs);
|
||||
offs++;
|
||||
}
|
||||
*pval=val;
|
||||
return count;
|
||||
|
||||
mem_op_error:
|
||||
return -4;
|
||||
}
|
||||
#endif /* WITH_TARGET_BUS32 */
|
||||
|
||||
/*******************************************************************/
|
||||
/* routines for 16 bit wide Intel or AMD flash or two interleaved
|
||||
8 bit flashes */
|
||||
|
||||
int bdmflash_check_id_x16(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2])
|
||||
{
|
||||
int ret=0;
|
||||
u_int16_t devid, manid;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR16(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read manufacturer ID */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
manid=FLASH_RD16(a+0);
|
||||
if(manid!=alg->manid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR16(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read device ID */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
devid=FLASH_RD16(a+2);
|
||||
if(devid!=alg->devid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
if(retid)
|
||||
{retid[0]=manid;retid[1]=devid;};
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
int bdmflash_prog_x16(const flash_alg_info_t *alg, void *addr, const void *data, long count)
|
||||
{
|
||||
int ret;
|
||||
u_int16_t old,new,fault,val;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
ret=bdmflash_prepval_x16(&val,addr,data,count);
|
||||
if(ret<=0)
|
||||
return ret;
|
||||
addr=(void*)((long)addr&~1l);
|
||||
/* check if FLASH needs programming */
|
||||
if(1){
|
||||
old=FLASH_RD16(addr);
|
||||
if(old==val) return ret;
|
||||
}
|
||||
/* security sequence */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR16(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* program command */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_prog);
|
||||
FLASH_WR16(addr,val);
|
||||
/* wait for result */
|
||||
old=FLASH_RD16(addr);
|
||||
while((new=FLASH_RD16(addr))!=old){
|
||||
if((fault=old&new&alg->fault_bit)){
|
||||
old=new;
|
||||
/* check for some false fault at finish or race of x8x2 */
|
||||
if(!(old^=(new=FLASH_RD16(addr)))) break; /* finished now */
|
||||
else{
|
||||
/* one chip of x8x2 configuration can finish earlier */
|
||||
if(!(old&0x00ff)||(fault&0x00ff))
|
||||
if(!(old&0xff00)||(fault&0xff00))
|
||||
{ret=-2;break;}
|
||||
}
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
if((FLASH_RD16(addr)!=val) && (ret>=0)) ret=-3;
|
||||
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
int bdmflash_erase_x16(const flash_alg_info_t *alg, void *addr, long size)
|
||||
{
|
||||
u_int16_t old,new,fault;
|
||||
int ret=0;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR16(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* erase command */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_erase);
|
||||
/* security sequence */
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR16(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* select erase range */
|
||||
a=addr;
|
||||
if(size==0)
|
||||
FLASH_WR16(a+alg->reg1_addr,alg->erase_all);
|
||||
else{
|
||||
FLASH_WR16(addr,alg->erase_sec);
|
||||
}
|
||||
/* wait for result */
|
||||
old=FLASH_RD16(addr);
|
||||
while((new=FLASH_RD16(addr))!=old){
|
||||
if((fault=old&new&alg->fault_bit)){
|
||||
old=new;
|
||||
/* check for some false fault at finish or race of x8x2 */
|
||||
if(!(old^=(new=FLASH_RD16(addr)))) break; /* finished now */
|
||||
else{
|
||||
/* one chip of x8x2 configuration can finish earlier */
|
||||
if(!(old&0x00ff)||(fault&0x00ff))
|
||||
if(!(old&0xff00)||(fault&0xff00))
|
||||
{ret=-2;break;}
|
||||
}
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR16(a,alg->cmd_reset);
|
||||
if(FLASH_RD16(addr)!=0xffff) ret--;
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* routines for single 8 bit wide Intel or AMD flash */
|
||||
|
||||
int bdmflash_check_id_x8(const flash_alg_info_t *alg, void *addr,
|
||||
flash_d_t retid[2])
|
||||
{
|
||||
int ret=0;
|
||||
u_int16_t devid, manid;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR8(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read manufacturer ID */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
manid=FLASH_RD8(a+0);
|
||||
if(manid!=alg->manid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR8(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read device ID */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
devid=FLASH_RD8(a+1);
|
||||
if(devid!=alg->devid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
if(retid)
|
||||
{retid[0]=manid;retid[1]=devid;};
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
int bdmflash_prog_x8(const flash_alg_info_t *alg, void *addr, const void *data, long count)
|
||||
{
|
||||
int ret=1;
|
||||
u_int8_t old,new,val;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
val=*(u_int8_t*)data;
|
||||
/* check if FLASH needs programming */
|
||||
if(1){
|
||||
old=FLASH_RD8(addr);
|
||||
if(old==val) return ret;
|
||||
}
|
||||
/* security sequence */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR8(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* program command */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_prog);
|
||||
FLASH_WR8(addr,val);
|
||||
/* wait for result */
|
||||
old=FLASH_RD8(addr);
|
||||
while((new=FLASH_RD8(addr))!=old){
|
||||
if((old&alg->fault_bit)&&(new&alg->fault_bit)){
|
||||
if((FLASH_RD8(addr))!=new) ret=-2;
|
||||
break;
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
if((FLASH_RD8(addr)!=val) && (ret>=0)) ret=-3;
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
int bdmflash_erase_x8(const flash_alg_info_t *alg, void *addr, long size)
|
||||
{
|
||||
u_int8_t old,new;
|
||||
int ret=0;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR8(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* erase command */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_erase);
|
||||
/* security sequence */
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR8(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* select erase range */
|
||||
a=addr;
|
||||
if(size==0)
|
||||
FLASH_WR8(a+alg->reg1_addr,alg->erase_all);
|
||||
else{
|
||||
FLASH_WR8(addr,alg->erase_sec);
|
||||
}
|
||||
old=FLASH_RD8(addr);
|
||||
while((new=FLASH_RD8(addr))!=old){
|
||||
if((old&alg->fault_bit)&&(new&alg->fault_bit)){
|
||||
if((FLASH_RD8(addr))!=new) ret=-2;
|
||||
break;
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR8(a,alg->cmd_reset);
|
||||
if(FLASH_RD16(addr)!=0xffff) ret--;
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* routines for two/four interleaved 16/8 bit wide Intel or AMD flashes */
|
||||
|
||||
#ifdef WITH_TARGET_BUS32
|
||||
|
||||
int bdmflash_check_id_x32(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2])
|
||||
{
|
||||
int ret=0;
|
||||
u_int32_t devid, manid;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR32(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read manufacturer ID */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
/* bank slecets swapped as i suspect (360DK only) !!!!!! */
|
||||
/*manid=FLASH_RD32(a+0xc); */
|
||||
manid=FLASH_RD32(a+0);
|
||||
if(manid!=alg->manid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR32(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* read device ID */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_rdid);
|
||||
devid=FLASH_RD32(a+4);
|
||||
if(devid!=alg->devid) ret=-1;
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
if(retid)
|
||||
{retid[0]=manid;retid[1]=devid;};
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
int bdmflash_prog_x32(const flash_alg_info_t *alg, void *addr, const void *data, long count)
|
||||
{
|
||||
int ret=4;
|
||||
u_int32_t old,new,fault,val;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
ret=bdmflash_prepval_x32(&val,addr,data,count);
|
||||
if(ret<=0)
|
||||
return ret;
|
||||
addr=(void*)((long)addr&~3l);
|
||||
/* check if FLASH needs programming */
|
||||
if(1){
|
||||
old=FLASH_RD32(addr);
|
||||
if(old==val) return ret;
|
||||
}
|
||||
/* security sequence */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR32(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* program command */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_prog);
|
||||
FLASH_WR32(addr,val);
|
||||
/* wait for result */
|
||||
old=FLASH_RD32(addr);
|
||||
while((new=FLASH_RD32(addr))!=old){
|
||||
if((fault=old&new&alg->fault_bit)){
|
||||
old=new;
|
||||
/* check for some false fault at finish or race of x8x2 */
|
||||
if(!(old^=(new=FLASH_RD32(addr)))) break; /* finished now */
|
||||
else{
|
||||
/* one chip of x16x2 or x8x4 configuration can finish earlier */
|
||||
if(!(old&0x000000ff)||(fault&0x000000ff))
|
||||
if(!(old&0x0000ff00)||(fault&0x0000ff00))
|
||||
if(!(old&0x00ff0000)||(fault&0x00ff0000))
|
||||
if(!(old&0xff000000)||(fault&0xff000000))
|
||||
{ret=-2;break;}
|
||||
}
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
if((FLASH_RD32(addr)!=val) && (ret>=0)) ret=-3;
|
||||
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
int bdmflash_erase_x32(const flash_alg_info_t *alg, void *addr, long size)
|
||||
{
|
||||
u_int32_t old,new,fault;
|
||||
int ret=0;
|
||||
caddr_t a=(caddr_t)((u_int32_t)addr&~alg->addr_mask);
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
/* security sequence */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR32(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* erase command */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_erase);
|
||||
/* security sequence */
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->cmd_unlock1);
|
||||
if(alg->cmd_unlock2)
|
||||
FLASH_WR32(a+alg->reg2_addr,alg->cmd_unlock2);
|
||||
/* select erase range */
|
||||
a=addr;
|
||||
if(size==0)
|
||||
FLASH_WR32(a+alg->reg1_addr,alg->erase_all);
|
||||
else{
|
||||
FLASH_WR32(addr,alg->erase_sec);
|
||||
}
|
||||
/* wait for result */
|
||||
old=FLASH_RD32(addr);
|
||||
while((new=FLASH_RD32(addr))!=old){
|
||||
if((fault=old&new&alg->fault_bit)){
|
||||
old=new;
|
||||
/* check for some false fault at finish or race of x16x2 or x8x4 */
|
||||
if(!(old^=(new=FLASH_RD32(addr)))) break; /* finished now */
|
||||
else{
|
||||
/* one chip of x16x2 or x8x4 configuration can finish earlier */
|
||||
if(!(old&0x000000ff)||(fault&0x000000ff))
|
||||
if(!(old&0x0000ff00)||(fault&0x0000ff00))
|
||||
if(!(old&0x00ff0000)||(fault&0x00ff0000))
|
||||
if(!(old&0xff000000)||(fault&0xff000000))
|
||||
{ret=-2;break;}
|
||||
}
|
||||
}
|
||||
old=new;
|
||||
}
|
||||
/* reset */
|
||||
FLASH_WR32(a,alg->cmd_reset);
|
||||
if(FLASH_RD32(addr)!=0xffffffff) ret--;
|
||||
return ret;
|
||||
|
||||
mem_op_error:
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_TARGET_BUS32 */
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
/* flash type independent check_id */
|
||||
int bdmflash_check_id(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2])
|
||||
{
|
||||
if(alg->check_id)
|
||||
return alg->check_id(alg, addr, retid);
|
||||
else
|
||||
return -10; /* we really need to define error constants in future */
|
||||
}
|
||||
|
||||
/* flash type independent program one location */
|
||||
int bdmflash_prog(const flash_alg_info_t *alg, void *addr, const void *data, long count)
|
||||
{
|
||||
if(alg->prog)
|
||||
return alg->prog(alg,addr,data,count);
|
||||
else
|
||||
return -10;
|
||||
}
|
||||
|
||||
/* flash type independent erase region */
|
||||
int bdmflash_erase(const flash_alg_info_t *alg, void *addr, long size)
|
||||
{
|
||||
if(alg->erase)
|
||||
return alg->erase(alg,addr,size);
|
||||
else
|
||||
return -10;
|
||||
}
|
||||
|
||||
const flash_alg_info_t *
|
||||
bdmflash_alg_from_id(flash_d_t id[2])
|
||||
{
|
||||
int i;
|
||||
const flash_alg_info_t *alg;
|
||||
for(i=0;(alg=flash_alg_infos_def[i])!=NULL;i++)
|
||||
if((alg->manid==id[0])&&(alg->devid==id[0]))
|
||||
return alg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const flash_alg_info_t *
|
||||
bdmflash_alg_probe(caddr_t flash_adr)
|
||||
{
|
||||
int i;
|
||||
const flash_alg_info_t *alg,*alg1;
|
||||
flash_d_t testid[2];
|
||||
for(i=0;(alg=flash_alg_infos_def[i])!=NULL;i++){
|
||||
if(bdmflash_check_id(alg,flash_adr,testid)>=0)
|
||||
return alg;
|
||||
alg1=bdmflash_alg_from_id(testid);
|
||||
if(alg1!=NULL)
|
||||
if(bdmflash_check_id(alg1,flash_adr,testid)>=0)
|
||||
return alg1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
bdmflash_wrb_filt(bdmlib_bfilt_t * filt, caddr_t in_adr,
|
||||
u_int size, u_char * bl_ptr)
|
||||
{
|
||||
int offs=0,res;
|
||||
flash_d_t val;
|
||||
const flash_alg_info_t *alg=(flash_alg_info_t*)filt->info;
|
||||
|
||||
#if 0
|
||||
if(alg->width!=FLASH_ALG_BITS_x8) {
|
||||
/* 16 bit wide flash write path */
|
||||
if((u_long)in_adr&1) {
|
||||
in_adr-=1;
|
||||
val=(FLASH_RD16(in_adr)&0xff00)|bl_ptr[offs];
|
||||
if((res=bdmflash_prog(alg, in_adr, val))<0) {
|
||||
fprintf(stderr, "flash byte write error %d at 0x%lx\n",
|
||||
res,(u_long)in_adr);
|
||||
return offs;
|
||||
}
|
||||
in_adr+=2;
|
||||
size-=1;
|
||||
offs+=1;
|
||||
}
|
||||
while(size>=2) {
|
||||
val=(bl_ptr[offs]<<8)|bl_ptr[offs+1];
|
||||
if((res=bdmflash_prog(alg, in_adr, val))<0) {
|
||||
fprintf(stderr, "flash write error %d at 0x%lx\n",
|
||||
res,(u_long)in_adr);
|
||||
return offs;
|
||||
}
|
||||
in_adr+=2;
|
||||
size-=2;
|
||||
offs+=2;
|
||||
}
|
||||
if(size) {
|
||||
val=(FLASH_RD16(in_adr)&0x00ff)|(bl_ptr[offs]<<8);
|
||||
if((res=bdmflash_prog(alg, in_adr, val))<0) {
|
||||
fprintf(stderr, "flash byte write error %d at 0x%lx\n",
|
||||
res,(u_long)in_adr);
|
||||
return offs;
|
||||
}
|
||||
size-=1;
|
||||
offs+=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while(size>=1) {
|
||||
val=bl_ptr[offs];
|
||||
if((res=bdmflash_prog(alg, in_adr, bl_ptr+offs, size))<=0) {
|
||||
fprintf(stderr, "flash write error %d at 0x%lx\n",
|
||||
res,(u_long)in_adr);
|
||||
return offs;
|
||||
}
|
||||
in_adr+=res;
|
||||
size-=res;
|
||||
offs+=res;
|
||||
}
|
||||
return offs;
|
||||
|
||||
#if 0
|
||||
mem_op_error:
|
||||
fprintf(stderr, "bdm memory access error\n");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
bdmflash_erase_filt(bdmlib_bfilt_t * filt, caddr_t in_adr,
|
||||
u_int size)
|
||||
{
|
||||
int res=0;
|
||||
const flash_alg_info_t *alg=(flash_alg_info_t*)filt->info;
|
||||
if(!in_adr) in_adr=filt->begin_adr;
|
||||
|
||||
res=bdmflash_erase(alg, in_adr,size);
|
||||
if(res<0)
|
||||
fprintf(stderr, "flash erase error %d\n",res);
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* slow version of blank check */
|
||||
int
|
||||
bdmflash_blankck_filt(bdmlib_bfilt_t * filt, caddr_t in_adr,
|
||||
u_int size)
|
||||
{
|
||||
int errors=0;
|
||||
if(!in_adr||!size){
|
||||
in_adr=filt->begin_adr;
|
||||
size=filt->end_adr-in_adr+1;
|
||||
}
|
||||
if(((long)in_adr&1)&&size){
|
||||
if(FLASH_RD8(in_adr)!=0xff){
|
||||
fprintf(stderr,"blank check error at 0x%06lX",(long)in_adr);
|
||||
errors++;
|
||||
}
|
||||
in_adr++; size--;
|
||||
}
|
||||
while(size>=2){
|
||||
if(FLASH_RD16(in_adr)!=0xffff){
|
||||
if(errors<5){
|
||||
if(errors) fprintf(stderr,",0x%06lX",(long)in_adr);
|
||||
else fprintf(stderr,"blank check error at 0x%06lX",(long)in_adr);
|
||||
}else if(errors==5) fprintf(stderr, " and more");
|
||||
errors++;
|
||||
}
|
||||
if(!((long)in_adr&0xfff)) bdmlib_propeller(stdout);
|
||||
in_adr+=2; size-=2;
|
||||
}
|
||||
if(size){
|
||||
if(FLASH_RD8(in_adr)!=0xff){
|
||||
if(errors) fprintf(stderr,",0x%06lX",(long)in_adr);
|
||||
else fprintf(stderr,"blank check error at 0x%06lX",(long)in_adr);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if(errors) fprintf(stderr,"\n");
|
||||
|
||||
return errors;
|
||||
|
||||
mem_op_error:
|
||||
fprintf(stderr, "bdm memory access error\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* hopefully faster version of blank check */
|
||||
int
|
||||
bdmflash_blankck_filt(bdmlib_bfilt_t * filt, caddr_t in_adr,
|
||||
u_int size)
|
||||
{
|
||||
int errors=0, in_buf;
|
||||
u_char buf[1024], *p;
|
||||
if(!in_adr||!size){
|
||||
in_adr=filt->begin_adr;
|
||||
size=filt->end_adr-in_adr+1;
|
||||
}
|
||||
|
||||
while(size){
|
||||
if(size<sizeof(buf)) in_buf=size;
|
||||
else in_buf=sizeof(buf);
|
||||
|
||||
if(bdmlib_read_block(in_adr,in_buf,buf)!=in_buf)
|
||||
goto mem_op_error;
|
||||
|
||||
size-=in_buf;
|
||||
for(p=buf;in_buf--;in_adr++,p++){
|
||||
if(*p!=0xff){
|
||||
if(errors<10){
|
||||
if(errors) fprintf(stderr,",0x%06lX",(long)in_adr);
|
||||
else fprintf(stderr,"blank check error at 0x%06lX",(long)in_adr);
|
||||
}else if(errors==10) fprintf(stderr, " and more");
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
bdmlib_propeller((u_long)in_adr, stdout);
|
||||
}
|
||||
|
||||
if(errors) fprintf(stderr,"\n");
|
||||
|
||||
return errors;
|
||||
|
||||
mem_op_error:
|
||||
fprintf(stderr, "\nbdm memory access error\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
#endif
|
||||
74
m683xx/bdm-load/bdmflash.h
Normal file
74
m683xx/bdm-load/bdmflash.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef BDMFLASH_H
|
||||
#define BDMFLASH_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define FLASH_ALG_BITS_x8 0
|
||||
#define FLASH_ALG_BITS_x16 2
|
||||
#define FLASH_ALG_BITS_x8x2 3
|
||||
#define FLASH_ALG_BITS_x32 4
|
||||
#define FLASH_ALG_BITS_x16x2 5
|
||||
#define FLASH_ALG_BITS_x8x4 7
|
||||
|
||||
#define WITH_TARGET_BUS32
|
||||
|
||||
#ifndef WITH_TARGET_BUS32
|
||||
typedef u_int16_t flash_d_t; /* Type able to store one flash location */
|
||||
#else /* WITH_TARGET_BUS32 */
|
||||
typedef u_int32_t flash_d_t; /* Type able to store one flash location */
|
||||
#endif /* WITH_TARGET_BUS32 */
|
||||
|
||||
/* Structure describing programming operations for flash type */
|
||||
typedef struct flash_alg_info {
|
||||
/* Sets retid to manufacturer and type ID, returns <0 in case of error */
|
||||
int (*check_id)(const struct flash_alg_info *alg, void *addr, flash_d_t retid[2]);
|
||||
/* Programs one location of flash and returns number of programmed bytes */
|
||||
int (*prog)(const struct flash_alg_info *alg, void *addr, const void *data, long count);
|
||||
/* Erase all sectors overlaped by region from addr of size bytes, size=0 => erase all */
|
||||
/* This version is capable only of full erase (size=0) and one sector (size=1) */
|
||||
int (*erase)(const struct flash_alg_info *alg, void *addr, long size);
|
||||
/* Numeric and string fields follows */
|
||||
u_int32_t addr_mask; /* Mask to take offset inside flash */
|
||||
u_int32_t reg1_addr; /* Flash control register 1 */
|
||||
u_int32_t reg2_addr; /* Flash control register 2 */
|
||||
u_int32_t sec_size; /* block size of bigger blocks */
|
||||
flash_d_t width; /* FLASH_ALG_BITS_x8 .. 8 bit data bus,
|
||||
FLASH_ALG_BITS_x16 .. 16 bit data,
|
||||
FLASH_ALG_BITS_x8x2 .. two interleaved 8 bit */
|
||||
flash_d_t cmd_unlock1;/* first byte of command sequence */
|
||||
flash_d_t cmd_unlock2;/* second byte of command sequence */
|
||||
flash_d_t cmd_rdid; /* read identifier */
|
||||
flash_d_t cmd_prog; /* program one loc */
|
||||
flash_d_t cmd_erase; /* erase command */
|
||||
flash_d_t cmd_reset; /* leave program mode */
|
||||
flash_d_t erase_all; /* erase all */
|
||||
flash_d_t erase_sec; /* erase sector */
|
||||
flash_d_t fault_bit; /* programing of location failed */
|
||||
flash_d_t manid; /* manufacturer ID */
|
||||
flash_d_t devid; /* device ID */
|
||||
char *alg_name; /* informative flash type name */
|
||||
} flash_alg_info_t;
|
||||
|
||||
int bdmflash_check_id(const flash_alg_info_t *alg, void *addr,
|
||||
flash_d_t retid[2]);
|
||||
|
||||
int bdmflash_prog(const flash_alg_info_t *alg, void *addr, const void *data, long count);
|
||||
|
||||
int bdmflash_erase(const flash_alg_info_t *alg, void *addr, long size);
|
||||
|
||||
flash_alg_info_t **flash_alg_infos;
|
||||
|
||||
const flash_alg_info_t *bdmflash_alg_from_id(flash_d_t id[2]);
|
||||
|
||||
const flash_alg_info_t *bdmflash_alg_probe(caddr_t flash_adr);
|
||||
|
||||
int bdmflash_wrb_filt(bdmlib_bfilt_t * filt, caddr_t in_adr,
|
||||
u_int size, u_char * bl_ptr);
|
||||
|
||||
int bdmflash_erase_filt(bdmlib_bfilt_t * filt, caddr_t in_adr, u_int size);
|
||||
|
||||
int bdmflash_blankck_filt(bdmlib_bfilt_t * filt, caddr_t in_adr, u_int size);
|
||||
|
||||
int bdmflash_check_id(const flash_alg_info_t *alg, void *addr, flash_d_t retid[2]);
|
||||
|
||||
#endif /* BDMFLASH_H */
|
||||
1701
m683xx/bdm-load/bdmlib.c
Normal file
1701
m683xx/bdm-load/bdmlib.c
Normal file
File diff suppressed because it is too large
Load Diff
83
m683xx/bdm-load/bdmlib.h
Normal file
83
m683xx/bdm-load/bdmlib.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* $Id: bdmlib.h,v 1.2 2003/08/15 12:06:47 ppisa Exp $
|
||||
*/
|
||||
|
||||
#ifndef BDMLIB_H
|
||||
#define BDMLIB_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef u_short bdmstatus;
|
||||
|
||||
extern int bdmlib_open(char *device);
|
||||
extern int bdmlib_close(int);
|
||||
extern int bdmlib_isopen(void);
|
||||
extern int bdmlib_ioctl(u_int code);
|
||||
extern int bdmlib_setioctl(u_int code, u_int val);
|
||||
extern bdmstatus bdmlib_getstatus(void);
|
||||
extern int bdmlib_write_var(caddr_t adr, u_short size, u_int val);
|
||||
extern int bdmlib_read_var(caddr_t adr, u_short size, void *val);
|
||||
extern int bdmlib_write_block(caddr_t adr, u_int size, u_char *block);
|
||||
extern int bdmlib_read_block(caddr_t adr, u_int size, u_char *block);
|
||||
extern int bdmlib_load(char *file, char *entry_name, u_long *entry_pt);
|
||||
extern int bdmlib_do_load_binary(char *file_name, char *entry_name,
|
||||
u_long *entry_pt);
|
||||
extern int bdmlib_do_load_macro(char *file_name, int is_begin_macro);
|
||||
extern int bdmlib_get_sys_reg(u_int, u_int *);
|
||||
extern int bdmlib_set_sys_reg(u_int, u_int);
|
||||
extern int bdmlib_get_reg(u_int, u_int *);
|
||||
extern int bdmlib_set_reg(u_int, u_int);
|
||||
extern int bdmlib_go(void);
|
||||
extern char *bdmlib_geterror_str(int);
|
||||
extern char *bdmlib_getstatus_str(bdmstatus);
|
||||
extern int bdmlib_set_mbar(u_long mbar_val);
|
||||
extern int bdmlib_reset(void);
|
||||
extern void bdmlib_setdebug(int switch_on);
|
||||
extern int bdmlib_querydebug(void);
|
||||
extern void bdmlib_showpc(void);
|
||||
extern void bdmlib_log(const char *format, ...);
|
||||
extern void bdmlib_propeller(u_long addr, FILE * fp);
|
||||
extern int bdmlib_do_load_binary_section(char *file_name, char *sect_name);
|
||||
|
||||
/* some additional error codes beyond those of the driver */
|
||||
|
||||
#define BDM_ERR_NOT_OPEN -650
|
||||
#define BDM_ERR_ILL_IOCTL -651
|
||||
#define BDM_ERR_WRITE_FAIL -652
|
||||
#define BDM_ERR_READ_FAIL -653
|
||||
#define BDM_ERR_ILL_SIZE -654
|
||||
#define BDM_ERR_OPEN -655
|
||||
#define BDM_ERR_LOAD -656
|
||||
#define BDM_ERR_MACROFILE -657
|
||||
#define BDM_ERR_SECTION -658
|
||||
#define BDM_ERR_VERSION -659
|
||||
#define BDM_NO_ERROR 0
|
||||
|
||||
/* support of filtered write for flash programming */
|
||||
|
||||
typedef struct bdmlib_bfilt{
|
||||
struct bdmlib_bfilt *next;
|
||||
caddr_t begin_adr;
|
||||
caddr_t end_adr;
|
||||
int filt_id;
|
||||
u_int flags;
|
||||
int (*wrb_filt)(struct bdmlib_bfilt *, caddr_t , u_int, u_char * );
|
||||
void *info;
|
||||
void *state;
|
||||
}bdmlib_bfilt_t;
|
||||
|
||||
#define BDMLIB_FILT_ERROR 0x08
|
||||
#define BDMLIB_FILT_ERASED 0x10
|
||||
#define BDMLIB_FILT_AUTO 0x20
|
||||
#define BDMLIB_FILT_FLASH 0x40
|
||||
|
||||
int bdmlib_load_use_lma; /* use LMA instead of VMA for load */
|
||||
bdmlib_bfilt_t * bdmlib_bfilt;
|
||||
|
||||
int
|
||||
bdmlib_wrb_filt(bdmlib_bfilt_t * bdmlib_bfilt, caddr_t in_adr,
|
||||
u_int size, u_char * bl_ptr);
|
||||
|
||||
#endif /* BDMLIB_H */
|
||||
65
m683xx/bdm-load/cpu32init
Normal file
65
m683xx/bdm-load/cpu32init
Normal file
@@ -0,0 +1,65 @@
|
||||
# initialization macro-file for MO_CPU1
|
||||
|
||||
# 0xFFFA00 - SIMCR - SIM Configuration Register
|
||||
w 0xfffa00 0x40cf 2
|
||||
|
||||
# 0xFFFA21 - SYPCR - System Protection Control Register
|
||||
w 0xfffa21 0x06 1
|
||||
|
||||
# 0xFFFA04 - SYNCR Clock Synthesizer Control Register
|
||||
w 0xfffa04 0xd408 2
|
||||
|
||||
# 0xFFFA17 - PEPAR - Port E Pin Assignment Register
|
||||
w 0xfffa17 0xf4 1
|
||||
|
||||
# 0xFFFA1F - PFPAR - Port F Pin Assignment Register
|
||||
w 0xfffa1f 0 1
|
||||
|
||||
# setup STANBY RAM at 0xFFD000
|
||||
w 0xFFFB40 0x8000 2
|
||||
w 0xFFFB44 0xFFD000 4
|
||||
w 0xFFFB40 0x0000 2
|
||||
|
||||
# setup TPU RAM at 0xFFE000
|
||||
w 0xFFFB00 0x8000 2
|
||||
w 0xFFFB04 0xFFE0 2
|
||||
w 0xFFFB00 0x0000 2
|
||||
|
||||
# 0xYFFA44 - CSPAR0 - Chip Select Pin Assignment Register 0
|
||||
w 0xfffa44 0x3bff 2
|
||||
|
||||
# 0xFFFA46 - CSPAR1 - Chip Select Pin Assignment Register 1
|
||||
w 0xfffa46 0x03a9 2
|
||||
|
||||
# BOOT ROM 0x800000 1MB RW UL - Boot FLASH
|
||||
w 0xfffa48 0x8007 2
|
||||
w 0xfffa4A 0x7830 2
|
||||
|
||||
# CS0 ROM 0x900000 1MB RW UL - 2nd FLASH
|
||||
w 0xfffa4c 0x9007 2
|
||||
w 0xfffa4e 0x7830 2
|
||||
|
||||
# CS2 RAM 0x000000 1MB RW UL - Main RAM first 1MB
|
||||
w 0xfffa54 0x0007 2
|
||||
w 0xfffa56 0x7830 2
|
||||
|
||||
# CS3 RAM 0x100000 1MB RW UL - Main RAM second 1MB
|
||||
w 0xfffa58 0x1007 2
|
||||
w 0xfffa5a 0x7830 2
|
||||
|
||||
# CS4 PER 0xf00000 512kB RW UL - CMOS RAM, RTC, other devices
|
||||
w 0xfffa5c 0xf006 2
|
||||
w 0xfffa5e 0x7cb0 2
|
||||
|
||||
# CS7 PER 0xf87000 2k RW UL - MO_PWR
|
||||
w 0xfffa68 0xf870 2
|
||||
w 0xfffa6a 0x7c70 2
|
||||
|
||||
# CS8 PER 0xf88000 2k RO UL - IRC
|
||||
w 0xfffa6c 0xf880 2
|
||||
w 0xfffa6e 0x7c70 2
|
||||
|
||||
# CS9 PER 0xf89000 2k WR UL - KBD
|
||||
w 0xfffa70 0xf890 2
|
||||
w 0xfffa72 0x7cf0 2
|
||||
|
||||
830
m683xx/bdm-load/tpudb.c
Normal file
830
m683xx/bdm-load/tpudb.c
Normal file
@@ -0,0 +1,830 @@
|
||||
/*******************************************************************
|
||||
TPUDB Project to Create Free Motorola 683xx TPU Debugger
|
||||
|
||||
tpudb.c - first test
|
||||
|
||||
(C) Copyright 2000 by Pavel Pisa - Original Author
|
||||
e-mail: pisa@cmp.felk.cvut.cz
|
||||
homepage: http://cmp.felk.cvut.cz/~pisa
|
||||
work: http://www.pikron.com/
|
||||
|
||||
This package can be copied and modified under
|
||||
GNU General Public License with all its conditions.
|
||||
See file GPL for details. Under this license nobody can
|
||||
distribute this work and any derived work without full source code
|
||||
for all modules compiled and linked into executable.
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <bfd.h>
|
||||
#include "bdm.h"
|
||||
#include "bdmlib.h"
|
||||
|
||||
#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
|
||||
#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
|
||||
|
||||
#define val2mfld __val2mfld
|
||||
#define mfld2val __mfld2val
|
||||
|
||||
#if 0
|
||||
#define TPU_WR16(adr,val) (*(volatile u_int16_t*)(adr)=(val))
|
||||
#define TPU_RD16(adr) (*(volatile u_int16_t*)(adr))
|
||||
#else
|
||||
#define TPU_WR16(adr,val) \
|
||||
({ \
|
||||
if(bdmlib_write_var(adr,BDM_SIZE_WORD,val)<0) \
|
||||
goto mem_op_error; \
|
||||
val; \
|
||||
})
|
||||
#define TPU_RD16(adr) \
|
||||
({ u_int16_t temp_val; \
|
||||
if(bdmlib_read_var(adr,BDM_SIZE_WORD,&temp_val)<0) \
|
||||
goto mem_op_error; \
|
||||
temp_val; \
|
||||
})
|
||||
#endif
|
||||
|
||||
char hashmark=0; /* flag set by "set hash" */
|
||||
int bdm_autoreset=1; /* automatic reset before load */
|
||||
int bdm_ttcu=0; /* time to come up for init by rom */
|
||||
char initname[255]; /* need reimplement !!!!!!!!! */
|
||||
char bdm_dev_name[255]="/dev/bdm"; /* device name */
|
||||
|
||||
/* Numberring of TPU register */
|
||||
/* First part are aliases for main CPU accesible registers */
|
||||
#define TPUREG_TSTMSRA 0x0 /* Master Shift Register A */
|
||||
#define TPUREG_TSTMSRB 0x1 /* Master Shift Register B */
|
||||
#define TPUREG_TSTSC 0x2 /* Test Module Shift Count */
|
||||
#define TPU_TSTSCA 0xff00 /* Bits Shifted from TSTMSRA to Tested Module */
|
||||
#define TPU_TSTSCB 0x00ff /* Bits Shifted from Tested Module to TSTMSRB */
|
||||
#define TPUREG_TSTRC 0x3 /* Test Module Repetition Count */
|
||||
#define TPUREG_CREG 0x4 /* Test Submodule Control Register */
|
||||
#define TPU_TSTBUSY 0x8000 /* Test Submodule Busy Status Bit */
|
||||
#define TPU_TMARM 0x4000 /* Test Mode Armed Status Bit (latched /TSTME) */
|
||||
#define TPU_COMP 0x2000 /* Compare Status Bit */
|
||||
#define TPU_IMBTST 0x1000 /* Intermodule Bus Test (SCANA/SCANB) */
|
||||
#define TPU_CPUTR 0x0800 /* Scan to CPU Test Register */
|
||||
#define TPU_QBIT 0x0400 /* Quotient Bit at FREEZE/QUOT Pin */
|
||||
#define TPU_MUXEL 0x0200 /* Multiplexer Select Bit for MSRB from Int/Ext */
|
||||
#define TPU_ACUT 0x0010 /* Activate Circuit Under Test */
|
||||
#define TPU_SCONT 0x0008 /* Start Continuous Operation */
|
||||
#define TPU_SSHOP 0x0004 /* Start Shifting Operation */
|
||||
#define TPU_SATO 0x0002 /* Start Automatic Test Operation */
|
||||
#define TPU_EMT 0x0001 /* Enter test mode */
|
||||
#define TPUREG_DREG 0x5 /* Distributed Register */
|
||||
#define TPU_WAIT 0x0700 /* Wait Counter Preset 2-16 SCLK */
|
||||
#define TPU_MSRAHI 0x0e0 /* MSRA High Bits 18-16 */
|
||||
#define TPU_MSRAC 0x0010 /* Master Shift Register A Configuration */
|
||||
#define TPU_MSRBHI 0x00e /* MSRB High Bits 18-16 */
|
||||
#define TPU_MSRBC 0x0001 /* Master Shift Register B Configuration */
|
||||
#define TPUREG_MCR 0x6 /* TPU Module Configuration Register */
|
||||
#define TPU_STOP 0x8000 /* Low-Power Stop Mode Enable */
|
||||
#define TPU_TCR1P 0x6000 /* Timer Count Register 1 Prescaler Control */
|
||||
#define TPU_TCR2P 0x1800 /* Timer Count Register 2 Prescaler Control */
|
||||
#define TPU_EMU 0x0400 /* Emulation Control */
|
||||
#define TPU_T2CG 0x0200 /* TCR2 Clock/Gate Control */
|
||||
#define TPU_STF 0x0100 /* Stop Flag */
|
||||
#define TPU_SUPV 0x0080 /* Supervisor/Unrestricted */
|
||||
#define TPU_PSCK 0x0040 /* Prescaler Clock */
|
||||
#define TPU_IARB 0x000f /* Interrupt Arbitration ID */
|
||||
#define TPUREG_TCR 0x7 /* Test Configuration Register */
|
||||
#define TPU_INCAD 0x1000 /* Increment Address in uPC at ACUTL */
|
||||
#define TPU_TCR1C 0x0800 /* TCR1 Clock - TCR2 pin */
|
||||
#define TPU_ACUTR 0x0600 /* Activate Circuit Under Test Response 1, 0 */
|
||||
#define TPU_ACUTR_NONE 0 /* None */
|
||||
#define TPU_ACUTR_STEPTPU 1 /* Run ONE TPU microcycle */
|
||||
#define TPU_ACUTR_SHEOT 2 /* Scheduler End of Time Slot */
|
||||
#define TPU_SOSEL 0x0070 /* Scan-Out Select */
|
||||
#define TPU_SISEL 0x000e /* Scan-in Select */
|
||||
#define TPU_SxSEL_NONE 0 /* None */
|
||||
#define TPU_SxSEL_PC 1 /* uPC */
|
||||
#define TPU_SxSEL_IR 2 /* Microinstruction */
|
||||
#define TPU_SxSEL_BPLA 3 /* Branch PLA */
|
||||
#define TPU_SxSEL_PCBR 4 /* uPC Breakpoint */
|
||||
#define TPU_SxSEL_SPLA 5 /* Scheduler PLA */
|
||||
#define TPU_SxSEL_CHANBR 6 /* Channel Breakpoint */
|
||||
#define TPU_TMW 0x0001 /* Test Memory Map */
|
||||
#define TPUREG_DSCR 0x8 /* Development Support Control Register */
|
||||
#define TPU_HOT4 0x8000 /* Hang on T4 */
|
||||
#define TPU_BLC 0x0400 /* Branch Latch Control */
|
||||
#define TPU_CLKS 0x0200 /* Stop Clocks (to TCRs) */
|
||||
#define TPU_FRZ 0x0180 /* FREEZE Assertion Response */
|
||||
#define TPU_CCL 0x0040 /* Channel Conditions Latch */
|
||||
#define TPU_BMSK 0x003F /* Break cond mask */
|
||||
#define TPU_BP 0x0020 /* Break mPC == mPC breakpoint register */
|
||||
#define TPU_BC 0x0010 /* Break if CHAN start or set */
|
||||
#define TPU_BH 0x0008 /* Break if host service latch set */
|
||||
#define TPU_BL 0x0004 /* Break if link service latch set */
|
||||
#define TPU_BM 0x0002 /* Break if MRL set at beginning*/
|
||||
#define TPU_BT 0x0001 /* Break if TDL set at beginnibg */
|
||||
#define TPUREG_DSSR 0x9 /* Development Support Status Register */
|
||||
#define TPU_BKPT 0x0080 /* Breakpoint Asserted Flag */
|
||||
#define TPU_PCBK 0x0040 /* mPC Breakpoint Flag */
|
||||
#define TPU_CHBK 0x0020 /* Channel Register Breakpoint Flag */
|
||||
#define TPU_SRBK 0x0010 /* Service Request Breakpoint Flag */
|
||||
#define TPU_TPUF 0x0008 /* TPU FREEZE Flag */
|
||||
#define TPUREG_TICR 0xA /* TPU Interrupt Configuration Register */
|
||||
#define TPU_CIRL 0x0700 /* Channel Interrupt Request Level */
|
||||
#define TPU_CIBV 0x00f0 /* Bits [7:4] of Channel Interrupt Base Vector */
|
||||
#define TPUREG_CIER 0xB /* Channel Interrupt Enable Register */
|
||||
#define TPUREG_CFSR 0xC /* Channel Function Select Register 0 */
|
||||
#define TPUREG_HSQR 0xD /* Host Sequence Register 0 */
|
||||
#define TPUREG_HSRR 0xE /* Host Service Request Register 0 */
|
||||
#define TPUREG_CPR 0xF /* Channel Priority Register 0 */
|
||||
#define TPUREG_CISR 0x10 /* Channel Interrupt Status Register */
|
||||
#define TPUREG_LR 0x11 /* Link Register */
|
||||
#define TPUREG_SGLR 0x12 /* Service Grant Latch Register */
|
||||
#define TPUREG_DCNR 0x13 /* Decoded Channel Number Register */
|
||||
/* Registers not accesible from main CPU */
|
||||
#define TPUREG_P 0x14 /* Parameter Register (16-bit) */
|
||||
#define TPUREG_A 0x15 /* Accumulator (16-bit) */
|
||||
#define TPUREG_DIOB 0x16 /* Data I/O Buffer (16-bit) */
|
||||
#define TPUREG_SR 0x17 /* Shift Register (16-bit) */
|
||||
#define TPUREG_ERT 0x18 /* Event Temporary Register (16-b.) */
|
||||
#define TPUREG_CHAN 0x19 /* Channel Number (4-bit) */
|
||||
#define TPUREG_DEC 0x1A /* Decrementator Reg (4-bit) */
|
||||
#define TPUREG_TCR2 0x1B /* Timebase Register 2 (16-bit) */
|
||||
#define TPUREG_TCR1 0x1C /* Timebase Register 1 (16-bit) */
|
||||
#define TPUREG_PC 0x1D /* Microprogram Counter (9-bit) */
|
||||
#define TPUREG_IR 0x1E /* */
|
||||
#define TPUREG_BPLA 0x1F /* */
|
||||
#define TPUREG_SPLA 0x20 /* */
|
||||
#define TPUREG_PCBR 0x21 /* */
|
||||
#define TPUREG_CHANBR 0x22 /* */
|
||||
/* Aditional CPU Accessible Registers */
|
||||
#define TPUREG_DEBPAR 0x23 /* Parameter register at 0xFFFF00 for debugging */
|
||||
#define TRAMREG_CR 0x24 /* TPURAM Configuration Register */
|
||||
#define TRAM_STOP 0x8000 /* Low-Power Stop Mode Enable */
|
||||
#define TRAM_RASP 0x0080 /* TPURAM Array Space */
|
||||
#define TRAMREG_TST 0x25 /* TPURAM Test Register */
|
||||
#define TRAMREG_BAR 0x26 /* TPURAM Base Address and Status Register */
|
||||
#define TRAM_ADDR 0xfff0 /* TPURAM Array Base Address */
|
||||
#define TRAM_RAMDS 0x0001 /* RAM Array Disable */
|
||||
|
||||
#define TPUREG_MAX 0x26
|
||||
|
||||
/* Descriptor of TPU register access */
|
||||
typedef struct tpu_reg_des {
|
||||
int (*reg_rd)(struct tpu_reg_des *des, int indx);
|
||||
int (*reg_wr)(struct tpu_reg_des *des, int indx, int val);
|
||||
int adr;
|
||||
int adr1;
|
||||
int flags;
|
||||
int arr_len; /* array size, 0 .. no array */
|
||||
int bfld_bits; /* bitfield length, 0 .. no bitfields */
|
||||
int bfld_arr_len; /* bitfield array */
|
||||
}tpu_reg_des_t;
|
||||
|
||||
int tpu_mem_rd16(struct tpu_reg_des *des, int indx);
|
||||
int tpu_mem_wr16(struct tpu_reg_des *des, int indx, int val);
|
||||
int tpu_t1_rd(struct tpu_reg_des *des, int indx);
|
||||
int tpu_t1_wr(struct tpu_reg_des *des, int indx, int val);
|
||||
int tpu_t2_rd(struct tpu_reg_des *des, int indx);
|
||||
int tpu_t2_wr(struct tpu_reg_des *des, int indx, int val);
|
||||
int tpu_reg_rd(int reg, int indx);
|
||||
int tpu_reg_wr(int reg, int indx, int val);
|
||||
int tpu_reg_or(int reg, int indx, int val);
|
||||
int tpu_reg_and(int reg, int indx, int val);
|
||||
|
||||
#define TPUREG_FL_SH4 1 /* shift value by 4 bits */
|
||||
#define TPUREG_FL_PMOD 2 /* modification for reg P */
|
||||
#define TPUREG_FL_DIOB 4 /* modification for reg DIOB */
|
||||
|
||||
#define TPUREG_INDX_BFLD (0x1<<24) /* index for bitfields */
|
||||
|
||||
/* Descriptors of TPU register access */
|
||||
tpu_reg_des_t tpu_regs[]={
|
||||
/* CPU accessible */
|
||||
[TPUREG_TSTMSRA]= {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA30,},
|
||||
[TPUREG_TSTMSRB]= {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA32,},
|
||||
[TPUREG_TSTSC] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA34,},
|
||||
[TPUREG_TSTRC] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA36,},
|
||||
[TPUREG_CREG] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA38,},
|
||||
[TPUREG_DREG] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFA3A,},
|
||||
[TPUREG_MCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE00,},
|
||||
[TPUREG_TCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE02,},
|
||||
[TPUREG_DSCR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE04,},
|
||||
[TPUREG_DSSR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE06,},
|
||||
[TPUREG_TICR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE08,},
|
||||
[TPUREG_CIER] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE0A,
|
||||
arr_len:0,bfld_bits:1,bfld_arr_len:16,},
|
||||
[TPUREG_CFSR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE0C,
|
||||
arr_len:4,bfld_bits:4,bfld_arr_len:16,},
|
||||
[TPUREG_HSQR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE14,
|
||||
arr_len:2,bfld_bits:2,bfld_arr_len:16,},
|
||||
[TPUREG_HSRR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE18,
|
||||
arr_len:2,bfld_bits:2,bfld_arr_len:16,},
|
||||
[TPUREG_CPR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE1C,
|
||||
arr_len:2,bfld_bits:2,bfld_arr_len:16,},
|
||||
[TPUREG_CISR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE20,
|
||||
arr_len:0,bfld_bits:1,bfld_arr_len:16,},
|
||||
[TPUREG_LR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE22,},
|
||||
[TPUREG_SGLR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE24,},
|
||||
[TPUREG_DCNR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFE26,},
|
||||
/* Special TPU - group 1 */
|
||||
/* internal TPU registers, ounly access possible through forced TPU microengine instructions */
|
||||
/* adr .. instruction for reg read, adr1 .. instruction for reg write */
|
||||
[TPUREG_P] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3fff,adr1:0x36ff,
|
||||
flags:TPUREG_FL_PMOD,},
|
||||
[TPUREG_A] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x327f,adr1:0x361f},
|
||||
[TPUREG_DIOB] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0,adr1:0,
|
||||
flags:TPUREG_FL_DIOB,},
|
||||
[TPUREG_SR] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x347f,adr1:0x363f},
|
||||
[TPUREG_ERT] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3c7f,adr1:0x365f},
|
||||
[TPUREG_CHAN] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x267f,adr1:0x373f,
|
||||
flags:TPUREG_FL_SH4,},
|
||||
[TPUREG_DEC] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x247f,adr1:0x375f},
|
||||
[TPUREG_TCR2] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x387f,adr1:0x379f},
|
||||
[TPUREG_TCR1] = {reg_rd:tpu_t1_rd,reg_wr:tpu_t1_wr,adr:0x3a7f,adr1:0x37bf},
|
||||
/* Special TPU - group 2 */
|
||||
/* access through test subsystem serial scan lines */
|
||||
/* adr .. number of register bits, adr1 .. TPU scan line selection */
|
||||
[TPUREG_PC] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 9,adr1:TPU_SxSEL_PC},
|
||||
[TPUREG_IR] = {reg_rd:NULL,reg_wr:NULL,adr:0,adr1:0},
|
||||
[TPUREG_BPLA] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr:16,adr1:TPU_SxSEL_BPLA},
|
||||
[TPUREG_SPLA] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr:15,adr1:TPU_SxSEL_SPLA},
|
||||
[TPUREG_PCBR] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 9,adr1:TPU_SxSEL_PCBR},
|
||||
[TPUREG_CHANBR] = {reg_rd:tpu_t2_rd,reg_wr:tpu_t2_wr,adr: 4,adr1:TPU_SxSEL_CHANBR},
|
||||
/* One of parameter registers used for internal registers access */ /* was TPUREG_DEBUR */
|
||||
[TPUREG_DEBPAR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFF00,},
|
||||
[TRAMREG_CR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB00,},
|
||||
[TRAMREG_TST] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB02,},
|
||||
[TRAMREG_BAR] = {reg_rd:tpu_mem_rd16,reg_wr:tpu_mem_wr16,adr:0xFFFB04,},
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/* Helper function for test register access */
|
||||
|
||||
static int use_fetched_reg;
|
||||
static u_int16_t fetched_dscr;
|
||||
static u_int16_t fetched_creg;
|
||||
static u_int16_t fetched_tcr;
|
||||
|
||||
static u_int16_t stored_diob;
|
||||
static u_int16_t stored_pc;
|
||||
static u_int16_t stored_debpar2; /* was strored_debur2 */
|
||||
static u_int32_t stored_ir; /* was strored_x1 */
|
||||
/* was strored_x2 */
|
||||
|
||||
static
|
||||
void test_shift_wait(unsigned creg)
|
||||
{
|
||||
int cnt=0x8000;
|
||||
tpu_reg_wr(TPUREG_CREG,0,creg|TPU_SSHOP); /* 4 */
|
||||
do{
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
if(!(creg&TPU_TSTBUSY)) return; /* 0x8000 */
|
||||
}while(cnt--);
|
||||
fprintf(stderr,"test_shift_wait : stalled busy condition\n");
|
||||
}
|
||||
|
||||
/* Write 32 Bit Instruction Register */
|
||||
static /* was test_shift_1 */
|
||||
void test_shift_irwr(u_int32_t new_ir )
|
||||
{
|
||||
u_int16_t dscr; /* [bp-6] */
|
||||
u_int16_t creg; /* si */
|
||||
u_int16_t tcr; /* di */
|
||||
|
||||
if (!use_fetched_reg){
|
||||
tpu_reg_wr(TPUREG_TSTMSRB,0,0);
|
||||
tpu_reg_wr(TPUREG_TSTRC,0,0);
|
||||
tpu_reg_wr(TPUREG_DREG,0,0);
|
||||
dscr=tpu_reg_rd(TPUREG_DSCR,0);
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
tcr=tpu_reg_rd(TPUREG_TCR,0);
|
||||
}else{
|
||||
creg=fetched_creg;
|
||||
tcr=fetched_tcr;
|
||||
dscr=fetched_dscr;
|
||||
}
|
||||
|
||||
creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/
|
||||
tpu_reg_wr(TPUREG_CREG,0,creg);
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4);
|
||||
|
||||
tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,0x1000);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,new_ir&0xffff);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,0x1000);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,(new_ir>>16)&0xffff);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr);
|
||||
}
|
||||
|
||||
/* Read 32 Bit Instruction Register */
|
||||
static /* was test_shift_2 */
|
||||
u_int32_t test_shift_irrd(void)
|
||||
{
|
||||
u_int16_t dscr; /* [bp-0a] */
|
||||
u_int16_t creg; /* si */
|
||||
u_int16_t tcr; /* di */
|
||||
u_int16_t ir_lo,ir_hi;
|
||||
|
||||
if (!use_fetched_reg){
|
||||
tpu_reg_wr(TPUREG_TSTMSRB,0,0);
|
||||
tpu_reg_wr(TPUREG_TSTRC,0,0);
|
||||
tpu_reg_wr(TPUREG_DREG,0,0);
|
||||
dscr=tpu_reg_rd(TPUREG_DSCR,0);
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
tcr=tpu_reg_rd(TPUREG_TCR,0);
|
||||
}else{
|
||||
creg=fetched_creg;
|
||||
tcr=fetched_tcr;
|
||||
dscr=fetched_dscr;
|
||||
}
|
||||
|
||||
creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/
|
||||
tpu_reg_wr(TPUREG_CREG,0,creg);
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4);
|
||||
|
||||
tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SOSEL,TPU_SxSEL_IR)); /* 0x220 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,0x0010);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
ir_lo=tpu_reg_rd(TPUREG_TSTMSRB,0);
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SOSEL,TPU_SxSEL_IR) |
|
||||
val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x224 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,0x1010);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,ir_lo);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
ir_hi=tpu_reg_rd(TPUREG_TSTMSRB,0);
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SISEL,TPU_SxSEL_IR)); /* 0x204 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,0x1000);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,ir_hi);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr);
|
||||
|
||||
return ir_lo|((u_int32_t)ir_hi<<16);
|
||||
}
|
||||
|
||||
static /* was test_shift_3 */
|
||||
int test_shift_regrd(int shiftcnt ,int sxsel)
|
||||
{
|
||||
u_int16_t dscr; /* [bp-8] */
|
||||
u_int16_t creg; /* si */
|
||||
u_int16_t tcr; /* di */
|
||||
u_int16_t ret;
|
||||
|
||||
if (!use_fetched_reg){
|
||||
tpu_reg_wr(TPUREG_TSTMSRB,0,0);
|
||||
tpu_reg_wr(TPUREG_TSTRC,0,0);
|
||||
tpu_reg_wr(TPUREG_DREG,0,0);
|
||||
dscr=tpu_reg_rd(TPUREG_DSCR,0);
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
tcr=tpu_reg_rd(TPUREG_TCR,0);
|
||||
}else{
|
||||
creg=fetched_creg;
|
||||
tcr=fetched_tcr;
|
||||
dscr=fetched_dscr;
|
||||
}
|
||||
|
||||
creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/
|
||||
tpu_reg_wr(TPUREG_CREG,0,creg);
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4);
|
||||
|
||||
tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SOSEL,sxsel)); /* (sxsel<<4)|0x200 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
ret=tpu_reg_rd(TPUREG_TSTMSRB,0)>>(0x10-shiftcnt);
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SISEL,sxsel)); /* (sxsel<<1)|0x200 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt<<8);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,ret);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static /* was test_shift_4 */
|
||||
int test_shift_regwr(int shiftcnt, int sxsel, int val)
|
||||
{
|
||||
u_int16_t dscr; /* di */
|
||||
u_int16_t creg; /* si */
|
||||
u_int16_t tcr; /* [bp-6] */
|
||||
|
||||
if (!use_fetched_reg){
|
||||
tpu_reg_wr(TPUREG_TSTMSRB,0,0);
|
||||
tpu_reg_wr(TPUREG_TSTRC,0,0);
|
||||
tpu_reg_wr(TPUREG_DREG,0,0);
|
||||
dscr=tpu_reg_rd(TPUREG_DSCR,0);
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
tcr=tpu_reg_rd(TPUREG_TCR,0);
|
||||
}else{
|
||||
creg=fetched_creg;
|
||||
tcr=fetched_tcr;
|
||||
dscr=fetched_dscr;
|
||||
}
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr|TPU_HOT4);
|
||||
|
||||
creg=(creg|TPU_IMBTST)&~TPU_MUXEL; /*!!!!!!!!!!!*/
|
||||
tpu_reg_wr(TPUREG_CREG,0,creg);
|
||||
tcr&=TPU_INCAD | TPU_TCR1C | TPU_TMW; /* 0x1801 */
|
||||
tpu_reg_wr(TPUREG_TCR,0,tcr | val2mfld(TPU_ACUTR,TPU_ACUTR_STEPTPU) |
|
||||
val2mfld(TPU_SISEL,sxsel)); /* (sxsel<<1)|0x200 */
|
||||
tpu_reg_wr(TPUREG_TSTSC,0,shiftcnt<<8);
|
||||
tpu_reg_wr(TPUREG_TSTMSRA,0,val);
|
||||
|
||||
test_shift_wait(creg); /* test shift */
|
||||
|
||||
if(!(dscr&TPU_HOT4)) /* ???????? */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,dscr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static /* was test_pha_2 */
|
||||
void test_forced_inst(u_int32_t new_ir)
|
||||
{
|
||||
test_shift_irwr(new_ir);
|
||||
tpu_reg_or(TPUREG_CREG,0,TPU_ACUT);
|
||||
}
|
||||
|
||||
static /* was test_pha_1 */
|
||||
void test_store_ir(void)
|
||||
{
|
||||
stored_debpar2=tpu_reg_rd(TPUREG_DEBPAR,0);
|
||||
stored_pc=tpu_reg_rd(TPUREG_PC,0);
|
||||
stored_ir=test_shift_irrd();
|
||||
test_forced_inst(0x3ffffc03);
|
||||
stored_diob=tpu_reg_rd(TPUREG_DEBPAR,0);
|
||||
}
|
||||
|
||||
static /* was test_pha_3 */
|
||||
void test_restore_ir(void)
|
||||
{
|
||||
tpu_reg_wr(TPUREG_DEBPAR,0,stored_diob);
|
||||
test_forced_inst(0x1ffffc03);
|
||||
tpu_reg_wr(TPUREG_DEBPAR,0,stored_debpar2);
|
||||
tpu_reg_wr(TPUREG_PC,0,stored_pc);
|
||||
test_shift_irwr(stored_ir);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* Other supporting routines */
|
||||
|
||||
static u_int16_t test_dssrdscr_1; /* 0 => stop, 1 =>run */
|
||||
static u_int16_t test_dscr_arm;
|
||||
static u_int16_t test_dssr_bkpt;
|
||||
|
||||
int test_init_1(void)
|
||||
{
|
||||
u_int16_t creg; /* bp-2 */
|
||||
int cnt=0x1000;
|
||||
|
||||
tpu_reg_wr(TPUREG_CREG,0,TPU_MUXEL|TPU_EMT);
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
do{
|
||||
creg=tpu_reg_rd(TPUREG_CREG,0);
|
||||
}while(!(creg&TPU_EMT)&&(--cnt));
|
||||
tpu_reg_wr(TPUREG_CIER,0,0); /* disable interrupt generation */
|
||||
if(!cnt){
|
||||
fprintf(stderr,"test_init_1 : cannot enter test mode\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_init_2(void)
|
||||
{
|
||||
u_int16_t dssr; /* si */
|
||||
u_int16_t dscr; /* bx */
|
||||
dssr=tpu_reg_rd(TPUREG_DSSR,0);
|
||||
dscr=tpu_reg_rd(TPUREG_DSCR,0);
|
||||
if((dssr&TPU_BKPT)||(dscr&TPU_HOT4))
|
||||
test_dssrdscr_1=0;
|
||||
else
|
||||
test_dssrdscr_1=1;
|
||||
test_dscr_arm=dscr&TPU_BMSK;
|
||||
if (dssr&TPU_BKPT)
|
||||
test_dssr_bkpt=1;
|
||||
else
|
||||
test_dssr_bkpt=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tpu_halt(void)
|
||||
{
|
||||
int i;
|
||||
if(test_dssrdscr_1==0){
|
||||
/* already halted */
|
||||
/* return 0; */
|
||||
}
|
||||
tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST); /* stop microengine */
|
||||
tpu_reg_wr(TPUREG_DSCR,0,TPU_HOT4|TPU_CLKS|test_dscr_arm);
|
||||
test_dssrdscr_1=0;
|
||||
/* old_cpr = CPR0,CPR1 */
|
||||
/* CPR0,CPR1 = 0 */
|
||||
for(i=0;i<5;i++){
|
||||
if(tpu_reg_rd(TPUREG_DSSR,0)&TPU_BKPT)
|
||||
tpu_reg_and(TPUREG_DSSR,0,~TPU_BKPT);
|
||||
tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST|TPU_ACUT);
|
||||
}
|
||||
/* CPR0,CPR1 = old_cpr */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TPU_UCODE_LEN 0x200
|
||||
|
||||
u_int32_t tpu_ucode_img[TPU_UCODE_LEN];
|
||||
|
||||
int tpu_ucode_read(int print)
|
||||
{
|
||||
int adr;
|
||||
u_int32_t ir;
|
||||
adr=0;
|
||||
|
||||
test_store_ir();
|
||||
|
||||
if(print)printf("reading microcode\n");
|
||||
tpu_reg_wr(TPUREG_PC,0,adr);
|
||||
for(;adr<TPU_UCODE_LEN;adr++){
|
||||
test_shift_irwr(0xffffffff);
|
||||
tpu_reg_or(TPUREG_CREG,0,TPU_ACUT);
|
||||
ir=test_shift_irrd();
|
||||
tpu_ucode_img[adr]=ir;
|
||||
if(print)printf(" %03X: %08lX\n",adr,(unsigned long)ir);
|
||||
}
|
||||
|
||||
test_restore_ir();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* Register read and write routines */
|
||||
|
||||
/* read TPU register - method 1 */
|
||||
int tpu_t1_rd(struct tpu_reg_des *des, int indx)
|
||||
{
|
||||
unsigned val;
|
||||
test_store_ir();
|
||||
if(des->flags&TPUREG_FL_DIOB){
|
||||
val=stored_diob; /* DIOB read */
|
||||
}else{
|
||||
if(des->flags&TPUREG_FL_PMOD)
|
||||
test_forced_inst(0xf403|(des->adr<<16)); /* P read */
|
||||
else
|
||||
test_forced_inst(0xfc03|(des->adr<<16)); /* rest */
|
||||
/* read value from mem 0xFFFF00 */
|
||||
val=tpu_reg_rd(TPUREG_DEBPAR,0);
|
||||
}
|
||||
test_restore_ir();
|
||||
if(des->flags&TPUREG_FL_SH4)
|
||||
val>>=4;
|
||||
return val;
|
||||
}
|
||||
|
||||
/* write TPU register - method 1 */
|
||||
int tpu_t1_wr(struct tpu_reg_des *des, int indx, int val)
|
||||
{
|
||||
int ret;
|
||||
test_store_ir();
|
||||
if(des->flags&TPUREG_FL_SH4)
|
||||
val<<=4;
|
||||
ret=tpu_reg_wr(TPUREG_DEBPAR,0,val);
|
||||
test_forced_inst(0x1ffffc03);
|
||||
if(des->flags&TPUREG_FL_DIOB){
|
||||
stored_diob=val; /* DIOB write */
|
||||
}else{
|
||||
test_forced_inst(0xffff|(des->adr1<<16)); /* rest */
|
||||
}
|
||||
test_restore_ir();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read TPU register - method 2 */
|
||||
int tpu_t2_rd(struct tpu_reg_des *des, int indx)
|
||||
{
|
||||
return test_shift_regrd(des->adr,des->adr1);
|
||||
}
|
||||
|
||||
/* write TPU register - method 2 */
|
||||
int tpu_t2_wr(struct tpu_reg_des *des, int indx, int val)
|
||||
{
|
||||
return test_shift_regwr(des->adr,des->adr1,val);
|
||||
}
|
||||
|
||||
/* read 16 bit variable from main CPU address space */
|
||||
int tpu_mem_rd16(struct tpu_reg_des *des, int indx)
|
||||
{
|
||||
u_int16_t val;
|
||||
int adr=des->adr;
|
||||
if(indx){
|
||||
if(indx>=des->arr_len) return -1;
|
||||
adr+=2*indx;
|
||||
}
|
||||
val=TPU_RD16((caddr_t)adr);
|
||||
return val;
|
||||
|
||||
mem_op_error:
|
||||
fprintf(stderr,"tpu_mem_rd16 : read from address %06x error\n",adr);
|
||||
fflush(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write 16 bit variable to main CPU address space */
|
||||
int tpu_mem_wr16(struct tpu_reg_des *des, int indx, int val)
|
||||
{
|
||||
int adr=des->adr;
|
||||
if(indx){
|
||||
if(indx>=des->arr_len) return -1;
|
||||
adr+=2*indx;
|
||||
}
|
||||
TPU_WR16((caddr_t)adr,val);
|
||||
return 0;
|
||||
|
||||
mem_op_error:
|
||||
fprintf(stderr,"tpu_mem_wr16 : write to address %06x error\n",adr);
|
||||
fflush(NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read TPU register */
|
||||
int tpu_reg_rd(int reg, int indx)
|
||||
{
|
||||
if((reg>TPUREG_MAX)||(tpu_regs[reg].reg_rd==NULL))
|
||||
return -1;
|
||||
return tpu_regs[reg].reg_rd(&tpu_regs[reg],indx);
|
||||
}
|
||||
|
||||
/* Write TPU register */
|
||||
int tpu_reg_wr(int reg, int indx, int val)
|
||||
{
|
||||
if((reg>TPUREG_MAX)||(tpu_regs[reg].reg_wr==NULL))
|
||||
return -1;
|
||||
return tpu_regs[reg].reg_wr(&tpu_regs[reg],indx,val);
|
||||
}
|
||||
|
||||
int tpu_reg_or(int reg, int indx, int val)
|
||||
{
|
||||
int reg_val;
|
||||
reg_val=tpu_reg_rd(reg,indx);
|
||||
reg_val|=val;
|
||||
tpu_reg_wr(reg,indx,reg_val);
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
int tpu_reg_and(int reg, int indx, int val)
|
||||
{
|
||||
int reg_val;
|
||||
reg_val=tpu_reg_rd(reg,indx);
|
||||
reg_val&=val;
|
||||
tpu_reg_wr(reg,indx,reg_val);
|
||||
return reg_val;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#define swap_l(x) (x>>24) | ((x>>8)&0xff00) | ((x<<8)&0xff0000) | ((x&0xff)<<24)
|
||||
|
||||
/* external TPU disassembler */
|
||||
void DisInst (unsigned long i, FILE * fp);
|
||||
|
||||
|
||||
int cpu_stat(void)
|
||||
{
|
||||
int ret;
|
||||
u_int rpc;
|
||||
|
||||
ret=bdmlib_getstatus();
|
||||
printf("MCU ");
|
||||
if(ret&BDM_TARGETRESET) printf("Reset ");
|
||||
if(ret&BDM_TARGETSTOPPED) printf("Stopped ");
|
||||
if(ret&BDM_TARGETPOWER) printf("NoPower ");
|
||||
if(ret&BDM_TARGETNC) printf("NoConnect ");
|
||||
printf("\n");
|
||||
if(ret&BDM_TARGETSTOPPED) {
|
||||
if((ret=bdmlib_get_sys_reg(BDM_REG_RPC, &rpc))<0) return ret;
|
||||
printf("RPC=0x%06x\n",swap_l(rpc));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
bdmlib_setdebug(1);
|
||||
if((ret=bdmlib_open(bdm_dev_name))<0)
|
||||
{ printf("bdmlib_open : %s\n",bdmlib_geterror_str(ret)); return 1; };
|
||||
bdmlib_setioctl(BDM_SPEED,0);
|
||||
if (!(bdmlib_getstatus() & BDM_TARGETSTOPPED))
|
||||
ret=bdmlib_ioctl(BDM_STOP_CHIP);
|
||||
|
||||
if(1){
|
||||
printf("We need to reset target for first run\n");
|
||||
if((ret=bdmlib_reset())<0){
|
||||
printf("Cannot reset target - exitting\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(cpu_stat()<0){
|
||||
printf("trying to reset !!!!!!!\n");
|
||||
ret=bdmlib_reset();
|
||||
cpu_stat();
|
||||
}
|
||||
|
||||
bdmlib_set_sys_reg(BDM_REG_DFC, 5);
|
||||
bdmlib_set_sys_reg(BDM_REG_SFC, 5);
|
||||
|
||||
ret=test_init_1();
|
||||
printf("test_init_1 returned %d\n",ret);
|
||||
ret=test_init_2();
|
||||
printf("test_init_2 returned %d\n",ret);
|
||||
printf("test_dssrdscr_1(run)=%d test_dscr_arm=0x%02x test_dssr_bkpt=%d\n",
|
||||
test_dssrdscr_1,test_dscr_arm,test_dssr_bkpt);
|
||||
|
||||
fflush(NULL);
|
||||
|
||||
// tpu_halt();
|
||||
|
||||
printf("DCNR %04X\n",tpu_reg_rd(TPUREG_DCNR,0));
|
||||
printf("DSCR %04X\n",tpu_reg_rd(TPUREG_DSCR,0));
|
||||
|
||||
// tpu_reg_or(TPUREG_CREG,0,TPU_IMBTST); /* stop microengine */
|
||||
// tpu_reg_or(TPUREG_DSCR,0,0x8200); /* ???????????? */
|
||||
|
||||
printf("P %04X DIOB %04X A %04X SR %04X DEC %01X\n"
|
||||
"ERT %04X TCR1 %04X TCR2 %04X PC %03X CHAN %01X\n",
|
||||
tpu_reg_rd(TPUREG_P,0),tpu_reg_rd(TPUREG_DIOB,0),
|
||||
tpu_reg_rd(TPUREG_A,0),tpu_reg_rd(TPUREG_SR,0),
|
||||
tpu_reg_rd(TPUREG_DEC,0),tpu_reg_rd(TPUREG_ERT,0),
|
||||
tpu_reg_rd(TPUREG_TCR1,0),tpu_reg_rd(TPUREG_TCR2,0),
|
||||
tpu_reg_rd(TPUREG_PC,0),tpu_reg_rd(TPUREG_CHAN,0));
|
||||
|
||||
if(0){
|
||||
printf("TCR2 %04X\n",tpu_reg_rd(TPUREG_TCR2,0));
|
||||
printf("TCR1 %04X\n",tpu_reg_rd(TPUREG_TCR1,0));
|
||||
printf("TCR2 %04X\n",tpu_reg_rd(TPUREG_TCR2,0));
|
||||
|
||||
tpu_reg_wr(TPUREG_P ,0,0xABCD);tpu_reg_wr(TPUREG_DIOB,0,0xEF01);
|
||||
tpu_reg_wr(TPUREG_A ,0,0x2345);tpu_reg_wr(TPUREG_SR ,0,0x6789);
|
||||
tpu_reg_wr(TPUREG_DEC ,0, 0xA);tpu_reg_wr(TPUREG_ERT ,0,0xBCDE);
|
||||
tpu_reg_wr(TPUREG_TCR1,0,0xF012);tpu_reg_wr(TPUREG_TCR2,0,0x3456);
|
||||
tpu_reg_wr(TPUREG_PC ,0, 0x789);tpu_reg_wr(TPUREG_CHAN,0, 0xB);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
tpu_ucode_read(0);
|
||||
|
||||
for(i=0;i<TPU_UCODE_LEN;i++){
|
||||
printf("%03x: %08x ",i,tpu_ucode_img[i]);
|
||||
DisInst (tpu_ucode_img[i],stdout);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
684
m683xx/bdm-load/tpudis.c
Normal file
684
m683xx/bdm-load/tpudis.c
Normal file
@@ -0,0 +1,684 @@
|
||||
/*******************************************************************
|
||||
|
||||
TPUDB Project to Create Free Motorola 683xx TPU Debugger
|
||||
|
||||
tpudis.c - TPU microcode disassembler
|
||||
|
||||
(C) Copyright 2000 by Wouter Vlothuizen - Original Author
|
||||
e-mail: wouter@vlothuizen.demon.nl
|
||||
|
||||
This package can be copied and modified under
|
||||
GNU General Public License with all its conditions.
|
||||
See file GPL for details. Under this license nobody can
|
||||
distribute this work and any derived work without full source code
|
||||
for all modules compiled and linked into executable.
|
||||
|
||||
*******************************************************************/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
static FILE *f;
|
||||
static unsigned long inst;
|
||||
|
||||
void
|
||||
Error (char *s)
|
||||
{
|
||||
fprintf (stderr, "\ntpudis: %s\n", s);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
#define put(x) s=x
|
||||
#define I(h,l) ( (inst>>(l)) & (((1<<((h)+1-(l))))-1) )
|
||||
|
||||
void
|
||||
T1ABS (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (I (28, 25))
|
||||
{
|
||||
case 0:
|
||||
put ("plow");
|
||||
break;
|
||||
case 1:
|
||||
put ("phi");
|
||||
break;
|
||||
case 2:
|
||||
put ("dec");
|
||||
break;
|
||||
case 3:
|
||||
put ("chan");
|
||||
break;
|
||||
case 4:
|
||||
put ("#0 special");
|
||||
break;
|
||||
case 5:
|
||||
put ("{Illegal T1ABS: 5}");
|
||||
break;
|
||||
case 6:
|
||||
put ("{Illegal T1ABS: 6}");
|
||||
break;
|
||||
case 7:
|
||||
put ("#0");
|
||||
break;
|
||||
case 8:
|
||||
put ("p");
|
||||
break;
|
||||
case 9:
|
||||
put ("a");
|
||||
break;
|
||||
case 10:
|
||||
put ("sr");
|
||||
break;
|
||||
case 11:
|
||||
put ("diob");
|
||||
break;
|
||||
case 12:
|
||||
put ("tcr1");
|
||||
break;
|
||||
case 13:
|
||||
put ("tcr2");
|
||||
break;
|
||||
case 14:
|
||||
put ("ert");
|
||||
break;
|
||||
case 15:
|
||||
put ("#0");
|
||||
break;
|
||||
default:
|
||||
Error ("T1ABS decoding error");
|
||||
}
|
||||
fprintf (f, "%s + ", s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
T3ABD (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (inst >> 21 & 0xF)
|
||||
{
|
||||
case 0:
|
||||
put ("a");
|
||||
break;
|
||||
case 1:
|
||||
put ("sr");
|
||||
break;
|
||||
case 2:
|
||||
put ("ert");
|
||||
break;
|
||||
case 3:
|
||||
put ("diob");
|
||||
break;
|
||||
case 4:
|
||||
put ("phi");
|
||||
break;
|
||||
case 5:
|
||||
put ("{Illegal T3ABD: 5}");
|
||||
break;
|
||||
case 6:
|
||||
put ("plow");
|
||||
break;
|
||||
case 7:
|
||||
put ("p");
|
||||
break;
|
||||
case 8:
|
||||
put ("link");
|
||||
break;
|
||||
case 9:
|
||||
put ("chan");
|
||||
break;
|
||||
case 10:
|
||||
put ("dec");
|
||||
break;
|
||||
case 11:
|
||||
put ("dec&chan");
|
||||
break;
|
||||
case 12:
|
||||
put ("tcr1");
|
||||
break;
|
||||
case 13:
|
||||
put ("tcr2");
|
||||
break;
|
||||
case 14:
|
||||
put ("{Illegal T3ABD: 14}");
|
||||
break;
|
||||
case 15:
|
||||
put ("Nil");
|
||||
break;
|
||||
default:
|
||||
Error ("T3ABD decoding error");
|
||||
}
|
||||
fprintf (f, "AU %s :=", s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SHF (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (inst >> 19 & 3)
|
||||
{
|
||||
case 0:
|
||||
s = "<<";
|
||||
break;
|
||||
case 1:
|
||||
s = ">>";
|
||||
break;
|
||||
case 2:
|
||||
s = "R>";
|
||||
break;
|
||||
case 3:
|
||||
s = "";
|
||||
break;
|
||||
default:
|
||||
Error ("SHF decoding error");
|
||||
}
|
||||
fprintf (f, "%s ", s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
T1BBSetc (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (inst >> 14 & 7)
|
||||
{
|
||||
case 0:
|
||||
s = "p";
|
||||
break;
|
||||
case 1:
|
||||
s = "a";
|
||||
break;
|
||||
case 2:
|
||||
s = "sr";
|
||||
break;
|
||||
case 3:
|
||||
s = "diob";
|
||||
break;
|
||||
case 7:
|
||||
s = "#0";
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
s = "{Illegal T1BBS}";
|
||||
break;
|
||||
default:
|
||||
Error ("T1BBS decoding error");
|
||||
}
|
||||
fprintf (f, "%s%s%s ",
|
||||
inst & (1L << 12) ? "" : "!", s, inst & (1L << 13) ? "" : " + 1");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SRCCCL (void)
|
||||
{
|
||||
if (~inst & (1L << 18))
|
||||
fprintf (f, ", ensr");
|
||||
if (~inst & (1L << 17))
|
||||
fprintf (f, ", cc");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
T1BBI (void)
|
||||
{
|
||||
fprintf (f, "#$%2lx", inst >> 9 & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DECEND (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (inst & 3)
|
||||
{
|
||||
case 0:
|
||||
s = "DEC_RTS";
|
||||
break;
|
||||
case 1:
|
||||
s = "DEC_RPT";
|
||||
break;
|
||||
case 2:
|
||||
s = "end";
|
||||
break;
|
||||
case 3:
|
||||
return;
|
||||
default:
|
||||
Error ("DECEND decoding error");
|
||||
}
|
||||
fprintf (f, "%s", s);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IOMetc (int rwPos)
|
||||
{
|
||||
char *fm=NULL;
|
||||
int aid=0;
|
||||
|
||||
switch (inst >> 9 & 7)
|
||||
{
|
||||
case 0:
|
||||
fm = "RAM p %s @prm%d ; ";
|
||||
aid = inst >> 2 & 7;
|
||||
break;
|
||||
case 1:
|
||||
fm = "RAM p %s by_diob ; ";
|
||||
break;
|
||||
case 2:
|
||||
fm = "RAM p %s @$%x ; ";
|
||||
aid = inst >> 2 & 0x7F;
|
||||
break;
|
||||
case 4:
|
||||
fm = "RAM diob %s @prm%d ; ";
|
||||
aid = inst >> 2 & 7;
|
||||
break;
|
||||
case 5:
|
||||
fm = "RAM diob %s by_diob ; ";
|
||||
break;
|
||||
case 6:
|
||||
fm = "RAM diob %s @$%x ; ";
|
||||
aid = inst >> 2 & 0x7F;
|
||||
break;
|
||||
case 3:
|
||||
case 7:
|
||||
return;
|
||||
default:
|
||||
Error ("IOM decoding error");
|
||||
|
||||
}
|
||||
fprintf (f, fm, inst & (1L << rwPos) ? "->" : "<-", aid);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CJCetc (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
if (I (29, 16) == 0x3FFF)
|
||||
return;
|
||||
|
||||
switch (inst >> 26 & 0xF)
|
||||
{
|
||||
case 0:
|
||||
s = "LESS_THAN";
|
||||
break;
|
||||
case 1:
|
||||
s = "LOW_SAME";
|
||||
break;
|
||||
case 2:
|
||||
s = "V";
|
||||
break;
|
||||
case 3:
|
||||
s = "N";
|
||||
break;
|
||||
case 4:
|
||||
s = "C";
|
||||
break;
|
||||
case 5:
|
||||
s = "Z";
|
||||
break;
|
||||
case 6:
|
||||
s = "cflg1";
|
||||
break;
|
||||
case 7:
|
||||
s = "cflg0";
|
||||
break;
|
||||
case 8:
|
||||
s = "TDL";
|
||||
break;
|
||||
case 9:
|
||||
s = "MRL";
|
||||
break;
|
||||
case 10:
|
||||
s = "LSL";
|
||||
break;
|
||||
case 11:
|
||||
s = "SEQ1";
|
||||
break;
|
||||
case 12:
|
||||
s = "SEQ0";
|
||||
break;
|
||||
case 13:
|
||||
s = "PSL";
|
||||
break;
|
||||
case 14:
|
||||
s = "{Illegal branch}";
|
||||
break;
|
||||
case 15:
|
||||
s = "false";
|
||||
break;
|
||||
default:
|
||||
Error ("CJC decoding error");
|
||||
}
|
||||
fprintf (f, "if %s = %s then goto $%lx%s; ",
|
||||
s,
|
||||
inst & (1L << 8) ? "true" : "false",
|
||||
inst >> 16 & 0x1FF, inst & (1L << 25) ? "" : ", flsh");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NMAetc (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (inst >> 26 & 3)
|
||||
{
|
||||
case 0:
|
||||
s = "jmp";
|
||||
break;
|
||||
case 1:
|
||||
s = "jsr";
|
||||
break;
|
||||
case 2:
|
||||
s = "rts";
|
||||
break;
|
||||
case 3:
|
||||
return;
|
||||
default:
|
||||
Error ("NMA decoding error");
|
||||
}
|
||||
fprintf (f, "%s%s $%lx ; ", s, inst & (1L << 25) ? "" : " ,flsh",
|
||||
inst >> 16 & 0x1FF);
|
||||
}
|
||||
|
||||
void
|
||||
TBS (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (I (15, 12))
|
||||
{
|
||||
case 0:
|
||||
s = "in_mtcr1_ctcr1";
|
||||
break;
|
||||
case 1:
|
||||
s = "in_mtcr2_ctcr1";
|
||||
break;
|
||||
case 2:
|
||||
s = "in_mtcr1_ctcr2";
|
||||
break;
|
||||
case 3:
|
||||
s = "in_mtcr2_ctcr2";
|
||||
break;
|
||||
case 4:
|
||||
s = "out_mtcr1_ctcr1";
|
||||
break;
|
||||
case 5:
|
||||
s = "out_mtcr2_ctcr1";
|
||||
break;
|
||||
case 6:
|
||||
s = "out_mtcr1_ctcr2";
|
||||
break;
|
||||
case 7:
|
||||
s = "out_mtcr2_ctcr2";
|
||||
break;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
return;
|
||||
default:
|
||||
Error ("TBS decoding error");
|
||||
}
|
||||
fprintf (f, "tbs:=%s ", s);
|
||||
}
|
||||
|
||||
void
|
||||
ERWTDLMRL (void)
|
||||
{
|
||||
if (~inst & (1L << 29))
|
||||
fprintf (f, "write_mer ");
|
||||
if (~inst & (1L << 18))
|
||||
fprintf (f, "neg_tdl ");
|
||||
if (~inst & (1L << 17))
|
||||
fprintf (f, "neg_mrl ");
|
||||
}
|
||||
|
||||
void
|
||||
PSC (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (I (7, 6))
|
||||
{
|
||||
case 0:
|
||||
s = "PAC";
|
||||
break;
|
||||
case 1:
|
||||
s = "high";
|
||||
break;
|
||||
case 2:
|
||||
s = "low";
|
||||
break;
|
||||
case 3:
|
||||
return;
|
||||
default:
|
||||
Error ("PSC decoding error");
|
||||
}
|
||||
fprintf (f, "pin:=%s ", s);
|
||||
}
|
||||
|
||||
void
|
||||
PAC (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (I (11, 9))
|
||||
{
|
||||
case 0:
|
||||
s = "off";
|
||||
break;
|
||||
case 1:
|
||||
s = "high";
|
||||
break;
|
||||
case 2:
|
||||
s = "low";
|
||||
break;
|
||||
case 3:
|
||||
s = "h+l";
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return;
|
||||
default:
|
||||
Error ("PAC decoding error");
|
||||
}
|
||||
fprintf (f, "pac:=%s ", s);
|
||||
}
|
||||
|
||||
void
|
||||
FLC (int pos) /* at position 5 or 15 */
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
fprintf (f, "chan ");
|
||||
switch (I (pos, pos - 2))
|
||||
{
|
||||
case 0:
|
||||
s = "clr cflg0";
|
||||
break;
|
||||
case 1:
|
||||
s = "set cflg0";
|
||||
break;
|
||||
case 2:
|
||||
s = "clr cflg1";
|
||||
break;
|
||||
case 3:
|
||||
s = "set cflg1";
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
return;
|
||||
default:
|
||||
Error ("FLC decoding error");
|
||||
}
|
||||
fprintf (f, "%s ", s);
|
||||
}
|
||||
|
||||
void
|
||||
LSL (int pos) /* at position 8 or 12 */
|
||||
{
|
||||
if (~inst & (1L << pos))
|
||||
fprintf (f, "neg_lsr ");
|
||||
}
|
||||
|
||||
void
|
||||
CIR (void)
|
||||
{
|
||||
if (~inst & (1L << 2))
|
||||
fprintf (f, "pir ");
|
||||
}
|
||||
|
||||
void
|
||||
CCM (void)
|
||||
{
|
||||
if (~inst & (1L << 2))
|
||||
fprintf (f, "by_p ");
|
||||
}
|
||||
|
||||
void
|
||||
MTD (void)
|
||||
{
|
||||
char *s=NULL;
|
||||
|
||||
switch (I (1, 0))
|
||||
{
|
||||
case 0:
|
||||
s = "en";
|
||||
break;
|
||||
case 1:
|
||||
s = "ds";
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
return;
|
||||
default:
|
||||
Error ("MTD decoding error");
|
||||
}
|
||||
fprintf (f, "%ssr ", s);
|
||||
}
|
||||
|
||||
void
|
||||
sep (void)
|
||||
{
|
||||
fprintf (f, "; ");
|
||||
}
|
||||
|
||||
void
|
||||
DisInst (unsigned long i, FILE * fp)
|
||||
{
|
||||
f = fp;
|
||||
inst = i;
|
||||
|
||||
if (inst != 0xffffffff)
|
||||
switch (inst >> 30 & 3) /* type of instruction */
|
||||
{
|
||||
case 0: /* format 1 */
|
||||
T3ABD ();
|
||||
SHF ();
|
||||
T1ABS ();
|
||||
T1BBSetc ();
|
||||
SRCCCL ();
|
||||
sep ();
|
||||
IOMetc (29);
|
||||
DECEND ();
|
||||
break;
|
||||
case 1: /* format 2 */
|
||||
T3ABD ();
|
||||
SHF ();
|
||||
T1ABS ();
|
||||
T1BBSetc ();
|
||||
sep ();
|
||||
FLC (5);
|
||||
ERWTDLMRL ();
|
||||
PAC ();
|
||||
LSL (8);
|
||||
PSC ();
|
||||
CIR ();
|
||||
sep ();
|
||||
DECEND ();
|
||||
break;
|
||||
case 2: /* format 3 */
|
||||
CJCetc ();
|
||||
FLC (5);
|
||||
TBS ();
|
||||
PAC ();
|
||||
PSC ();
|
||||
CCM ();
|
||||
MTD ();
|
||||
break;
|
||||
case 3:
|
||||
if (inst & (1L << 29)) /* format 5 */
|
||||
{
|
||||
T3ABD ();
|
||||
SHF ();
|
||||
T1ABS ();
|
||||
T1BBI ();
|
||||
SRCCCL ();
|
||||
sep ();
|
||||
FLC (5);
|
||||
LSL (8);
|
||||
CIR ();
|
||||
sep ();
|
||||
}
|
||||
else /* format 4 */
|
||||
{
|
||||
NMAetc ();
|
||||
FLC (15);
|
||||
LSL (12);
|
||||
sep ();
|
||||
IOMetc (28);
|
||||
}
|
||||
DECEND ();
|
||||
break;
|
||||
default:
|
||||
Error ("format decoding error");
|
||||
}
|
||||
fprintf (f, "\n");
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
EntryPoint (unsigned int ep)
|
||||
{
|
||||
int pc;
|
||||
|
||||
pc = ep & 0x1FF;
|
||||
|
||||
if (ep >> 9 & 3 == 0)
|
||||
{
|
||||
fprintf (f, "Error in EntryPoint format\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (f, "PreLoad=%d ME=%d PPD=%4s PC=$%03x\n",
|
||||
ep >> 13 & 7,
|
||||
ep & (1L << 12) ? 1 : 0, ep & (1L << 11) ? "DIOB" : "P", pc);
|
||||
epCnt[pc]++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user