Message-ID: <3B8659BB.C6CE272@student.uni-ulm.de> Date: Fri, 24 Aug 2001 15:42:19 +0200 From: Karsten Schmidt Organization: =?iso-8859-1?Q?Universit=E4t?= Ulm X-Mailer: Mozilla 4.77 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: Thoughts on physical address and DMA References: <3b8141a5 DOT sandmann AT clio DOT rice DOT edu> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit NNTP-Posting-Host: pcks.e-technik.uni-ulm.de X-Trace: news.uni-ulm.de 998660499 pcks.e-technik.uni-ulm.de (24 Aug 2001 15:41:39 +0200) Lines: 115 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com 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; }