On Sat, Apr 19, 2003 at 05:32:50AM +0000, Erik J. Green wrote: > I *think* I understand how the TLB translates addresses for ckseg2 in mips64. > Can someone tell me if my understanding is correct? > > Given: Physical memory starts at 0x0000000020004000; > > Therefore, an offset 0x2000 from the start of physical memory should be at > > 0x0000000020006000, or 0xa000000020006000 as a 64 bit xkphys address. > > So if I construct a TLB entry such that cp0_entryhi is 0xffffffffc0002000, and > cp0_entrylo0 has a PFN address of 0x0000000020006, giving it the correct ASID > (0) and valid bitflags(VG), I should be able to access the physical memory > offset above using the ckseg2 virtual address 0xffffffffc0002000? You also want to set the dirty flag or otherwise the page is not writable. Which page size have you been using? The physical address must be a multiple of the page size of the page and the virtual address must be a multiple of the double of the page size of entry - remember that each TLB entry maps a pair of adjacent pages! The entrylo value is computed by shifting the physical address right by 6 bits then inserting the right flag bits into the low 6 bits. In your case you want to set the valid, dirty and global bits. You also need to set the 3 coherency bits. We want cachable coherent, the same mode as used in the 0xa8... portion of XKPHYS. So we set them to 5. So: c0_entrylo0 = (phyaddr >> 6) | cacheable_coherent | dirty | valid | global c0_entrylo0 = 0x800180 | 0x28 | 0x4 | 0x2 | 0x1 c0_entrylo0 = 0x8001af An extra word about the global bit - there exists only one global bit in the TLB entry though both c0_entrylo0 and c0_entrylo1 have a global bit. The way this works is that the global bit of the TLB entry is written as tlb[entry].g = (c0_entrylo0.g & c0_entrylo1.g) when writing an entry and when read is copied into both entrylo global bits. In other words writing a TLB entry with only one of the G bits in the entrylo register pair set will result in a TLB entry with the G bit cleared. For your example this means: c0_entryhi = 0xc0000000:00002000 c0_entrylo0 = 0x00000000:008001af c0_entrylo1 = 0x00000000:00000001 c0_pagemask = 0x00000000 # 4kB pages c0_framemask = 0x00000000 c0_index = 0x00000000 c0_wired = 0x00000001 tlbwi would generated the mapping and make sure the entry won't be overwritten by random TLB writes. > Of course, the reason I discuss all this is that the above doesn't work. =) Every Linux port has started in a state as advanced as where you are so keep up :-) Ralf