mtrr
mtrr
Could anyone help me again please?
Guys I´ve been trying to understand intel manual, chapter 11:11 that says about mtrr
I´m trying to set memory regions, like from 0 to 64 set as writeback,
from vesa memory set as writecombining,
but I expending to much time trying to understand
Caches 0-64 MByte as WB cache type.
IA32_MTRR_PHYSBASE0 = 0000 0000 0000 0006H <- this I understand, everyting ok!
IA32_MTRR_PHYSMASK0 = 0000 000F FC00 0800H <- this is odd to me, how to calc that mask, intel doen´t says that,
it just says that for that memory address that mask is need it..
this is an example from intel manual, chapter 11:11
could anyone help me please ?
Guys I´ve been trying to understand intel manual, chapter 11:11 that says about mtrr
I´m trying to set memory regions, like from 0 to 64 set as writeback,
from vesa memory set as writecombining,
but I expending to much time trying to understand
Caches 0-64 MByte as WB cache type.
IA32_MTRR_PHYSBASE0 = 0000 0000 0000 0006H <- this I understand, everyting ok!
IA32_MTRR_PHYSMASK0 = 0000 000F FC00 0800H <- this is odd to me, how to calc that mask, intel doen´t says that,
it just says that for that memory address that mask is need it..
this is an example from intel manual, chapter 11:11
could anyone help me please ?
-
- Member
- Posts: 255
- Joined: Tue Jun 15, 2010 9:27 am
- Location: Flyover State, United States
- Contact:
Re: mtrr
In case others didn't know which volume he is talking about, it is 3A (Systems Programming). Check out figure 11-7 in section 11.11.2.3, which describes the structure of the IA32_MTRR_PHYSBASEn and IA32_MTRR_PHYSMASKn registers. In brief, bits 0-10 of the PHYSMASK are reserved, bit 11 marks whether it is valid, bits 12 to MAXPHYSADDR set the range mask, and all other bits are reserved.
Re: mtrr
this is kinda of how many memory I want to set ? " bits 12 to MAXPHYSADDR set the range mask "
something like
physbase = 0x200 = " 0x200000"
physmask = 0xfffe = " 1048575 kb"
is like that ? sorry if this question is kinda of stupid, I´m trying to learn reading reading, then asking asking for help,
something like
physbase = 0x200 = " 0x200000"
physmask = 0xfffe = " 1048575 kb"
is like that ? sorry if this question is kinda of stupid, I´m trying to learn reading reading, then asking asking for help,
-
- Member
- Posts: 255
- Joined: Tue Jun 15, 2010 9:27 am
- Location: Flyover State, United States
- Contact:
Re: mtrr
I actually have no idea since I've never messed with the MTRRs. I just searched the manual for the relevant sections, and only glanced at it.
From looking at it again, the PHYSMASK field doesn't seem to set the amount of memory mapped per se, but rather the extent of the range. It allows for discontinuous ranges, although the manually specifically warns against using them. In the example mapping section, the important distinction of the PHYSMASK field is:
I would go into detail on how to calculate PHYSMASK, but I am really tired right now and can't think straight.
From looking at it again, the PHYSMASK field doesn't seem to set the amount of memory mapped per se, but rather the extent of the range. It allows for discontinuous ranges, although the manually specifically warns against using them. In the example mapping section, the important distinction of the PHYSMASK field is:
So let's say you have a memory location named "addr." Then the following equation holds:This mask is chosen so that when any address in the 200000H to 3FFFFFH range is AND’d with the mask
value, it will return the same value as when the base address is AND’d with the mask value (which is 200000H).
Code: Select all
addr & PHYSMASK = PHYSBASE & PHYSMASK
Re: mtrr
my big problem is my english, is so poor, this is why I have to much problem trying to understand some code.
example in the intel manual it says:
This mask is chosen so
that when any address in the 200000H to 3FFFFFH range is AND’d with the mask
value, it will return the same value as when the base address is AND’d with the mask
value (which is 200000H).
what this means ? "AND’d " ???
please
example in the intel manual it says:
This mask is chosen so
that when any address in the 200000H to 3FFFFFH range is AND’d with the mask
value, it will return the same value as when the base address is AND’d with the mask
value (which is 200000H).
what this means ? "AND’d " ???
please
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: mtrr
It serves to make a verb of a noun: You have been Bewing'd (I prefer the 'd because the "regular" Bewinged can be ambiguously interpreted as be-winged rather than bewing-ed, and the same for some other cases)
But I consider it rather elementary English to strip the past or perfect tense from a regular verb (A kiss, to kiss, I kissed; The Rickroll, to Rickroll, I was Rickroll'd)
But I consider it rather elementary English to strip the past or perfect tense from a regular verb (A kiss, to kiss, I kissed; The Rickroll, to Rickroll, I was Rickroll'd)
Re: mtrr
Hi,
It's worth noting here that it is impossible to cover some address ranges with a single variable MTTR. To be able to cover an address range with one variable MTTR, the base address of that range must be on a "size of the range" boundary and the size of the range must be a power of 2. For example, a 2 MiB address range would have to be on a 2 MiB boundary, a 4 KiB address range would have to be on a 4 KiB boundary, etc.
If the size of the range is a power of 2 and the base address of the range is on a "size of the range" boundary; then the calculation is simple:
If the size of the range is not a power of 2, or if the base address of the range is not on a "size of the range" boundary; then you have to split it up into multiple ranges that are. This can be tricky.
For an example, imagine you've got 56 KiB area at 0xA8642000. To start with the size of the area isn't a power of 2, so you need to split it up into smaller areas that are a power of 2. The largest area would be 32 KiB (which leaves you with 24 KiB that still needs splitting up), the next area would be 16 KiB and the last area would be 8 KiB. The 32 KiB area can't use "base address 0xA8642000" because it's not aligned, and neither can the 16 KiB area. The 8 KiB area can though. If the 16 KiB area placed directly above that, and the 32 KiB area is directly above that, then it all works. You end up with:
1st: 8 KiB from 0xA8642000 to 0xA8643FFF (MTRR_base = 0xA8642000, MTTR_mask = 0xFFFFE000)
2nd: 16 KiB from 0xA8644000 to 0xA8647FFF (MTRR_base = 0xA8644000, MTTR_mask = 0xFFFFC000)
3rd: 32 KiB from 0xA8648000 to 0xA864FFFF (MTRR_base = 0xA8648000, MTTR_mask = 0xFFFF8000)
What if there's a 56 KiB area at 0xE0000000? In that case you'd still need to split it into 3 areas, but the largest area can go first, and you'd end up with:
1st: 32 KiB from 0xE0000000 to 0xE0007FFF (MTRR_base = 0xE0000000, MTTR_mask = 0xFFFF8000)
2nd: 16 KiB from 0xE0008000 to 0xE000BFFF (MTRR_base = 0xE0008000, MTTR_mask = 0xFFFFC000)
3rd: 8 KiB from 0xE000C000 to 0xA8643FFF (MTRR_base = 0xE000C000, MTTR_mask = 0xFFFFE000)
However, this is a special case; where you may be able to do it more efficiently by having one area that is "too large" and another area to correct the wrong part. For the area that is too large, you'd round up to the nearest power of 2 and get a 64 KiB area. This is 8 KiB larger than it should be, so you can create a second area that says "ignore the first MTTR, this 8 KiB is uncachable". The result might look like this:
1st: 64 KiB from 0xE0000000 to 0xE000FFFF (MTRR_base = 0xE0000000, MTTR_mask = 0xFFFF0000) - "write through"
2nd: 8 KiB from 0xE000E000 to 0xE000FFFF (MTRR_base = 0xE000E000, MTTR_mask = 0xFFFFE000) - "uncachable"
This only works in some cases though - that second area must be "uncachable", and (if I remember right) the first area can't be "write combining". It'd be best to look up the details in Intel's manual if you're considering this..
Fortunately, the PCI specifications have restrictions that device manufacturers have to follow for memory mapped IO areas; and these restrictions happen to be virtually the same as the MTRR restrictions. This means that for memory mapped PCI areas you'll only need one MTTR; and the only case where you need to use more than one is for RAM (which the firmware would've already done for you).
Cheers,
Brendan
You could convert that paragraph directly into C code:digo_rp wrote:example in the intel manual it says:
This mask is chosen so
that when any address in the 200000H to 3FFFFFH range is AND’d with the mask
value, it will return the same value as when the base address is AND’d with the mask
value (which is 200000H).
Code: Select all
if( (address & MTTR_MASK) == MTTR_BASE) { /* MTRR effects this access */ }
If the size of the range is a power of 2 and the base address of the range is on a "size of the range" boundary; then the calculation is simple:
Code: Select all
MTRR_MASK = ~(size_of_range)
For an example, imagine you've got 56 KiB area at 0xA8642000. To start with the size of the area isn't a power of 2, so you need to split it up into smaller areas that are a power of 2. The largest area would be 32 KiB (which leaves you with 24 KiB that still needs splitting up), the next area would be 16 KiB and the last area would be 8 KiB. The 32 KiB area can't use "base address 0xA8642000" because it's not aligned, and neither can the 16 KiB area. The 8 KiB area can though. If the 16 KiB area placed directly above that, and the 32 KiB area is directly above that, then it all works. You end up with:
1st: 8 KiB from 0xA8642000 to 0xA8643FFF (MTRR_base = 0xA8642000, MTTR_mask = 0xFFFFE000)
2nd: 16 KiB from 0xA8644000 to 0xA8647FFF (MTRR_base = 0xA8644000, MTTR_mask = 0xFFFFC000)
3rd: 32 KiB from 0xA8648000 to 0xA864FFFF (MTRR_base = 0xA8648000, MTTR_mask = 0xFFFF8000)
What if there's a 56 KiB area at 0xE0000000? In that case you'd still need to split it into 3 areas, but the largest area can go first, and you'd end up with:
1st: 32 KiB from 0xE0000000 to 0xE0007FFF (MTRR_base = 0xE0000000, MTTR_mask = 0xFFFF8000)
2nd: 16 KiB from 0xE0008000 to 0xE000BFFF (MTRR_base = 0xE0008000, MTTR_mask = 0xFFFFC000)
3rd: 8 KiB from 0xE000C000 to 0xA8643FFF (MTRR_base = 0xE000C000, MTTR_mask = 0xFFFFE000)
However, this is a special case; where you may be able to do it more efficiently by having one area that is "too large" and another area to correct the wrong part. For the area that is too large, you'd round up to the nearest power of 2 and get a 64 KiB area. This is 8 KiB larger than it should be, so you can create a second area that says "ignore the first MTTR, this 8 KiB is uncachable". The result might look like this:
1st: 64 KiB from 0xE0000000 to 0xE000FFFF (MTRR_base = 0xE0000000, MTTR_mask = 0xFFFF0000) - "write through"
2nd: 8 KiB from 0xE000E000 to 0xE000FFFF (MTRR_base = 0xE000E000, MTTR_mask = 0xFFFFE000) - "uncachable"
This only works in some cases though - that second area must be "uncachable", and (if I remember right) the first area can't be "write combining". It'd be best to look up the details in Intel's manual if you're considering this..
Fortunately, the PCI specifications have restrictions that device manufacturers have to follow for memory mapped IO areas; and these restrictions happen to be virtually the same as the MTRR restrictions. This means that for memory mapped PCI areas you'll only need one MTTR; and the only case where you need to use more than one is for RAM (which the firmware would've already done for you).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: mtrr
Brendan, for example:
I want to set as write-combining the vesa frame buffer that is at this case 0xC0000000
how do I get mask for that address? so sorry for this question again, some cases I have some problem
understanding some explanations in english... I´m learning english too
please could you help me ?
I want to set as write-combining the vesa frame buffer that is at this case 0xC0000000
how do I get mask for that address? so sorry for this question again, some cases I have some problem
understanding some explanations in english... I´m learning english too
please could you help me ?
Re: mtrr
Guys I found a good way to calculate the physmask this I found from google
PhysMask and PhysBase Values. Software can calculate the PhysMask value using the following procedure:
1. Substract the memory-range physical base-address from the upper physical-address of the memory range.
2. Substract the value calculated in Step 1 from the physical memory size.
3. Truncate the lower 12 bits of the result in Step 2 to create the PhysMask value to be loaded into the MTRRphysMaskn register.
Truncation is performed by right-shifting the value 12 bits.
For example, assume a 32-Mbyte memory range is specified within the 52-bit physical address space, starting at address 200_0000h.
The upper address of the range is 3FF_FFFFh.
Following the process outlined above yields:
1. 3FF_FFFFh-200_0000h = 1FF_FFFFh
2. F_FFFF_FFFF_FFFFh-1_FF_FFFFh = F_FFFF_FE00_0000h
3. Right shift (F_FFFF_FE00_0000h) by 12 = FF_FFFF_E000h
In this example, the 40-bit value loaded into the PhysMask field is FF_FFFF_E000h.
Software must also truncate the lower 12 bits of the physical base address before loading it into the PhysBase field.
In the example above, the 40-bit PhysBase field is 00_0000_2000h
PhysMask and PhysBase Values. Software can calculate the PhysMask value using the following procedure:
1. Substract the memory-range physical base-address from the upper physical-address of the memory range.
2. Substract the value calculated in Step 1 from the physical memory size.
3. Truncate the lower 12 bits of the result in Step 2 to create the PhysMask value to be loaded into the MTRRphysMaskn register.
Truncation is performed by right-shifting the value 12 bits.
For example, assume a 32-Mbyte memory range is specified within the 52-bit physical address space, starting at address 200_0000h.
The upper address of the range is 3FF_FFFFh.
Following the process outlined above yields:
1. 3FF_FFFFh-200_0000h = 1FF_FFFFh
2. F_FFFF_FFFF_FFFFh-1_FF_FFFFh = F_FFFF_FE00_0000h
3. Right shift (F_FFFF_FE00_0000h) by 12 = FF_FFFF_E000h
In this example, the 40-bit value loaded into the PhysMask field is FF_FFFF_E000h.
Software must also truncate the lower 12 bits of the physical base address before loading it into the PhysBase field.
In the example above, the 40-bit PhysBase field is 00_0000_2000h
Re: mtrr
FTFY.This mask is chosen so
that when any address in the 200000H to 3FFFFFH range is logically conjugated with the mask
value, it will return the same value as when the base address is logically conjugated with the mask
value (which is 200000H).