Mail Archives: djgpp/2001/08/24/10:00:18
Hi!
More than one year ago I had almost the same problem:
I was trying to access a digital IO-card using Bus-Master DMA.
The following function virtToPhys is based on the source code
from N. Jarvis and has been adopted to run with PMODE/DJ.
The resulting program will only run under protection level 0
(e.g. CWSDPR0 or PMODE/DJ).
/****************************************************************************/
/* University of
Ulm */
/*--------------------------------------------------------------------------*/
/* Microelectronics
Department */
/* Physical address
mapping */
/*
phys_adr.c
*/
/* K. Schmidt
(Author) */
/* 07.12.2000 (last
changed) */
/* 1.1 (last tested
version) */
/*--------------------------------------------------------------------------*/
/* Special
features: */
/* - Based on the sourcecode of N. Jarvis from the DJGPP Mail
Archiv */
/*
djgpp/1996/09/18/05:03:32 */
/* - Calculation of the physical adress for an given linear
address */
/* - Requires protection level 0 (z.B. CWSDPR0.EXE,
PMODEDJ.EXE) */
/* - Compile with -D PMODE to use with
PMODEDJ.EXE */
/*--------------------------------------------------------------------------*/
/*
Changes:
*/
/*
*/
/* Date Ver Author where ?
what? */
/* 13.03.2000 1.0 KS Initial
release */
/* 07.12.2000 1.1 KS Startup flags
_CRT0_FLAG_UNIX_SBRK */
/* virtToPhys() Changed for
PMODE/DJ */
/****************************************************************************/
/* Just to make me feel happier, I use the following. May not be needed.
*/
int _crt0_startup_flags = (_CRT0_FLAG_FILL_SBRK_MEMORY |
_CRT0_FLAG_FILL_DEADBEEF |
_CRT0_FLAG_NONMOVE_SBRK |
_CRT0_FLAG_LOCK_MEMORY
#ifdef PMODE
/* Additional flag for PMODE/DJ*/
| _CRT0_FLAG_UNIX_SBRK
#endif
);
static __inline__ unsigned long _my_cr3(void)
{
unsigned long result;
__asm__("mov %%cr3,%0" : "=r" (result));
return result;
}
/* Convert virtual to physical address */
unsigned long virtToPhys(void *virtualPtr)
{
unsigned long DSLinearAddr;
if (__dpmi_get_segment_base_address(_go32_my_ds(), &DSLinearAddr) !=
-1)
{
unsigned long pde, pdeAddr, pte, pteAddr, linear;
/* Calculate linear address */
linear = (unsigned long) virtualPtr + DSLinearAddr;
/* Changed for PMODE/DJ 1.3:
Physical Address == Linear Address! */
#ifdef PMODE
return (linear);
#endif
/* Calculate Page Directory Entry address */
pdeAddr = _my_cr3() + ((linear & 0xffc00000L) >> 20);
/* Read Page Directory Entry */
pde = _farpeekl(_dos_ds, pdeAddr);
/* Calculate Page Table Entry address */
pteAddr = (pde & 0xfffff000L) + ((linear & 0x003ff000L) >> 10);
/* Read Page Table Entry */
pte = _farpeekl(_dos_ds, pteAddr);
/* Calculate and return Page Frame address */
return (pte & 0xfffff000L) + (linear & 0x00000fffL);
}
else
return 0L;
}
- Raw text -