12.04.2012 20:34, Bart Oldeman написал: > Hello Stas, > > First of all I'm sorry for my general non-responsiveness, I've just > been busy in general. I havent noticed: wasn't writing anything. Actually, I was unsubscribed from the list, as you explained, because of the bounces. Now obviously to re-subscribe the one only need to post to the list. After my today's post I started to receive all mails. I wonder if I need to commit something to get re-subscribed to the notify list...
>> Then, if this is fixed, I think all the uses of LOWMEM() should >> be killed, except those intended initially: for the use by the mappers. >> No one, except "mappers", should use LOWMEM(). Fortunately, >> the uses of LOWMEM() are already very few in the code. > The problem is as follows: the reason why LOWMEM is used, is that > DOSEMU needs to write to DOS memory, on pages that are potentially > write-protected by the CPU emulator. I know, but not looking into the code for 6 years, I have confused somethng. I was mentioning zero page instead, thinking that you write-protect it to trap the NULL derefs, but this doesn't seem to be the case. > Most of these writes involve just data, and it's expensive to > unprotect, than write, and then again protect the page: an alias is > cheaper. What I meant to say is that: 1. The LOWMEM() _macro_ is only intended for mappers (my patch also uses it btw) 2. lowmem_base is not the real alias, so you can only access it if you got the reference to it from the _properly written_ dosaddr_to_unixaddr(), which doesn't exist as of yet. The things like IS_GENERIC_LOWMEM_ADDR() and the direct uses of LOWMEM() is basically the violation of the design I intended, but the properly written dosaddr_to_unixaddr() looks like the valid extension to it. But then it is not written. :) (but at least we agree that it have to be written, so fear not) > Some writes (mainly disk reads by int13 and the mfs, and xms > transfers) may actually involve code. That's one place where > e_invalidate() comes in -- the other places are where the memory is > potentially outside the non-aliased conventional memory range, which > is why e_invalidate() is also in dpmi.c. (In total I counted 6 or 7 > e_invalidate() calls, which doesn't look so excessive to me). Yes but then the emm.c is a candidate too... What's the use destinguishing the code and the data? If you have an area protected with the CPU emulator and someone writes to it, you'd better invalidate, no matter is it a code or data, or am I missing something? Now, if the area is _not_ protected, then calling e_invalidate() to it is hopefully a no-op, so it can just be called in any case. And we already have the macros for the DOS memory accesses, so why not just something like that: #define WRITE_WORD() { \ if (cpu_emulator) e_invalidate(); \ write_word(); \ } while (0) > If neither the alias nor invalidation is used, DOSEMU page faults, > which is then corrected by the CPU emulator, much like an exception > that is caught, that is, an expensive way of doing things. These > exceptions are logged in boot.log. OK, that explains why, after applying my patch, the guy mailed me the boot.log full of the exceptions. > looking at the code again: lowmemp(ptr) can actually be coded like this: > > return LINEAR2UNIX((unsigned char *)ptr-mem_base); > > it maps a *Linux* pointer to the equivalent address in the aliased r/w > low memory if it exists, and otherwise it just returns ptr. OK, I still don't understand anything. Firstly, this: --- #define MEMCPY_P2UNIX(unix_addr, dos_addr, n) \ memcpy((unix_addr), lowmemp(dos_addr), (n)) --- suggests that it takes the DOS address. Secondly, I can't follow the logic. I think we never had the precise definition of what is the linux pointer and what is the DOS pointer, but de-facto the DOS pointer was anything directly addressable from DOS, and the rest was the linux pointer. There was a pathological case of the kmem mapping, where both the pointers are equal, but, since lowmemp() doesn't seem to deal with this case, lets disregard it. With this definition, there is simply NO linux pointer at the low memory (kmem case is discarded for simplisity). > When I adjusted the DOSEMU code to work with non-zero mem_base I tried > to make sure that every time you have a pointer it is the actual Linux > address. A DOS address like 0xb8000 is stored as an unsigned int, > never explicitly as (void *)(0xb8000); when stored as a Linux pointer > it is stored as p=&mem_base[0xb8000]. I think you are basically working around the lack of the properly functional dosaddr_to_unixaddr(). You shouldn't do p=&mem_base[0xb8000], but rather p=dosaddr_to_unixaddr(0xb8000). Or are there other reasons to keep lowmemp()? I mean, let's aim for simplicity. :) If the meaning of the function is not obvious, it is a suspect for cleanup. > I haven't looked a lot at KVM's CPU emulator, I think it is not a JIT > emulator, but interpretative with some tricks to speed up flag > handling. Most of the bugs in the CPU emulator were gotten rid of by > using QEMU's test program and various fixes from Reinhard and Michael > Karcher. And I sped up the FPU emulation by having it use the real FPU > stack, so most of the FPU instructions could simply be copied for the > JIT. I think that's a great work! Run win.com, and hooplah - windows-3.1 is up and running on x86-64 dosemu... I'd say WOW! :) ------------------------------------------------------------------------------ For Developers, A Lot Can Happen In A Second. Boundary is the first to Know...and Tell You. Monitor Your Applications in Ultra-Fine Resolution. Try it FREE! http://p.sf.net/sfu/Boundary-d2dvs2 _______________________________________________ Dosemu-devel mailing list Dosemu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dosemu-devel