Though on second thought maybe it's not worth truncating the linear address at all... in protected mode, I expect that the proper behavior for an address that overflows 32 bits is to fail the segment limit test, which is probably easier if we just leave the address at 33 bits and do a 64-bit compare with the limit. The 32-bit real mode issue is one I'm willing to punt on, since (1) we don't run BIOS code at this point and afaik don't have plans to, (2) even if we did decide to run BIOS code we'd be crazy/stupid not to just use UEFI which won't have this issue, and (3) even if we're crazy/stupid and try to run a BIOS that uses this mode, I'd think there's a decent chance it doesn't rely on handling this corner case correctly. So actually going through the bother of figuring out if we should be doing the truncation and then doing it on every single memory access seems like a high price to pay relative to the odds that it will ever really matter.
Steve On Thu, Mar 15, 2012 at 7:55 AM, Steve Reinhardt <[email protected]> wrote: > From what I can glean from the manual, the address size prefix controls > the size of the "effective address", which in x86 lingo is the segment > offset, not the "linear address", which is post-segmentation but > pre-translation. So I think the only issue here is that we're truncating > the linear address to the effective address size. As long as we're not > bothering with emulating the A20 bit (which I think we shouldn't), then > there's no need to truncate the linear address in real mode. > > I couldn't find anything specific in the documentation on 32-bit code > beyond this assertion: "16-bit and 32-bit applications running in > compatibility mode can access only the low 4GB of the long-mode > virtual-address space. Likewise, a 32-bit address generated in 64-bit mode > can access only the low 4GB of the long-mode virtual-address space." > > So overall I would suggest doing the address calc in two steps, an x86 > effective address calc truncated to the address size (as stored in > addrSize) followed by a linear address calc (addition of the segment base > register) truncated to either 32 or 64 bits depending on the mode. Maybe > we need a linearAddrSize variable to track the second limit? > > Steve > > > On Thu, Mar 15, 2012 at 2:17 AM, Gabriel Michael Black < > [email protected]> wrote: > >> Ok, I see why that's a problem, but now the question is what's the right >> thing to do? In the 16 bit real mode case it would be to truncate the >> address to 16 bits and then add the segment base, but what about, say, the >> 32 bit real mode case when an address size prefix is used and we've >> inherited segment attributes from protected mode (a legal behavior used by >> real BIOSes)? Do we let those addresses spill into bit 33? That same >> problem would apply to 32 bit code in general. What about 32 bit protected >> mode code with an address size prefix (inducing 16 bit addresses) where >> adding in the 16 bit address carries into the 17th bit? If we can determine >> what the rules for address sizes truly are in a broad, ideally >> comprehensive, set of circumstances, then we can figure out what this code >> should actually be doing so it always (or some approximation there of) gets >> the right answer. >> >> Gabe >> >> >> Quoting Nilay Vaish <[email protected]>: >> >> Yasuko, are you saying that the bits() operation below converts the >>> address from 20-bits to a 16-bits? >>> >>> EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); >>> >>> Note that all the addition operations are 64-bit, but the bits() >>> operation will suitably choose the required bits. >>> >>> -- >>> Nilay >>> >>> On Thu, 15 Mar 2012, Watanabe, Yasuko wrote: >>> >>> Hi Gabe, >>>> >>>> Unfortunately, I cannot easily send an example because it is >>>> proprietary code. But I will try to be more specific. >>>> >>>> Macro-op MOV_R_M has the following single micro-op: >>>> Ld req, seg, sib, disp >>>> >>>> In 16-bit mode, seg contains a 20-bit segment-base address, and sib and >>>> disp are used to compute a 16-bit offset. However, when the segment-base >>>> address is added to the offset, it uses 16-bit addition, so the load >>>> address becomes 16 bits, not 20 bits. >>>> >>>> Does this make sense? >>>> >>>> Yasuko >>>> >>>> -----Original Message----- >>>> From: [email protected] >>>> [mailto:gem5-dev-bounces@gem5.**org<[email protected]>] >>>> On Behalf Of Gabriel Michael Black >>>> Sent: Wednesday, March 14, 2012 3:33 AM >>>> To: [email protected] >>>> Subject: Re: [gem5-dev] x86 segmentation support in gem5 >>>> >>>> It would be really helpful if you could send me an example I could run >>>> that demonstrates the problem. >>>> >>>> Gabe >>>> >>>> Quoting "Watanabe, Yasuko" <[email protected]>: >>>> >>>> Hi Gabe, >>>>> >>>>> Let me clarify. Setting a segment-base address is done correctly, as >>>>> you pointed out by the MOV_REAL_* macro-ops. The issue is adding the >>>>> 20-bit base address to a 16-bit address to produce a 20-bit linear >>>>> address when accessing the memory. Specific examples include MOV_R_MI >>>>> and MOV_R_M, just to name a few. >>>>> >>>>> Yasuko >>>>> >>>>> -----Original Message----- >>>>> From: [email protected] >>>>> [mailto:gem5-dev-bounces@gem5.**org<[email protected]> >>>>> ] >>>>> On Behalf Of Gabriel Michael Black >>>>> Sent: Monday, March 12, 2012 11:32 PM >>>>> To: [email protected] >>>>> Subject: Re: [gem5-dev] x86 segmentation support in gem5 >>>>> >>>>> 16 bit real mode and 32 bit legacy mode are already supported, >>>>> although not as well as 64 bit mode. When the address size is 16 bits, >>>>> that's the size of the virtual address from the instruction. >>>>> It's then turned into a linear address by applying segmentation, and >>>>> then a physical address by applying paging. The first of those is done >>>>> by the instruction itself. Paging and the permission checks for >>>>> segmentation and paging are done by the TLB. The 16 bit real mode >>>>> segment base should be used to compute the base added to the virtual >>>>> address by shifting it to the left by 4, as defined by the ISA. >>>>> That's done when the selector is assigned in real mode. See here: >>>>> >>>>> http://repo.gem5.org/gem5/**file/6df06e5975c6/src/arch/** >>>>> x86/isa/insts/gen<http://repo.gem5.org/gem5/file/6df06e5975c6/src/arch/x86/isa/insts/gen> >>>>> eral_purpose/data_transfer/**move.py#l214 >>>>> >>>>> Gabe >>>>> >>>>> Quoting "Watanabe, Yasuko" <[email protected]>: >>>>> >>>>> Hi, >>>>>> >>>>>> I have been working on adding x86 16-bit and 32-bit legacy mode >>>>>> operations. The current infrastructure makes it very hard to compute >>>>>> linear addresses due to segmentation, and I would like to get advice >>>>>> from the gem5 community. >>>>>> >>>>>> Here is the issue. In 16-bit legacy mode, the default effective >>>>>> address size is 16-bits; however, it has to be zero-extended and >>>>>> added to a 16-bit segment-base address that is left-shifted by four >>>>>> bits, producing a 20-bit linear address. My understanding is that >>>>>> gem5 does not differentiate the effective address computation part >>>>>> from the latter part of adding a 20-bit segment-base address. That >>>>>> is, when you specify an address size either in predecoder.cc through >>>>>> emi.addrSize or in the macro-op definition files through addressSize, >>>>>> that size is enforced even to a segment-base address. >>>>>> As a result, in a typical case of 16-bit effective addresses in >>>>>> legacy mode, you are truncating the upper four bits from a >>>>>> segment-base address, getting a wrong 16-bit linear address. >>>>>> >>>>>> I have temporary workarounds but would love to implement a more >>>>>> permanent solution. Please let me know if you have thoughts on this. >>>>>> >>>>>> Thank you, >>>>>> Yasuko >>>>>> >>>>>> ______________________________**_________________ >>>>>> gem5-dev mailing list >>>>>> [email protected] >>>>>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>>>>> >>>>>> >>>>> ______________________________**_________________ >>>>> gem5-dev mailing list >>>>> [email protected] >>>>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>>>> >>>>> >>>>> ______________________________**_________________ >>>>> gem5-dev mailing list >>>>> [email protected] >>>>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>>>> >>>>> >>>> >>>> ______________________________**_________________ >>>> gem5-dev mailing list >>>> [email protected] >>>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>>> >>>> >>>> ______________________________**_________________ >>>> gem5-dev mailing list >>>> [email protected] >>>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>>> >>>> ______________________________**_________________ >>> gem5-dev mailing list >>> [email protected] >>> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >>> >>> >> >> ______________________________**_________________ >> gem5-dev mailing list >> [email protected] >> http://m5sim.org/mailman/**listinfo/gem5-dev<http://m5sim.org/mailman/listinfo/gem5-dev> >> > > _______________________________________________ gem5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/gem5-dev
