8 //------------------------------------------------------------------------------
13 #include "ptab_base.h"
24 Htab_entry = 0x00000400, ///< is raw entry of htab
25 Valid = 0x00000004, ///< Valid
26 Pse_bit = 0x00000800, ///< Indicates a super page in hierarch. pgt.
27 Writable = 0x00000002, ///< Writable
28 User = 0x00000001, ///< User accessible
29 Write_through = 0x00000050, ///< Write through
30 Cacheable = 0x00000000, ///< Cache is enabled
31 Cacheable_mask= 0xffffff87,
32 Noncacheable = 0x00000020, ///< Caching is off
33 Referenced = 0x00000100, ///< Page was referenced
34 Dirty = 0x00000080, ///< Page was modified
35 Pfn = 0xfffff000, ///< page frame number
36 // Cpu_global = 0x00000100, ///< pinned in the TLB
37 // L4_global = 0x00000200, ///< pinned in the TLB
41 Pte_ptr(void *p, unsigned char level) : pte((Mword*)p), level(level) {}
43 bool is_valid() const { return *pte & Valid; }
44 void clear() { *pte = 0; }
47 return !is_super_page(); // CHECK!
50 Mword next_level() const
55 void set_next_level(Mword phys)
60 Mword addr() const { return *pte & Pfn;}
61 bool is_super_page() const { return *pte & Pse_bit; }
62 Mword raw() const { return *pte; }
69 class Pt_entry : public Pte_ptr
72 Mword leaf() const { return true; }
73 void set(Address p, bool intermed, bool /*present*/, unsigned long attrs = 0)
76 | (intermed ? (Writable | User) : 0) | attrs;
77 *pte &= intermed ? (Mword)Cacheable_mask : ~0;
81 class Pd_entry : public Pte_ptr
84 Mword leaf() const { return false; }
85 void set(Address p, bool intermed, bool present, unsigned long attrs = 0)
87 *pte = (p & Pfn) | (present ? (Mword)Valid : 0)
88 | (intermed ? (Writable | User) : Pse_bit) | attrs;
89 *pte &= intermed ? (Mword)Cacheable_mask : ~0;
96 Pte_htab(Mword, Mword, Mword);
100 Mword valid : 1; // valid bit
101 Mword vsid :24; // address-space id
102 Mword h : 1; // hash-function bit
103 Mword api : 6; // abbreviated-page index
104 Mword rpn :20; // physical-page numer
105 Mword zero : 3; // reserved
106 Mword r : 1; // referenced bit
107 Mword c : 1; // changed bit
108 Mword wimg : 4; // cache controls
109 Mword zero1 : 1; // reserved
110 Mword pp : 2; // protection bits
119 { return this->pte.valid; }
121 bool inline v_equal(Pte_htab *entry)
122 { return this->raw.raw0 == entry->raw.raw0; }
124 bool inline p_equal(Pte_htab *entry)
125 { return this->raw.raw1 == entry->raw.raw1; }
127 Address inline virt()
128 { return this->raw.raw0; }
130 Address inline phys()
131 { return this->raw.raw1; }
137 typedef Unsigned32 Attribs;
140 Cache_mask = 0x00000078,
141 CACHEABLE = 0x00000000,
142 NONCACHEABLE = 0x00000040,
143 BUFFERED = 0x00000080, //XXX not sure
148 typedef Ptab::List< Ptab::Traits<Unsigned32, 22, 10, true>,
149 Ptab::Traits<Unsigned32, 12, 10, true> > Ptab_traits;
151 typedef Ptab::Shift<Ptab_traits, Virt_addr::Shift>::List Ptab_traits_vpn;
152 typedef Ptab::Page_addr_wrap<Page_number, Virt_addr::Shift> Ptab_va_vpn;
155 IMPLEMENTATION[ppc32]:
159 #include "lock_guard.h"
160 #include "cpu_lock.h"
163 /* this functions do nothing on PPC32 architecture */
166 Paging::canonize(Address addr)
173 Paging::decanonize(Address addr)
178 //---------------------------------------------------------------------------
180 Mword PF::is_translation_error(Mword error)
182 return !(error & 1 << 30) /* DSISR/SRR1 bit 1 */;
185 IMPLEMENT inline NEEDS["msr.h"]
186 Mword PF::is_usermode_error(Mword error)
188 return (error & Msr::Msr_pr);
192 Mword PF::is_read_error(Mword error)
194 return !(error & (1 << 25)) /* DSISR bit 6*/;
198 Mword PF::addr_to_msgword0(Address pfa, Mword error)
201 if(is_translation_error(error))
203 if(!is_read_error(error))
208 //---------------------------------------------------------------------------
213 Pte_base::operator = (Pte_base const &other)
221 Pte_base::operator = (Mword raw)
229 Pte_base::raw() const
237 Pte_ptr::add_attr(Page::Attr attr)
246 //Pte_base::del_attr(Mword attr)
254 Pte_base::writable() const
256 return *pte & Writable;
262 Pte_ptr::is_htab_entry() const
264 return ((*pte & Htab_entry) && !(*pte & Valid));
269 Pte_ptr::to_htab_entry(unsigned page_attribs = 0)
273 return page_attribs & ~Valid;
278 Pte_ptr::is_htab_ptr() const
280 return (*pte & Valid);
285 Pte_ptr::to_htab_ptr()
292 //Pt_entry::pfn() const
297 //------------------------------------------------------------------------------
299 * Hash Page-table entries
301 IMPLEMENT inline NEEDS[Pte_htab::api]
302 Pte_htab::Pte_htab(Address pa, Address ea, Address vsid)
306 this->pte.vsid = vsid;
307 this->pte.api = api(ea);
311 PRIVATE static inline
313 Pte_htab::api(Address ea)
316 return (ea >> 22) & 0x3f;
321 Pte_htab::api_reverse()
323 return this->pte.api << 22;
326 PUBLIC inline NEEDS[Pte_htab::api_reverse, "config.h"]
328 Pte_htab::pte_to_ea()
330 Address pteg = (Address)this;
335 Address va = 0x3ff /*10bit*/ & (this->pte.vsid ^ (pteg >> 6));
336 va <<= Config::PAGE_SHIFT;
337 va |= this->api_reverse();
338 va |= (this->pte.vsid & 0xf) << 28;
345 Pte_htab::addr_to_pte(Address pte_addr)
347 return reinterpret_cast<Pte_htab*>(pte_addr & ~Pte_ptr::Valid);
352 Pte_htab::pte_to_addr(Pte_ptr *e)
356 if (e->is_htab_entry())
360 Pte_htab *pte_phys = addr_to_pte(e->raw());
361 raw = pte_phys->phys();
369 Pte_htab::pte_lookup(Pte_ptr *e, Address *phys = 0,
370 unsigned *page_attribs = 0)
372 auto guard = lock_guard(cpu_lock);
376 if(e->is_htab_entry())
382 Pte_htab *pte = addr_to_pte(e->raw());
391 if(phys) *phys = raw & (~0UL << Config::PAGE_SHIFT);
392 if(page_attribs) *page_attribs = raw;
399 Pte_ptr::need_cache_write_back(bool current_pt)
400 { return current_pt; }
402 PUBLIC inline// NEEDS["mem_unit.h"]
404 Pte_ptr::write_back_if(bool current_pt, Mword /*asid*/ = 0)
408 // Mem_unit::clean_dcache(pte);
411 PUBLIC static inline// NEEDS["mem_unit.h"]
413 Pte_ptr::write_back(void *start, void *end)
414 { (void)start; (void)end; }