ftp.delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019