Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

DJGPP - Mapping small blocks of physmem beyond 1MB - __dpmi? (Developers)

posted by RayeR Homepage, CZ, 13.07.2011, 14:58
(edited by RayeR on 13.07.2011, 16:26)

I asked on DJGPP google groups but maybe someone other here will know - it's more generic DMPI question than DJGPP question:

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
}


Utility can be tested here:
http://rayer.ic.cz/350d/ACPINFO.EXE

---
DOS gives me freedom to unlimited HW access.

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 269 users online (0 registered, 269 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum