7 //------------------------------------------------------------------------------
12 #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
40 Mword addr() const { return _raw & Pfn;}
41 bool is_super_page() const { return _raw & Pse_bit; }
46 class Pt_entry : public Pte_base
49 Mword leaf() const { return true; }
50 void set(Address p, bool intermed, bool /*present*/, unsigned long attrs = 0)
53 | (intermed ? (Writable | User) : 0) | attrs;
54 _raw &= intermed ? (Mword)Cacheable_mask : ~0;
58 class Pd_entry : public Pte_base
61 Mword leaf() const { return false; }
62 void set(Address p, bool intermed, bool present, unsigned long attrs = 0)
64 _raw = (p & Pfn) | (present ? (Mword)Valid : 0)
65 | (intermed ? (Writable | User) : Pse_bit) | attrs;
66 _raw &= intermed ? (Mword)Cacheable_mask : ~0;
72 Pte_htab(Mword, Mword, Mword);
76 Mword valid : 1; // valid bit
77 Mword vsid :24; // address-space id
78 Mword h : 1; // hash-function bit
79 Mword api : 6; // abbreviated-page index
80 Mword rpn :20; // physical-page numer
81 Mword zero : 3; // reserved
82 Mword r : 1; // referenced bit
83 Mword c : 1; // changed bit
84 Mword wimg : 4; // cache controls
85 Mword zero1 : 1; // reserved
86 Mword pp : 2; // protection bits
95 { return this->pte.valid; }
97 bool inline v_equal(Pte_htab *entry)
98 { return this->raw.raw0 == entry->raw.raw0; }
100 bool inline p_equal(Pte_htab *entry)
101 { return this->raw.raw1 == entry->raw.raw1; }
103 Address inline virt()
104 { return this->raw.raw0; }
106 Address inline phys()
107 { return this->raw.raw1; }
112 typedef Unsigned32 Attribs;
115 KERN_RW = 0x00000000,
116 USER_RO = 0x00000001,
117 USER_RW = 0x00000002,
118 Cache_mask = 0x00000078,
119 CACHEABLE = 0x00000000,
120 NONCACHEABLE = 0x00000040,
121 BUFFERED = 0x00000080, //XXX not sure
126 typedef Ptab::List< Ptab::Traits<Pd_entry, 22, 10, true>,
127 Ptab::Traits<Pt_entry, 12, 10, true> > Ptab_traits;
129 typedef Ptab::Shift<Ptab_traits, Virt_addr::Shift>::List Ptab_traits_vpn;
130 typedef Ptab::Page_addr_wrap<Page_number, Virt_addr::Shift> Ptab_va_vpn;
133 IMPLEMENTATION[ppc32]:
137 #include "lock_guard.h"
138 #include "cpu_lock.h"
141 /* this functions do nothing on PPC32 architecture */
144 Paging::canonize(Address addr)
151 Paging::decanonize(Address addr)
156 //---------------------------------------------------------------------------
158 Mword PF::is_translation_error(Mword error)
160 return !(error & 1 << 30) /* DSISR/SRR1 bit 1 */;
163 IMPLEMENT inline NEEDS["msr.h"]
164 Mword PF::is_usermode_error(Mword error)
166 return (error & Msr::Msr_pr);
170 Mword PF::is_read_error(Mword error)
172 return !(error & (1 << 25)) /* DSISR bit 6*/;
176 Mword PF::addr_to_msgword0(Address pfa, Mword error)
179 if(is_translation_error(error))
181 if(!is_read_error(error))
186 //---------------------------------------------------------------------------
189 Pte_base::Pte_base(Mword raw) : _raw(raw) {}
192 Pte_base::Pte_base() {}
196 Pte_base::operator = (Pte_base const &other)
204 Pte_base::operator = (Mword raw)
212 Pte_base::raw() const
219 Pte_base::add_attr(Mword attr)
226 Pte_base::del_attr(Mword attr)
238 Pte_base::valid() const
241 _raw & Valid || is_htab_entry();
246 Pte_base::writable() const
248 return _raw & Writable;
253 Pte_base::is_htab_entry() const
255 return ((_raw & Htab_entry) && !(_raw & Valid));
260 Pte_base::to_htab_entry(unsigned page_attribs = 0)
264 return page_attribs & ~Valid;
269 Pte_base::is_htab_ptr() const
271 return (_raw & Valid);
276 Pte_base::to_htab_ptr()
283 Pt_entry::pfn() const
288 //------------------------------------------------------------------------------
290 * Hash Page-table entries
292 IMPLEMENT inline NEEDS[Pte_htab::api]
293 Pte_htab::Pte_htab(Address pa, Address ea, Address vsid)
297 this->pte.vsid = vsid;
298 this->pte.api = api(ea);
302 PRIVATE static inline
304 Pte_htab::api(Address ea)
307 return (ea >> 22) & 0x3f;
312 Pte_htab::api_reverse()
314 return this->pte.api << 22;
317 PUBLIC inline NEEDS[Pte_htab::api_reverse, "config.h"]
319 Pte_htab::pte_to_ea()
321 Address pteg = (Address)this;
326 Address va = 0x3ff /*10bit*/ & (this->pte.vsid ^ (pteg >> 6));
327 va <<= Config::PAGE_SHIFT;
328 va |= this->api_reverse();
329 va |= (this->pte.vsid & 0xf) << 28;
336 Pte_htab::addr_to_pte(Address pte_addr)
338 return reinterpret_cast<Pte_htab*>(pte_addr & ~Pte_base::Valid);
343 Pte_htab::pte_to_addr(Pte_base *e)
347 if(e->is_htab_entry())
351 Pte_htab *pte_phys = addr_to_pte(e->raw());
352 raw = pte_phys->phys();
360 Pte_htab::pte_lookup(Pte_base *e, Address *phys = 0,
361 unsigned *page_attribs = 0)
363 auto guard = lock_guard(cpu_lock);
367 if(e->is_htab_entry())
373 Pte_htab *pte = addr_to_pte(e->raw());
382 if(phys) *phys = raw & (~0UL << Config::PAGE_SHIFT);
383 if(page_attribs) *page_attribs = raw;