Mail Archives: djgpp/2011/07/11/10:30:21
| X-Authentication-Warning:  | delorie.com: mail set sender to djgpp-bounces using -f
 | 
| From:  | RayeR <glaux AT centrum DOT cz>
 | 
| Newsgroups:  | comp.os.msdos.djgpp
 | 
| Subject:  | Mapping small blocks of physical memory beyond 1MB -
 | 
 | __dpmi_physical_address_mapping minimum size?
 | 
| Date:  | Mon, 11 Jul 2011 07:18:25 -0700 (PDT)
 | 
| Organization:  | http://groups.google.com
 | 
| Lines:  | 74
 | 
| Message-ID:  | <773bd52e-eb0c-4a90-9e15-f6c5bbf4ae10@q5g2000yqj.googlegroups.com>
 | 
| NNTP-Posting-Host:  | 90.181.199.10
 | 
| Mime-Version:  | 1.0
 | 
| X-Trace:  | posting.google.com 1310393905 29859 127.0.0.1 (11 Jul 2011 14:18:25 GMT)
 | 
| X-Complaints-To:  | groups-abuse AT google DOT com
 | 
| NNTP-Posting-Date:  | Mon, 11 Jul 2011 14:18:25 +0000 (UTC)
 | 
| Complaints-To:  | groups-abuse AT google DOT com
 | 
| Injection-Info:  | q5g2000yqj.googlegroups.com; posting-host=90.181.199.10; posting-account=Q0wMHAoAAADjYrghh94FTf6YnbpTqZgp
 | 
| User-Agent:  | G2/1.0
 | 
| X-Google-Web-Client:  | true
 | 
| X-Google-Header-Order:  | HUAESNKRC
 | 
| X-HTTP-UserAgent:  | Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.19)
 | 
 | Gecko/20110420 SeaMonkey/2.0.14,gzip(gfe)
 | 
| Bytes:  | 4835
 | 
| To:  | djgpp AT delorie DOT com
 | 
| DJ-Gateway:  | from newsgroup comp.os.msdos.djgpp
 | 
| Reply-To:  | djgpp AT delorie DOT com
 | 
Hi,
I'm programming a small ACPI info utility in DJGPP v2.04 and I need to
map and copy some small blocks of physical memory. I don't know exact
size before reading whole table. E.g. the header is only 36B long and
when I get it I will know the entire size and repeat the mapping and
reading of physical memory. I do it via
__dpmi_physical_address_mapping() but I read this function has some
limits like minimum size should be 4kB and in multiple of 4kB blocks
(and   __dpmi_set_segment_limit should be >64kB). I found that it
works for me for small sizes (tested under DOS 6.22+CWSDPMI and Win98
DOS box) but I want to make it realiable. Of cource I can map large
enough (let's say 64kB) block and don't remap and don't change segment
limit then. But it may occur that base + size will exceed physical
memory top margin or 32bit adress range. E.g. base=0xFFFFF000 and
size=0xFFFF - I don't know if it cause something bad if I will not
read the memory beyond limit via movedata() function. If it is OK then
I'm safe. BTW why __dpmi_physical_address_mapping() needs size
paramerer at all? I checked that meminfo.address didn't changed when I
changed the size and call __dpmi_physical_address_mapping() again...
Current (experimentally working) code is here:
long copy_sdt(Byte *p_buffer, DWord phys_ptr) // returns SDT length, 0
if bad checksum, negative if read error
{
  ACPI_SDT_HEADER sdt_header;          // temporarly stored SDT header
to obtain full SDT size
  __dpmi_meminfo meminfo;              // DPMI meminfo structure for
physical memory mapping
  int sdt_selector;                    // selector of segment
descriptor of mapped SDT
  meminfo.address=phys_ptr;            // mapped physical address
  meminfo.size=sizeof(ACPI_SDT_HEADER);// mapped physical area size
  if (__dpmi_physical_address_mapping(&meminfo)!=0) // map physical
memory area to linear
    return(-2);                        // if failed return -2
  if ((sdt_selector=__dpmi_allocate_ldt_descriptors(1))<0) // allocate
1 descriptor (desribing our new segment) in LDT and return it's
selector
    return(-1);                        // if failed return -1
  __dpmi_set_segment_base_address(sdt_selector, meminfo.address); //
set segment base to linear ptr
  __dpmi_set_segment_limit(sdt_selector, meminfo.size-1); // set
segment limit accorning to SDT header size
  movedata(sdt_selector, 0, _my_ds(), (unsigned)&sdt_header,
sizeof(ACPI_SDT_HEADER)); // copy SDT header from physical memory to
temp buffer
  if (sdt_header.length<sizeof(ACPI_SDT_HEADER)) // check SDT lenght
    return(0);                        // if less than SDT header
return 0
// do I need this remapping step?
 meminfo.address=phys_ptr;           // mapped physical address
 meminfo.size=sdt_header.length;     // mapped physical area size
 if (__dpmi_physical_address_mapping(&meminfo)!=0) // map physical
memory area to linear
   return(-1);                       // if failed return -2
  __dpmi_set_segment_base_address(sdt_selector, meminfo.address); //
set segment base to linear ptr
  __dpmi_set_segment_limit(sdt_selector, sdt_header.length-1); // set
segment limit accorning to full SDT length
  movedata(sdt_selector, 0, _my_ds(), (unsigned)p_buffer,
sdt_header.length); // copy full SDT from physical memory to target
buffer
  __dpmi_free_ldt_descriptor(sdt_selector); // free temporary
allocated LDT descriptor
  if (calc_checksum(p_buffer, sdt_header.length)==0) // calculate
checksum
    return(sdt_header.length);         // if match return full lenght
  else
    return(0);                         // else return 0
}
- Raw text -