123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- #include "u.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "lib.h"
- static int debug;
- static uvlong by2pg; /* hwrpb->by2pg */
- static uvlong pte2pg; /* by2pg/8 */
- static uvlong pgmask; /* by2pg-1 */
- static uvlong ptemask; /* pte2pg-1 */
- static uvlong pgshift; /* log2(by2pg) */
- static uvlong pteshift; /* log2(pte2pg) = pgshift - 3 */
- #define L1(va) (((uvlong)(va)>>3*pteshift+3) & (pte2pg-1))
- #define L2(va) (((uvlong)(va)>>2*pteshift+3) & (pte2pg-1))
- #define L3(va) (((uvlong)(va)>>pgshift) & (pte2pg-1))
- #define OFF(va) (((uvlong)(va)) & (by2pg-1))
- #define V1(l1) (((vlong)l1<<(64-pteshift)) >> 64-(3*pteshift+3))
- #define V2(l2) (((uvlong)l2<<(64-pteshift)) >> 64-(2*pteshift+3))
- #define V3(l3) (((uvlong)l3<<(64-pteshift)) >> 64-pgshift)
- #define VA(l1, l2, l3, off) (V1(l1) | V2(l2) | V3(l3) | (off))
- static int
- log2(uvlong x)
- {
- int i;
- if ((x & (x-1)) == 0)
- for (i = 0; i < 64; i++)
- if (x & (1<<i))
- return i;
- panic("log2: %llux", x);
- return -1;
- }
- void
- mmuinit(void)
- {
- int i;
- uvlong npage, nlvl2, nlvl3;
- uvlong l1p, l2p, lvl2, lvl3;
- extern ulong _main[], edata[];
- /* map entire physical memory at KZERO */
- by2pg = hwrpb->by2pg;
- pte2pg = (by2pg >> 3);
- pgmask = by2pg-1;
- ptemask = pte2pg-1;
- pgshift = log2(by2pg);
- pteshift = pgshift-3;
- l1p = (1LL<<3*pteshift+3)|(1LL<<2*pteshift+3)|(1LL<<pgshift);
- if (rdv(l1p+8*(pte2pg-1)) != 0 || rdv(l1p+8*(pte2pg-2)) != 0)
- panic("KZERO lvl1 already mapped");
- npage = (conf.maxphys+pgmask)>>pgshift;
- nlvl3 = (npage+ptemask)>>pteshift;
- nlvl2 = (nlvl3+ptemask)>>pteshift;
- if (nlvl2 > 1)
- panic("meminit: nlvl2"); /* cannot happen, due to virtual space limitation */
- if (debug)
- print("nlvl1 %llud nlvl2 %llud nlvl3 %llud npage %llud\n", 1LL, nlvl2, nlvl3, npage);
- lvl2 = allocate(nlvl2+nlvl3);
- lvl3 = lvl2 + nlvl2*by2pg;
- wrv(l1p+8*(pte2pg-2), rdv(l1p+8)|PTEASM);
- wrv(l1p+8*(pte2pg-1), (lvl2<<(32-pgshift)) | PTEKVALID | PTEASM);
- l2p = (1LL<<3*pteshift+3)|(1LL<<2*pteshift+3)|((vlong)KZERO >> 2*pteshift)&((1LL<<2*pteshift+3)-1);
- for (i = 0; i < nlvl3; i++)
- stqp(lvl2+(l2p&(by2pg-1))+8*i, ((lvl3+i*by2pg)<<(32-pgshift)) | PTEKVALID | PTEASM);
- for (i = 0; i < npage; i++)
- stqp(lvl3+8*i, ((uvlong)i<<32) | PTEKVALID | PTEASM);
- tlbflush();
- if (debug)
- print("\n");
- }
- uvlong
- paddr(uvlong va)
- {
- uvlong ptbr, x, pte;
- ptbr = getptbr();
- pte = ldqp((ptbr<<pgshift)+8*L1(va));
- if ((pte&PTEKVALID) != PTEKVALID)
- return 0;
- x = ((pte>>32)<<pgshift);
- pte = ldqp(x+8*L2(va));
- if ((pte&PTEKVALID) != PTEKVALID)
- return 0;
- x = ((pte>>32)<<pgshift);
- pte = ldqp(x+8*L3(va));
- if ((pte&PTEKVALID) != PTEKVALID)
- return 0;
- x = ((pte>>32)<<pgshift);
- return x;
- }
- uvlong
- pground(uvlong x)
- {
- return (x+pgmask) & ~pgmask;
- }
|