📄 agdi.cpp
字号:
supp.hTrace = 0; // trace support
supp.hCover = 0; // code coverage support
supp.hPaLyze = 0; // Performance-Analyzer support
supp.hMemMap = 0; // Memory-Map support
supp.ResetR = 0; // Reset while running support
supp.LaSupp = 1; // Logic-Analyzer support
//---Note: if InitTarget() fails, then set nE=1, else nE=0.
// if 1 is returned, then uVision will cancel using this driver
InitCache(); // init Cache
bootflag = 1;
nE = InitTarget(); // Initialize your target...
bootflag = 0;
if (nE == 0) { // initialization was Ok.
InitRegs(); // define register layout for RegWindow
}
if (nE == 0) { // everything is ok so far
pCbFunc (AG_CB_EXECCMD, "U $\n"); // force disassemble @curPC
}
break;
case AG_INITITEM: // init item
switch (nCode & 0x00FF) {
case AG_INITMENU: // init extension menu
*((DYMENU **) vp) = (DYMENU *) Menu;
break;
case AG_INITEXTDLGUPD: // init modeless extesion dlg update function
*((UC8 **) vp) = (UC8 *) DlgUpdate;
break;
case AG_INITMHANDLEP: // setup ptr to HWND of active modeless dlg
pHwnd = (HWND *) vp;
break;
case AG_INITPHANDLEP: // pointer to parent handle (MainFrame)
hMfrm = (HWND) vp;
break;
case AG_INITINSTHANDLE: // pointer to Agdi-instance handle
hInst = (HMODULE) vp;
break;
case AG_INITBPHEAD: // pointer to head of Bp-List
pBhead = (AG_BP **) vp;
break;
case AG_INITCURPC: // pointer to program counter
pCURPC = (UL32 *) vp;
break;
case AG_INITDOEVENTS: // DoEvents function pointer
//--- this is no longer relevant due to uVision's threading.
break;
case AG_INITUSRMSG: // Registered Message for SendMessage
Uv2Msg = (DWORD) vp; // (Serial-Window, TextOut messages)
break;
case AG_INITCALLBACK: // pointer to callback function
pCbFunc = (pCBF) vp; // call-back function of s166
break;
case AG_INITSTARTLOAD: // about to start 'load file'
if (vp != NULL) {
lParms = *((LOADPARMS *) vp);
// lParms.szFile[] : full path name of App to load
// lParms.Incremental : 1:= incremental load
// lParms.NoCode : 1:= load debug info only, no code
}
break;
case AG_INITENDLOAD: // Load is now completed.
break;
}
break;
case AG_GETFEATURE: // uVision2 want's details about features...
switch (nCode & 0x00FF) {
case AG_F_MEMACCR: nE = supp.MemAccR; break;
case AG_F_REGACCR: nE = supp.RegAccR; break;
case AG_F_TRACE: nE = supp.hTrace; break;
case AG_F_COVERAGE: nE = supp.hCover; break;
case AG_F_PALYZE: nE = supp.hPaLyze; break;
case AG_F_MEMMAP: nE = supp.hMemMap; break;
case AG_F_RESETR: nE = supp.ResetR; break;
case AG_F_LANALYZER: nE = supp.LaSupp; break; // Logic-Analyzer support
}
break;
case AG_EXECITEM: // execute various commands
switch (nCode & 0x00FF) {
case AG_QUERY_LASIG: // is LA-Signal acceptable ?
if (vp == NULL) { // NOTE: just for Test...
//---NOTE: vp == NULL is just for test only, it is not a real case !!!
SineSig(); // generate a sine Wave for test data
break; // LA should show the sine wave...
}
nE = QueryLaSig ((AGDI_LA *) vp);
break;
case AG_KILLED_LASIG: // LA-Signal was killed
nE = KilledLaSig ((AGDI_LA *) vp);
break;
case AG_UNINIT: // Clean up target system settings
PlayDead = 1; // mark target as disconnected.
CloseAllDlg(); // close all open dialogs
StopTarget(); // shutdown target & communication
WriteMonParms (pdbg->TargArgs); // update argument string
FreeCache(); // free memory clusters.
break;
case AG_RESET: // perform a reset on the target system
if (PlayDead || hMfrm == NULL) break; // target is disconnected
ResetTarget(); // reset the target
pCbFunc (AG_CB_EXECCMD, "U $\n"); // dasm $
#if 1
TestScope (0x1000B1C);
TestEnumScopes();
#endif
break;
}
break;
}
if (PlayDead) { // driver is disconnected
StopTarget(); // shut down driver
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0); // unload this driver
}
return (nE);
}
/*
* Memory Interface functions
*/
UL32 ReadMemory (UL32 Adr, UC8 *pB, UL32 nMany) { // reads memory
UL32 len, temp;
U16 i;
struct EMM (*s)[256];
struct EMM acc;
MAMAP x;
x.a32 = Adr; // requested address
while (nMany) {
s = slots [x.ub[3]]; // a24 ... a31
if (s) acc = (*s)[x.ub[2]];
#if 0 // could map memory here...
if (s == NULL || acc.mem == NULL) { // accessing unmapped memory !
MapSeg (x.a32 >> 16, x.a32 & 0xFFFF, 0x10000 - (x.a32 & 0xFFFF), 0); // map a segment
}
#endif
if (s) acc = (*s)[x.ub[2]];
if (s == NULL || acc.mem == NULL) { // accessing unmapped memory !
return (x.a32); // return error-address
}
//---fetch data out of cache, if content is valid:
if ((acc.atr [x.w16 >> 2] & ATRX_UPTD) && (CacheMode & READ_CACHE) && !iRun) {
*pB = acc.mem [x.w16];
++pB; // advance receive pointer
--nMany; // decrease 'many'
++x.a32; // increase address
continue;
}
//---
len = nMany;
if (x.a32 & 0x01) { // JTAG cannot handle odd addresses
x.a32--; // decrease address by one to make it even
len++; // increase len by 1 to get all requested bytes
}
if (len > 0x1000) len = 0x1000; // can't handle more than 4096 bytes because of buffer size
if (len < 0x0040) len = 0x40;//0x001f; // avoid too small memory transfers
if ((0x00010000 - (UL32)x.w16) < len) len = (0x00010000 - x.w16); // do not write across segment boundaries
if (PlayDead) return(0); // Disables the driver after the communication breaks down.
while (read_block (x.a32, len));
memcpy (&acc.mem [x.w16], &comm_buffer[0], len); // copy bytes from communication buffer into memory
temp = len;
for ( i = x.w16 >> 2 ; temp ; temp--, i++) {
acc.atr[i] |= ATRX_UPTD; // set 'cache valid' bit for address
}
if (len > nMany) len = nMany; // if more bytes have been requested as needed to return
memcpy (pB, &acc.mem[x.w16], len); // copy bytes from communication buffer
nMany -= len;
x.a32 += len;
pB += len;
}
return(0);
}
UL32 WriteOpcode (UL32 Adr, UC8 *pB, UL32 nMany) { // writing opcodes and variables is idential
UL32 len;
WriteToCache (Adr, pB, nMany);
if (!(CacheMode & WRITE_BEHIND_CACHE)) {
RegUpToDate = 0;
while(nMany) { // write new data to target system immediately
if (PlayDead) return(0);
len = nMany;
if (len > 0x1000) len = 0x1000;
memcpy(&comm_buffer[0], pB, len); // copy bytes into communication buffer
while(write_block(Adr, len));
nMany -= len;
Adr += len;
pB += len;
}
}
return(0);
}
UL32 ReadOpcode (UL32 Adr, UC8 *pB, UL32 nMany) { // reads opcodes (does not care about the updated flag when mapped as code)
UL32 len, temp;
U16 i;
struct EMM (*s)[256];
struct EMM acc;
MAMAP x;
x.a32 = Adr; // requested address
while (nMany) {
s = slots [x.ub[3]]; // a24-a31
#if 0 // could map memory here...
if (s == NULL || acc.mem == NULL) { // accessing unmapped memory !
MapSeg (x.a32 >> 16, x.a32 & 0xFFFF, 0x10000 - (x.a32 & 0xFFFF), 0); // map a segment
}
#endif
if (s) acc = (*s)[x.ub[2]];
if (s == NULL || acc.mem == NULL) { // accessing unmapped memory !
return (x.a32); // access violation address
}
//---fetch data out of cache, if content is valid:
if (((acc.atr [x.w16>>2] & ATRX_UPTD) && (CacheMode & READ_CACHE)) ||
((acc.atr [x.w16>>2] & ATRX_EXEC) && !(acc.atr [x.w16>>2] & ATRX_WRITE) && (CacheMode & READ_CODE_CACHE))) {
*pB = acc.mem [x.w16];
pB++;
nMany--;
x.a32++;
continue;
}
len = nMany;
if (x.a32 & 0x01) { // JTAG cannot handle odd addresses
x.a32--; // decrease address by one to make it even
len++; // increase len by 1 to get all requested bytes
}
if (len > 0x1000) len = 0x1000; // can't handle more than 4096 bytes because of buffer size
if (len < 0x0040) len = 0x0040; // avoid too small memory transfers
if ((0x00010000 - (UL32)x.w16) < len) len = (0x00010000 - x.w16); // do not write across segment boundaries
if (PlayDead) return(0);
while(read_block(x.a32, (UC8)len));
memcpy(&acc.mem [x.w16], &comm_buffer[0], len); // copy bytes from communication buffer into memory
temp = len;
for (i = x.w16>>2; temp; temp--, i++) {
acc.atr [i] |= ATRX_UPTD;
}
if (len > nMany) len = nMany; // if more bytes have been requested as needed to return
memcpy(pB, &acc.mem[x.w16], len); // copy bytes from communication buffer
nMany -= len;
x.a32 += len;
pB += len;
}
return(0);
}
/*
* Access target memory
*/
U32 _EXPO_ AG_MemAcc (U16 nCode, UC8 *pB, GADR *pA, UL32 nMany) {
U16 nErr;
if (iRun && !supp.MemAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return(AG_NOACCESS);
nErr = 0;
if (hMfrm == NULL) {
memset (pB, 0, nMany);
return(nErr);
}
switch (nCode) {
case AG_READ: // need 'read' permission
pA->ErrAdr = ReadMemory (pA->Adr, pB, nMany);
break;
case AG_WRITE: // need 'write' permission
pA->ErrAdr = WriteOpcode (pA->Adr, pB, nMany);
if (pA->ErrAdr != 0) {
nErr = AG_WRFAILED;
}
break;
case AG_F_WRITE: // Flash-Write
// pA->ErrAdr = WriteFlash (pA->Adr, pB, nMany);
break;
// used for Program download
case AG_WROPC: // need 'Read/Execute' permissions
pA->ErrAdr = WriteOpcode (pA->Adr, pB, nMany);
if (pA->ErrAdr != 0) {
nErr = AG_WRFAILED;
}
break;
// used for disassembly etc.
case AG_RDOPC: // need 'Read/Execute' permissions
pA->ErrAdr = ReadOpcode (pA->Adr, pB, nMany);
if (pA->ErrAdr != 0) {
nErr = AG_RDFAILED;
}
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) { // Disables the driver after the communication breaks down.
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write Registers
*/
U32 _EXPO_ AG_AllReg (U16 nCode, void *vp) {
U16 nErr;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return(AG_NOACCESS);
nErr = 0;
switch (nCode) { // which Opcode
case AG_READ: // read register
if (!RegUpToDate) GetRegs();
memcpy (vp, ®ARM, sizeof (RgARM));
break;
case AG_WRITE:
memcpy (®ARM, vp, sizeof (RgARM));
SetRegs(®ARM); // write Regs + PC
*pCURPC = REGARM.cur[15];
WritePC(REGARM.cur[15]);
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
if (PlayDead == 1) { // Disables the driver after the communication breaks down.
PostMessage (hMfrm, Uv2Msg, MSG_UV2_TERMINATE, 0);
}
return (nErr);
}
/*
* Read/Write a single Register (ARM7)
*/
U32 _EXPO_ AG_RegAcc (U16 nCode, U32 nReg, GVAL *pV) {
U16 nErr;
DWORD val;
int i;
if (iRun && !supp.RegAccR) { // currently running, can't access.
return (AG_NOACCESS); // error: can't access register
}
if (PlayDead) return(AG_NOACCESS);
nErr = 0;
switch (nCode) { // which Opcode
case AG_READ: // read register
if (!RegUpToDate) GetRegs();
switch (nReg) {
case nR0: case nR1: case nR2: case nR3:
case nR4: case nR5: case nR6: case nR7:
case nR8: case nR9: case nR10: case nR11:
case nR12: case nR13: case nR14: case nR15:
pV->u32 = REGARM.cur[nReg];
break;
case mPC: // current PC
pV->u32 = REGARM.cur[15];
break;
case nCPSR:
pV->u32 = REGARM.cpsr;
break;
case nSPSR:
pV->u32 = REGARM.spsr;
break;
default:
nErr = AG_INVALOP; // invalid Operation
break;
}
break;
case AG_WRITE:
switch (nReg) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -