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 -