Corey, I am a little confused about the significance of the row_offset in the i82810 raminit.c.
1. What do you mean by row? Each row of DRAM technologies (Side) or each row of DIMM (Socket)?? Two different things.
/* Set the row offset, in KBytes (should this be * Kbits?). Note that this offset is the start of the * next row. */ row_offset = (dimm_size * 4 * 1024);
2. If this the start of the next row should it be row_offset +1 Kilobyte??
3. Lastly, is row_offset from function spd_set_dram_size supposed show up in sdram_enable?? Wouldn?t we need a:
return row_offset;
At the end of spd_set_dram_size?? For me it just shows as 0?
Thanks - Joe
Joseph Smith wrote:
Corey, I am a little confused about the significance of the row_offset in the i82810 raminit.c.
- What do you mean by row? Each row of DRAM technologies (Side) or
each row of DIMM (Socket)?? Two different things.
/* Set the row offset, in KBytes (should this be
- Kbits?). Note that this offset is the start of the
- next row.
*/ row_offset = (dimm_size * 4 * 1024);
I'm not entirely sure. I think I asked on the mailing list at one point, but never really got a definite answer. I honestly never got around to testing dual sided function at all, I couldn't find any known-good sticks around here, just one very flaky one.
- If this the start of the next row should it be row_offset +1
Kilobyte??
Perhaps I'm a bit too tired, but I don't think so. IIRC, if you have 64mb of ram, ie 65536k, the last address is at 65535 because addressing starts at 0. The next address, at 65536, would be address 0 of the next row. But I could easily be wrong. And I think that if you screw up the addressing, you also screw up the mode register set, so gotta get it right ;)
- Lastly, is row_offset from function spd_set_dram_size supposed show
up in sdram_enable?? Wouldn?t we need a:
return row_offset;
At the end of spd_set_dram_size??
I don't think so, but again I could be wrong. row_offset is declared in sdram_enable then passed along to spd_set_dram_size, which should then be able to modify it. This is one of those "lack of coding experience" situations, where I simply don't know. I really should have checked it, but the cn700 docs were dumped in my lap and it was time to get back to that. I suppose the easiest way to check if this is working correctly or not would be to set row_offset to some arbitrary number at the end of spd_set_dram_size, then dump it to the console after exiting, ie in sdram_enable.
For me it just shows as 0?
Thanks - Joe
Not exactly sure what you mean. Are you dumping it inside spd_set_dram_size or after?
-Corey
Corey, I am a little confused about the significance of the row_offset in the i82810 raminit.c.
- What do you mean by row? Each row of DRAM technologies (Side) or
each row of DIMM (Socket)?? Two different things.
"GMCH supports 4 physical rows of system memory in 2 DIMMs. The width of a row is 64 bits. The DRAM Row Population Register defines the population of each Side of each DIMM." - from IntelĀ® 82810/82810-DC100 (GMCH)
a row in the intel datasheets is always one side of a memory module. one side means: there are single-sided dimms and double sided dimms. you have to configure each side of the memory module in order to make it work correctly. please take a look at my previous post: "Intel DRB HOWTO .. a 1st draft.". i tried to explain how those registers work..on the Intel 430FX. they work the same on every other (intel) chipset, too.
/* Set the row offset, in KBytes (should this be
- Kbits?). Note that this offset is the start of the
- next row.
*/ row_offset = (dimm_size * 4 * 1024);
- If this the start of the next row should it be row_offset +1 Kilobyte??
As Corey already stated: a memory region starts at 0 and ends at regionsize-1. the next memory region starts at regionsize then. example: 1MB = 1*1024*1024 = 1048576 (decimal) = 100000h. the 1MB region would start at 0 and end at 100000h-1 = 0FFFFFh. take a look at the intel datasheet mentioned above, there is a memory map at page 72.
just if someone was wondering: i can provide a sniplet of code that calculates the start address of the current region from the contents of the Intel row offset register for the previous row.
btw. converting between kilobytes and kilobits is just a simple left shift by 3 digits.
i'll restart working on more memory init functions in mid september. my implementation will work without reading any spd data and detect the size of a memory module just by reading/writing data. when i'm done with the socket 7 chipsets, i'll continue with the slot1/s370 ones..hope it won't take too long.
Quoting popkonserve popkonserve@gmx.de:
I am a little confused about the significance of the row_offset in the i82810 raminit.c.
please take a look at my previous post: "Intel DRB HOWTO .. a 1st draft.". i tried to explain how those registers work..on the Intel 430FX. they work the same on every other (intel) chipset, too.
Don't worry Holger, I understand perfectly how the DRB registers work on the i828** chipsets I am just a little confused on how the whole row_offset thing plays into it. I am already able to setup ALL FOUR DRB registers with out it. So, I am questioning if I really need to use it at all. I noticed the i440bx does not use it.....
Thanks - Joe
Hi Joseph, if you get the size of the modules from the SPD you can ignore all offset addressing stuff as long as you don't need to write anything to a specific module row. SPD is a nice thing as it tells you everything you need to set up the northbridge memory controller :) if you would want to write to a special module row you could use code like this to calculate the starting address:
1. assume the DRB stores the size of the memory module row in 4MB granularity. 2. calculate starting address: if (previous_DRB == 0) {starting_address = 0;} else {starting_address = (1<<22)<<(previous_DRB - 1);} 4MB ^^^^^ ^^^^^^^^^^^^^^ no. of additional 4MB portions
the last address of the previous memory row would btw. be: last_address_of_prev_row = starting_address - 1;
i didn't take a look at the code for the i82810 yet, so i'm unaware why and how the row_offset is used. Holger
I am a little confused about the significance of the row_offset in the i82810 raminit.c.
- What do you mean by row? Each row of DRAM technologies (Side) or
each row of DIMM (Socket)?? Two different things.
"GMCH supports 4 physical rows of system memory in 2 DIMMs. The width of a row is 64 bits. The DRAM Row Population Register defines the population of each Side of each DIMM." - from IntelĀ® 82810/82810-DC100 (GMCH)
a row in the intel datasheets is always one side of a memory module.
More common (and way less confusing) terms for "physical row" are "rank" and "chip select" (the latter isn't fully technically correct of course, a rank is what a chip select connects to -- but people use the term anyway and it is obvious what they mean).
Maybe this clears up things a bit -- if the opposite, please ignore :-)
Segher