===================================================================
@@ -2936,7 +2936,11 @@ void flush_tlb_kernel_range(unsigned lon
}
if (end > HI_OBP_ADDRESS) {
flush_tsb_kernel_range(HI_OBP_ADDRESS, end);
+ printk(KERN_ERR "INIT[%s:%d]: DEBUG flush_tlb_kernel_range about to call long do_flush_tlb_kernel_range...\n",
+ current->comm, current->pid);
do_flush_tlb_kernel_range(HI_OBP_ADDRESS, end);
+ printk(KERN_ERR "INIT[%s:%d]: DEBUG flush_tlb_kernel_range ended call to long do_flush_tlb_kernel_range!\n",
+ current->comm, current->pid);
}
} else {
flush_tsb_kernel_range(start, end);
===================================================================
@@ -14,6 +14,9 @@
#include <asm/tlb.h>
#include <asm/oplib.h>
+#define _ALIGN_UP(addr, size) __ALIGN_KERNEL(addr, size)
+#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
+
extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES];
static inline unsigned long tsb_hash(unsigned long vaddr, unsigned long hash_shift, unsigned long nentries)
@@ -32,10 +35,13 @@ static inline int tag_compare(unsigned l
* Only the TLB flush needs that treatment.
*/
-void flush_tsb_kernel_range(unsigned long start, unsigned long end)
+static void __flush_tsb_kernel_range_short(unsigned long start, unsigned long end)
{
unsigned long v;
+ printk(KERN_ERR "TSB[%s:%d]: DEBUG __flush_tsb_kernel_range_short start=%016lx end=%016lx PAGE_SIZE=%lx\n",
+ current->comm, current->pid, start, end, (unsigned long) PAGE_SIZE);
+
for (v = start; v < end; v += PAGE_SIZE) {
unsigned long hash = tsb_hash(v, PAGE_SHIFT,
KERNEL_TSB_NENTRIES);
@@ -46,6 +52,42 @@ void flush_tsb_kernel_range(unsigned lon
}
}
+static void __flush_tsb_kernel_range_block(unsigned long start, unsigned long end)
+{
+ unsigned long i;
+
+ printk(KERN_ERR "TSB[%s:%d]: DEBUG __flush_tsb_kernel_range_block start=%016lx end=%016lx PAGE_SIZE=%lx\n",
+ current->comm, current->pid, start, end, (unsigned long) PAGE_SIZE);
+
+ for (i = 0; i < KERNEL_TSB_NENTRIES; i++) {
+ struct tsb *ent = &swapper_tsb[i];
+ unsigned long vaddr_block = (ent->tag << 22);
+ if (start <= vaddr_block &&
+ vaddr_block < end &&
+ tag_compare(ent->tag, vaddr_block))
+ ent->tag = (1UL << TSB_TAG_INVALID_BIT);
+ }
+}
+
+void flush_tsb_kernel_range(unsigned long start, unsigned long end)
+{
+ unsigned long start_block, end_block;
+
+ printk(KERN_ERR "TSB[%s:%d]: DEBUG flush_tsb_kernel_range start=%016lx end=%016lx PAGE_SIZE=%lx\n",
+ current->comm, current->pid, start, end, (unsigned long) PAGE_SIZE);
+
+ start_block = _ALIGN_UP(start, 1 << 22);
+ end_block = _ALIGN_DOWN(end, 1 << 22);
+
+ if (start_block < end_block) {
+ __flush_tsb_kernel_range_short(start, start_block);
+ __flush_tsb_kernel_range_block(start_block, end_block);
+ __flush_tsb_kernel_range_short(end_block, end);
+ } else {
+ __flush_tsb_kernel_range_short(start, end);
+ }
+}
+
static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v,
unsigned long hash_shift,
unsigned long nentries)