public PmemStack(PhysMem _pmem, nuint paddrbase, nuint len, nuint _ssize = 4096) { pmem = _pmem; ssize = _ssize; // Calculate start addresse and length for the ring buffer structure nuint sbasep = paddrbase; nuint slen = len / _ssize * (nuint)sizeof(nuint); // Create the ring buffer rbs = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(sbasep, slen, 0, 0).vaddr, (int)slen); // Add the pages nuint x = slen + sbasep; x = util.align(x, ssize); StartAddr = x; Length = len - (x - paddrbase); while (x + ssize <= paddrbase + len) { rbs.Enqueue(x); x += ssize; } }
public PmemBitmap(PhysMem _pmem, nuint paddrbase, nuint len, nuint _ssize = 4096) { pmem = _pmem; ssize = _ssize; // Calculate the size of the bitmap bcount = (ulong)len / ssize; ucount = util.align(bcount, 64) / 64; // Zero out the array bmp = (ulong *)pmem.vmem.Map(paddrbase, bcount, 0, 0).vaddr; for (ulong i = 0; i < ucount; i++) { bmp[i] = 0UL; } // Add the used pages var x = util.align(paddrbase + ucount * 8, ssize); StartAddr = x; Length = len - (x - paddrbase); baddr = util.align(paddrbase, ssize); while (x + ssize <= (ulong)paddrbase + (ulong)len) { var bit_idx = (x - baddr) / ssize; var uidx = bit_idx / 64; var bidx = bit_idx % 64; bmp[uidx] |= (1UL) << (int)bidx; x += ssize; } }
public PmemTwoLevelStack(PhysMem _pmem, nuint paddrbase, nuint len, nuint _ssize = 4096, nuint _lsize = 2048 * 1024) { pmem = _pmem; ssize = _ssize; lsize = _lsize; // Calculate start addresses and lengths for the ring buffer structure nuint sbasep = paddrbase; nuint slen = len / _ssize * (nuint)sizeof(nuint); nuint lbasep = sbasep + slen; nuint llen = len / _lsize * (nuint)sizeof(nuint); // Create the ring buffers rbs = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(sbasep, slen, 0, 0).vaddr, (int)slen); rbl = new Collections.RingBuffer <nuint>((void *)pmem.vmem.Map(lbasep, llen, 0, 0).vaddr, (int)llen); // Add the pages, use small pages at either end and then large pages in the middle nuint x = llen + lbasep; x = util.align(x, ssize); StartAddr = x; Length = len - (x - paddrbase); // This assumes page sizes are powers of 2 var lmask = lsize - 1; // Small pages at start while ((x & lmask) != 0 & (x + ssize <= paddrbase + len)) { rbs.Enqueue(x); x += ssize; } // Large pages in middle while (x + lsize <= paddrbase + len) { rbl.Enqueue(x); x += lsize; } // Small pages at end while (x + ssize <= paddrbase + len) { rbs.Enqueue(x); x += ssize; } // Debug Formatter.Write("PmemTwoLevelStack: rbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbs.Count, Program.arch.DebugOutput); Formatter.Write(", lbs count ", Program.arch.DebugOutput); Formatter.Write((ulong)rbl.Count, Program.arch.DebugOutput); Formatter.WriteLine(Program.arch.DebugOutput); }