All of lore.kernel.org
 help / color / mirror / Atom feed
* PATCH
@ 2004-10-11  0:01 Pete Popov
  2004-10-11  0:32 ` PATCH Maciej W. Rozycki
  0 siblings, 1 reply; 77+ messages in thread
From: Pete Popov @ 2004-10-11  0:01 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips@linux-mips.org

Ralf,

Sorry, one more update to the 36 bit patch. The only difference is that
I removed the hunk that updates arch/mips/au1000/common/setup.c because
I'll apply that part myself, and then make other updates to setup.c that
would then conflict with the patch I sent you. This is the final version
you can apply ;)

Pete


Index: arch/mips/mm/Makefile
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/Makefile,v
retrieving revision 1.68
diff -u -r1.68 Makefile
--- arch/mips/mm/Makefile	20 Jun 2004 23:52:17 -0000	1.68
+++ arch/mips/mm/Makefile	19 Sep 2004 22:51:21 -0000
@@ -41,10 +41,11 @@
 obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-r4k.o
+obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
 obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
+obj-$(CONFIG_64BIT_PHYS_ADDR)	+= remap.o
 endif
 ifdef CONFIG_MIPS64
 obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o tlbex64-r4k.o
Index: arch/mips/mm/ioremap.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/ioremap.c,v
retrieving revision 1.19
diff -u -r1.19 ioremap.c
--- arch/mips/mm/ioremap.c	19 Apr 2004 16:36:35 -0000	1.19
+++ arch/mips/mm/ioremap.c	19 Sep 2004 22:51:21 -0000
@@ -97,6 +97,15 @@
 }
 
 /*
+ * Allow physical addresses to be fixed up to help 36 bit peripherals.
+ */
+phys_t __attribute__ ((weak))
+fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+/*
  * Generic mapping function (not visible outside):
  */
 
@@ -110,7 +119,7 @@
  * caller shouldn't need to know that small detail.
  */
 
-#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL))
+#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
 
 void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 {
@@ -119,6 +128,8 @@
 	phys_t last_addr;
 	void * addr;
 
+	phys_addr = fixup_bigphys_addr(phys_addr, size);
+
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
 	if (!size || last_addr < phys_addr)
@@ -190,3 +201,4 @@
 
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(fixup_bigphys_addr);
Index: arch/mips/mm/remap.c
===================================================================
RCS file: arch/mips/mm/remap.c
diff -N arch/mips/mm/remap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/remap.c	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,115 @@
+/*
+ *  arch/mips/mm/remap.c
+ *
+ *  A copy of mm/memory.c, with mods for 64 bit physical I/O addresses on
+ *  32 bit native word platforms.
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ */
+
+
+#include <linux/kernel_stat.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/rmap.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <linux/swapops.h>
+#include <linux/elf.h>
+
+
+/*
+ * maps a range of physical memory into the requested pages. the old
+ * mappings are removed. any references to nonexistent pages results
+ * in null mappings (currently treated as "copy-on-access")
+ */
+static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long end;
+	unsigned long pfn;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		BUG_ON(!pte_none(*pte));
+		if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
+ 			set_pte(pte, pfn_pte(pfn, prot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long base, end;
+
+	base = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	do {
+		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
+		if (!pte)
+			return -ENOMEM;
+		remap_pte_range(pte, base + address, end - address, address + phys_addr, prot);
+		pte_unmap(pte);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+/*  Note: this is only safe if the mm semaphore is held when called. */
+int remap_page_range_high(struct vm_area_struct *vma, unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	int error = 0;
+	pgd_t * dir;
+	unsigned long beg = from;
+	unsigned long end = from + size;
+	struct mm_struct *mm = vma->vm_mm;
+
+	phys_addr -= from;
+	dir = pgd_offset(mm, from);
+	flush_cache_range(vma, beg, end);
+	if (from >= end)
+		BUG();
+
+	spin_lock(&mm->page_table_lock);
+	do {
+		pmd_t *pmd = pmd_alloc(mm, dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (from && (from < end));
+	/*
+	 * Why flush? remap_pte_range has a BUG_ON for !pte_none()
+	 */
+	flush_tlb_range(vma, beg, end);
+	spin_unlock(&mm->page_table_lock);
+	return error;
+}
+
+EXPORT_SYMBOL(remap_page_range_high);
Index: arch/mips/mm/tlb-r4k.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/tlb-r4k.c,v
retrieving revision 1.38
diff -u -r1.38 tlb-r4k.c
--- arch/mips/mm/tlb-r4k.c	19 Mar 2004 04:07:59 -0000	1.38
+++ arch/mips/mm/tlb-r4k.c	19 Sep 2004 22:51:21 -0000
@@ -255,8 +255,14 @@
 	idx = read_c0_index();
 	ptep = pte_offset_map(pmdp, address);
 
-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
-	write_c0_entrylo1(pte_val(*ptep) >> 6);
+ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ 	write_c0_entrylo0(ptep->pte_high);
+ 	ptep++;
+ 	write_c0_entrylo1(ptep->pte_high);
+#else
+  	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+  	write_c0_entrylo1(pte_val(*ptep) >> 6);
+#endif
 	write_c0_entryhi(address | pid);
 	mtc0_tlbw_hazard();
 	if (idx < 0)
Index: arch/mips/mm/tlbex32-mips32.S
===================================================================
RCS file: arch/mips/mm/tlbex32-mips32.S
diff -N arch/mips/mm/tlbex32-mips32.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/tlbex32-mips32.S	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,325 @@
+/*
+ * TLB exception handling code for MIPS32 CPUs.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-cpu abstraction and reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Pete Popov, ppopov@pacbell.net
+ * Added 36 bit phys address support.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+
+/* We really only support 36 bit physical addresses on MIPS32 */
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
+#define PTE_SIZE        8
+#define PTEP_INDX_MSK	0xff0
+#define PTE_INDX_MSK	0xff8
+#define PTE_INDX_SHIFT 9
+#define CONVERT_PTE(pte)
+#define PTE_MAKEWRITE_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#define PTE_MAKEVALID_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, pte, _PAGE_VALID; \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#else
+
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        0
+#define PTE_SIZE	4
+#define PTEP_INDX_MSK	0xff8
+#define PTE_INDX_MSK	0xffc
+#define PTE_INDX_SHIFT	10
+#define CONVERT_PTE(pte) srl pte, pte, 6
+#define PTE_MAKEWRITE_HIGH(pte, ptr)
+#define PTE_MAKEVALID_HIGH(pte, ptr)
+
+#endif  /* CONFIG_64BIT_PHYS_ADDR */
+
+	__INIT
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define GET_PTE_OFF(reg)
+#else
+#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+#endif
+
+/*	
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, MIPS32 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, pgd_current
+	srl	k1, 23
+	sll	k1, 2				# log2(sizeof(pgd_t)
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else 
+	lw	k1, pgd_current			# get pgd pointer
+#endif	
+	nop
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	GET_PTE_OFF(k0)				# get pte offset
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+
+	PTE_L	k0, PTE_HALF(k1)		# get even pte
+	CONVERT_PTE(k0)
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_L	k1, (PTE_HALF+PTE_SIZE)(k1)	# get odd pte
+	CONVERT_PTE(k1)
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+/*
+ * These are here to avoid putting ifdefs in tlb-r4k.c
+ */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_nevada)
+	.set	mips3
+	PANIC("Nevada Exception Vec 0 called")
+	END(except_vec0_nevada)
+
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	PANIC("R4600 Exception Vec 0 called")
+	END(except_vec0_r4600)
+
+	__FINIT
+
+/*
+ * ABUSE of CPP macros 101.
+ *
+ * After this macro runs, the pte faulted on is
+ * in register PTE, a ptr into the table in which
+ * the pte belongs is in PTR.
+ */
+
+#ifdef CONFIG_SMP
+#define GET_PGD(scratch, ptr)        \
+	mfc0    ptr, CP0_CONTEXT;    \
+	la      scratch, pgd_current;\
+	srl     ptr, 23;             \
+	sll     ptr, 2;              \
+	addu    ptr, scratch, ptr;   \
+	lw      ptr, (ptr);          
+#else
+#define GET_PGD(scratch, ptr)    \
+	lw	ptr, pgd_current;
+#endif
+
+#define LOAD_PTE(pte, ptr) \
+	GET_PGD(pte, ptr)          \
+	mfc0	pte, CP0_BADVADDR; \
+	srl	pte, pte, _PGDIR_SHIFT; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, (ptr); \
+	srl	pte, pte, PTE_INDX_SHIFT; \
+	and	pte, pte, PTE_INDX_MSK; \
+	addu	ptr, ptr, pte; \
+	PTE_L	pte, (ptr);
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr, tmp) \
+	ori	ptr, ptr, PTE_SIZE; \
+	xori	ptr, ptr, PTE_SIZE; \
+	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
+	CONVERT_PTE(tmp); \
+	P_MTC0	tmp, CP0_ENTRYLO1; \
+	PTE_L	ptr, PTE_HALF(ptr); \
+	CONVERT_PTE(ptr); \
+	P_MTC0	ptr, CP0_ENTRYLO0;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	STI; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	PTE_S	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	PTE_S	pte, (ptr);
+
+	.set	noreorder
+
+#define R5K_HAZARD nop
+
+	.align	5
+	NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+invalid_tlbl:
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp
+	PTE_PRESENT(k0, k1, nopage_tlbl)
+	PTE_MAKEVALID_HIGH(k0, k1)
+	PTE_MAKEVALID(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3	
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbl:
+	DO_FAULT(0)
+	END(handle_tlbl)
+
+	.align	5
+	NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+        li      k0,0
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp				# find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbs:
+	DO_FAULT(1)
+	END(handle_tlbs)
+
+	.align	5
+	NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	PTE_L	k0, (k1)
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+	END(handle_mod)
+
Index: include/asm-mips/addrspace.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/addrspace.h,v
retrieving revision 1.13
diff -u -r1.13 addrspace.h
--- include/asm-mips/addrspace.h	30 Nov 2003 01:52:25 -0000	1.13
+++ include/asm-mips/addrspace.h	19 Sep 2004 22:51:28 -0000
@@ -80,7 +80,11 @@
 #define XKSSEG			0x4000000000000000
 #define XKPHYS			0x8000000000000000
 #define XKSEG			0xc000000000000000
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define CKSEG0			0x80000000
+#else
 #define CKSEG0			0xffffffff80000000
+#endif
 #define CKSEG1			0xffffffffa0000000
 #define CKSSEG			0xffffffffc0000000
 #define CKSEG3			0xffffffffe0000000
Index: include/asm-mips/io.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/io.h,v
retrieving revision 1.72
diff -u -r1.72 io.h
--- include/asm-mips/io.h	19 Aug 2004 15:27:41 -0000	1.72
+++ include/asm-mips/io.h	19 Sep 2004 22:51:29 -0000
@@ -171,7 +171,7 @@
 extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
 extern void __iounmap(void *addr);
 
-static inline void * __ioremap_mode(unsigned long offset, unsigned long size,
+static inline void * __ioremap_mode(phys_t offset, unsigned long size,
 	unsigned long flags)
 {
 	if (cpu_has_64bit_addresses) {
Index: include/asm-mips/page.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/page.h,v
retrieving revision 1.44
diff -u -r1.44 page.h
--- include/asm-mips/page.h	20 Aug 2004 12:02:18 -0000	1.44
+++ include/asm-mips/page.h	19 Sep 2004 22:51:29 -0000
@@ -32,7 +32,7 @@
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PAGE_SHIFT	16
 #endif
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(1L << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
@@ -75,15 +75,22 @@
  * These are used to make use of C type-checking..
  */
 #ifdef CONFIG_64BIT_PHYS_ADDR
-typedef struct { unsigned long long pte; } pte_t;
+  #ifdef CONFIG_CPU_MIPS32
+    typedef struct { unsigned long pte_low, pte_high; } pte_t;
+    #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+  #else
+     typedef struct { unsigned long long pte; } pte_t;
+     #define pte_val(x)	((x).pte)
+  #endif
 #else
 typedef struct { unsigned long pte; } pte_t;
+#define pte_val(x)	((x).pte)
 #endif
+
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
Index: include/asm-mips/pgtable-32.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-32.h,v
retrieving revision 1.11
diff -u -r1.11 pgtable-32.h
--- include/asm-mips/pgtable-32.h	26 Jun 2004 15:15:24 -0000	1.11
+++ include/asm-mips/pgtable-32.h	19 Sep 2004 22:51:29 -0000
@@ -130,8 +130,21 @@
 static inline int pgd_present(pgd_t pgd)	{ return 1; }
 static inline void pgd_clear(pgd_t *pgdp)	{ }
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_pfn(x)		((unsigned long)((x).pte_high >> 6))
+static inline pte_t
+pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+	pte_t pte;
+	pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f);
+	pte.pte_low = pgprot_val(prot);
+	return pte;
+}
+
+#else
 
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
 
 #ifdef CONFIG_CPU_VR41XX
 #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
@@ -140,6 +153,7 @@
 #define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #endif
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32) */
 
 #define __pgd_offset(address)	pgd_index(address)
 #define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
@@ -207,11 +221,19 @@
  */
 #define PTE_FILE_MAX_BITS	27
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+	/* fixme */
+#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
+#define pgoff_to_pte(off) \
+ 	((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)})
+  
+#else
 #define pte_to_pgoff(_pte) \
 	((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 ))
 
 #define pgoff_to_pte(off) \
 	((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE })
+#endif
 
 #endif
 
Index: include/asm-mips/pgtable-bits.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-bits.h,v
retrieving revision 1.9
diff -u -r1.9 pgtable-bits.h
--- include/asm-mips/pgtable-bits.h	24 Jun 2004 20:31:11 -0000	1.9
+++ include/asm-mips/pgtable-bits.h	19 Sep 2004 22:51:29 -0000
@@ -33,6 +33,31 @@
  * unpredictable things.  The code (when it is written) to deal with
  * this problem will be in the update_mmu_cache() code for the r4k.
  */
+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+
+#define _PAGE_PRESENT               (1<<6)  /* implemented in software */
+#define _PAGE_READ                  (1<<7)  /* implemented in software */
+#define _PAGE_WRITE                 (1<<8)  /* implemented in software */
+#define _PAGE_ACCESSED              (1<<9)  /* implemented in software */
+#define _PAGE_MODIFIED              (1<<10) /* implemented in software */
+#define _PAGE_FILE                  (1<<10)  /* set:pagecache unset:swap */
+
+#define _PAGE_R4KBUG                (1<<0)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL                (1<<0)
+#define _PAGE_VALID                 (1<<1)
+#define _PAGE_SILENT_READ           (1<<1)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<2)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<2)
+#define _CACHE_MASK                 (7<<3)
+
+/* MIPS32 defines only values 2 and 3. The rest are implementation
+ * dependent.
+ */
+#define _CACHE_UNCACHED             (2<<3)  
+#define _CACHE_CACHABLE_NONCOHERENT (3<<3) 
+
+#else
+
 #define _PAGE_PRESENT               (1<<0)  /* implemented in software */
 #define _PAGE_READ                  (1<<1)  /* implemented in software */
 #define _PAGE_WRITE                 (1<<2)  /* implemented in software */
@@ -97,6 +122,7 @@
 
 #endif
 #endif
+#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */
 
 #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
 #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -113,6 +139,10 @@
 #define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
 #endif
 
+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 3)
+#else
 #define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+#endif
 
 #endif /* _ASM_PGTABLE_BITS_H */
Index: include/asm-mips/pgtable.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable.h,v
retrieving revision 1.97
diff -u -r1.97 pgtable.h
--- include/asm-mips/pgtable.h	19 Jun 2004 01:39:24 -0000	1.97
+++ include/asm-mips/pgtable.h	19 Sep 2004 22:51:29 -0000
@@ -80,6 +80,34 @@
 #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
 #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	ptep->pte_high = pte.pte_high;
+	smp_wmb();
+	ptep->pte_low = pte.pte_low;
+	//printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
+
+	if (pte_val(pte) & _PAGE_GLOBAL) {
+		pte_t *buddy = ptep_buddy(ptep);
+		/*
+		 * Make sure the buddy is global too (if it's !none,
+		 * it better already be global)
+		 */
+		if (pte_none(*buddy))
+			buddy->pte_low |= _PAGE_GLOBAL;
+	}
+}
+
+static inline void pte_clear(pte_t *ptep)
+{
+	/* Preserve global status for the pair */
+	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+		set_pte(ptep, __pte(_PAGE_GLOBAL));
+	else
+		set_pte(ptep, __pte(0));
+}
+#else
 /*
  * Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
@@ -111,6 +139,7 @@
 #endif
 		set_pte(ptep, __pte(0));
 }
+#endif
 
 /*
  * (pmds are folded into pgds so this doesn't get actually called,
@@ -130,6 +159,79 @@
  * Undefined behaviour if not..
  */
 static inline int pte_user(pte_t pte)	{ BUG(); return 0; }
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline int pte_read(pte_t pte)	{ return (pte).pte_low & _PAGE_READ; }
+static inline int pte_write(pte_t pte)	{ return (pte).pte_low & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte)	{ return (pte).pte_low & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)	{ return (pte).pte_low & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)	{ return (pte).pte_low & _PAGE_FILE; }
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_WRITE;
+	if ((pte).pte_low & _PAGE_MODIFIED) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_READ;
+	if ((pte).pte_low & _PAGE_ACCESSED) {
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_MODIFIED;
+	if ((pte).pte_low & _PAGE_WRITE) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_ACCESSED;
+	if ((pte).pte_low & _PAGE_READ)
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	return pte;
+}
+#else
 static inline int pte_read(pte_t pte)	{ return pte_val(pte) & _PAGE_READ; }
 static inline int pte_write(pte_t pte)	{ return pte_val(pte) & _PAGE_WRITE; }
 static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_MODIFIED; }
@@ -191,6 +293,7 @@
 		pte_val(pte) |= _PAGE_SILENT_READ;
 	return pte;
 }
+#endif
 
 /*
  * Macro to make mark a page protection value as "uncacheable".  Note
@@ -215,10 +318,20 @@
  */
 #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte_low &= _PAGE_CHG_MASK;
+	pte.pte_low |= pgprot_val(newprot);
+	pte.pte_high |= pgprot_val(newprot) & 0x3f;
+	return pte;
+}
+#else
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
 }
+#endif
 
 
 extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
@@ -245,7 +358,27 @@
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 
+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
+
+extern int remap_page_range_high(struct vm_area_struct *vma,
+		unsigned long from,
+		phys_t phys_addr,
+		unsigned long size,
+		pgprot_t prot);
+
+static inline int io_remap_page_range(struct vm_area_struct *vma,
+		unsigned long from,
+		unsigned long phys_addr,
+		unsigned long size,
+		pgprot_t prot)
+{
+	phys_t phys_addr_high = fixup_bigphys_addr(phys_addr, size);
+	return remap_page_range_high(vma, from, phys_addr_high, size, prot);
+}
+#else
 #define io_remap_page_range remap_page_range
+#endif
 
 /*
  * No page table caches to initialise

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch
@ 2024-06-18 16:19 Solegaiter
  2024-06-18 16:40 ` Patch bluez.test.bot
  0 siblings, 1 reply; 77+ messages in thread
From: Solegaiter @ 2024-06-18 16:19 UTC (permalink / raw)
  To: linux-bluetooth


[-- Attachment #1.1: Type: text/plain, Size: 70 bytes --]

This patches a bug that made it impossible to compile on gentoo musl.

[-- Attachment #1.2: Type: text/html, Size: 99 bytes --]

[-- Attachment #2: parche.patch --]
[-- Type: text/x-patch, Size: 486 bytes --]

diff --git a/client/player.c b/client/player.c
index 25fd837..47b5d0a 100644
--- a/client/player.c
+++ b/client/player.c
@@ -5142,7 +5142,7 @@ static void cmd_send_transport(int argc, char *argv[])
 			struct sockaddr_iso addr;
 			socklen_t optlen;
 
-			err = getpeername(transport->sk, &addr, &optlen);
+			err = getpeername(transport->sk, (struct sockaddr *)&addr, &optlen);
 			if (!err) {
 				if (!(bacmp(&addr.iso_bdaddr, BDADDR_ANY)))
 					err = transport_send(transport, fd,

^ permalink raw reply related	[flat|nested] 77+ messages in thread
* Patch
@ 2020-06-23 23:14 Joe Slater
  0 siblings, 0 replies; 77+ messages in thread
From: Joe Slater @ 2020-06-23 23:14 UTC (permalink / raw)
  To: 'openembedded-core@lists.openembedded.org'


[-- Attachment #1.1: Type: text/plain, Size: 180 bytes --]

I have attached a patch which I could not send using git send-email which complained about lines that are too long for its taste.  I generated it using format-patch, so...

Joe

[-- Attachment #1.2: Type: text/html, Size: 1917 bytes --]

[-- Attachment #2: 0001-json-c-Fix-CVE-2020-12762.patch --]
[-- Type: application/octet-stream, Size: 13522 bytes --]

From 0ad5349424be97f2e8dc3c337367e3716bd2734f Mon Sep 17 00:00:00 2001
From: Joe Slater <joe.slater@windriver.com>
Date: Tue, 23 Jun 2020 15:42:20 -0700
Subject: [oe-core][PATCH 1/1] json-c:  Fix CVE-2020-12762

Import fix from json-c.git created after the 0.14 release.

Signed-off-by: Joe Slater <joe.slater@windriver.com>
---
 .../json-c/json-c/Fix-CVE-2020-12762.patch         | 204 +++++++++++++++++++++
 meta/recipes-devtools/json-c/json-c_0.14.bb        |   2 +
 2 files changed, 206 insertions(+)
 create mode 100644 meta/recipes-devtools/json-c/json-c/Fix-CVE-2020-12762.patch

diff --git a/meta/recipes-devtools/json-c/json-c/Fix-CVE-2020-12762.patch b/meta/recipes-devtools/json-c/json-c/Fix-CVE-2020-12762.patch
new file mode 100644
index 0000000..cbbcfcb
--- /dev/null
+++ b/meta/recipes-devtools/json-c/json-c/Fix-CVE-2020-12762.patch
@@ -0,0 +1,204 @@
+From 5d6fa331418d49f1bd488553fd1cfa9ab023fabb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= <besser82@fedoraproject.org>
+Date: Thu, 14 May 2020 12:32:30 +0200
+Subject: [PATCH 1/1] Fix CVE-2020-12762.
+
+This commit is a squashed backport of the following commits
+on the master branch:
+
+  * 099016b7e8d70a6d5dd814e788bba08d33d48426
+  * 77d935b7ae7871a1940cd827e850e6063044ec45
+  * d07b91014986900a3a75f306d302e13e005e9d67
+  * 519dfe1591d85432986f9762d41d1a883198c157
+  * a59d5acfab4485d5133114df61785b1fc633e0c6
+  * 26f080997d41cfdb17beab65e90c82217d0ac43b
+---
+ arraylist.c          |  3 +++
+ linkhash.c           |  9 ++++++++-
+ printbuf.c           | 18 ++++++++++++++++--
+ tests/test4.c        | 29 +++++++++++++++++++++++++++++
+ tests/test4.expected |  1 +
+ 5 files changed, 57 insertions(+), 3 deletions(-)
+
+--- end of original patch header ---
+
+Applied from branch json-c-0.14 unmodified to release 0.14.
+
+CVE: CVE-2020-12762
+
+Upstream-Status:  backport [https://github.com/json-c/json-c.git]
+
+Signed-off-by:  Joe Slater <joe.slater@windriver.com>
+
+
+diff --git a/arraylist.c b/arraylist.c
+index 12ad8af..e5524ac 100644
+--- a/arraylist.c
++++ b/arraylist.c
+@@ -136,6 +136,9 @@ int array_list_del_idx(struct array_list *arr, size_t idx, size_t count)
+ {
+ 	size_t i, stop;
+ 
++	/* Avoid overflow in calculation with large indices. */
++	if (idx > SIZE_T_MAX - count)
++		return -1;
+ 	stop = idx + count;
+ 	if (idx >= arr->length || stop > arr->length)
+ 		return -1;
+diff --git a/linkhash.c b/linkhash.c
+index 7ea58c0..b021ef1 100644
+--- a/linkhash.c
++++ b/linkhash.c
+@@ -12,6 +12,7 @@
+ 
+ #include "config.h"
+ 
++#include <assert.h>
+ #include <limits.h>
+ #include <stdarg.h>
+ #include <stddef.h>
+@@ -499,6 +500,8 @@ struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *h
+ 	int i;
+ 	struct lh_table *t;
+ 
++	/* Allocate space for elements to avoid divisions by zero. */
++	assert(size > 0);
+ 	t = (struct lh_table *)calloc(1, sizeof(struct lh_table));
+ 	if (!t)
+ 		return NULL;
+@@ -578,8 +581,12 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con
+ 	unsigned long n;
+ 
+ 	if (t->count >= t->size * LH_LOAD_FACTOR)
+-		if (lh_table_resize(t, t->size * 2) != 0)
++	{
++		/* Avoid signed integer overflow with large tables. */
++		int new_size = (t->size > INT_MAX / 2) ? INT_MAX : (t->size * 2);
++		if (t->size == INT_MAX || lh_table_resize(t, new_size) != 0)
+ 			return -1;
++	}
+ 
+ 	n = h % t->size;
+ 
+diff --git a/printbuf.c b/printbuf.c
+index 976c12d..f9b15b1 100644
+--- a/printbuf.c
++++ b/printbuf.c
+@@ -15,6 +15,7 @@
+ 
+ #include "config.h"
+ 
++#include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -66,9 +67,16 @@ static int printbuf_extend(struct printbuf *p, int min_size)
+ 	if (p->size >= min_size)
+ 		return 0;
+ 
+-	new_size = p->size * 2;
+-	if (new_size < min_size + 8)
++	/* Prevent signed integer overflows with large buffers. */
++	if (min_size > INT_MAX - 8)
++		return -1;
++	if (p->size > INT_MAX / 2)
+ 		new_size = min_size + 8;
++	else {
++		new_size = p->size * 2;
++		if (new_size < min_size + 8)
++			new_size = min_size + 8;
++	}
+ #ifdef PRINTBUF_DEBUG
+ 	MC_DEBUG("printbuf_memappend: realloc "
+ 	         "bpos=%d min_size=%d old_size=%d new_size=%d\n",
+@@ -83,6 +91,9 @@ static int printbuf_extend(struct printbuf *p, int min_size)
+ 
+ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+ {
++	/* Prevent signed integer overflows with large buffers. */
++	if (size > INT_MAX - p->bpos - 1)
++		return -1;
+ 	if (p->size <= p->bpos + size + 1)
+ 	{
+ 		if (printbuf_extend(p, p->bpos + size + 1) < 0)
+@@ -100,6 +111,9 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
+ 
+ 	if (offset == -1)
+ 		offset = pb->bpos;
++	/* Prevent signed integer overflows with large buffers. */
++	if (len > INT_MAX - offset)
++		return -1;
+ 	size_needed = offset + len;
+ 	if (pb->size < size_needed)
+ 	{
+diff --git a/tests/test4.c b/tests/test4.c
+index bd964ec..288cec1 100644
+--- a/tests/test4.c
++++ b/tests/test4.c
+@@ -3,12 +3,15 @@
+  */
+ 
+ #include "config.h"
++#include <assert.h>
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <string.h>
+ 
+ #include "json_inttypes.h"
+ #include "json_object.h"
+ #include "json_tokener.h"
++#include "snprintf_compat.h"
+ 
+ void print_hex(const char *s)
+ {
+@@ -24,6 +27,29 @@ void print_hex(const char *s)
+ 	putchar('\n');
+ }
+ 
++static void test_lot_of_adds(void);
++static void test_lot_of_adds()
++{
++	int ii;
++	char key[50];
++	json_object *jobj = json_object_new_object();
++	assert(jobj != NULL);
++	for (ii = 0; ii < 500; ii++)
++	{
++		snprintf(key, sizeof(key), "k%d", ii);
++		json_object *iobj = json_object_new_int(ii);
++		assert(iobj != NULL);
++		if (json_object_object_add(jobj, key, iobj))
++		{
++			fprintf(stderr, "FAILED to add object #%d\n", ii);
++			abort();
++		}
++	}
++	printf("%s\n", json_object_to_json_string(jobj));
++	assert(json_object_object_length(jobj) == 500);
++	json_object_put(jobj);
++}
++
+ int main(void)
+ {
+ 	const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
+@@ -52,5 +78,8 @@ int main(void)
+ 		retval = 1;
+ 	}
+ 	json_object_put(parse_result);
++
++	test_lot_of_adds();
++
+ 	return retval;
+ }
+diff --git a/tests/test4.expected b/tests/test4.expected
+index 68d4336..cb27440 100644
+--- a/tests/test4.expected
++++ b/tests/test4.expected
+@@ -1,3 +1,4 @@
+ input: "\ud840\udd26,\ud840\udd27,\ud800\udd26,\ud800\udd27"
+ JSON parse result is correct: 𠄦,𠄧,𐄦,𐄧
+ PASS
++{ "k0": 0, "k1": 1, "k2": 2, "k3": 3, "k4": 4, "k5": 5, "k6": 6, "k7": 7, "k8": 8, "k9": 9, "k10": 10, "k11": 11, "k12": 12, "k13": 13, "k14": 14, "k15": 15, "k16": 16, "k17": 17, "k18": 18, "k19": 19, "k20": 20, "k21": 21, "k22": 22, "k23": 23, "k24": 24, "k25": 25, "k26": 26, "k27": 27, "k28": 28, "k29": 29, "k30": 30, "k31": 31, "k32": 32, "k33": 33, "k34": 34, "k35": 35, "k36": 36, "k37": 37, "k38": 38, "k39": 39, "k40": 40, "k41": 41, "k42": 42, "k43": 43, "k44": 44, "k45": 45, "k46": 46, "k47": 47, "k48": 48, "k49": 49, "k50": 50, "k51": 51, "k52": 52, "k53": 53, "k54": 54, "k55": 55, "k56": 56, "k57": 57, "k58": 58, "k59": 59, "k60": 60, "k61": 61, "k62": 62, "k63": 63, "k64": 64, "k65": 65, "k66": 66, "k67": 67, "k68": 68, "k69": 69, "k70": 70, "k71": 71, "k72": 72, "k73": 73, "k74": 74, "k75": 75, "k76": 76, "k77": 77, "k78": 78, "k79": 79, "k80": 80, "k81": 81, "k82": 82, "k83": 83, "k84": 84, "k85": 85, "k86": 86, "k87": 87, "k88": 88, "k89": 89, "k90": 90, "k91": 91, "k92": 92, "k93": 93, "k94": 94, "k95": 95, "k96": 96, "k97": 97, "k98": 98, "k99": 99, "k100": 100, "k101": 101, "k102": 102, "k103": 103, "k104": 104, "k105": 105, "k106": 106, "k107": 107, "k108": 108, "k109": 109, "k110": 110, "k111": 111, "k112": 112, "k113": 113, "k114": 114, "k115": 115, "k116": 116, "k117": 117, "k118": 118, "k119": 119, "k120": 120, "k121": 121, "k122": 122, "k123": 123, "k124": 124, "k125": 125, "k126": 126, "k127": 127, "k128": 128, "k129": 129, "k130": 130, "k131": 131, "k132": 132, "k133": 133, "k134": 134, "k135": 135, "k136": 136, "k137": 137, "k138": 138, "k139": 139, "k140": 140, "k141": 141, "k142": 142, "k143": 143, "k144": 144, "k145": 145, "k146": 146, "k147": 147, "k148": 148, "k149": 149, "k150": 150, "k151": 151, "k152": 152, "k153": 153, "k154": 154, "k155": 155, "k156": 156, "k157": 157, "k158": 158, "k159": 159, "k160": 160, "k161": 161, "k162": 162, "k163": 163, "k164": 164, "k165": 165, "k166": 166, "k167": 167, "k168": 168, "k169": 169, "k170": 170, "k171": 171, "k172": 172, "k173": 173, "k174": 174, "k175": 175, "k176": 176, "k177": 177, "k178": 178, "k179": 179, "k180": 180, "k181": 181, "k182": 182, "k183": 183, "k184": 184, "k185": 185, "k186": 186, "k187": 187, "k188": 188, "k189": 189, "k190": 190, "k191": 191, "k192": 192, "k193": 193, "k194": 194, "k195": 195, "k196": 196, "k197": 197, "k198": 198, "k199": 199, "k200": 200, "k201": 201, "k202": 202, "k203": 203, "k204": 204, "k205": 205, "k206": 206, "k207": 207, "k208": 208, "k209": 209, "k210": 210, "k211": 211, "k212": 212, "k213": 213, "k214": 214, "k215": 215, "k216": 216, "k217": 217, "k218": 218, "k219": 219, "k220": 220, "k221": 221, "k222": 222, "k223": 223, "k224": 224, "k225": 225, "k226": 226, "k227": 227, "k228": 228, "k229": 229, "k230": 230, "k231": 231, "k232": 232, "k233": 233, "k234": 234, "k235": 235, "k236": 236, "k237": 237, "k238": 238, "k239": 239, "k240": 240, "k241": 241, "k242": 242, "k243": 243, "k244": 244, "k245": 245, "k246": 246, "k247": 247, "k248": 248, "k249": 249, "k250": 250, "k251": 251, "k252": 252, "k253": 253, "k254": 254, "k255": 255, "k256": 256, "k257": 257, "k258": 258, "k259": 259, "k260": 260, "k261": 261, "k262": 262, "k263": 263, "k264": 264, "k265": 265, "k266": 266, "k267": 267, "k268": 268, "k269": 269, "k270": 270, "k271": 271, "k272": 272, "k273": 273, "k274": 274, "k275": 275, "k276": 276, "k277": 277, "k278": 278, "k279": 279, "k280": 280, "k281": 281, "k282": 282, "k283": 283, "k284": 284, "k285": 285, "k286": 286, "k287": 287, "k288": 288, "k289": 289, "k290": 290, "k291": 291, "k292": 292, "k293": 293, "k294": 294, "k295": 295, "k296": 296, "k297": 297, "k298": 298, "k299": 299, "k300": 300, "k301": 301, "k302": 302, "k303": 303, "k304": 304, "k305": 305, "k306": 306, "k307": 307, "k308": 308, "k309": 309, "k310": 310, "k311": 311, "k312": 312, "k313": 313, "k314": 314, "k315": 315, "k316": 316, "k317": 317, "k318": 318, "k319": 319, "k320": 320, "k321": 321, "k322": 322, "k323": 323, "k324": 324, "k325": 325, "k326": 326, "k327": 327, "k328": 328, "k329": 329, "k330": 330, "k331": 331, "k332": 332, "k333": 333, "k334": 334, "k335": 335, "k336": 336, "k337": 337, "k338": 338, "k339": 339, "k340": 340, "k341": 341, "k342": 342, "k343": 343, "k344": 344, "k345": 345, "k346": 346, "k347": 347, "k348": 348, "k349": 349, "k350": 350, "k351": 351, "k352": 352, "k353": 353, "k354": 354, "k355": 355, "k356": 356, "k357": 357, "k358": 358, "k359": 359, "k360": 360, "k361": 361, "k362": 362, "k363": 363, "k364": 364, "k365": 365, "k366": 366, "k367": 367, "k368": 368, "k369": 369, "k370": 370, "k371": 371, "k372": 372, "k373": 373, "k374": 374, "k375": 375, "k376": 376, "k377": 377, "k378": 378, "k379": 379, "k380": 380, "k381": 381, "k382": 382, "k383": 383, "k384": 384, "k385": 385, "k386": 386, "k387": 387, "k388": 388, "k389": 389, "k390": 390, "k391": 391, "k392": 392, "k393": 393, "k394": 394, "k395": 395, "k396": 396, "k397": 397, "k398": 398, "k399": 399, "k400": 400, "k401": 401, "k402": 402, "k403": 403, "k404": 404, "k405": 405, "k406": 406, "k407": 407, "k408": 408, "k409": 409, "k410": 410, "k411": 411, "k412": 412, "k413": 413, "k414": 414, "k415": 415, "k416": 416, "k417": 417, "k418": 418, "k419": 419, "k420": 420, "k421": 421, "k422": 422, "k423": 423, "k424": 424, "k425": 425, "k426": 426, "k427": 427, "k428": 428, "k429": 429, "k430": 430, "k431": 431, "k432": 432, "k433": 433, "k434": 434, "k435": 435, "k436": 436, "k437": 437, "k438": 438, "k439": 439, "k440": 440, "k441": 441, "k442": 442, "k443": 443, "k444": 444, "k445": 445, "k446": 446, "k447": 447, "k448": 448, "k449": 449, "k450": 450, "k451": 451, "k452": 452, "k453": 453, "k454": 454, "k455": 455, "k456": 456, "k457": 457, "k458": 458, "k459": 459, "k460": 460, "k461": 461, "k462": 462, "k463": 463, "k464": 464, "k465": 465, "k466": 466, "k467": 467, "k468": 468, "k469": 469, "k470": 470, "k471": 471, "k472": 472, "k473": 473, "k474": 474, "k475": 475, "k476": 476, "k477": 477, "k478": 478, "k479": 479, "k480": 480, "k481": 481, "k482": 482, "k483": 483, "k484": 484, "k485": 485, "k486": 486, "k487": 487, "k488": 488, "k489": 489, "k490": 490, "k491": 491, "k492": 492, "k493": 493, "k494": 494, "k495": 495, "k496": 496, "k497": 497, "k498": 498, "k499": 499 }
+-- 
+2.7.4
+
diff --git a/meta/recipes-devtools/json-c/json-c_0.14.bb b/meta/recipes-devtools/json-c/json-c_0.14.bb
index 99fde87..1ee7305 100644
--- a/meta/recipes-devtools/json-c/json-c_0.14.bb
+++ b/meta/recipes-devtools/json-c/json-c_0.14.bb
@@ -7,6 +7,8 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=de54b60fbbc35123ba193fea8ee216f2"
 SRC_URI = "https://s3.amazonaws.com/json-c_releases/releases/${BP}.tar.gz"
 SRC_URI[sha256sum] = "b377de08c9b23ca3b37d9a9828107dff1de5ce208ff4ebb35005a794f30c6870"
 
+SRC_URI += "file://Fix-CVE-2020-12762.patch"
+
 UPSTREAM_CHECK_URI = "https://github.com/${BPN}/${BPN}/releases"
 UPSTREAM_CHECK_REGEX = "json-c-(?P<pver>\d+(\.\d+)+)-\d+"
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 77+ messages in thread
[parent not found: <06c7632e-9e21-7428-bfa3-4ec122f637fd@synopsys.com>]
* Patch
@ 2013-11-22 16:35 Arthur Schwalbenberg
  2013-11-22 17:36 ` Patch Levente Kurusa
  0 siblings, 1 reply; 77+ messages in thread
From: Arthur Schwalbenberg @ 2013-11-22 16:35 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, intel-gfx, dri-devel, linux-kernel,
	Arthur Schwalbenberg


 From 340fa01dfe8f699e27ece111996ea088bca6b5c4 Mon Sep 17 00:00:00 2001
From: Arthur Schwalbenberg <aschwal@hotmail.com>
Date: Thu, 21 Nov 2013 19:42:44 -0500
Subject: [PATCH] Staging: Fixed compilar warnings and coding style
issues in i915_debugfs.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is a patch fixing both a compilar warning:
‘val’ may be used uninitialized in this function
and various coding style issues which include line length
warnings and a few errors as defined by 'checkpatch.pl' tool

Signed-off-by: Arthur Schwalbenberg <aschwal@hotmail.com>
---
drivers/gpu/drm/i915/i915_debugfs.c | 75 ++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 6ed45a9..01135d4 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2008 Intel Corporation
+ * Copyright © 2008 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -87,8 +87,8 @@ static int i915_capabilities(struct seq_file *m, void 
*data)

seq_printf(m, "gen: %d\n", info->gen);
seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev));
-#define PRINT_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x))
-#define SEP_SEMICOLON ;
+#define PRINT_FLAG(x) seq_printf(m, #x ": %s\n", yesno(info->x));
+#define SEP_SEMICOLON
DEV_INFO_FOR_EACH_FLAG(PRINT_FLAG, SEP_SEMICOLON);
#undef PRINT_FLAG
#undef SEP_SEMICOLON
@@ -144,7 +144,7 @@ describe_obj(struct seq_file *m, struct 
drm_i915_gem_object *obj)
if (obj->pin_count)
seq_printf(m, " (pinned x %d)", obj->pin_count);
if (obj->pin_display)
- seq_printf(m, " (display)");
+ seq_puts(m, " (display)");
if (obj->fence_reg != I915_FENCE_REG_NONE)
seq_printf(m, " (fence: %d)", obj->fence_reg);
list_for_each_entry(vma, &obj->vma_list, vma_link) {
@@ -210,9 +210,9 @@ static int i915_gem_object_list_info(struct seq_file 
*m, void *data)

total_obj_size = total_gtt_size = count = 0;
list_for_each_entry(vma, head, mm_list) {
- seq_printf(m, " ");
+ seq_puts(m, " ");
describe_obj(m, vma->obj);
- seq_printf(m, "\n");
+ seq_puts(m, "\n");
total_obj_size += vma->obj->base.size;
total_gtt_size += vma->node.size;
count++;
@@ -333,7 +333,7 @@ static int per_file_stats(int id, void *ptr, void *data)
} \
} while (0)

-static int i915_gem_object_info(struct seq_file *m, void* data)
+static int i915_gem_object_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
@@ -460,6 +460,7 @@ static int i915_gem_gtt_info(struct seq_file *m, 
void *data)

static int i915_gem_pageflip_info(struct seq_file *m, void *data)
{
+ struct drm_i915_gem_object *obj = NULL;
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
unsigned long flags;
@@ -487,19 +488,22 @@ static int i915_gem_pageflip_info(struct seq_file 
*m, void *data)
seq_puts(m, "Stall check enabled, ");
else
seq_puts(m, "Stall check waiting for page flip ioctl, ");
- seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
+
+ seq_printf(m, "%d prepares\n",
+ atomic_read(&work->pending));

if (work->old_fb_obj) {
- struct drm_i915_gem_object *obj = work->old_fb_obj;
+ obj = work->old_fb_obj;
if (obj)
seq_printf(m, "Old framebuffer gtt_offset 0x%08lx\n",
- i915_gem_obj_ggtt_offset(obj));
+ i915_gem_obj_ggtt_offset(obj));
}
if (work->pending_flip_obj) {
- struct drm_i915_gem_object *obj = work->pending_flip_obj;
+ obj = work->pending_flip_obj;
if (obj)
- seq_printf(m, "New framebuffer gtt_offset 0x%08lx\n",
- i915_gem_obj_ggtt_offset(obj));
+ seq_printf(m,
+ "New framebuffer gtt_offset 0x%08lx\n",
+ i915_gem_obj_ggtt_offset(obj));
}
}
spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -530,9 +534,8 @@ static int i915_gem_request_info(struct seq_file *m, 
void *data)
list_for_each_entry(gem_request,
&ring->request_list,
list) {
- seq_printf(m, " %d @ %d\n",
- gem_request->seqno,
- (int) (jiffies - gem_request->emitted_jiffies));
+ seq_printf(m, " %d @ %d\n", gem_request->seqno,
+ (int) (jiffies - gem_request->emitted_jiffies));
}
count++;
}
@@ -909,7 +912,9 @@ static int i915_rstdby_delays(struct seq_file *m, 
void *unused)

mutex_unlock(&dev->struct_mutex);

- seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, 
(crstanddelay & 0x3f));
+ seq_printf(m, "w/ctx: %d, w/o ctx: %d\n",
+ (crstanddelay >> 8) & 0x3f,
+ (crstanddelay & 0x3f));

return 0;
}
@@ -929,10 +934,11 @@ static int i915_cur_delayinfo(struct seq_file *m, 
void *unused)

seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf);
seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f);
- seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >>
- MEMSTAT_VID_SHIFT);
+ seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK)
+ >> MEMSTAT_VID_SHIFT);
seq_printf(m, "Current P-state: %d\n",
- (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT);
+ (rgvstat & MEMSTAT_PSTATE_MASK) >>
+ MEMSTAT_PSTATE_SHIFT);
} else if ((IS_GEN6(dev) || IS_GEN7(dev)) && !IS_VALLEYVIEW(dev)) {
u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS);
@@ -1173,13 +1179,13 @@ static int gen6_drpc_info(struct seq_file *m)
spin_unlock_irq(&dev_priv->uncore.lock);

if (forcewake_count) {
- seq_puts(m, "RC information inaccurate because somebody "
- "holds a forcewake reference \n");
+ seq_puts(m, "RC information inaccurate because somebody holds a 
forcewake reference\n");
} else {
/* NB: we cannot use forcewake, else we read the wrong values */
while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
udelay(10);
- seq_printf(m, "RC information accurate: %s\n", yesno(count < 51));
+ seq_printf(m, "RC information accurate: %s\n",
+ yesno(count < 51));
}

gt_core_status = readl(dev_priv->regs + GEN6_GT_CORE_STATUS);
@@ -1549,7 +1555,8 @@ static int i915_context_status(struct seq_file *m, 
void *unused)
describe_ctx(m, ctx);
for_each_ring(ring, dev_priv, i)
if (ring->default_context == ctx)
- seq_printf(m, "(default context %s) ", ring->name);
+ seq_printf(m, "(default context %s) ",
+ ring->name);

describe_obj(m, ctx->obj);
seq_putc(m, '\n');
@@ -1683,10 +1690,15 @@ static void gen6_ppgtt_info(struct seq_file *m, 
struct drm_device *dev)
for_each_ring(ring, dev_priv, i) {
seq_printf(m, "%s\n", ring->name);
if (INTEL_INFO(dev)->gen == 7)
- seq_printf(m, "GFX_MODE: 0x%08x\n", I915_READ(RING_MODE_GEN7(ring)));
- seq_printf(m, "PP_DIR_BASE: 0x%08x\n", I915_READ(RING_PP_DIR_BASE(ring)));
- seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n", 
I915_READ(RING_PP_DIR_BASE_READ(ring)));
- seq_printf(m, "PP_DIR_DCLV: 0x%08x\n", I915_READ(RING_PP_DIR_DCLV(ring)));
+ seq_printf(m, "GFX_MODE: 0x%08x\n",
+ I915_READ(RING_MODE_GEN7(ring)));
+
+ seq_printf(m, "PP_DIR_BASE: 0x%08x\n",
+ I915_READ(RING_PP_DIR_BASE(ring)));
+ seq_printf(m, "PP_DIR_BASE_READ: 0x%08x\n",
+ I915_READ(RING_PP_DIR_BASE_READ(ring)));
+ seq_printf(m, "PP_DIR_DCLV: 0x%08x\n",
+ I915_READ(RING_PP_DIR_DCLV(ring)));
}
if (dev_priv->mm.aliasing_ppgtt) {
struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
@@ -2347,7 +2359,7 @@ static int pipe_crc_set_source(struct drm_device 
*dev, enum pipe pipe,
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
- u32 val;
+ u32 val = 0;
int ret;

if (pipe_crc->source == source)
@@ -2362,7 +2374,7 @@ static int pipe_crc_set_source(struct drm_device 
*dev, enum pipe pipe,
else if (INTEL_INFO(dev)->gen < 5)
ret = i9xx_pipe_crc_ctl_reg(dev, pipe, &source, &val);
else if (IS_VALLEYVIEW(dev))
- ret = vlv_pipe_crc_ctl_reg(dev,pipe, &source, &val);
+ ret = vlv_pipe_crc_ctl_reg(dev, pipe, &source, &val);
else if (IS_GEN5(dev) || IS_GEN6(dev))
ret = ilk_pipe_crc_ctl_reg(&source, &val);
else
@@ -3046,7 +3058,8 @@ static const struct drm_info_list 
i915_debugfs_list[] = {
{"i915_gem_gtt", i915_gem_gtt_info, 0},
{"i915_gem_pinned", i915_gem_gtt_info, 0, (void *) PINNED_LIST},
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
- {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) 
INACTIVE_LIST},
+ {"i915_gem_inactive", i915_gem_object_list_info, 0,
+ (void *) INACTIVE_LIST},
{"i915_gem_stolen", i915_gem_stolen_list_info },
{"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 77+ messages in thread
* Patch for ip setting on bridge interface and vlan
@ 2013-01-23 22:12 Kevin Yung
  2013-01-23 22:51 ` Patch Kevin Yung
  0 siblings, 1 reply; 77+ messages in thread
From: Kevin Yung @ 2013-01-23 22:12 UTC (permalink / raw)
  To: initramfs-u79uwXL29TY76Z2rM5mHXA

Hi all,

I have an environment that needs to boot on bridged interface or 
interface using vlan. 

I found curent dracut release will by pass ip settings on these interfaces. 

So I wrote the a patch to set up provided ip options on the interfaces 
that using bridge or vlan. 

Please let me know if I need to tidy it up a bit more or 
add additional code to handle ip settings on bridge 

and vlan.

Cheers
Kevin

^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2010-05-04 16:48 Kristoffer Ericson
  0 siblings, 0 replies; 77+ messages in thread
From: Kristoffer Ericson @ 2010-05-04 16:48 UTC (permalink / raw)
  To: jeff; +Cc: linux-kernel

Hey,

did you get my patch concerning those hash changes? Havent gotten any reply.

Best wishes
Kristoffer

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2009-01-29 10:11 gabriele.paoloni
  0 siblings, 0 replies; 77+ messages in thread
From: gabriele.paoloni @ 2009-01-29 10:11 UTC (permalink / raw)
  To: netdev, redesign, ppp_mp_explode
  Cc: gabriele.paoloni, ken.reynolds, arjan.van.de.ven

Hi,
 
My name is Gabriele Paoloni, I am a Software Engineer working in the Intel
Research and Development Center in Shannon, Ireland.
I found the PPP subsystem to not work properly when connecting channels
with different speeds to the same bundle.

Problem Description:

As the "ppp_mp_explode" function fragments the sk_buff buffer evenly among
 the PPP channels that are connected to a certain PPP unit to make up a bundle,
 if we are transmitting using an upper layer protocol that requires an Ack 
before sending the next packet (like TCP/IP for example), we will have a 
bandwidth bottleneck on the slowest channel of the bundle. 
Let's clarify by an example. Let's consider a scenario where we have two PPP 
links making up a bundle: a slow link (10KB/sec) and a fast link (1000KB/sec) 
working at the best (full bandwidth). On the top we have a TCP/IP stack sending 
a 1000 Bytes sk_buff buffer down to the PPP subsystem. The  "ppp_mp_explode" 
function will divide the buffer in two fragments of 500B each (we are neglecting 
all the headers, crc, flags etc?.). Before the TCP/IP stack sends out the next 
buffer, it will have to wait for the ACK response from the remote peer, so it will 
have to wait for both fragments to have been sent over the two PPP links, received 
by the remote peer and reconstructed. The resulting behaviour is that, rather than 
having a bundle working @1010KB/sec (the sum of the channels bandwidths), we'll 
have a bundle working @20KB/sec (the double of the slowest channels bandwidth).


Problem Solution:

The problem has been solved by redesigning the "ppp_mp_explode" function in such 
a way to make it split the sk_buff buffer according to the speeds of the underlying 
PPP channels (the speeds of the serial interfaces respectively attached to the PPP 
channels). Referring to the above example, the redesigned "ppp_mp_explode" function 
will now divide the 1000 Bytes buffer into two fragments whose sizes are set 
according to the speeds of the channels where they are going to be sent on (e.g . 
10 Byets on 10KB/sec channel and 990 Bytes on 1000KB/sec channel). 
The reworked function grants the same performances of the original one in optimal 
working conditions (i.e. a bundle made up of PPP links all working at the same 
speed), while greatly improving performances on the bundles made up of channels 
working at different speeds.


Find inline a possible solution patch.

 
Note: the kernel patch has been generated against the last stable version
      2.6.28.2
 
Best Regards
 
Gabriele Paoloni
 
email: gabriele.paoloni@intel.com
phone: +353 6 147 7753
mobile1: 00353 8333 52390
mobile2: 0039 3937498940
 
 
*******************************************************************************
*******************************************************************************
*******************************************************************************





Signed-off-by: Gabriele Paoloni <paoloni.gabriele@gmail.com> <gabriele.paoloni@intel.com>

diff -urN ./linux-2.6.28.2/drivers/net/ppp_async.c ./linux-2.6.28.2.new/drivers/net/ppp_async.c
--- ./linux-2.6.28.2/drivers/net/ppp_async.c	2009-01-25 00:42:07.000000000 +0000
+++ ./linux-2.6.28.2.new/drivers/net/ppp_async.c	2009-01-28 16:54:37.000000000 +0000
@@ -157,6 +157,7 @@
 {
 	struct asyncppp *ap;
 	int err;
+	int speed;
 
 	if (tty->ops->write == NULL)
 		return -EOPNOTSUPP;
@@ -187,6 +188,8 @@
 	ap->chan.private = ap;
 	ap->chan.ops = &async_ops;
 	ap->chan.mtu = PPP_MRU;
+	speed = tty_get_baud_rate(tty);
+	ap->chan.speed = speed;
 	err = ppp_register_channel(&ap->chan);
 	if (err)
 		goto out_free;
diff -urN ./linux-2.6.28.2/drivers/net/ppp_generic.c ./linux-2.6.28.2.new/drivers/net/ppp_generic.c
--- ./linux-2.6.28.2/drivers/net/ppp_generic.c	2009-01-25 00:42:07.000000000 +0000
+++ ./linux-2.6.28.2.new/drivers/net/ppp_generic.c	2009-01-28 16:53:06.000000000 +0000
@@ -160,6 +160,7 @@
 	u8		avail;		/* flag used in multilink stuff */
 	u8		had_frag;	/* >= 1 fragments have been sent */
 	u32		lastseq;	/* MP: last sequence # received */
+	int     speed;		/* speed of the corresponding ppp channel*/
 #endif /* CONFIG_PPP_MULTILINK */
 };
 
@@ -1235,138 +1236,181 @@
  */
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 {
-	int len, fragsize;
-	int i, bits, hdrlen, mtu;
-	int flen;
-	int navail, nfree;
-	int nbigger;
+	int	len, totlen;
+	int	i, bits, hdrlen, mtu;
+	int	flen;
+	int	navail,	nfree, nzero;
+	int	nbigger;
+	int	totspeed;
+	int	totfree;
 	unsigned char *p, *q;
 	struct list_head *list;
 	struct channel *pch;
 	struct sk_buff *frag;
 	struct ppp_channel *chan;
 
-	nfree = 0;	/* # channels which have no packet already queued */
+	totspeed = 0; /*total bitrate of the bundle*/
+	nfree =	0;	/* # channels which	have no	packet already queued */
 	navail = 0;	/* total # of usable channels (not deregistered) */
+	nzero =	0; /* number of	channels with zero speed associated*/
+	totfree	= 0; /*total # of channels available and
+				  *having no queued packets before
+				  *starting the fragmentation*/
+
 	hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
-	i = 0;
-	list_for_each_entry(pch, &ppp->channels, clist) {
+	i =	0;
+	list_for_each_entry(pch, &ppp->channels, clist)	{
 		navail += pch->avail = (pch->chan != NULL);
-		if (pch->avail) {
+		pch->speed = pch->chan->speed;
+		if (pch->avail)	{
 			if (skb_queue_empty(&pch->file.xq) ||
-			    !pch->had_frag) {
-				pch->avail = 2;
-				++nfree;
-			}
-			if (!pch->had_frag && i < ppp->nxchan)
-				ppp->nxchan = i;
+				!pch->had_frag)	{
+					if (pch->speed == 0)
+						nzero++;
+					else
+						totspeed += pch->speed;
+
+					pch->avail = 2;
+					++nfree;
+					++totfree;
+				}
+			if (!pch->had_frag && i	< ppp->nxchan)
+				ppp->nxchan	= i;
 		}
 		++i;
 	}
-
 	/*
-	 * Don't start sending this packet unless at least half of
-	 * the channels are free.  This gives much better TCP
-	 * performance if we have a lot of channels.
+	 * Don't start sending this	packet unless at least half	of
+	 * the channels	are	free.  This	gives much better TCP
+	 * performance if we have a	lot	of channels.
 	 */
-	if (nfree == 0 || nfree < navail / 2)
-		return 0;	/* can't take now, leave it in xmit_pending */
+	if (nfree == 0 || nfree	< navail / 2)
+		return 0; /* can't take now, leave it in xmit_pending	*/
 
 	/* Do protocol field compression (XXX this should be optional) */
-	p = skb->data;
-	len = skb->len;
+	p =	skb->data;
+	len	= skb->len;
 	if (*p == 0) {
 		++p;
 		--len;
 	}
 
-	/*
-	 * Decide on fragment size.
-	 * We create a fragment for each free channel regardless of
-	 * how small they are (i.e. even 0 length) in order to minimize
-	 * the time that it will take to detect when a channel drops
-	 * a fragment.
-	 */
-	fragsize = len;
-	if (nfree > 1)
-		fragsize = DIV_ROUND_UP(fragsize, nfree);
-	/* nbigger channels get fragsize bytes, the rest get fragsize-1,
-	   except if nbigger==0, then they all get fragsize. */
-	nbigger = len % nfree;
+	totlen = len;
+	nbigger	= len %	nfree;
 
-	/* skip to the channel after the one we last used
-	   and start at that one */
+	/* skip	to the channel after the one we	last used
+	   and start at	that one */
 	list = &ppp->channels;
-	for (i = 0; i < ppp->nxchan; ++i) {
+	for	(i = 0;	i <	ppp->nxchan; ++i) {
 		list = list->next;
-		if (list == &ppp->channels) {
-			i = 0;
+		if (list ==	&ppp->channels)	{
+			i =	0;
 			break;
 		}
 	}
 
-	/* create a fragment for each channel */
+	/* create a	fragment for each channel */
 	bits = B;
-	while (nfree > 0 || len > 0) {
+	while (nfree > 0 &&	len	> 0) {
 		list = list->next;
-		if (list == &ppp->channels) {
-			i = 0;
+		if (list ==	&ppp->channels)	{
+			i =	0;
 			continue;
 		}
-		pch = list_entry(list, struct channel, clist);
+		pch	= list_entry(list, struct channel, clist);
 		++i;
 		if (!pch->avail)
 			continue;
 
 		/*
-		 * Skip this channel if it has a fragment pending already and
-		 * we haven't given a fragment to all of the free channels.
+		 * Skip	this channel if	it has a fragment pending already and
+		 * we haven't given	a fragment to all of the free channels.
 		 */
 		if (pch->avail == 1) {
-			if (nfree > 0)
+			if (nfree >	0)
 				continue;
 		} else {
-			--nfree;
 			pch->avail = 1;
 		}
 
 		/* check the channel's mtu and whether it is still attached. */
 		spin_lock_bh(&pch->downl);
 		if (pch->chan == NULL) {
-			/* can't use this channel, it's being deregistered */
+			/* can't use this channel, it's	being deregistered */
+			if (pch->speed == 0)
+				nzero--;
+			else
+				totspeed -=	pch->speed;
+
 			spin_unlock_bh(&pch->downl);
 			pch->avail = 0;
-			if (--navail == 0)
+			totlen = len;
+			totfree--;
+			nfree--;
+			if (--navail ==	0)
 				break;
 			continue;
 		}
 
 		/*
-		 * Create a fragment for this channel of
-		 * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
-		 * If mtu+2-hdrlen < 4, that is a ridiculously small
-		 * MTU, so we use mtu = 2 + hdrlen.
+		*if the channel speed is not set divide
+		*the packet	evenly among the free channels;
+		*otherwise divide it according to the speed
+		*of the channel we are going to transmit on
+		*/
+		if (pch->speed == 0) {
+			flen = totlen/nfree	;
+			if (nbigger > 0) {
+				flen++;
+				nbigger--;
+			}
+		} else {
+			flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+				((totspeed*totfree)/pch->speed)) - hdrlen;
+			if (nbigger > 0) {
+				flen += ((totfree - nzero)*pch->speed)/totspeed;
+				nbigger -= ((totfree - nzero)*pch->speed)/
+							totspeed;
+			}
+		}
+		nfree--;
+
+		/*
+		 *check	if we are on the last channel or
+		 *we exceded the lenght	of the data	to
+		 *fragment
+		 */
+		if ((nfree == 0) || (flen > len))
+			flen = len;
+		/*
+		 *it is not worth to tx on slow channels:
+		 *in that case from the resulting flen according to the
+		 *above formula will be equal or less than zero.
+		 *Skip the channel in this case
 		 */
-		if (fragsize > len)
-			fragsize = len;
-		flen = fragsize;
-		mtu = pch->chan->mtu + 2 - hdrlen;
-		if (mtu < 4)
-			mtu = 4;
+		if (flen <=	0) {
+			pch->avail = 2;
+			spin_unlock_bh(&pch->downl);
+			continue;
+		}
+
+		mtu	= pch->chan->mtu + 2 - hdrlen;
+		if (mtu	< 4)
+			mtu	= 4;
 		if (flen > mtu)
 			flen = mtu;
-		if (flen == len && nfree == 0)
-			bits |= E;
-		frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+		if (flen ==	len)
+			bits |=	E;
+		frag = alloc_skb(flen +	hdrlen + (flen == 0), GFP_ATOMIC);
 		if (!frag)
 			goto noskb;
-		q = skb_put(frag, flen + hdrlen);
+		q =	skb_put(frag, flen + hdrlen);
 
-		/* make the MP header */
+		/* make	the	MP header */
 		q[0] = PPP_MP >> 8;
 		q[1] = PPP_MP;
 		if (ppp->flags & SC_MP_XSHORTSEQ) {
-			q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+			q[2] = bits	+ ((ppp->nxseq >> 8) & 0xf);
 			q[3] = ppp->nxseq;
 		} else {
 			q[2] = bits;
@@ -1375,43 +1419,28 @@
 			q[5] = ppp->nxseq;
 		}
 
-		/*
-		 * Copy the data in.
-		 * Unfortunately there is a bug in older versions of
-		 * the Linux PPP multilink reconstruction code where it
-		 * drops 0-length fragments.  Therefore we make sure the
-		 * fragment has at least one byte of data.  Any bytes
-		 * we add in this situation will end up as padding on the
-		 * end of the reconstructed packet.
-		 */
-		if (flen == 0)
-			*skb_put(frag, 1) = 0;
-		else
-			memcpy(q + hdrlen, p, flen);
+		memcpy(q + hdrlen, p, flen);
 
 		/* try to send it down the channel */
 		chan = pch->chan;
-		if (!skb_queue_empty(&pch->file.xq) ||
-		    !chan->ops->start_xmit(chan, frag))
+		if (!skb_queue_empty(&pch->file.xq)	||
+			!chan->ops->start_xmit(chan, frag))
 			skb_queue_tail(&pch->file.xq, frag);
-		pch->had_frag = 1;
+		pch->had_frag =	1;
 		p += flen;
-		len -= flen;
+		len	-= flen;
 		++ppp->nxseq;
 		bits = 0;
 		spin_unlock_bh(&pch->downl);
-
-		if (--nbigger == 0 && fragsize > 0)
-			--fragsize;
 	}
-	ppp->nxchan = i;
+	ppp->nxchan	= i;
 
 	return 1;
 
  noskb:
 	spin_unlock_bh(&pch->downl);
 	if (ppp->debug & 1)
-		printk(KERN_ERR "PPP: no memory (fragment)\n");
+		printk(KERN_ERR	"PPP: no memory	(fragment)\n");
 	++ppp->dev->stats.tx_errors;
 	++ppp->nxseq;
 	return 1;	/* abandon the frame */
diff -urN ./linux-2.6.28.2/drivers/net/ppp_synctty.c ./linux-2.6.28.2.new/drivers/net/ppp_synctty.c
--- ./linux-2.6.28.2/drivers/net/ppp_synctty.c	2009-01-25 00:42:07.000000000 +0000
+++ ./linux-2.6.28.2.new/drivers/net/ppp_synctty.c	2009-01-28 16:55:16.000000000 +0000
@@ -206,6 +206,7 @@
 {
 	struct syncppp *ap;
 	int err;
+	int speed;
 
 	if (tty->ops->write == NULL)
 		return -EOPNOTSUPP;
@@ -234,6 +235,8 @@
 	ap->chan.ops = &sync_ops;
 	ap->chan.mtu = PPP_MRU;
 	ap->chan.hdrlen = 2;	/* for A/C bytes */
+	speed = tty_get_baud_rate(tty);
+	ap->chan.speed = speed;
 	err = ppp_register_channel(&ap->chan);
 	if (err)
 		goto out_free;
diff -urN ./linux-2.6.28.2/include/linux/ppp_channel.h ./linux-2.6.28.2.new/include/linux/ppp_channel.h
--- ./linux-2.6.28.2/include/linux/ppp_channel.h	2009-01-25 00:42:07.000000000 +0000
+++ ./linux-2.6.28.2.new/include/linux/ppp_channel.h	2009-01-28 16:54:01.000000000 +0000
@@ -39,8 +39,8 @@
 	int		mtu;		/* max transmit packet size */
 	int		hdrlen;		/* amount of headroom channel needs */
 	void		*ppp;		/* opaque to channel */
-	/* the following are not used at present */
 	int		speed;		/* transfer rate (bytes/second) */
+	/* the following is not used at present */
 	int		latency;	/* overhead time in milliseconds */
 };
 
---------------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: One Spencer Dock, North Wall Quay, Dublin 1
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2004-10-10 23:43 Pete Popov
  0 siblings, 0 replies; 77+ messages in thread
From: Pete Popov @ 2004-10-10 23:43 UTC (permalink / raw)
  To: linux-mips@linux-mips.org

Ralf,

Here is another patch for consideration. No updates are needed to other
platforms that need/require the obsolete ide probing. When enabled, the
patch gets rid of all the probing of obsolete ide devices.

diff -Naur --exclude=CVS linux-2.6-orig/arch/mips/Kconfig linux-2.6-dev/arch/mips/Kconfig
--- linux-2.6-orig/arch/mips/Kconfig	2004-09-25 23:33:01.000000000 -0700
+++ linux-2.6-dev/arch/mips/Kconfig	2004-10-10 11:41:45.000000000 -0700
@@ -577,6 +577,7 @@
 	depends on SOC_AU1500
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
+	select MIPS_DISABLE_OBSOLETE_IDE
 
 config MIPS_DB1550
 	bool "DB1550 board"
@@ -896,6 +897,9 @@
 	depends on LASAT
 	default y
 
+config MIPS_DISABLE_OBSOLETE_IDE
+	bool
+
 config CPU_LITTLE_ENDIAN
 	bool "Generate little endian code"
 	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || HP_LASERJET || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
diff -Naur --exclude=CVS linux-2.6-orig/include/asm-mips/mach-generic/ide.h linux-2.6-dev/include/asm-mips/mach-generic/ide.h
--- linux-2.6-orig/include/asm-mips/mach-generic/ide.h	2004-06-09 07:12:13.000000000 -0700
+++ linux-2.6-dev/include/asm-mips/mach-generic/ide.h	2004-10-10 11:44:22.000000000 -0700
@@ -20,6 +20,7 @@
 # endif
 #endif
 
+#ifndef CONFIG_MIPS_DISABLE_OBSOLETE_IDE
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
 static inline int ide_default_irq(unsigned long base)
@@ -49,6 +50,7 @@
 			return 0;
 	}
 }
+#endif /* CONFIG_MIPS_DISABLE_OBSOLETE_IDE */
 
 #define IDE_ARCH_OBSOLETE_INIT
 #define ide_default_io_ctl(base)	((base) + 0x206) /* obsolete */

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2004-10-10 17:17 Pete Popov
  2004-10-10 18:01 ` PATCH Geert Uytterhoeven
  0 siblings, 1 reply; 77+ messages in thread
From: Pete Popov @ 2004-10-10 17:17 UTC (permalink / raw)
  To: linux-mips@linux-mips.org

Ralf, or anyone else, any suggestions on how to get a patch like the one
below accepted in 2.6? It's needed due to the 36 bit address of the
pcmcia controller on the Au1x CPUs.

diff -Naur --exclude=CVS linux-2.6-orig/include/pcmcia/cs_types.h linux-2.6-dev/include/pcmcia/cs_types.h
--- linux-2.6-orig/include/pcmcia/cs_types.h	2004-02-24 18:09:31.000000000 -0800
+++ linux-2.6-dev/include/pcmcia/cs_types.h	2004-09-25 19:57:11.000000000 -0700
@@ -36,8 +36,10 @@
 #include <sys/types.h>
 #endif
 
-#if defined(__arm__) || defined(__mips__)
-typedef u_int   ioaddr_t;
+#if defined(__arm__)
+typedef u_int ioaddr_t;
+#elif defined(__mips__)
+typedef phys_t ioaddr_t;
 #else
 typedef u_short	ioaddr_t;
 #endif
diff -Naur --exclude=CVS linux-2.6-orig/include/pcmcia/ss.h linux-2.6-dev/include/pcmcia/ss.h
--- linux-2.6-orig/include/pcmcia/ss.h	2004-09-22 23:20:17.000000000 -0700
+++ linux-2.6-dev/include/pcmcia/ss.h	2004-09-25 19:57:47.000000000 -0700
@@ -103,7 +103,7 @@
     u_char	map;
     u_char	flags;
     u_short	speed;
-    u_long	static_start;
+    ioaddr_t	static_start;
     u_int	card_start;
     struct resource *res;
 } pccard_mem_map;

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2004-10-10  7:17 Pete Popov
  0 siblings, 0 replies; 77+ messages in thread
From: Pete Popov @ 2004-10-10  7:17 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips@linux-mips.org


36 bit I/O support patch, one more time -- looks like my email program
corrupted the patch, sorry.


Pete

Index: arch/mips/au1000/common/setup.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/au1000/common/setup.c,v
retrieving revision 1.17
diff -u -r1.17 setup.c
--- arch/mips/au1000/common/setup.c	14 Sep 2004 06:38:46 -0000	1.17
+++ arch/mips/au1000/common/setup.c	19 Sep 2004 22:51:20 -0000
@@ -56,10 +56,6 @@
 extern void au1x_time_init(void);
 extern void (*board_timer_setup)(struct irqaction *irq);
 extern void au1x_timer_setup(struct irqaction *irq);
-#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550))
-extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size);
-static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size);
-#endif
 extern void au1xxx_time_init(void);
 extern void au1xxx_timer_setup(struct irqaction *irq);
 extern void set_cpuspec(void);
@@ -147,9 +143,6 @@
 	_machine_power_off = au1000_power_off;
 	board_time_init = au1xxx_time_init;
 	board_timer_setup = au1xxx_timer_setup;
-#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550))
-	fixup_bigphys_addr = au1500_fixup_bigphys_addr;
-#endif
 
 	/* IO/MEM resources. */
 	set_io_port_base(0);
@@ -200,7 +193,7 @@
 
 #if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550))
 /* This routine should be valid for all Au1500 based boards */
-static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 {
 	u32 pci_start = (u32)Au1500_PCI_MEM_START;
 	u32 pci_end = (u32)Au1500_PCI_MEM_END;
Index: arch/mips/mm/Makefile
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/Makefile,v
retrieving revision 1.68
diff -u -r1.68 Makefile
--- arch/mips/mm/Makefile	20 Jun 2004 23:52:17 -0000	1.68
+++ arch/mips/mm/Makefile	19 Sep 2004 22:51:21 -0000
@@ -41,10 +41,11 @@
 obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-r4k.o
+obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
 obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
 obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
+obj-$(CONFIG_64BIT_PHYS_ADDR)	+= remap.o
 endif
 ifdef CONFIG_MIPS64
 obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o tlbex64-r4k.o
Index: arch/mips/mm/ioremap.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/ioremap.c,v
retrieving revision 1.19
diff -u -r1.19 ioremap.c
--- arch/mips/mm/ioremap.c	19 Apr 2004 16:36:35 -0000	1.19
+++ arch/mips/mm/ioremap.c	19 Sep 2004 22:51:21 -0000
@@ -97,6 +97,15 @@
 }
 
 /*
+ * Allow physical addresses to be fixed up to help 36 bit peripherals.
+ */
+phys_t __attribute__ ((weak))
+fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+/*
  * Generic mapping function (not visible outside):
  */
 
@@ -110,7 +119,7 @@
  * caller shouldn't need to know that small detail.
  */
 
-#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL))
+#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
 
 void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 {
@@ -119,6 +128,8 @@
 	phys_t last_addr;
 	void * addr;
 
+	phys_addr = fixup_bigphys_addr(phys_addr, size);
+
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
 	if (!size || last_addr < phys_addr)
@@ -190,3 +201,4 @@
 
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(fixup_bigphys_addr);
Index: arch/mips/mm/remap.c
===================================================================
RCS file: arch/mips/mm/remap.c
diff -N arch/mips/mm/remap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/remap.c	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,115 @@
+/*
+ *  arch/mips/mm/remap.c
+ *
+ *  A copy of mm/memory.c, with mods for 64 bit physical I/O addresses on
+ *  32 bit native word platforms.
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ */
+
+
+#include <linux/kernel_stat.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/rmap.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <linux/swapops.h>
+#include <linux/elf.h>
+
+
+/*
+ * maps a range of physical memory into the requested pages. the old
+ * mappings are removed. any references to nonexistent pages results
+ * in null mappings (currently treated as "copy-on-access")
+ */
+static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long end;
+	unsigned long pfn;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		BUG_ON(!pte_none(*pte));
+		if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
+ 			set_pte(pte, pfn_pte(pfn, prot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long base, end;
+
+	base = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	do {
+		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
+		if (!pte)
+			return -ENOMEM;
+		remap_pte_range(pte, base + address, end - address, address + phys_addr, prot);
+		pte_unmap(pte);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+/*  Note: this is only safe if the mm semaphore is held when called. */
+int remap_page_range_high(struct vm_area_struct *vma, unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	int error = 0;
+	pgd_t * dir;
+	unsigned long beg = from;
+	unsigned long end = from + size;
+	struct mm_struct *mm = vma->vm_mm;
+
+	phys_addr -= from;
+	dir = pgd_offset(mm, from);
+	flush_cache_range(vma, beg, end);
+	if (from >= end)
+		BUG();
+
+	spin_lock(&mm->page_table_lock);
+	do {
+		pmd_t *pmd = pmd_alloc(mm, dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (from && (from < end));
+	/*
+	 * Why flush? remap_pte_range has a BUG_ON for !pte_none()
+	 */
+	flush_tlb_range(vma, beg, end);
+	spin_unlock(&mm->page_table_lock);
+	return error;
+}
+
+EXPORT_SYMBOL(remap_page_range_high);
Index: arch/mips/mm/tlb-r4k.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/tlb-r4k.c,v
retrieving revision 1.38
diff -u -r1.38 tlb-r4k.c
--- arch/mips/mm/tlb-r4k.c	19 Mar 2004 04:07:59 -0000	1.38
+++ arch/mips/mm/tlb-r4k.c	19 Sep 2004 22:51:21 -0000
@@ -255,8 +255,14 @@
 	idx = read_c0_index();
 	ptep = pte_offset_map(pmdp, address);
 
-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
-	write_c0_entrylo1(pte_val(*ptep) >> 6);
+ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ 	write_c0_entrylo0(ptep->pte_high);
+ 	ptep++;
+ 	write_c0_entrylo1(ptep->pte_high);
+#else
+  	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+  	write_c0_entrylo1(pte_val(*ptep) >> 6);
+#endif
 	write_c0_entryhi(address | pid);
 	mtc0_tlbw_hazard();
 	if (idx < 0)
Index: arch/mips/mm/tlbex32-mips32.S
===================================================================
RCS file: arch/mips/mm/tlbex32-mips32.S
diff -N arch/mips/mm/tlbex32-mips32.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/tlbex32-mips32.S	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,325 @@
+/*
+ * TLB exception handling code for MIPS32 CPUs.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-cpu abstraction and reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Pete Popov, ppopov@pacbell.net
+ * Added 36 bit phys address support.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+
+/* We really only support 36 bit physical addresses on MIPS32 */
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
+#define PTE_SIZE        8
+#define PTEP_INDX_MSK	0xff0
+#define PTE_INDX_MSK	0xff8
+#define PTE_INDX_SHIFT 9
+#define CONVERT_PTE(pte)
+#define PTE_MAKEWRITE_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#define PTE_MAKEVALID_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, pte, _PAGE_VALID; \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#else
+
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        0
+#define PTE_SIZE	4
+#define PTEP_INDX_MSK	0xff8
+#define PTE_INDX_MSK	0xffc
+#define PTE_INDX_SHIFT	10
+#define CONVERT_PTE(pte) srl pte, pte, 6
+#define PTE_MAKEWRITE_HIGH(pte, ptr)
+#define PTE_MAKEVALID_HIGH(pte, ptr)
+
+#endif  /* CONFIG_64BIT_PHYS_ADDR */
+
+	__INIT
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define GET_PTE_OFF(reg)
+#else
+#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+#endif
+
+/*	
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, MIPS32 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, pgd_current
+	srl	k1, 23
+	sll	k1, 2				# log2(sizeof(pgd_t)
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else 
+	lw	k1, pgd_current			# get pgd pointer
+#endif	
+	nop
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	GET_PTE_OFF(k0)				# get pte offset
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+
+	PTE_L	k0, PTE_HALF(k1)		# get even pte
+	CONVERT_PTE(k0)
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_L	k1, (PTE_HALF+PTE_SIZE)(k1)	# get odd pte
+	CONVERT_PTE(k1)
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+/*
+ * These are here to avoid putting ifdefs in tlb-r4k.c
+ */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_nevada)
+	.set	mips3
+	PANIC("Nevada Exception Vec 0 called")
+	END(except_vec0_nevada)
+
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	PANIC("R4600 Exception Vec 0 called")
+	END(except_vec0_r4600)
+
+	__FINIT
+
+/*
+ * ABUSE of CPP macros 101.
+ *
+ * After this macro runs, the pte faulted on is
+ * in register PTE, a ptr into the table in which
+ * the pte belongs is in PTR.
+ */
+
+#ifdef CONFIG_SMP
+#define GET_PGD(scratch, ptr)        \
+	mfc0    ptr, CP0_CONTEXT;    \
+	la      scratch, pgd_current;\
+	srl     ptr, 23;             \
+	sll     ptr, 2;              \
+	addu    ptr, scratch, ptr;   \
+	lw      ptr, (ptr);          
+#else
+#define GET_PGD(scratch, ptr)    \
+	lw	ptr, pgd_current;
+#endif
+
+#define LOAD_PTE(pte, ptr) \
+	GET_PGD(pte, ptr)          \
+	mfc0	pte, CP0_BADVADDR; \
+	srl	pte, pte, _PGDIR_SHIFT; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, (ptr); \
+	srl	pte, pte, PTE_INDX_SHIFT; \
+	and	pte, pte, PTE_INDX_MSK; \
+	addu	ptr, ptr, pte; \
+	PTE_L	pte, (ptr);
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr, tmp) \
+	ori	ptr, ptr, PTE_SIZE; \
+	xori	ptr, ptr, PTE_SIZE; \
+	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
+	CONVERT_PTE(tmp); \
+	P_MTC0	tmp, CP0_ENTRYLO1; \
+	PTE_L	ptr, PTE_HALF(ptr); \
+	CONVERT_PTE(ptr); \
+	P_MTC0	ptr, CP0_ENTRYLO0;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	STI; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	PTE_S	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	PTE_S	pte, (ptr);
+
+	.set	noreorder
+
+#define R5K_HAZARD nop
+
+	.align	5
+	NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+invalid_tlbl:
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp
+	PTE_PRESENT(k0, k1, nopage_tlbl)
+	PTE_MAKEVALID_HIGH(k0, k1)
+	PTE_MAKEVALID(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3	
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbl:
+	DO_FAULT(0)
+	END(handle_tlbl)
+
+	.align	5
+	NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+        li      k0,0
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp				# find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbs:
+	DO_FAULT(1)
+	END(handle_tlbs)
+
+	.align	5
+	NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	PTE_L	k0, (k1)
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+	END(handle_mod)
+
Index: include/asm-mips/addrspace.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/addrspace.h,v
retrieving revision 1.13
diff -u -r1.13 addrspace.h
--- include/asm-mips/addrspace.h	30 Nov 2003 01:52:25 -0000	1.13
+++ include/asm-mips/addrspace.h	19 Sep 2004 22:51:28 -0000
@@ -80,7 +80,11 @@
 #define XKSSEG			0x4000000000000000
 #define XKPHYS			0x8000000000000000
 #define XKSEG			0xc000000000000000
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define CKSEG0			0x80000000
+#else
 #define CKSEG0			0xffffffff80000000
+#endif
 #define CKSEG1			0xffffffffa0000000
 #define CKSSEG			0xffffffffc0000000
 #define CKSEG3			0xffffffffe0000000
Index: include/asm-mips/io.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/io.h,v
retrieving revision 1.72
diff -u -r1.72 io.h
--- include/asm-mips/io.h	19 Aug 2004 15:27:41 -0000	1.72
+++ include/asm-mips/io.h	19 Sep 2004 22:51:29 -0000
@@ -171,7 +171,7 @@
 extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
 extern void __iounmap(void *addr);
 
-static inline void * __ioremap_mode(unsigned long offset, unsigned long size,
+static inline void * __ioremap_mode(phys_t offset, unsigned long size,
 	unsigned long flags)
 {
 	if (cpu_has_64bit_addresses) {
Index: include/asm-mips/page.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/page.h,v
retrieving revision 1.44
diff -u -r1.44 page.h
--- include/asm-mips/page.h	20 Aug 2004 12:02:18 -0000	1.44
+++ include/asm-mips/page.h	19 Sep 2004 22:51:29 -0000
@@ -32,7 +32,7 @@
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PAGE_SHIFT	16
 #endif
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(1L << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
@@ -75,15 +75,22 @@
  * These are used to make use of C type-checking..
  */
 #ifdef CONFIG_64BIT_PHYS_ADDR
-typedef struct { unsigned long long pte; } pte_t;
+  #ifdef CONFIG_CPU_MIPS32
+    typedef struct { unsigned long pte_low, pte_high; } pte_t;
+    #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+  #else
+     typedef struct { unsigned long long pte; } pte_t;
+     #define pte_val(x)	((x).pte)
+  #endif
 #else
 typedef struct { unsigned long pte; } pte_t;
+#define pte_val(x)	((x).pte)
 #endif
+
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
Index: include/asm-mips/pgtable-32.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-32.h,v
retrieving revision 1.11
diff -u -r1.11 pgtable-32.h
--- include/asm-mips/pgtable-32.h	26 Jun 2004 15:15:24 -0000	1.11
+++ include/asm-mips/pgtable-32.h	19 Sep 2004 22:51:29 -0000
@@ -130,8 +130,21 @@
 static inline int pgd_present(pgd_t pgd)	{ return 1; }
 static inline void pgd_clear(pgd_t *pgdp)	{ }
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
 #define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_pfn(x)		((unsigned long)((x).pte_high >> 6))
+static inline pte_t
+pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+	pte_t pte;
+	pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f);
+	pte.pte_low = pgprot_val(prot);
+	return pte;
+}
+
+#else
 
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
 
 #ifdef CONFIG_CPU_VR41XX
 #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
@@ -140,6 +153,7 @@
 #define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
 #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
 #endif
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32) */
 
 #define __pgd_offset(address)	pgd_index(address)
 #define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
@@ -207,11 +221,19 @@
  */
 #define PTE_FILE_MAX_BITS	27
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+	/* fixme */
+#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f))
+#define pgoff_to_pte(off) \
+ 	((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)})
+  
+#else
 #define pte_to_pgoff(_pte) \
 	((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 ))
 
 #define pgoff_to_pte(off) \
 	((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE })
+#endif
 
 #endif
 
Index: include/asm-mips/pgtable-bits.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-bits.h,v
retrieving revision 1.9
diff -u -r1.9 pgtable-bits.h
--- include/asm-mips/pgtable-bits.h	24 Jun 2004 20:31:11 -0000	1.9
+++ include/asm-mips/pgtable-bits.h	19 Sep 2004 22:51:29 -0000
@@ -33,6 +33,31 @@
  * unpredictable things.  The code (when it is written) to deal with
  * this problem will be in the update_mmu_cache() code for the r4k.
  */
+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+
+#define _PAGE_PRESENT               (1<<6)  /* implemented in software */
+#define _PAGE_READ                  (1<<7)  /* implemented in software */
+#define _PAGE_WRITE                 (1<<8)  /* implemented in software */
+#define _PAGE_ACCESSED              (1<<9)  /* implemented in software */
+#define _PAGE_MODIFIED              (1<<10) /* implemented in software */
+#define _PAGE_FILE                  (1<<10)  /* set:pagecache unset:swap */
+
+#define _PAGE_R4KBUG                (1<<0)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL                (1<<0)
+#define _PAGE_VALID                 (1<<1)
+#define _PAGE_SILENT_READ           (1<<1)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<2)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<2)
+#define _CACHE_MASK                 (7<<3)
+
+/* MIPS32 defines only values 2 and 3. The rest are implementation
+ * dependent.
+ */
+#define _CACHE_UNCACHED             (2<<3)  
+#define _CACHE_CACHABLE_NONCOHERENT (3<<3) 
+
+#else
+
 #define _PAGE_PRESENT               (1<<0)  /* implemented in software */
 #define _PAGE_READ                  (1<<1)  /* implemented in software */
 #define _PAGE_WRITE                 (1<<2)  /* implemented in software */
@@ -97,6 +122,7 @@
 
 #endif
 #endif
+#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */
 
 #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
 #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -113,6 +139,10 @@
 #define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
 #endif
 
+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 3)
+#else
 #define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+#endif
 
 #endif /* _ASM_PGTABLE_BITS_H */
Index: include/asm-mips/pgtable.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable.h,v
retrieving revision 1.97
diff -u -r1.97 pgtable.h
--- include/asm-mips/pgtable.h	19 Jun 2004 01:39:24 -0000	1.97
+++ include/asm-mips/pgtable.h	19 Sep 2004 22:51:29 -0000
@@ -80,6 +80,34 @@
 #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
 #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	ptep->pte_high = pte.pte_high;
+	smp_wmb();
+	ptep->pte_low = pte.pte_low;
+	//printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
+
+	if (pte_val(pte) & _PAGE_GLOBAL) {
+		pte_t *buddy = ptep_buddy(ptep);
+		/*
+		 * Make sure the buddy is global too (if it's !none,
+		 * it better already be global)
+		 */
+		if (pte_none(*buddy))
+			buddy->pte_low |= _PAGE_GLOBAL;
+	}
+}
+
+static inline void pte_clear(pte_t *ptep)
+{
+	/* Preserve global status for the pair */
+	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+		set_pte(ptep, __pte(_PAGE_GLOBAL));
+	else
+		set_pte(ptep, __pte(0));
+}
+#else
 /*
  * Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
@@ -111,6 +139,7 @@
 #endif
 		set_pte(ptep, __pte(0));
 }
+#endif
 
 /*
  * (pmds are folded into pgds so this doesn't get actually called,
@@ -130,6 +159,79 @@
  * Undefined behaviour if not..
  */
 static inline int pte_user(pte_t pte)	{ BUG(); return 0; }
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline int pte_read(pte_t pte)	{ return (pte).pte_low & _PAGE_READ; }
+static inline int pte_write(pte_t pte)	{ return (pte).pte_low & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte)	{ return (pte).pte_low & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)	{ return (pte).pte_low & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)	{ return (pte).pte_low & _PAGE_FILE; }
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_WRITE;
+	if ((pte).pte_low & _PAGE_MODIFIED) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_READ;
+	if ((pte).pte_low & _PAGE_ACCESSED) {
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_MODIFIED;
+	if ((pte).pte_low & _PAGE_WRITE) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_ACCESSED;
+	if ((pte).pte_low & _PAGE_READ)
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	return pte;
+}
+#else
 static inline int pte_read(pte_t pte)	{ return pte_val(pte) & _PAGE_READ; }
 static inline int pte_write(pte_t pte)	{ return pte_val(pte) & _PAGE_WRITE; }
 static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_MODIFIED; }
@@ -191,6 +293,7 @@
 		pte_val(pte) |= _PAGE_SILENT_READ;
 	return pte;
 }
+#endif
 
 /*
  * Macro to make mark a page protection value as "uncacheable".  Note
@@ -215,10 +318,20 @@
  */
 #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
 
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte_low &= _PAGE_CHG_MASK;
+	pte.pte_low |= pgprot_val(newprot);
+	pte.pte_high |= pgprot_val(newprot) & 0x3f;
+	return pte;
+}
+#else
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
 	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
 }
+#endif
 

 extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
@@ -245,7 +358,27 @@
  */
 #define HAVE_ARCH_UNMAPPED_AREA
 
+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
+
+extern int remap_page_range_high(struct vm_area_struct *vma,
+		unsigned long from,
+		phys_t phys_addr,
+		unsigned long size,
+		pgprot_t prot);
+
+static inline int io_remap_page_range(struct vm_area_struct *vma,
+		unsigned long from,
+		unsigned long phys_addr,
+		unsigned long size,
+		pgprot_t prot)
+{
+	phys_t phys_addr_high = fixup_bigphys_addr(phys_addr, size);
+	return remap_page_range_high(vma, from, phys_addr_high, size, prot);
+}
+#else
 #define io_remap_page_range remap_page_range
+#endif
 
 /*
  * No page table caches to initialise

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2004-10-10  5:31 Pete Popov
  0 siblings, 0 replies; 77+ messages in thread
From: Pete Popov @ 2004-10-10  5:31 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

Ralf,

Here is the 2.6 36 bit I/O support patch. We beat up on it quite a bit 
and it seems solid on the Au1x (Db1500 board).

Pete

Index: arch/mips/au1000/common/setup.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/au1000/common/setup.c,v
retrieving revision 1.17
diff -u -r1.17 setup.c
--- arch/mips/au1000/common/setup.c	14 Sep 2004 06:38:46 -0000	1.17
+++ arch/mips/au1000/common/setup.c	19 Sep 2004 22:51:20 -0000
@@ -56,10 +56,6 @@
  extern void au1x_time_init(void);
  extern void (*board_timer_setup)(struct irqaction *irq);
  extern void au1x_timer_setup(struct irqaction *irq);
-#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || 
defined(CONFIG_SOC_AU1550))
-extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size);
-static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size);
-#endif
  extern void au1xxx_time_init(void);
  extern void au1xxx_timer_setup(struct irqaction *irq);
  extern void set_cpuspec(void);
@@ -147,9 +143,6 @@
  	_machine_power_off = au1000_power_off;
  	board_time_init = au1xxx_time_init;
  	board_timer_setup = au1xxx_timer_setup;
-#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || 
defined(CONFIG_SOC_AU1550))
-	fixup_bigphys_addr = au1500_fixup_bigphys_addr;
-#endif

  	/* IO/MEM resources. */
  	set_io_port_base(0);
@@ -200,7 +193,7 @@

  #if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || 
defined(CONFIG_SOC_AU1550))
  /* This routine should be valid for all Au1500 based boards */
-static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
  {
  	u32 pci_start = (u32)Au1500_PCI_MEM_START;
  	u32 pci_end = (u32)Au1500_PCI_MEM_END;
Index: arch/mips/mm/Makefile
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/Makefile,v
retrieving revision 1.68
diff -u -r1.68 Makefile
--- arch/mips/mm/Makefile	20 Jun 2004 23:52:17 -0000	1.68
+++ arch/mips/mm/Makefile	19 Sep 2004 22:51:21 -0000
@@ -41,10 +41,11 @@
  obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
  obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
  obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-r4k.o
+obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
  obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
  obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
  obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
+obj-$(CONFIG_64BIT_PHYS_ADDR)	+= remap.o
  endif
  ifdef CONFIG_MIPS64
  obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o tlbex64-r4k.o
Index: arch/mips/mm/ioremap.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/ioremap.c,v
retrieving revision 1.19
diff -u -r1.19 ioremap.c
--- arch/mips/mm/ioremap.c	19 Apr 2004 16:36:35 -0000	1.19
+++ arch/mips/mm/ioremap.c	19 Sep 2004 22:51:21 -0000
@@ -97,6 +97,15 @@
  }

  /*
+ * Allow physical addresses to be fixed up to help 36 bit peripherals.
+ */
+phys_t __attribute__ ((weak))
+fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+/*
   * Generic mapping function (not visible outside):
   */

@@ -110,7 +119,7 @@
   * caller shouldn't need to know that small detail.
   */

-#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL))
+#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))

  void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
  {
@@ -119,6 +128,8 @@
  	phys_t last_addr;
  	void * addr;

+	phys_addr = fixup_bigphys_addr(phys_addr, size);
+
  	/* Don't allow wraparound or zero size */
  	last_addr = phys_addr + size - 1;
  	if (!size || last_addr < phys_addr)
@@ -190,3 +201,4 @@

  EXPORT_SYMBOL(__ioremap);
  EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(fixup_bigphys_addr);
Index: arch/mips/mm/remap.c
===================================================================
RCS file: arch/mips/mm/remap.c
diff -N arch/mips/mm/remap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/remap.c	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,115 @@
+/*
+ *  arch/mips/mm/remap.c
+ *
+ *  A copy of mm/memory.c, with mods for 64 bit physical I/O addresses on
+ *  32 bit native word platforms.
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ */
+
+
+#include <linux/kernel_stat.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/rmap.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <linux/swapops.h>
+#include <linux/elf.h>
+
+
+/*
+ * maps a range of physical memory into the requested pages. the old
+ * mappings are removed. any references to nonexistent pages results
+ * in null mappings (currently treated as "copy-on-access")
+ */
+static inline void remap_pte_range(pte_t * pte, unsigned long address, 
unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long end;
+	unsigned long pfn;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		BUG_ON(!pte_none(*pte));
+		if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
+ 			set_pte(pte, pfn_pte(pfn, prot));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, 
unsigned long address, unsigned long size,
+	phys_t phys_addr, pgprot_t prot)
+{
+	unsigned long base, end;
+
+	base = address & PGDIR_MASK;
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	do {
+		pte_t * pte = pte_alloc_map(mm, pmd, base + address);
+		if (!pte)
+			return -ENOMEM;
+		remap_pte_range(pte, base + address, end - address, address + 
phys_addr, prot);
+		pte_unmap(pte);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+/*  Note: this is only safe if the mm semaphore is held when called. */
+int remap_page_range_high(struct vm_area_struct *vma, unsigned long 
from, phys_t phys_addr, unsigned long size, pgprot_t prot)
+{
+	int error = 0;
+	pgd_t * dir;
+	unsigned long beg = from;
+	unsigned long end = from + size;
+	struct mm_struct *mm = vma->vm_mm;
+
+	phys_addr -= from;
+	dir = pgd_offset(mm, from);
+	flush_cache_range(vma, beg, end);
+	if (from >= end)
+		BUG();
+
+	spin_lock(&mm->page_table_lock);
+	do {
+		pmd_t *pmd = pmd_alloc(mm, dir, from);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		error = remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, 
prot);
+		if (error)
+			break;
+		from = (from + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (from && (from < end));
+	/*
+	 * Why flush? remap_pte_range has a BUG_ON for !pte_none()
+	 */
+	flush_tlb_range(vma, beg, end);
+	spin_unlock(&mm->page_table_lock);
+	return error;
+}
+
+EXPORT_SYMBOL(remap_page_range_high);
Index: arch/mips/mm/tlb-r4k.c
===================================================================
RCS file: /home/cvs/linux/arch/mips/mm/tlb-r4k.c,v
retrieving revision 1.38
diff -u -r1.38 tlb-r4k.c
--- arch/mips/mm/tlb-r4k.c	19 Mar 2004 04:07:59 -0000	1.38
+++ arch/mips/mm/tlb-r4k.c	19 Sep 2004 22:51:21 -0000
@@ -255,8 +255,14 @@
  	idx = read_c0_index();
  	ptep = pte_offset_map(pmdp, address);

-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
-	write_c0_entrylo1(pte_val(*ptep) >> 6);
+ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ 	write_c0_entrylo0(ptep->pte_high);
+ 	ptep++;
+ 	write_c0_entrylo1(ptep->pte_high);
+#else
+  	write_c0_entrylo0(pte_val(*ptep++) >> 6);
+  	write_c0_entrylo1(pte_val(*ptep) >> 6);
+#endif
  	write_c0_entryhi(address | pid);
  	mtc0_tlbw_hazard();
  	if (idx < 0)
Index: arch/mips/mm/tlbex32-mips32.S
===================================================================
RCS file: arch/mips/mm/tlbex32-mips32.S
diff -N arch/mips/mm/tlbex32-mips32.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mm/tlbex32-mips32.S	19 Sep 2004 22:51:21 -0000
@@ -0,0 +1,325 @@
+/*
+ * TLB exception handling code for MIPS32 CPUs.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-cpu abstraction and reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Pete Popov, ppopov@pacbell.net
+ * Added 36 bit phys address support.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+
+/* We really only support 36 bit physical addresses on MIPS32 */
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go 
entry */
+#define PTE_SIZE        8
+#define PTEP_INDX_MSK	0xff0
+#define PTE_INDX_MSK	0xff8
+#define PTE_INDX_SHIFT 9
+#define CONVERT_PTE(pte)
+#define PTE_MAKEWRITE_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#define PTE_MAKEVALID_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, pte, _PAGE_VALID; \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#else
+
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        0
+#define PTE_SIZE	4
+#define PTEP_INDX_MSK	0xff8
+#define PTE_INDX_MSK	0xffc
+#define PTE_INDX_SHIFT	10
+#define CONVERT_PTE(pte) srl pte, pte, 6
+#define PTE_MAKEWRITE_HIGH(pte, ptr)
+#define PTE_MAKEVALID_HIGH(pte, ptr)
+
+#endif  /* CONFIG_64BIT_PHYS_ADDR */
+
+	__INIT
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define GET_PTE_OFF(reg)
+#else
+#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+#endif
+
+/*	
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, MIPS32 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, pgd_current
+	srl	k1, 23
+	sll	k1, 2				# log2(sizeof(pgd_t)
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else
+	lw	k1, pgd_current			# get pgd pointer
+#endif	
+	nop
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, _PGDIR_SHIFT		# get pgd only bits
+
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	GET_PTE_OFF(k0)				# get pte offset
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+
+	PTE_L	k0, PTE_HALF(k1)		# get even pte
+	CONVERT_PTE(k0)
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_L	k1, (PTE_HALF+PTE_SIZE)(k1)	# get odd pte
+	CONVERT_PTE(k1)
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+/*
+ * These are here to avoid putting ifdefs in tlb-r4k.c
+ */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_nevada)
+	.set	mips3
+	PANIC("Nevada Exception Vec 0 called")
+	END(except_vec0_nevada)
+
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	PANIC("R4600 Exception Vec 0 called")
+	END(except_vec0_r4600)
+
+	__FINIT
+
+/*
+ * ABUSE of CPP macros 101.
+ *
+ * After this macro runs, the pte faulted on is
+ * in register PTE, a ptr into the table in which
+ * the pte belongs is in PTR.
+ */
+
+#ifdef CONFIG_SMP
+#define GET_PGD(scratch, ptr)        \
+	mfc0    ptr, CP0_CONTEXT;    \
+	la      scratch, pgd_current;\
+	srl     ptr, 23;             \
+	sll     ptr, 2;              \
+	addu    ptr, scratch, ptr;   \
+	lw      ptr, (ptr);
+#else
+#define GET_PGD(scratch, ptr)    \
+	lw	ptr, pgd_current;
+#endif
+
+#define LOAD_PTE(pte, ptr) \
+	GET_PGD(pte, ptr)          \
+	mfc0	pte, CP0_BADVADDR; \
+	srl	pte, pte, _PGDIR_SHIFT; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, (ptr); \
+	srl	pte, pte, PTE_INDX_SHIFT; \
+	and	pte, pte, PTE_INDX_MSK; \
+	addu	ptr, ptr, pte; \
+	PTE_L	pte, (ptr);
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr, tmp) \
+	ori	ptr, ptr, PTE_SIZE; \
+	xori	ptr, ptr, PTE_SIZE; \
+	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
+	CONVERT_PTE(tmp); \
+	P_MTC0	tmp, CP0_ENTRYLO1; \
+	PTE_L	ptr, PTE_HALF(ptr); \
+	CONVERT_PTE(ptr); \
+	P_MTC0	ptr, CP0_ENTRYLO0;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	STI; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	PTE_S	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	PTE_S	pte, (ptr);
+
+	.set	noreorder
+
+#define R5K_HAZARD nop
+
+	.align	5
+	NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+invalid_tlbl:
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp
+	PTE_PRESENT(k0, k1, nopage_tlbl)
+	PTE_MAKEVALID_HIGH(k0, k1)
+	PTE_MAKEVALID(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3	
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbl:
+	DO_FAULT(0)
+	END(handle_tlbl)
+
+	.align	5
+	NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+        li      k0,0
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp				# find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbs:
+	DO_FAULT(1)
+	END(handle_tlbs)
+
+	.align	5
+	NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	PTE_L	k0, (k1)
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+	END(handle_mod)
+
Index: include/asm-mips/addrspace.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/addrspace.h,v
retrieving revision 1.13
diff -u -r1.13 addrspace.h
--- include/asm-mips/addrspace.h	30 Nov 2003 01:52:25 -0000	1.13
+++ include/asm-mips/addrspace.h	19 Sep 2004 22:51:28 -0000
@@ -80,7 +80,11 @@
  #define XKSSEG			0x4000000000000000
  #define XKPHYS			0x8000000000000000
  #define XKSEG			0xc000000000000000
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define CKSEG0			0x80000000
+#else
  #define CKSEG0			0xffffffff80000000
+#endif
  #define CKSEG1			0xffffffffa0000000
  #define CKSSEG			0xffffffffc0000000
  #define CKSEG3			0xffffffffe0000000
Index: include/asm-mips/io.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/io.h,v
retrieving revision 1.72
diff -u -r1.72 io.h
--- include/asm-mips/io.h	19 Aug 2004 15:27:41 -0000	1.72
+++ include/asm-mips/io.h	19 Sep 2004 22:51:29 -0000
@@ -171,7 +171,7 @@
  extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags);
  extern void __iounmap(void *addr);

-static inline void * __ioremap_mode(unsigned long offset, unsigned long 
size,
+static inline void * __ioremap_mode(phys_t offset, unsigned long size,
  	unsigned long flags)
  {
  	if (cpu_has_64bit_addresses) {
Index: include/asm-mips/page.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/page.h,v
retrieving revision 1.44
diff -u -r1.44 page.h
--- include/asm-mips/page.h	20 Aug 2004 12:02:18 -0000	1.44
+++ include/asm-mips/page.h	19 Sep 2004 22:51:29 -0000
@@ -32,7 +32,7 @@
  #ifdef CONFIG_PAGE_SIZE_64KB
  #define PAGE_SHIFT	16
  #endif
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(1L << PAGE_SHIFT)
  #define PAGE_MASK	(~(PAGE_SIZE-1))

  #ifdef __KERNEL__
@@ -75,15 +75,22 @@
   * These are used to make use of C type-checking..
   */
  #ifdef CONFIG_64BIT_PHYS_ADDR
-typedef struct { unsigned long long pte; } pte_t;
+  #ifdef CONFIG_CPU_MIPS32
+    typedef struct { unsigned long pte_low, pte_high; } pte_t;
+    #define pte_val(x)    ((x).pte_low | ((unsigned long 
long)(x).pte_high << 32))
+  #else
+     typedef struct { unsigned long long pte; } pte_t;
+     #define pte_val(x)	((x).pte)
+  #endif
  #else
  typedef struct { unsigned long pte; } pte_t;
+#define pte_val(x)	((x).pte)
  #endif
+
  typedef struct { unsigned long pmd; } pmd_t;
  typedef struct { unsigned long pgd; } pgd_t;
  typedef struct { unsigned long pgprot; } pgprot_t;

-#define pte_val(x)	((x).pte)
  #define pmd_val(x)	((x).pmd)
  #define pgd_val(x)	((x).pgd)
  #define pgprot_val(x)	((x).pgprot)
Index: include/asm-mips/pgtable-32.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-32.h,v
retrieving revision 1.11
diff -u -r1.11 pgtable-32.h
--- include/asm-mips/pgtable-32.h	26 Jun 2004 15:15:24 -0000	1.11
+++ include/asm-mips/pgtable-32.h	19 Sep 2004 22:51:29 -0000
@@ -130,8 +130,21 @@
  static inline int pgd_present(pgd_t pgd)	{ return 1; }
  static inline void pgd_clear(pgd_t *pgdp)	{ }

+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
  #define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_pfn(x)		((unsigned long)((x).pte_high >> 6))
+static inline pte_t
+pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+	pte_t pte;
+	pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f);
+	pte.pte_low = pgprot_val(prot);
+	return pte;
+}
+
+#else

+#define pte_page(x)		pfn_to_page(pte_pfn(x))

  #ifdef CONFIG_CPU_VR41XX
  #define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
@@ -140,6 +153,7 @@
  #define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
  #define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
  #endif
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32) */

  #define __pgd_offset(address)	pgd_index(address)
  #define __pmd_offset(address)	(((address) >> PMD_SHIFT) & 
(PTRS_PER_PMD-1))
@@ -207,11 +221,19 @@
   */
  #define PTE_FILE_MAX_BITS	27

+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+	/* fixme */
+#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 
0x3f))
+#define pgoff_to_pte(off) \
+ 	((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)})
+
+#else
  #define pte_to_pgoff(_pte) \
  	((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 ))

  #define pgoff_to_pte(off) \
  	((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE })
+#endif

  #endif

Index: include/asm-mips/pgtable-bits.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable-bits.h,v
retrieving revision 1.9
diff -u -r1.9 pgtable-bits.h
--- include/asm-mips/pgtable-bits.h	24 Jun 2004 20:31:11 -0000	1.9
+++ include/asm-mips/pgtable-bits.h	19 Sep 2004 22:51:29 -0000
@@ -33,6 +33,31 @@
   * unpredictable things.  The code (when it is written) to deal with
   * this problem will be in the update_mmu_cache() code for the r4k.
   */
+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+
+#define _PAGE_PRESENT               (1<<6)  /* implemented in software */
+#define _PAGE_READ                  (1<<7)  /* implemented in software */
+#define _PAGE_WRITE                 (1<<8)  /* implemented in software */
+#define _PAGE_ACCESSED              (1<<9)  /* implemented in software */
+#define _PAGE_MODIFIED              (1<<10) /* implemented in software */
+#define _PAGE_FILE                  (1<<10)  /* set:pagecache unset:swap */
+
+#define _PAGE_R4KBUG                (1<<0)  /* workaround for r4k bug  */
+#define _PAGE_GLOBAL                (1<<0)
+#define _PAGE_VALID                 (1<<1)
+#define _PAGE_SILENT_READ           (1<<1)  /* synonym                 */
+#define _PAGE_DIRTY                 (1<<2)  /* The MIPS dirty bit      */
+#define _PAGE_SILENT_WRITE          (1<<2)
+#define _CACHE_MASK                 (7<<3)
+
+/* MIPS32 defines only values 2 and 3. The rest are implementation
+ * dependent.
+ */
+#define _CACHE_UNCACHED             (2<<3)
+#define _CACHE_CACHABLE_NONCOHERENT (3<<3)
+
+#else
+
  #define _PAGE_PRESENT               (1<<0)  /* implemented in software */
  #define _PAGE_READ                  (1<<1)  /* implemented in software */
  #define _PAGE_WRITE                 (1<<2)  /* implemented in software */
@@ -97,6 +122,7 @@

  #endif
  #endif
+#endif /* defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR) */

  #define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
  #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
@@ -113,6 +139,10 @@
  #define PAGE_CACHABLE_DEFAULT	_CACHE_CACHABLE_COW
  #endif

+#if defined(CONFIG_CPU_MIPS32) && defined(CONFIG_64BIT_PHYS_ADDR)
+#define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 3)
+#else
  #define CONF_CM_DEFAULT		(PAGE_CACHABLE_DEFAULT >> 9)
+#endif

  #endif /* _ASM_PGTABLE_BITS_H */
Index: include/asm-mips/pgtable.h
===================================================================
RCS file: /home/cvs/linux/include/asm-mips/pgtable.h,v
retrieving revision 1.97
diff -u -r1.97 pgtable.h
--- include/asm-mips/pgtable.h	19 Jun 2004 01:39:24 -0000	1.97
+++ include/asm-mips/pgtable.h	19 Sep 2004 22:51:29 -0000
@@ -80,6 +80,34 @@
  #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
  #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)

+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	ptep->pte_high = pte.pte_high;
+	smp_wmb();
+	ptep->pte_low = pte.pte_low;
+	//printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
+
+	if (pte_val(pte) & _PAGE_GLOBAL) {
+		pte_t *buddy = ptep_buddy(ptep);
+		/*
+		 * Make sure the buddy is global too (if it's !none,
+		 * it better already be global)
+		 */
+		if (pte_none(*buddy))
+			buddy->pte_low |= _PAGE_GLOBAL;
+	}
+}
+
+static inline void pte_clear(pte_t *ptep)
+{
+	/* Preserve global status for the pair */
+	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+		set_pte(ptep, __pte(_PAGE_GLOBAL));
+	else
+		set_pte(ptep, __pte(0));
+}
+#else
  /*
   * Certain architectures need to do special things when pte's
   * within a page table are directly modified.  Thus, the following
@@ -111,6 +139,7 @@
  #endif
  		set_pte(ptep, __pte(0));
  }
+#endif

  /*
   * (pmds are folded into pgds so this doesn't get actually called,
@@ -130,6 +159,79 @@
   * Undefined behaviour if not..
   */
  static inline int pte_user(pte_t pte)	{ BUG(); return 0; }
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline int pte_read(pte_t pte)	{ return (pte).pte_low & 
_PAGE_READ; }
+static inline int pte_write(pte_t pte)	{ return (pte).pte_low & 
_PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte)	{ return (pte).pte_low & 
_PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)	{ return (pte).pte_low & 
_PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)	{ return (pte).pte_low & 
_PAGE_FILE; }
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_rdprotect(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	(pte).pte_high &= ~_PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	(pte).pte_low &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	(pte).pte_high &= ~_PAGE_SILENT_READ;
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_WRITE;
+	if ((pte).pte_low & _PAGE_MODIFIED) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_READ;
+	if ((pte).pte_low & _PAGE_ACCESSED) {
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_MODIFIED;
+	if ((pte).pte_low & _PAGE_WRITE) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+		(pte).pte_high |= _PAGE_SILENT_WRITE;
+	}
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	(pte).pte_low |= _PAGE_ACCESSED;
+	if ((pte).pte_low & _PAGE_READ)
+		(pte).pte_low |= _PAGE_SILENT_READ;
+		(pte).pte_high |= _PAGE_SILENT_READ;
+	return pte;
+}
+#else
  static inline int pte_read(pte_t pte)	{ return pte_val(pte) & 
_PAGE_READ; }
  static inline int pte_write(pte_t pte)	{ return pte_val(pte) & 
_PAGE_WRITE; }
  static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & 
_PAGE_MODIFIED; }
@@ -191,6 +293,7 @@
  		pte_val(pte) |= _PAGE_SILENT_READ;
  	return pte;
  }
+#endif

  /*
   * Macro to make mark a page protection value as "uncacheable".  Note
@@ -215,10 +318,20 @@
   */
  #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))

+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_MIPS32)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	pte.pte_low &= _PAGE_CHG_MASK;
+	pte.pte_low |= pgprot_val(newprot);
+	pte.pte_high |= pgprot_val(newprot) & 0x3f;
+	return pte;
+}
+#else
  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  {
  	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
  }
+#endif


  extern void __update_tlb(struct vm_area_struct *vma, unsigned long 
address,
@@ -245,7 +358,27 @@
   */
  #define HAVE_ARCH_UNMAPPED_AREA

+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size);
+
+extern int remap_page_range_high(struct vm_area_struct *vma,
+		unsigned long from,
+		phys_t phys_addr,
+		unsigned long size,
+		pgprot_t prot);
+
+static inline int io_remap_page_range(struct vm_area_struct *vma,
+		unsigned long from,
+		unsigned long phys_addr,
+		unsigned long size,
+		pgprot_t prot)
+{
+	phys_t phys_addr_high = fixup_bigphys_addr(phys_addr, size);
+	return remap_page_range_high(vma, from, phys_addr_high, size, prot);
+}
+#else
  #define io_remap_page_range remap_page_range
+#endif

  /*
   * No page table caches to initialise

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch
@ 2004-02-28 22:06 Tommy McCabe
  0 siblings, 0 replies; 77+ messages in thread
From: Tommy McCabe @ 2004-02-28 22:06 UTC (permalink / raw)
  To: linux-8086

[-- Attachment #1: Type: text/plain, Size: 483 bytes --]

This is a patch that fixes three annoying little bugs
in 0.13pre1:

#1, the extra set of parentheses in
elks/arch/i86/boot/setup.S which it won't compile
with;

#2, the extra set of apostrophes in
elks/kernel/printk.c which will cause the kernel to
print out weird messages filled with 0's;

#3, the /mnt/elks in elkscmd/Make.defs is changed to /mnt/test.

__________________________________
Do you Yahoo!?
Get better spam protection with Yahoo! Mail.
http://antispam.yahoo.com/tools

[-- Attachment #2: patch.diff --]
[-- Type: application/octet-stream, Size: 1348 bytes --]

Index: elks/arch/i86/boot/setup.S
===================================================================
RCS file: /cvsroot/elks/elks/arch/i86/boot/setup.S,v
retrieving revision 1.11
diff -u -r1.11 setup.S
--- elks/arch/i86/boot/setup.S	13 Jul 2002 06:35:36 -0000	1.11
+++ elks/arch/i86/boot/setup.S	28 Feb 2004 21:39:43 -0000
@@ -585,7 +585,7 @@
 	or	al,al
 	jnz	is486
 #endif
-#ifdef(CONFIG_CPU_80386)
+#ifdef CONFIG_CPU_80386
         mov cl,#7
 	lea	si,p80386
 	br	getfpu
Index: elks/kernel/printk.c
===================================================================
RCS file: /cvsroot/elks/elks/kernel/printk.c,v
retrieving revision 1.19
diff -u -r1.19 printk.c
--- elks/kernel/printk.c	12 Jul 2003 19:08:33 -0000	1.19
+++ elks/kernel/printk.c	28 Feb 2004 21:39:43 -0000
@@ -136,7 +136,7 @@
 		continue;
 	    }
 
-	    width = zero = '0';
+	    width = zero = 0;
 	    if (c == '0')
 		zero++;
 	    while (c >= '0' && c <= '9') {
Index: elkscmd/Make.defs
===================================================================
RCS file: /cvsroot/elks/elkscmd/Make.defs,v
retrieving revision 1.15
diff -u -r1.15 Make.defs
--- elkscmd/Make.defs	3 Mar 2002 23:17:05 -0000	1.15
+++ elkscmd/Make.defs	28 Feb 2004 21:39:44 -0000
@@ -159,7 +159,7 @@
 endif
 
 ifeq ($(TARGET_MODE),LOOP)
-TARGET_MNT=/mnt/elks
+TARGET_MNT=/mnt/test
 LOOP=-o loop
 endif
 

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2004-02-22  0:44 Pete Popov
  2004-02-22 16:08 ` PATCH Kronos
  0 siblings, 1 reply; 77+ messages in thread
From: Pete Popov @ 2004-02-22  0:44 UTC (permalink / raw)
  To: linux-fbdev-devel; +Cc: pete_popov


This is a 2.4 patch for the SMI 501 chip. I don't know if anyone is
interested in applying it and/or using it, but I thought I'd send it.
The driver has been tested on the AMD Mirage platform. The I2C portion
of the driver has been sent to the I2C maintainer. 

Pete

diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/Config.in linux-2.4-dev/drivers/video/Config.in
--- linux-2.4-orig/drivers/video/Config.in	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/Config.in	2004-02-21 16:19:24.000000000 -0800
@@ -159,6 +159,7 @@
 	    bool '    SIS 300 series support' CONFIG_FB_SIS_300
 	    bool '    SIS 315/330 series support' CONFIG_FB_SIS_315
 	 fi
+	 bool '  SiliconMotion 501 Driver' CONFIG_FB_SMI501
 	 tristate '  NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
 	 tristate '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
 	 tristate '  3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/fbmem.c linux-2.4-dev/drivers/video/fbmem.c
--- linux-2.4-orig/drivers/video/fbmem.c	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/fbmem.c	2004-02-21 16:19:24.000000000 -0800
@@ -145,6 +145,8 @@
 extern int sstfb_setup(char*);
 extern int it8181fb_init(void);
 extern int it8181fb_setup(char*);
+extern int smi501fb_init(void);
+extern int smi501fb_setup(char*);
 
 static struct {
 	const char *name;
@@ -254,6 +256,9 @@
 #ifdef CONFIG_FB_VESA
 	{ "vesa", vesafb_init, vesafb_setup },
 #endif 
+#ifdef CONFIG_FB_SMI501
+	{ "smi501fb", smi501fb_init, smi501fb_setup },
+#endif
 
 	/*
 	 * Chipset specific drivers that don't use resource management (yet)
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/Makefile linux-2.4-dev/drivers/video/Makefile
--- linux-2.4-orig/drivers/video/Makefile	2004-01-13 21:51:28.000000000 -0800
+++ linux-2.4-dev/drivers/video/Makefile	2004-02-21 16:19:24.000000000 -0800
@@ -88,6 +88,7 @@
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o
 obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
 obj-$(CONFIG_FB_IT8181)		  += it8181fb.o fbgen.o
+obj-$(CONFIG_FB_SMI501)           += smi501fb.o fbgen.o
 
 subdir-$(CONFIG_STI_CONSOLE)      += sti
 ifeq ($(CONFIG_STI_CONSOLE),y)
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/smi501fb.c linux-2.4-dev/drivers/video/smi501fb.c
--- linux-2.4-orig/drivers/video/smi501fb.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4-dev/drivers/video/smi501fb.c	2004-02-21 16:29:07.000000000 -0800
@@ -0,0 +1,801 @@
+/***************************************************************************
+        smifb.c  -  Silicon Motion, Inc. LynxEM+ frame buffer device
+                             -------------------
+    begin                : Thu Aug 9 2001
+    copyright            : (C) 2001 by Szu-Tao Huang
+    email                : johuang@siliconmotion.com
+    
+    Updated to SM501 by Eric.Devolder@amd.com and dan@embeddededge.com
+    for the AMD Mirage Portable Tablet.  20 Oct 2003
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+
+static char *SMIRegs;		// point to virtual Memory Map IO starting address
+static char *SMILFB;		// point to virtual video memory starting address
+static struct smifb_info fb_info;
+static struct smifb_par current_par;	// used to record hardware information
+static struct display disp;
+
+#include "smi501fb.h"
+
+static int initdone = 0;
+
+static int
+smifb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+              u_long arg, int con, struct fb_info *info)
+{
+	unsigned char	bcmd, status;
+	unsigned int	bval;
+	struct	smireg_op	sreg;
+	int	retval;
+
+	retval = 0;
+	if (cmd == 1) {
+		/* Send command to battery charger.
+		*/
+		bcmd = (unsigned char)arg;
+
+		/* 0x22 is the slave address.
+		*/
+		smi_mmiowb(0x22, I2C_SLAVE_ADDRESS);
+		wmb();
+		smi_mmiowb(bcmd, I2C_DATA);
+		wmb();
+		smi_mmiowb(0, I2C_BYTE_COUNT);	/* byte count - 1 */
+		wmb();
+		smi_mmiowb(0x05, I2C_CONTROL);	/* enable, 100kHz, start */
+		wmb();
+		do {
+			status = smi_mmiorb(I2C_STATUS_RESET);
+			wmb();
+		} while (status == 0);
+		smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+		if (status & 0x40)
+			smi_mmiowb(0x00, I2C_STATUS_RESET);
+	}
+	else if (cmd == 2) {
+		/* Read results of command.
+		*/
+		smi_mmiowb(0x23, I2C_SLAVE_ADDRESS);
+		wmb();
+		smi_mmiowb(1, I2C_BYTE_COUNT);	/* byte count - 1 */
+		wmb();
+		smi_mmiowb(0x05, I2C_CONTROL);	/* enable, 100kHz, start */
+		wmb();
+		do {
+			status = smi_mmiorb(I2C_STATUS_RESET);
+			wmb();
+		} while (status == 0);
+		bval = smi_mmiorl(I2C_DATA);
+		wmb();
+		smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+		wmb();
+		if (copy_to_user((char *)arg, &bval, 4))
+			retval = -EFAULT;
+		if (status & 0x40)
+			smi_mmiowb(0x00, I2C_STATUS_RESET);
+	}
+	else if (cmd == 3) {	/* Debug test */
+		bval = smi_mmiorl(GPIO_DATA_HI);
+		bval ^= 0x0000c000;
+		smi_mmiowl(bval, GPIO_DATA_HI);
+
+	}
+	else if (cmd == 4) {	/* Register operation */
+		if (copy_from_user(&sreg, (void *)arg, sizeof(struct smireg_op))) {
+			return -EFAULT;
+		}
+
+		/* Just 32-bit access for now.
+		*/
+		if (sreg.sr_op == SMI_LOAD_REG) {
+			sreg.sr_val = smi_mmiorl(sreg.sr_reg);
+		}
+		else if (sreg.sr_op == SMI_STORE_REG) {
+			smi_mmiowl(sreg.sr_val, sreg.sr_reg);
+		}
+		else if (sreg.sr_op == SMI_AND_REG) {
+			bval = smi_mmiorl(sreg.sr_reg);
+			smi_mmiowl((bval & sreg.sr_val), sreg.sr_reg);
+			sreg.sr_val = bval;
+		}
+		else if (sreg.sr_op == SMI_OR_REG) {
+			bval = smi_mmiorl(sreg.sr_reg);
+			smi_mmiowl((bval | sreg.sr_val), sreg.sr_reg);
+			sreg.sr_val = bval;
+		}
+		else {
+			retval = -EINVAL;
+		}
+		if (copy_to_user((void *)arg, &sreg, sizeof(struct smireg_op))) {
+			retval = -EFAULT;
+		}
+	}
+	else {
+		retval = -EINVAL;
+	}
+
+	return retval;
+}
+
+static int
+smifb_mmap(struct fb_info *_fb,
+         struct file *file,
+         struct vm_area_struct *vma)
+{
+	unsigned int len;
+	unsigned long start=0, off;
+	struct smifb_info *fb = (struct smifb_info *)_fb;
+
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
+		return -EINVAL;
+	}
+
+	start = fb->fb_phys & PAGE_MASK;
+	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb->fb_size);
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > len) {
+		return -EINVAL;
+	}
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
+
+	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
+	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
+
+	/* This is an IO map - tell maydump to skip this VMA */
+	vma->vm_flags |= VM_IO;
+
+	if (io_remap_page_range(vma->vm_start, off,
+                vma->vm_end - vma->vm_start,
+                vma->vm_page_prot)) {
+		return -EAGAIN;
+	}
+
+	fb->mmaped = 1;
+	return 0;
+}
+
+static struct fb_ops smifb_ops = {
+	owner:			THIS_MODULE,
+	fb_get_fix:		fbgen_get_fix,
+	fb_get_var:		fbgen_get_var,
+	fb_set_var:		fbgen_set_var,
+	fb_get_cmap:		fbgen_get_cmap,
+	fb_set_cmap:		fbgen_set_cmap,
+	fb_pan_display:		fbgen_pan_display,
+	fb_ioctl:		smifb_ioctl,
+	fb_mmap:		smifb_mmap,
+};
+
+static void smi_nocursor(struct display *p, int mode, int xx, int yy){};
+
+static void
+smi_detect (void)
+{
+	/*
+	 *  This function should detect the current video mode settings
+	 *  and store it as the default video mode
+	 */
+
+	/*
+	 * Yeh, well, we're not going to change any settings so we're
+	 * always stuck with the default ...
+	 */
+}
+
+static int
+smi_encode_fix(struct fb_fix_screeninfo *fix,
+        const void *_par, struct fb_info_gen *_info)
+{
+	struct smifb_info *info = (struct smifb_info *) _info;
+	struct smifb_par *par = (struct smifb_par *) _par;
+	struct fb_var_screeninfo *var = &par->var;
+
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	fix->smem_start = info->fb_phys;
+	fix->smem_len = info->fb_size;
+	fix->type = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+	fix->visual = (var->bits_per_pixel == 8) ?
+            FB_VISUAL_PSEUDOCOLOR   : FB_VISUAL_TRUECOLOR;
+	fix->ywrapstep = 0;
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->line_length = current_par.line_length;
+	return 0;
+}
+
+static void
+set_color_bitfields(struct fb_var_screeninfo *var)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset = 0;
+		var->red.length = 8;
+		var->green.offset = 0;
+		var->green.length = 8;
+		var->blue.offset = 0;
+		var->blue.length = 8;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	case 16:    /* RGB 565 */
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		var->transp.offset = 0;
+		var->transp.length = 0;
+		break;
+	}
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+}
+
+static int
+smi_decode_var(const struct fb_var_screeninfo *var,
+        void *_par, struct fb_info_gen *_info)
+{
+
+	struct smifb_par *par = (struct smifb_par *)_par;
+
+	/*
+	 * Don't allow setting any of these yet: xres and yres don't
+	 * make sense for LCD panels.
+	 */
+/*
+	if (var->xres != p_lcd->xres || var->yres != p_lcd->yres ||
+			var->xres != p_lcd->xres || var->yres != p_lcd->yres) {
+		return -EINVAL;
+	}
+	if(var->bits_per_pixel != p_lcd->bpp) {
+		return -EINVAL;
+	} */
+
+	memset(par, 0, sizeof(struct smifb_par));
+	par->var = *var;
+
+	/* FIXME */
+	switch (var->bits_per_pixel) {
+	case 8:
+		par->var.bits_per_pixel = 8;
+		break;
+	case 16:
+		par->var.bits_per_pixel = 16;
+		break;
+	default:
+		printk("color depth %d bpp not supported\n",
+						var->bits_per_pixel);
+		return -EINVAL;
+
+	}
+	set_color_bitfields(&par->var);
+	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
+	return 0;
+}
+
+static int
+smi_encode_var(struct fb_var_screeninfo *var,
+        const void *par, struct fb_info_gen *_info)
+{
+	*var = ((struct smifb_par *)par)->var;
+	return 0;
+}
+
+static void
+smi_get_par(void *_par, struct fb_info_gen *_info)
+{
+	*(struct smifb_par *)_par = current_par;
+}
+
+static void
+smi_set_par(const void *par, struct fb_info_gen *info)
+{
+	/* nothing to do: we don't change any settings */
+}
+
+static int
+smi_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+             unsigned *blue, unsigned *transp,
+             struct fb_info *info)
+{
+	struct smifb_info* i = (struct smifb_info*)info;
+
+	if (regno > 255)
+		return 1;
+
+	*red    = i->palette[regno].red;
+	*green  = i->palette[regno].green;
+	*blue   = i->palette[regno].blue;
+	*transp = 0;
+
+	return 0;
+}
+
+static int
+smi_setcolreg(unsigned regno, unsigned red, unsigned green,
+	unsigned blue, unsigned transp,
+	struct fb_info *info)
+{
+	struct smifb_info* i = (struct smifb_info *)info;
+
+	if (regno > 255)
+		return 1;
+
+	i->palette[regno].red    = red;
+	i->palette[regno].green  = green;
+	i->palette[regno].blue   = blue;
+
+	switch(current_par.var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		red >>= 10;
+		green >>= 10;
+		blue >>= 10;
+			// FIX!!! fill palette
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		i->fbcon_cmap16[regno] =
+		    ((red & 0xf800) >> 0) |
+		    ((green & 0xfc00) >> 5) |
+		    ((blue & 0xf800) >> 11);
+		break;
+#endif
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int
+smi_blank(int blank_mode, struct fb_info_gen *_info)
+{
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		/* turn on panel */
+		break;
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+	case VESA_POWERDOWN:
+		/* turn off panel */
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void
+smi_set_disp(const void *unused, struct display *disp,
+             struct fb_info_gen *info)
+{
+	disp->screen_base = (char *)fb_info.fb_virt_start;
+
+	switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		//fbcon_cfb8.cursor = smi_nocursor;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = fb_info.fbcon_cmap16;
+		//fbcon_cfb16.cursor = smi_nocursor;
+		break;
+#endif
+	default:
+		disp->dispsw = &fbcon_dummy;
+		disp->dispsw_data = NULL;
+		break;
+    }
+}
+
+static int
+smi_pan_display(const struct fb_var_screeninfo *var,
+               struct fb_info_gen *info)
+{
+	return 0;
+}
+
+static struct fbgen_hwswitch smi_switch = {
+	detect:		smi_detect,
+	encode_fix:	smi_encode_fix,
+	decode_var:	smi_decode_var,
+	encode_var:	smi_encode_var,
+	get_par:	smi_get_par,
+	set_par:	smi_set_par,
+	getcolreg:	smi_getcolreg,
+	setcolreg:	smi_setcolreg,
+	pan_display:	smi_pan_display,
+	blank:		smi_blank,
+	set_disp:	smi_set_disp
+};
+
+/* GPIO functions to set/clear bits and direction for the bit-bang
+ * I2C algorithm.  Someday, these will need to be protected with
+ * spinlocks/irq.  Right now, I2C is the only one to modify GPIOs.
+ */
+void
+smi501_set_gpio_hi_data(unsigned int val)
+{
+	unsigned int reg;
+
+	reg = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	reg |= val;
+	smi_mmiowl(reg, GPIO_DATA_HI);
+	wmb();
+}
+
+void
+smi501_clr_gpio_hi_data(unsigned int val)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	new &= ~val;
+	smi_mmiowl(new, GPIO_DATA_HI);
+	wmb();
+}
+
+unsigned int
+smi501_get_gpio_hi_data(unsigned int mask)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+
+	return (new & mask);
+}
+
+void
+smi501_set_gpio_hi_direction(unsigned int mask, unsigned int val)
+{
+	unsigned int new;
+
+	new = smi_mmiorl(GPIO_DATA_DIR_HI);
+	wmb();
+	new &= ~mask;
+	new |= val;
+	smi_mmiowl(new, GPIO_DATA_DIR_HI);
+	wmb();
+}
+
+
+/* This function still needs lots of work to generically support
+ * different output devices (CRT or LCD) and resolutions.
+ * Currently hard-coded for Mirage 1024x768 LCD panel.
+ */
+static void
+smi_setmode(struct smifb_info *sfb,struct smifb_par *hw)
+{
+	uint	reg;
+
+	if (initdone)
+		return;
+
+	initdone = 1;
+
+	/* Just blast in some control values based upon the chip
+	 * documentation.  We use the internal memory, I don't know
+	 * how to determine the amount available yet.
+	 */
+	smi_mmiowl(0x07F127C2, DRAM_CTRL);
+	smi_mmiowl(0x02000020, PANEL_HWC_ADDRESS);
+	smi_mmiowl(0x007FF800, PANEL_HWC_ADDRESS);
+	smi_mmiowl(0x00021827, POWER_MODE1_GATE);
+	smi_mmiowl(0x011A0A09, POWER_MODE1_CLOCK);
+	smi_mmiowl(0x00000001, POWER_MODE_CTRL);
+	smi_mmiowl(0x80000000, PANEL_FB_ADDRESS);
+	smi_mmiowl(0x08000800, PANEL_FB_WIDTH);
+	smi_mmiowl(0x04000000, PANEL_WINDOW_WIDTH);
+	smi_mmiowl(0x03000000, PANEL_WINDOW_HEIGHT);
+	smi_mmiowl(0x00000000, PANEL_PLANE_TL);
+	smi_mmiowl(0x02FF03FF, PANEL_PLANE_BR);
+	smi_mmiowl(0x05D003FF, PANEL_HORIZONTAL_TOTAL);
+	smi_mmiowl(0x00C80424, PANEL_HORIZONTAL_SYNC);
+	smi_mmiowl(0x032502FF, PANEL_VERTICAL_TOTAL);
+	smi_mmiowl(0x00060302, PANEL_VERTICAL_SYNC);
+	smi_mmiowl(0x00013905, PANEL_DISPLAY_CTRL);
+	smi_mmiowl(0x01013105, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x03013905, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x07013905, PANEL_DISPLAY_CTRL);
+	waitforvsync();
+	smi_mmiowl(0x0F013905, PANEL_DISPLAY_CTRL);
+	smi_mmiowl(0x0002187F, POWER_MODE1_GATE);
+	smi_mmiowl(0x01011801, POWER_MODE1_CLOCK);
+	smi_mmiowl(0x00000001, POWER_MODE_CTRL);
+
+	smi_mmiowl(0x80000000, PANEL_FB_ADDRESS);
+	smi_mmiowl(0x00000000, PANEL_PAN_CTRL);
+	smi_mmiowl(0x00000000, PANEL_COLOR_KEY);
+
+	/* Enable I2C in GPIO.
+	*/
+#if 0
+	reg = smi_mmiorl(GPIO_HI_CTRL);
+	wmb();
+	reg |= 0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_HI_CTRL);
+	wmb();
+	smi_mmiowb(0x00, I2C_CONTROL);	/* enable, 100kHz, stop */
+	wmb();
+	smi_mmiowb(0x00, I2C_STATUS_RESET);
+#else
+	/* Enable GPIO pins and make them inputs.
+	*/
+	reg = smi_mmiorl(GPIO_DATA_DIR_HI);
+	wmb();
+	reg &= ~0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_DATA_DIR_HI);
+	reg = smi_mmiorl(GPIO_HI_CTRL);
+	wmb();
+	reg &= ~0x0000c000;		/* Enable bits 46, 47 */
+	smi_mmiowl(reg, GPIO_HI_CTRL);
+	wmb();
+	reg = smi_mmiorl(GPIO_DATA_HI);
+	wmb();
+	reg |= 0x0000c000;		/* Let 'em float */
+	smi_mmiowl(reg, GPIO_DATA_HI);
+#endif
+
+	/* Enable 8-bit ZV Port.
+	*/
+	reg = smi_mmiorl(GPIO_LO_CTRL);
+	wmb();
+	reg |= 0x00ff0000;		/* Enable bits 16-23 */
+	smi_mmiowl(reg, GPIO_LO_CTRL);
+	wmb();
+}
+
+/* Set up the zv port to be displayed on the screen.  Currently
+ * coded to expect CCIR 656, YUV 4:2:2 cosited from the PNX1302.
+ */
+static void
+set_videoport(int loc_x, int loc_y, int size_x, int size_y)
+{
+	int nbytes;
+	int top, left, bot, right;
+
+	/* Initialize registers, most power up undefined.
+	*/
+	smi_mmiowl(0x0014008a, ZV_CAPTURE_CLIP);
+	smi_mmiowl(((size_y << 16) | size_x), ZV_CAPTURE_SIZE);
+
+	/* Magic buffer addresses.  Just ensure they don't
+	 * collide with something else in memory.
+	 */
+	smi_mmiowl(0x00200000, ZV_CAPTURE_BUF0);
+	smi_mmiowl(0x00400000, ZV_CAPTURE_BUF1);
+	smi_mmiowl(0x00000000, ZV_CAPTURE_OFFSET);
+	smi_mmiowl(0x00000004, ZV_FIFO_CTRL);
+
+#if 0
+	smi_mmiowl(0x00016007, VIDEO_DISPLAY_CTRL);
+#else
+	smi_mmiowl(0x00010005, VIDEO_DISPLAY_CTRL);
+#endif
+	smi_mmiowl(0x00400000, VIDEO_DISPLAY_FB0);
+	smi_mmiowl(0x00400000, VIDEO_DISPLAY_FB1);
+	smi_mmiowl(((size_x * 2) << 16), VIDEO_DISPLAY_FBWIDTH);
+	nbytes = (size_x * 2) * size_y;
+	nbytes += 127;
+	nbytes &= ~127;
+	smi_mmiowl(0x00400000 + nbytes, VIDEO_DISPLAY_FB0LAST);
+	smi_mmiowl(0x00400000 + nbytes, VIDEO_DISPLAY_FB1LAST);
+
+
+	top = loc_y;
+	left = loc_x;
+	smi_mmiowl(((top << 16) | left), VIDEO_DISPLAY_TL);
+
+	/* Use max ntsc.
+	*/
+	bot = top + size_y;
+	right = left + size_x;
+	smi_mmiowl(((bot << 16) | right), VIDEO_DISPLAY_BR);
+
+	smi_mmiowl(0x00000000, VIDEO_SCALE);
+	smi_mmiowl(0x00000000, VIDEO_INITIAL_SCALE);
+
+	smi_mmiowl(0x00ededed, VIDEO_YUV_CONSTANTS);
+
+	smi_mmiowl(0x17010000, VIDEO_ALPHA_CTRL);
+
+	/* Enable
+	*/
+#if 0
+	smi_mmiowl(0x00000211, ZV_CAPTURE_CTRL);
+#endif
+
+}
+
+/*
+ * Unmap in the memory mapped IO registers
+ *
+ */
+
+static void __devinit
+smi_unmap_mmio(struct smifb_info *sfb)
+{
+	if (sfb && SMIRegs) {
+		iounmap(SMIRegs);
+		SMIRegs = NULL;
+	}
+}
+
+
+/*
+ * Unmap in the screen memory
+ *
+ */
+static void __devinit
+smi_unmap_smem(struct smifb_info *sfb)
+{
+	if (sfb && sfb->fb_virt_start) {
+		iounmap(sfb->fb_virt_start);
+		sfb->fb_virt_start = NULL;
+	}
+}
+
+void
+smi501fb_setup (char *options, int *ints)
+{
+	return;
+}
+
+int __init smi501fb_init(void)
+{
+	struct smifb_info *sfb;
+	char name[16];
+	int err;
+
+	struct pci_dev *pdev = NULL;
+	int i = 0;
+
+	/* Find and enable Voyager
+	 * Rev. AA is 0x501, Rev. B is 0x510.
+	 */
+	pdev = pci_find_device(0x126f,0x510, pdev);
+	if (pdev == NULL)
+		pdev = pci_find_device(0x126f,0x501, pdev);
+	if (pdev == NULL)
+		return -ENODEV;
+	
+	/* Enable the chip.
+	*/
+	err = pci_enable_device(pdev);
+	if (err)
+		return err;
+	current_par.chipID = 0x510;
+
+	err = -ENOMEM;
+	sprintf(name, "smifb");
+	sfb = &fb_info;
+	memset(sfb, 0, sizeof(struct smifb_info));
+	memset(&disp, 0, sizeof(struct display));
+
+	sfb->currcon = -1;
+	sfb->dev = pdev;
+
+
+	/* Set up MMIO space.
+	*/
+	sfb->mmio_phys = pci_resource_start(pdev,1);
+	sfb->mmio_size = 0x00200000;
+	sfb->mmio_virt_start = ioremap(sfb->mmio_phys, sfb->mmio_size);
+	SMIRegs = sfb->mmio_virt_start;
+
+	/* Set up framebuffer.  It's a 64M space, various amount of
+	 * internal memory.  I don't know how to determine the real
+	 * amount of memory (yet).
+	 */
+	sfb->fb_phys = pci_resource_start(pdev,0);
+	sfb->fb_size = 0x00800000;
+	sfb->fb_virt_start = ioremap(sfb->fb_phys, sfb->fb_size);
+	SMILFB = sfb->fb_virt_start;
+
+	 memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
+
+	current_par.var.xres =
+   	current_par.var.xres_virtual = 1024; //sfb->fb.var.xres;
+	current_par.var.yres =
+	current_par.var.yres_virtual = 768; //sfb->fb.var.yres;
+	current_par.var.bits_per_pixel = 16; //sfb->fb.var.bits_per_pixel;
+	current_par.line_length = (current_par.var.bits_per_pixel * current_par.var.xres) / 8;
+
+	smi_setmode(sfb, &current_par);
+
+	fb_info.gen.parsize = sizeof(struct smifb_par);
+	fb_info.gen.fbhw = &smi_switch;
+
+	strcpy(fb_info.gen.info.modename, "SMI Voyager");
+	fb_info.gen.info.changevar = NULL;
+	fb_info.gen.info.node = -1;
+
+	fb_info.gen.info.fbops = &smifb_ops;
+	fb_info.gen.info.disp = &disp;
+	fb_info.gen.info.switch_con = &fbgen_switch;
+	fb_info.gen.info.updatevar = &fbgen_update_var;
+	fb_info.gen.info.blank = &fbgen_blank;
+	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* This should give a reasonable default video mode
+	*/
+	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
+	fbgen_set_disp(-1, &fb_info.gen);
+	fbgen_install_cmap(0, &fb_info.gen);
+
+	if (register_framebuffer(&fb_info.gen.info) < 0)
+		goto failed;
+
+#if 0
+	/* This is for videoport testing.  The Mirage uses an 8-bit
+	 * video port, which is now known to not work properly
+	 * on the SMI501 part.
+	 */
+	set_videoport(150, 150, 768, 576);
+#endif
+
+	MOD_INC_USE_COUNT;
+	printk("Silicon Motion Inc. VOYAGER Init complete.\n");
+
+	return 0;
+
+failed:
+	smi_unmap_smem(sfb);
+	smi_unmap_mmio(sfb);
+
+	return err;
+}
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/smi501fb.h linux-2.4-dev/drivers/video/smi501fb.h
--- linux-2.4-orig/drivers/video/smi501fb.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4-dev/drivers/video/smi501fb.h	2004-02-21 16:19:24.000000000 -0800
@@ -0,0 +1,171 @@
+/***************************************************************************
+			smifb.h  -  SiliconMotion LynxEM+ frame buffer device
+                             -------------------
+    begin                : Thu Aug 9 2001
+    copyright            : (C) 2001 by Szu-Tao Huang
+    email                : johuang@siliconmotion.com
+    
+    Updated to SM501 by Eric.Devolder@amd.com and dan@embeddededge.com
+    for the AMD Mirage Portable Tablet.  20 Oct 2003
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include <linux/config.h>
+
+#define smi_mmiowb(dat,reg)	writeb(dat, (unsigned int)(SMIRegs + reg))
+#define smi_mmioww(dat,reg)	writew(dat, (unsigned int)(SMIRegs + reg))
+#define smi_mmiowl(dat,reg)	writel(dat, (unsigned int)(SMIRegs + reg))
+
+#define smi_mmiorb(reg)	        readb(SMIRegs + reg)
+#define smi_mmiorw(reg)	        readw(SMIRegs + reg)
+#define smi_mmiorl(reg)	        readl(SMIRegs + reg)
+
+#define NR_PALETTE      256
+
+/* Address space offsets for various control/status registers.
+*/
+#define MISC_CTRL			0x000004
+#define GPIO_LO_CTRL			0x000008
+#define GPIO_HI_CTRL			0x00000c
+#define DRAM_CTRL			0x000010
+#define CURRENT_POWER_GATE		0x000038
+#define CURRENT_POWER_CLOCK		0x00003C
+#define POWER_MODE1_GATE                0x000048
+#define POWER_MODE1_CLOCK               0x00004C
+#define POWER_MODE_CTRL			0x000054
+
+#define GPIO_DATA_LO			0x010000
+#define GPIO_DATA_HI			0x010004
+#define GPIO_DATA_DIR_LO		0x010008
+#define GPIO_DATA_DIR_HI		0x01000c
+#define I2C_BYTE_COUNT			0x010040
+#define I2C_CONTROL			0x010041
+#define I2C_STATUS_RESET		0x010042
+#define I2C_SLAVE_ADDRESS		0x010043
+#define I2C_DATA			0x010044
+
+#define DE_COLOR_COMPARE		0x100020
+#define DE_COLOR_COMPARE_MASK		0x100024
+#define DE_MASKS			0x100028
+#define DE_WRAP				0x10004C
+
+#define PANEL_DISPLAY_CTRL              0x080000
+#define PANEL_PAN_CTRL                  0x080004
+#define PANEL_COLOR_KEY                 0x080008
+#define PANEL_FB_ADDRESS                0x08000C
+#define PANEL_FB_WIDTH                  0x080010
+#define PANEL_WINDOW_WIDTH              0x080014
+#define PANEL_WINDOW_HEIGHT             0x080018
+#define PANEL_PLANE_TL                  0x08001C
+#define PANEL_PLANE_BR                  0x080020
+#define PANEL_HORIZONTAL_TOTAL          0x080024
+#define PANEL_HORIZONTAL_SYNC           0x080028
+#define PANEL_VERTICAL_TOTAL            0x08002C
+#define PANEL_VERTICAL_SYNC             0x080030
+#define PANEL_CURRENT_LINE              0x080034
+#define VIDEO_DISPLAY_CTRL		0x080040
+#define VIDEO_DISPLAY_FB0		0x080044
+#define VIDEO_DISPLAY_FBWIDTH		0x080048
+#define VIDEO_DISPLAY_FB0LAST		0x08004C
+#define VIDEO_DISPLAY_TL		0x080050
+#define VIDEO_DISPLAY_BR		0x080054
+#define VIDEO_SCALE			0x080058
+#define VIDEO_INITIAL_SCALE		0x08005C
+#define VIDEO_YUV_CONSTANTS		0x080060
+#define VIDEO_DISPLAY_FB1		0x080064
+#define VIDEO_DISPLAY_FB1LAST		0x080068
+#define VIDEO_ALPHA_CTRL		0x080080
+#define PANEL_HWC_ADDRESS		0x0800F0
+#define CRT_DISPLAY_CTRL		0x080200
+
+#define ZV_CAPTURE_CTRL			0x090000
+#define ZV_CAPTURE_CLIP			0x090004
+#define ZV_CAPTURE_SIZE			0x090008
+#define ZV_CAPTURE_BUF0			0x09000c
+#define ZV_CAPTURE_BUF1			0x090010
+#define ZV_CAPTURE_OFFSET		0x090014
+#define ZV_FIFO_CTRL			0x090018
+
+#define waitforvsync() udelay(100); udelay(100); udelay(100); udelay(100);
+
+/*
+ * Minimum X and Y resolutions
+ */
+#define MIN_XRES	640
+#define MIN_YRES	480
+
+/*
+* Private structure
+*/
+struct smifb_info
+{
+        /*
+        * The following is a pointer to be passed into the
+        * functions below.  The modules outside the main
+        * smifb.c driver have no knowledge as to what
+        * is within this structure.
+        */
+        struct fb_info_gen          gen;
+        struct display_switch   *dispsw;
+        struct pci_dev	        *dev;
+        signed int              currcon;
+
+        struct {
+                u8 red, green, blue;
+        } palette[NR_PALETTE];
+
+        u_int                   palette_size;
+
+		int mmaped;
+		u32 mmio_phys;
+		u32 mmio_size;
+		char *mmio_virt_start;
+
+		u32 fb_phys;
+		u32 fb_size;
+		char *fb_virt_start;
+
+#if defined(FBCON_HAS_CFB16)
+		u16 fbcon_cmap16[16];
+#endif
+
+		/* smi_alloc_fb_info has struct display + 16*sizeof(u32)
+		*/
+		u32 yyy[16];
+};
+
+struct smifb_par
+{
+	struct fb_var_screeninfo var;
+	int line_length;	/* in bytes */
+	int cmap_len;		/* color-map length */
+
+	/*
+	 * Hardware
+	 */
+	u16		chipID;
+
+	u_int	width;
+	u_int	height;
+	u_int	hz;
+};
+
+/* User access to registers for debug and development.
+*/
+struct smireg_op {
+	uint	sr_op;
+	uint	sr_reg;
+	uint	sr_val;
+};
+
+#define SMI_LOAD_REG	1
+#define SMI_STORE_REG	2
+#define SMI_AND_REG	3
+#define SMI_OR_REG	4





-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click

^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2003-12-01  5:58 Diyab
  2003-12-01 14:36 ` patch Stephen Smalley
  0 siblings, 1 reply; 77+ messages in thread
From: Diyab @ 2003-12-01  5:58 UTC (permalink / raw)
  To: SELinux

Where can one locate the AT_SECURE patch for glibc?  AT_SECURE does not 
exist in the current version of glibc, there is no patch in the  SE 
Linux archives and the glibc source RPM from the fedora project contains 
a patched glibc and not a seperate glibc and patch.

Timothy,

-- 
I put instant coffee in a microwave and almost went back in time.
		-- Steven Wright


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch
@ 2003-11-03 22:45 Frank Borich
  2003-11-03 23:00 ` Patch Patrick Mansfield
  0 siblings, 1 reply; 77+ messages in thread
From: Frank Borich @ 2003-11-03 22:45 UTC (permalink / raw)
  To: linux-scsi; +Cc: David Lethe, Bill Krempp

Hi,

I work for a Xyratex International.  We are currently manufacturing a
FC-SATA RAID subsystem called Kashi-II.  We sell only to OEMs, hence we
have run into a problem involving scsi_scan.c and the "device_list[]".
We need to set the BLIST_SPARSELUN flag to support non-contiguous lun
numbering.  Because we sell only to OEMs, the Vendor ID will change.
The logic in scsi_scan.c will not handle a wild card or "NULL" for the
Vendor ID.  Can we 
add code to allow a wildcard for this?  The Model "Kashi-II" will remain
constant across all OEMs.  If we cannot do this, each OEM will have to
submit an entry to this list for 2.4.x support.

Thanks in advance for your time!    

Frank Borich
------------------------------------------------------------------
Systems Engineer
Direct 630 654 6089
Fax 630 325 2513
e-mail frank_borich@us.xyratex.com
 


^ permalink raw reply	[flat|nested] 77+ messages in thread
[parent not found: <OE58jbP3SIGYF2rEF6f00001796@hotmail.com>]
* Patch
@ 2002-12-25 17:36 Mailhebuau Christophe
       [not found] ` <1040837764.2777.8.camel-SH3sQJamR4OeZLLa646FqQ@public.gmane.org>
  0 siblings, 1 reply; 77+ messages in thread
From: Mailhebuau Christophe @ 2002-12-25 17:36 UTC (permalink / raw)
  To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]

Hi,

I have compiled my kernel with acpi support, but i don't have
subdirectory :

/proc/acpi

What must i do ?

apply patch ? and compiled again ?

what i must used patch, which version ? my kernel is 2.4.19-16

which command i must used to apply patch ?
-- 
Cordialement,
Christophe Mailhebuau    http://www.justlinux.org
                           http://www.abul.org
GPG: 1024D/75B07F8D: BD18 2D01 D954 A339 E35B 9EA1 4240 0410 75B0 7F8D

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2002-12-14  4:52 Pete Popov
  2002-12-17 22:29 ` PATCH Greg Lindahl
  2002-12-20 20:43 ` PATCH James Simmons
  0 siblings, 2 replies; 77+ messages in thread
From: Pete Popov @ 2002-12-14  4:52 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips


This patch was sent to the RageXL maintainer but I don't think he was
interested in it. Others might find it useful on embedded systems. It
initializes the RageXL card when there is no system bios to initialize
it from the video bios.  Tested on the Pb1500; makes a really good
workstation.

Pete

diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/Config.in linux-2.4/drivers/video/Config.in
--- linux-2.4-orig/drivers/video/Config.in	Wed Nov 13 15:07:55 2002
+++ linux-2.4/drivers/video/Config.in	Wed Dec 11 22:21:31 2002
@@ -138,6 +138,9 @@
 	 if [ "$CONFIG_FB_ATY" != "n" ]; then
 	    bool '    Mach64 GX support (EXPERIMENTAL)' CONFIG_FB_ATY_GX
 	    bool '    Mach64 CT/VT/GT/LT (incl. 3D RAGE) support' CONFIG_FB_ATY_CT
+	    if [ "$CONFIG_FB_ATY_CT" != "n" ]; then
+	       bool '    Rage XL No-BIOS Init support' CONFIG_FB_ATY_XL_INIT
+	    fi
 	 fi
  	 tristate '  ATI Radeon display support (EXPERIMENTAL)' CONFIG_FB_RADEON
 	 tristate '  ATI Rage128 display support (EXPERIMENTAL)' CONFIG_FB_ATY128
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/Makefile linux-2.4/drivers/video/aty/Makefile
--- linux-2.4-orig/drivers/video/aty/Makefile	Wed Nov 13 15:07:59 2002
+++ linux-2.4/drivers/video/aty/Makefile	Wed Dec 11 22:21:31 2002
@@ -6,6 +6,7 @@
 obj-y				:= atyfb_base.o mach64_accel.o
 obj-$(CONFIG_FB_ATY_GX)		+= mach64_gx.o
 obj-$(CONFIG_FB_ATY_CT)		+= mach64_ct.o mach64_cursor.o
+obj-$(CONFIG_FB_ATY_XL_INIT)    += xlinit.o
 obj-m				:= $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/atyfb.h linux-2.4/drivers/video/aty/atyfb.h
--- linux-2.4-orig/drivers/video/aty/atyfb.h	Wed Nov 13 15:07:59 2002
+++ linux-2.4/drivers/video/aty/atyfb.h	Wed Dec 11 22:21:31 2002
@@ -43,13 +43,17 @@
     u8 pll_ref_div;
     u8 pll_gen_cntl;
     u8 mclk_fb_div;
+    u8 mclk_fb_mult;    /* 2 or 4 */
+    u8 sclk_fb_div;
     u8 pll_vclk_cntl;
     u8 vclk_post_div;
     u8 vclk_fb_div;
     u8 pll_ext_cntl;
+    u8 spll_cntl2;
     u32 dsp_config;	/* Mach64 GTB DSP */
     u32 dsp_on_off;	/* Mach64 GTB DSP */
     u8 mclk_post_div_real;
+    u8 xclk_post_div_real;
     u8 vclk_post_div_real;
 };
 
@@ -105,6 +109,7 @@
     u32 ref_clk_per;
     u32 pll_per;
     u32 mclk_per;
+    u32 xclk_per;
     u8 bus_type;
     u8 ram_type;
     u8 mem_refresh_rate;
@@ -163,6 +168,7 @@
 #define M64F_EXTRA_BRIGHT	0x00020000
 #define M64F_LT_SLEEP		0x00040000
 #define M64F_XL_DLL		0x00080000
+#define M64F_MFB_TIMES_4	0x00100000
 

     /*
@@ -197,6 +203,34 @@
 #endif
 }
 
+static inline u16 aty_ld_le16(int regindex,
+			      const struct fb_info_aty *info)
+{
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
+#if defined(__mc68000__)
+    return le16_to_cpu(*((volatile u16 *)(info->ati_regbase+regindex)));
+#else
+    return readw (info->ati_regbase + regindex);
+#endif
+}
+
+static inline void aty_st_le16(int regindex, u16 val,
+			       const struct fb_info_aty *info)
+{
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
+#if defined(__mc68000__)
+    *((volatile u16 *)(info->ati_regbase+regindex)) = cpu_to_le16(val);
+#else
+    writew (val, info->ati_regbase + regindex);
+#endif
+}
+
 static inline u8 aty_ld_8(int regindex,
 			  const struct fb_info_aty *info)
 {
@@ -236,6 +270,19 @@
     return res;
 }
 
+/*
+ * CT family only.
+ */
+static inline void aty_st_pll(int offset, u8 val,
+			      const struct fb_info_aty *info)
+{
+    /* write addr byte */
+    aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
+    /* write the register value */
+    aty_st_8(CLOCK_CNTL + 2, val, info);
+    aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
+}
+
 
     /*
      *  DAC operations
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/atyfb_base.c linux-2.4/drivers/video/aty/atyfb_base.c
--- linux-2.4-orig/drivers/video/aty/atyfb_base.c	Wed Nov 13 15:07:59 2002
+++ linux-2.4/drivers/video/aty/atyfb_base.c	Wed Dec 11 23:47:00 2002
@@ -225,6 +225,9 @@
 #ifndef MODULE
 int atyfb_setup(char*);
 #endif
+#ifdef CONFIG_FB_ATY_XL_INIT
+extern int atyfb_xl_init(struct fb_info_aty *info);
+#endif
 
 static int currcon = 0;
 
@@ -252,6 +255,7 @@
 static u32 default_vram __initdata = 0;
 static int default_pll __initdata = 0;
 static int default_mclk __initdata = 0;
+static int default_xclk __initdata = 0;
 
 #ifndef MODULE
 static char *mode_option __initdata = NULL;
@@ -298,6 +302,8 @@
 static char m64n_gtc_pp[] __initdata = "3D RAGE PRO (PQFP, PCI)";
 static char m64n_gtc_ppl[] __initdata = "3D RAGE PRO (PQFP, PCI, limited 3D)";
 static char m64n_xl[] __initdata = "3D RAGE (XL)";
+static char m64n_xl_33[] __initdata = "3D RAGE (XL PCI-33MHz)";
+static char m64n_xl_66[] __initdata = "3D RAGE (XL PCI-66MHz)";
 static char m64n_ltp_a[] __initdata = "3D RAGE LT PRO (AGP)";
 static char m64n_ltp_p[] __initdata = "3D RAGE LT PRO (PCI)";
 static char m64n_mob_p[] __initdata = "3D RAGE Mobility (PCI)";
@@ -308,59 +314,61 @@
     u16 pci_id, chip_type;
     u8 rev_mask, rev_val;
     const char *name;
-    int pll, mclk;
+    int pll, mclk, xclk;
     u32 features;
 } aty_chips[] __initdata = {
 #ifdef CONFIG_FB_ATY_GX
     /* Mach64 GX */
-    { 0x4758, 0x00d7, 0x00, 0x00, m64n_gx,      135,  50, M64F_GX },
-    { 0x4358, 0x0057, 0x00, 0x00, m64n_cx,      135,  50, M64F_GX },
+    { 0x4758, 0x00d7, 0x00, 0x00, m64n_gx,      135,  50, 50, M64F_GX },
+    { 0x4358, 0x0057, 0x00, 0x00, m64n_cx,      135,  50, 50, M64F_GX },
 #endif /* CONFIG_FB_ATY_GX */
 
 #ifdef CONFIG_FB_ATY_CT
     /* Mach64 CT */
-    { 0x4354, 0x4354, 0x00, 0x00, m64n_ct,      135,  60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
-    { 0x4554, 0x4554, 0x00, 0x00, m64n_et,      135,  60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
+    { 0x4354, 0x4354, 0x00, 0x00, m64n_ct,      135,  60, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
+    { 0x4554, 0x4554, 0x00, 0x00, m64n_et,      135,  60, 60, M64F_CT | M64F_INTEGRATED | M64F_CT_BUS | M64F_MAGIC_FIFO },
 
     /* Mach64 VT */
-    { 0x5654, 0x5654, 0xc7, 0x00, m64n_vta3,    170,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 },
-    { 0x5654, 0x5654, 0xc7, 0x40, m64n_vta4,    200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV },
-    { 0x5654, 0x5654, 0x00, 0x00, m64n_vtb,     200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 },
-    { 0x5655, 0x5655, 0x00, 0x00, m64n_vtb,     200,  67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL },
-    { 0x5656, 0x5656, 0x00, 0x00, m64n_vt4,     230,  83, M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP },
+    { 0x5654, 0x5654, 0xc7, 0x00, m64n_vta3,    170,  67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 },
+    { 0x5654, 0x5654, 0xc7, 0x40, m64n_vta4,    200,  67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_MAGIC_POSTDIV },
+    { 0x5654, 0x5654, 0x00, 0x00, m64n_vtb,     200,  67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 },
+    { 0x5655, 0x5655, 0x00, 0x00, m64n_vtb,     200,  67, 67, M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL },
+    { 0x5656, 0x5656, 0x00, 0x00, m64n_vt4,     230,  83, 83, M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP },
 
     /* Mach64 GT (3D RAGE) */
-    { 0x4754, 0x4754, 0x07, 0x00, m64n_gt,      135,  63, M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_EXTRA_BRIGHT },
-    { 0x4754, 0x4754, 0x07, 0x01, m64n_gt,      170,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4754, 0x4754, 0x07, 0x02, m64n_gt,      200,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4755, 0x4755, 0x00, 0x00, m64n_gtb,     200,  67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4756, 0x4756, 0x00, 0x00, m64n_iic_p,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4757, 0x4757, 0x00, 0x00, m64n_iic_a,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x475a, 0x475a, 0x00, 0x00, m64n_iic_a,   230,  83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4754, 0x4754, 0x07, 0x00, m64n_gt,      135,  63, 63, M64F_GT | M64F_INTEGRATED | M64F_MAGIC_FIFO | M64F_FIFO_24 | M64F_EXTRA_BRIGHT },
+    { 0x4754, 0x4754, 0x07, 0x01, m64n_gt,      170,  67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4754, 0x4754, 0x07, 0x02, m64n_gt,      200,  67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4755, 0x4755, 0x00, 0x00, m64n_gtb,     200,  67, 67, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4756, 0x4756, 0x00, 0x00, m64n_iic_p,   230,  83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4757, 0x4757, 0x00, 0x00, m64n_iic_a,   230,  83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x475a, 0x475a, 0x00, 0x00, m64n_iic_a,   230,  83, 83, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_FIFO_24 | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
 
     /* Mach64 LT */
-    { 0x4c54, 0x4c54, 0x00, 0x00, m64n_lt,      135,  63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP },
-    { 0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg,     230,  63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
+    { 0x4c54, 0x4c54, 0x00, 0x00, m64n_lt,      135,  63, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP },
+    { 0x4c47, 0x4c47, 0x00, 0x00, m64n_ltg,     230,  63, 63, M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_LT_SLEEP | M64F_G3_PB_1024x768 },
 
     /* Mach64 GTC (3D RAGE PRO) */
-    { 0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE },
-    { 0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp,  230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-    { 0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
-
-    /* 3D RAGE XL */
-    { 0x4752, 0x4752, 0x00, 0x00, m64n_xl, 230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL },
+    { 0x4742, 0x4742, 0x00, 0x00, m64n_gtc_ba,  230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4744, 0x4744, 0x00, 0x00, m64n_gtc_ba1, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4749, 0x4749, 0x00, 0x00, m64n_gtc_bp,  230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_MAGIC_VRAM_SIZE },
+    { 0x4750, 0x4750, 0x00, 0x00, m64n_gtc_pp,  230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+    { 0x4751, 0x4751, 0x00, 0x00, m64n_gtc_ppl, 230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT },
+
+    /* 3D RAGE XL PCI-66/BGA */
+    { 0x474f, 0x474f, 0x00, 0x00, m64n_xl_66, 230, 83, 63, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL | M64F_MFB_TIMES_4 },
+    /* 3D RAGE XL PCI-33/BGA */
+    { 0x4752, 0x4752, 0x00, 0x00, m64n_xl_33, 230, 83, 63, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL | M64F_EXTRA_BRIGHT | M64F_XL_DLL | M64F_MFB_TIMES_4 },
 
     /* Mach64 LT PRO */
-    { 0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
-    { 0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
-    { 0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
-    { 0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p,   230, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+    { 0x4c42, 0x4c42, 0x00, 0x00, m64n_ltp_a,   230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+    { 0x4c44, 0x4c44, 0x00, 0x00, m64n_ltp_p,   230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
+    { 0x4c49, 0x4c49, 0x00, 0x00, m64n_ltp_p,   230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_EXTRA_BRIGHT | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
+    { 0x4c50, 0x4c50, 0x00, 0x00, m64n_ltp_p,   230, 100, 100, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP },
 
     /* 3D RAGE Mobility */
-    { 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p,   230,  50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
-    { 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a,   230,  50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
+    { 0x4c4d, 0x4c4d, 0x00, 0x00, m64n_mob_p,   230,  50, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
+    { 0x4c4e, 0x4c4e, 0x00, 0x00, m64n_mob_a,   230,  50, 50, M64F_GT | M64F_INTEGRATED | M64F_RESET_3D | M64F_GTB_DSP | M64F_MOBIL_BUS },
 #endif /* CONFIG_FB_ATY_CT */
 };
 
@@ -777,7 +785,7 @@
     } else {
 	i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
 	if (!M64_HAS(MAGIC_POSTDIV))
-	    i |= info->mem_refresh_rate << 20;
+		i |= info->mem_refresh_rate << 20;
 	switch (par->crtc.bpp) {
 	    case 8:
 	    case 24:
@@ -1249,7 +1257,10 @@
     u32 ref_clk_per;
     u8 pll_ref_div;
     u8 mclk_fb_div;
+    u8 sclk_fb_div;
     u8 mclk_post_div;		/* 1,2,3,4,8 */
+    u8 mclk_fb_mult;            /* 2 or 4 */
+    u8 xclk_post_div;		/* 1,2,3,4,8 */
     u8 vclk_fb_div;
     u8 vclk_post_div;		/* 1,2,3,4,6,8,12 */
     u32 dsp_xclks_per_row;	/* 0-16383 */
@@ -1302,14 +1313,17 @@
 	    clk.ref_clk_per = info->ref_clk_per;
 	    clk.pll_ref_div = pll->ct.pll_ref_div;
 	    clk.mclk_fb_div = pll->ct.mclk_fb_div;
+	    clk.sclk_fb_div = pll->ct.sclk_fb_div;
 	    clk.mclk_post_div = pll->ct.mclk_post_div_real;
+	    clk.mclk_fb_mult = pll->ct.mclk_fb_mult;
+	    clk.xclk_post_div = pll->ct.xclk_post_div_real;
 	    clk.vclk_fb_div = pll->ct.vclk_fb_div;
 	    clk.vclk_post_div = pll->ct.vclk_post_div_real;
 	    clk.dsp_xclks_per_row = dsp_config & 0x3fff;
 	    clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
 	    clk.dsp_precision = (dsp_config>>20) & 7;
-	    clk.dsp_on = dsp_on_off & 0x7ff;
-	    clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
+	    clk.dsp_off = dsp_on_off & 0x7ff;
+	    clk.dsp_on = (dsp_on_off>>16) & 0x7ff;
 	    if (copy_to_user((struct atyclk *)arg, &clk, sizeof(clk)))
 		    return -EFAULT;
 	} else
@@ -1324,14 +1338,17 @@
 	    info->ref_clk_per = clk.ref_clk_per;
 	    pll->ct.pll_ref_div = clk.pll_ref_div;
 	    pll->ct.mclk_fb_div = clk.mclk_fb_div;
+	    pll->ct.sclk_fb_div = clk.sclk_fb_div;
 	    pll->ct.mclk_post_div_real = clk.mclk_post_div;
+	    pll->ct.mclk_fb_mult = clk.mclk_fb_mult;
+	    pll->ct.xclk_post_div_real = clk.xclk_post_div;
 	    pll->ct.vclk_fb_div = clk.vclk_fb_div;
 	    pll->ct.vclk_post_div_real = clk.vclk_post_div;
 	    pll->ct.dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
 				 ((clk.dsp_loop_latency & 0xf)<<16) |
 				 ((clk.dsp_precision & 7)<<20);
-	    pll->ct.dsp_on_off = (clk.dsp_on & 0x7ff) |
-				 ((clk.dsp_off & 0x7ff)<<16);
+	    pll->ct.dsp_on_off = (clk.dsp_off & 0x7ff) |
+				 ((clk.dsp_on & 0x7ff)<<16);
 	    aty_calc_pll_ct(info, &pll->ct);
 	    aty_set_pll_ct(info, pll);
 	} else
@@ -1371,6 +1388,7 @@
 	unsigned long off;
 	int i;
 
+	printk("aty_mmap\n");
 	if (!fb->mmap_map)
 		return -ENXIO;
 
@@ -1416,9 +1434,14 @@
 		pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
 		pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
 
+		printk("calling remap_page_range: start %x offset %x\n",
+				vma->vm_start + page, map_offset);
 		if (remap_page_range(vma->vm_start + page, map_offset,
-				     map_size, vma->vm_page_prot))
+				     map_size, vma->vm_page_prot)) {
+			printk("remap failed\n");
 			return -EAGAIN;
+		}
+		printk("remap done\n");
 
 		page += map_size;
 	}
@@ -1751,6 +1774,36 @@
 #endif /* CONFIG_PMAC_BACKLIGHT */
 

+static void __init aty_calc_mem_refresh(struct fb_info_aty *info,
+					u16 id,
+					int xclk)
+{
+	int i, size;
+	const int ragepro_tbl[] = {
+		44, 50, 55, 66, 75, 80, 100
+	};
+	const int ragexl_tbl[] = {
+		50, 66, 75, 83, 90, 95, 100, 105,
+		110, 115, 120, 125, 133, 143, 166
+	};
+	const int *refresh_tbl;
+
+	if (IS_XL(id)) {
+		refresh_tbl = ragexl_tbl;
+		size = sizeof(ragexl_tbl)/sizeof(int);
+	} else {
+		refresh_tbl = ragepro_tbl;
+		size = sizeof(ragepro_tbl)/sizeof(int);
+	}
+	
+	for (i=0; i < size; i++) {
+		if (xclk < refresh_tbl[i])
+			break;
+	}
+	
+	info->mem_refresh_rate = i;
+}
+
 
     /*
      *  Initialisation
@@ -1768,12 +1821,12 @@
     u16 type;
     u8 rev;
     const char *chipname = NULL, *ramname = NULL, *xtal;
-    int pll, mclk, gtb_memsize;
+    int pll, mclk, xclk, gtb_memsize;
 #if defined(CONFIG_PPC)
     int sense;
 #endif
     u8 pll_ref_div;
-
+    
     info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
     chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
     type = chip_id & CFG_CHIP_TYPE;
@@ -1784,6 +1837,7 @@
 	    chipname = aty_chips[j].name;
 	    pll = aty_chips[j].pll;
 	    mclk = aty_chips[j].mclk;
+	    xclk = aty_chips[j].xclk;
 	    info->features = aty_chips[j].features;
 	    goto found;
 	}
@@ -1854,17 +1908,39 @@
 	}
     }
 #endif /* CONFIG_FB_ATY_GX */
+
 #ifdef CONFIG_FB_ATY_CT
     if (M64_HAS(INTEGRATED)) {
-	info->bus_type = PCI;
-	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
-	ramname = aty_ct_ram[info->ram_type];
-	info->dac_ops = &aty_dac_ct;
-	info->pll_ops = &aty_pll_ct;
 	/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
 	if (mclk == 67 && info->ram_type < SDRAM)
 	    mclk = 63;
     }
+#endif
+    
+    if (default_pll)
+	pll = default_pll;
+    if (default_mclk)
+	mclk = default_mclk;
+    if (default_xclk)
+	xclk = default_xclk;
+
+    aty_calc_mem_refresh(info, type, xclk);
+    info->pll_per = 1000000/pll;
+    info->mclk_per = 1000000/mclk;
+    info->xclk_per = 1000000/xclk;
+
+#ifdef CONFIG_FB_ATY_CT
+    if (M64_HAS(INTEGRATED)) {
+	info->dac_ops = &aty_dac_ct;
+	info->pll_ops = &aty_pll_ct;
+	info->bus_type = PCI;
+#ifdef CONFIG_FB_ATY_XL_INIT
+	if (IS_XL(type))
+		atyfb_xl_init(info);
+#endif
+	info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
+	ramname = aty_ct_ram[info->ram_type];
+    }
 #endif /* CONFIG_FB_ATY_CT */
 
     info->ref_clk_per = 1000000000000ULL/14318180;
@@ -1954,33 +2030,11 @@
 	    i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
 	aty_st_le32(MEM_CNTL, i, info);
     }
-    if (default_pll)
-	pll = default_pll;
-    if (default_mclk)
-	mclk = default_mclk;
 
-    printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK\n",
+    printk("%d%c %s, %s MHz XTAL, %d MHz PLL, %d Mhz MCLK, %d Mhz XCLK\n",
     	   info->total_vram == 0x80000 ? 512 : (info->total_vram >> 20),
-    	   info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll, mclk);
-
-    if (mclk < 44)
-	info->mem_refresh_rate = 0;	/* 000 = 10 Mhz - 43 Mhz */
-    else if (mclk < 50)
-	info->mem_refresh_rate = 1;	/* 001 = 44 Mhz - 49 Mhz */
-    else if (mclk < 55)
-	info->mem_refresh_rate = 2;	/* 010 = 50 Mhz - 54 Mhz */
-    else if (mclk < 66)
-	info->mem_refresh_rate = 3;	/* 011 = 55 Mhz - 65 Mhz */
-    else if (mclk < 75)
-	info->mem_refresh_rate = 4;	/* 100 = 66 Mhz - 74 Mhz */
-    else if (mclk < 80)
-	info->mem_refresh_rate = 5;	/* 101 = 75 Mhz - 79 Mhz */
-    else if (mclk < 100)
-	info->mem_refresh_rate = 6;	/* 110 = 80 Mhz - 100 Mhz */
-    else
-	info->mem_refresh_rate = 7;	/* 111 = 100 Mhz and above */
-    info->pll_per = 1000000/pll;
-    info->mclk_per = 1000000/mclk;
+    	   info->total_vram == 0x80000 ? 'K' : 'M', ramname, xtal, pll,
+	   mclk, xclk);
 
 #ifdef DEBUG
     if (M64_HAS(INTEGRATED)) {
@@ -2280,7 +2334,7 @@
 		j++;
 	    }
 
-	    if (pdev->device != XL_CHIP_ID) {
+	    if (!IS_XL(pdev->device)) {
 		    /*
 		     * Fix PROMs idea of MEM_CNTL settings...
 		     */
@@ -2390,7 +2444,7 @@
 		 *
 		 * where R is XTALIN (= 14318 or 29498 kHz).
 		 */
-		if (pdev->device == XL_CHIP_ID)
+		if (IS_XL(pdev->device))
 			R = 29498;
 		else
 			R = 14318;
@@ -2580,6 +2634,8 @@
 		default_pll = simple_strtoul(this_opt+4, NULL, 0);
 	else if (!strncmp(this_opt, "mclk:", 5))
 		default_mclk = simple_strtoul(this_opt+5, NULL, 0);
+	else if (!strncmp(this_opt, "xclk:", 5))
+		default_xclk = simple_strtoul(this_opt+5, NULL, 0);
 #ifdef CONFIG_PPC
 	else if (!strncmp(this_opt, "vmode:", 6)) {
 	    unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/mach64.h linux-2.4/drivers/video/aty/mach64.h
--- linux-2.4-orig/drivers/video/aty/mach64.h	Thu Aug 23 20:38:49 2001
+++ linux-2.4/drivers/video/aty/mach64.h	Wed Dec 11 22:21:31 2002
@@ -849,7 +849,18 @@
 #define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
 #define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
 #define LT_CHIP_ID	0x4c54	/* RAGE LT */
-#define XL_CHIP_ID	0x4752	/* RAGE (XL) */
+
+#define GR_CHIP_ID	0x4752	/* RAGE XL, BGA, PCI33 */
+#define GS_CHIP_ID	0x4753	/* RAGE XL, PQFP, PCI33 */
+#define GM_CHIP_ID	0x474d	/* RAGE XL, BGA, AGP 1x,2x */
+#define GN_CHIP_ID	0x474e	/* RAGE XL, PQFP,AGP 1x,2x */
+#define GO_CHIP_ID	0x474f	/* RAGE XL, BGA, PCI66 */
+#define GL_CHIP_ID	0x474c	/* RAGE XL, PQFP, PCI66 */
+
+#define IS_XL(id) ((id)==GR_CHIP_ID || (id)==GS_CHIP_ID || \
+                   (id)==GM_CHIP_ID || (id)==GN_CHIP_ID || \
+                   (id)==GO_CHIP_ID || (id)==GL_CHIP_ID)
+
 #define GT_CHIP_ID	0x4754	/* RAGE (GT) */
 #define GU_CHIP_ID	0x4755	/* RAGE II/II+ (GTB) */
 #define GV_CHIP_ID	0x4756	/* RAGE IIC, PCI */
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/mach64_ct.c linux-2.4/drivers/video/aty/mach64_ct.c
--- linux-2.4-orig/drivers/video/aty/mach64_ct.c	Thu Aug 23 20:38:49 2001
+++ linux-2.4/drivers/video/aty/mach64_ct.c	Wed Dec 11 22:21:31 2002
@@ -4,6 +4,7 @@
  */
 
 #include <linux/fb.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 
@@ -12,15 +13,14 @@
 #include "mach64.h"
 #include "atyfb.h"
 
+#undef DEBUG
 
 /* FIXME: remove the FAIL definition */
 #define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
-static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
-
 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
 			    struct pll_ct *pll);
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info_aty *info, u32 bpp,
 		      struct pll_ct *pll);
 static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
 			     u8 bpp, union aty_pll *pll);
@@ -28,34 +28,30 @@
 			     const union aty_pll *pll);
 

-
-static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
-{
-    /* write addr byte */
-    aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
-    /* write the register value */
-    aty_st_8(CLOCK_CNTL + 2, val, info);
-    aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
-}
-
-
 /* ------------------------------------------------------------------------- */
 
     /*
      *  PLL programming (Mach64 CT family)
      */
-
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+static int aty_dsp_gt(const struct fb_info_aty *info, u32 bpp,
 		      struct pll_ct *pll)
 {
     u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
-    u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
+    u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size;
+    u32 memcntl, n, t_pfc, t_rp, t_ras, t_rcd, t_crd, t_rcc, t_lat;
+
+#ifdef DEBUG
+    printk(__FUNCTION__ ": mclk_fb_mult=%d\n", pll->mclk_fb_mult);
+#endif
+    
+    /* (64*xclk/vclk/bpp)<<11 = xclocks_per_row<<11 */
+    xclks_per_row = ((u32)pll->mclk_fb_mult * (u32)pll->mclk_fb_div *
+		     (u32)pll->vclk_post_div_real * 64) << 11;
+    xclks_per_row /=
+	    (2 * (u32)pll->vclk_fb_div * (u32)pll->xclk_post_div_real * bpp);
 
-    /* xclocks_per_row<<11 */
-    xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/
-		    (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);
     if (xclks_per_row < (1<<11))
-	FAIL("Dotclock to high");
+	FAIL("Dotclock too high");
     if (M64_HAS(FIFO_24)) {
 	fifo_size = 24;
 	dsp_loop_latency = 0;
@@ -70,35 +66,54 @@
 	dsp_precision++;
     }
     dsp_precision -= 5;
+
     /* fifo_off<<6 */
-    fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(3<<6);
+    fifo_off = ((xclks_per_row*(fifo_size-1))>>5); // + (3<<6);
 
     if (info->total_vram > 1*1024*1024) {
-	if (info->ram_type >= SDRAM) {
+	switch (info->ram_type) {
+	case WRAM:
+	    /* >1 MB WRAM */
+	    dsp_loop_latency += 9;
+	    n = 4;
+	    break;
+	case SDRAM:
+	case SGRAM:
 	    /* >1 MB SDRAM */
 	    dsp_loop_latency += 8;
-	    page_size = 8;
-	} else {
+	    n = 2;
+	    break;
+	default:
 	    /* >1 MB DRAM */
 	    dsp_loop_latency += 6;
-	    page_size = 9;
+	    n = 3;
+	    break;
 	}
     } else {
 	if (info->ram_type >= SDRAM) {
 	    /* <2 MB SDRAM */
 	    dsp_loop_latency += 9;
-	    page_size = 10;
+	    n = 2;
 	} else {
 	    /* <2 MB DRAM */
 	    dsp_loop_latency += 8;
-	    page_size = 10;
+	    n = 3;
 	}
     }
+
+    memcntl = aty_ld_le32(MEM_CNTL, info);
+    t_rcd = ((memcntl >> 10) & 0x03) + 1;
+    t_crd = ((memcntl >> 12) & 0x01);
+    t_rp  = ((memcntl >>  8) & 0x03) + 1;
+    t_ras = ((memcntl >> 16) & 0x07) + 1;
+    t_lat =  (memcntl >>  4) & 0x03;
+    
+    t_pfc = t_rp + t_rcd + t_crd;
+    
+    t_rcc = max(t_rp + t_ras, t_pfc + n);
+    
     /* fifo_on<<6 */
-    if (xclks_per_row >= (page_size<<11))
-	fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
-    else
-	fifo_on = (3*page_size+2)<<6;
+    fifo_on = (2 * t_rcc + t_pfc + n - 1) << 6;
 
     dsp_xclks_per_row = xclks_per_row>>dsp_precision;
     dsp_on = fifo_on>>dsp_precision;
@@ -107,20 +122,27 @@
     pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
 		      ((dsp_loop_latency & 0xf)<<16) |
 		      ((dsp_precision & 7)<<20);
-    pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);
+    pll->dsp_on_off = (dsp_off & 0x7ff) | ((dsp_on & 0x7ff)<<16);
     return 0;
 }
 
+
 static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
 			    struct pll_ct *pll)
 {
+#ifdef DEBUG
+    int pllmclk, pllsclk;
+#endif
     u32 q, x;			/* x is a workaround for sparc64-linux-gcc */
     x = x;			/* x is a workaround for sparc64-linux-gcc */
-
+    
     pll->pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
-
+    
     /* FIXME: use the VTB/GTB /3 post divider if it's better suited */
-    q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per;	/* actually 8*q */
+
+    /* actually 8*q */
+    q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per;
+
     if (q < 16*8 || q > 255*8)
 	FAIL("mclk out of range");
     else if (q < 32*8)
@@ -131,8 +153,40 @@
 	pll->mclk_post_div_real = 2;
     else
 	pll->mclk_post_div_real = 1;
-    pll->mclk_fb_div = q*pll->mclk_post_div_real/8;
+    pll->sclk_fb_div = q*pll->mclk_post_div_real/8;
+    
+#ifdef DEBUG
+    pllsclk = (1000000 * 2 * pll->sclk_fb_div) /
+	    (info->ref_clk_per * pll->pll_ref_div);
+    printk(__FUNCTION__ ": pllsclk=%d MHz, mclk=%d MHz\n",
+	   pllsclk, pllsclk / pll->mclk_post_div_real);
+#endif
+    
+    pll->mclk_fb_mult = M64_HAS(MFB_TIMES_4) ? 4 : 2;
+
+    /* actually 8*q */
+    q = info->ref_clk_per * pll->pll_ref_div * 8 /
+	    (pll->mclk_fb_mult * info->xclk_per);
 
+    if (q < 16*8 || q > 255*8)
+	FAIL("mclk out of range");
+    else if (q < 32*8)
+	pll->xclk_post_div_real = 8;
+    else if (q < 64*8)
+	pll->xclk_post_div_real = 4;
+    else if (q < 128*8)
+	pll->xclk_post_div_real = 2;
+    else
+	pll->xclk_post_div_real = 1;
+    pll->mclk_fb_div = q*pll->xclk_post_div_real/8;
+    
+#ifdef DEBUG
+    pllmclk = (1000000 * pll->mclk_fb_mult * pll->mclk_fb_div) /
+	    (info->ref_clk_per * pll->pll_ref_div);
+    printk(__FUNCTION__ ": pllmclk=%d MHz, xclk=%d MHz\n",
+	   pllmclk, pllmclk / pll->xclk_post_div_real);
+#endif
+    
     /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
     q = info->ref_clk_per*pll->pll_ref_div*4/vclk_per;	/* actually 8*q */
     if (q < 16*8 || q > 255*8)
@@ -151,13 +205,14 @@
 
 void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
 {
+    u8 xpostdiv = 0;
     u8 mpostdiv = 0;
     u8 vpostdiv = 0;
-
+    
     if (M64_HAS(SDRAM_MAGIC_PLL) && (info->ram_type >= SDRAM))
-	pll->pll_gen_cntl = 0x04;
+	    pll->pll_gen_cntl = 0x64; /* mclk = sclk */
     else
-	pll->pll_gen_cntl = 0x84;
+	pll->pll_gen_cntl = 0xe4; /* mclk = sclk */
 
     switch (pll->mclk_post_div_real) {
 	case 1:
@@ -166,9 +221,6 @@
 	case 2:
 	    mpostdiv = 1;
 	    break;
-	case 3:
-	    mpostdiv = 4;
-	    break;
 	case 4:
 	    mpostdiv = 2;
 	    break;
@@ -176,12 +228,34 @@
 	    mpostdiv = 3;
 	    break;
     }
-    pll->pll_gen_cntl |= mpostdiv<<4;	/* mclk */
+
+    pll->spll_cntl2 = mpostdiv << 4; /* sclk == pllsclk / mpostdiv */
+    
+    switch (pll->xclk_post_div_real) {
+	case 1:
+	    xpostdiv = 0;
+	    break;
+	case 2:
+	    xpostdiv = 1;
+	    break;
+	case 3:
+	    xpostdiv = 4;
+	    break;
+	case 4:
+	    xpostdiv = 2;
+	    break;
+	case 8:
+	    xpostdiv = 3;
+	    break;
+    }
 
     if (M64_HAS(MAGIC_POSTDIV))
 	pll->pll_ext_cntl = 0;
     else
-    	pll->pll_ext_cntl = mpostdiv;	/* xclk == mclk */
+	pll->pll_ext_cntl = xpostdiv;	/* xclk == pllmclk / xpostdiv */
+
+    if (pll->mclk_fb_mult == 4)
+	    pll->pll_ext_cntl |= 0x08;
 
     switch (pll->vclk_post_div_real) {
 	case 2:
@@ -234,24 +308,54 @@
 
 void aty_set_pll_ct(const struct fb_info_aty *info, const union aty_pll *pll)
 {
+#ifdef DEBUG
+    printk(__FUNCTION__ ": about to program:\n"
+	   "refdiv=%d, extcntl=0x%02x, mfbdiv=%d\n"
+	   "spllcntl2=0x%02x, sfbdiv=%d, gencntl=0x%02x\n"
+	   "vclkcntl=0x%02x, vpostdiv=0x%02x, vfbdiv=%d\n"
+	   "clocksel=%d\n",
+	   pll->ct.pll_ref_div, pll->ct.pll_ext_cntl,
+	   pll->ct.mclk_fb_div, pll->ct.spll_cntl2,
+	   pll->ct.sclk_fb_div, pll->ct.pll_gen_cntl,
+	   pll->ct.pll_vclk_cntl, pll->ct.vclk_post_div,
+	   pll->ct.vclk_fb_div, aty_ld_le32(CLOCK_CNTL, info) & 0x03);
+#endif
+
     aty_st_pll(PLL_REF_DIV, pll->ct.pll_ref_div, info);
+
+    aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, info);
+    aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, info); // for XCLK
+    
+    aty_st_pll(SPLL_CNTL2, pll->ct.spll_cntl2, info);
+    aty_st_pll(SCLK_FB_DIV, pll->ct.sclk_fb_div, info); // for MCLK
+
     aty_st_pll(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, info);
-    aty_st_pll(MCLK_FB_DIV, pll->ct.mclk_fb_div, info);
+    
+    aty_st_pll(EXT_VPLL_CNTL, 0, info);
     aty_st_pll(PLL_VCLK_CNTL, pll->ct.pll_vclk_cntl, info);
     aty_st_pll(VCLK_POST_DIV, pll->ct.vclk_post_div, info);
     aty_st_pll(VCLK0_FB_DIV, pll->ct.vclk_fb_div, info);
-    aty_st_pll(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, info);
 
     if (M64_HAS(GTB_DSP)) {
+	u8 dll_cntl;
+
 	if (M64_HAS(XL_DLL))
-	    aty_st_pll(DLL_CNTL, 0x80, info);
+	    dll_cntl = 0x80;
 	else if (info->ram_type >= SDRAM)
-	    aty_st_pll(DLL_CNTL, 0xa6, info);
+	    dll_cntl = 0xa6;
 	else
-	    aty_st_pll(DLL_CNTL, 0xa0, info);
+	    dll_cntl = 0xa0;
+	aty_st_pll(DLL_CNTL, dll_cntl, info);
 	aty_st_pll(VFC_CNTL, 0x1b, info);
 	aty_st_le32(DSP_CONFIG, pll->ct.dsp_config, info);
 	aty_st_le32(DSP_ON_OFF, pll->ct.dsp_on_off, info);
+
+	mdelay(10);
+	aty_st_pll(DLL_CNTL, dll_cntl, info);
+	mdelay(10);
+	aty_st_pll(DLL_CNTL, dll_cntl | 0x40, info);
+	mdelay(10);
+	aty_st_pll(DLL_CNTL, dll_cntl & ~0x40, info);
     }
 }
 
diff -Naur --exclude=CVS linux-2.4-orig/drivers/video/aty/xlinit.c linux-2.4/drivers/video/aty/xlinit.c
--- linux-2.4-orig/drivers/video/aty/xlinit.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4/drivers/video/aty/xlinit.c	Wed Dec 11 22:21:31 2002
@@ -0,0 +1,374 @@
+/*
+ *  ATI Rage XL Initialization. Support for Xpert98 and Victoria
+ *  PCI cards.
+ *
+ *  Copyright (C) 2002 MontaVista Software Inc.
+ *  Author: MontaVista Software, Inc.
+ *         	stevel@mvista.com or source@mvista.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h> 
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vt_kern.h>
+#include <linux/kd.h> 
+#include <asm/io.h>
+#include <video/fbcon.h>
+#include "mach64.h"
+#include "atyfb.h"
+
+#define MPLL_GAIN       0xad
+#define VPLL_GAIN       0xd5
+
+enum {
+	VICTORIA = 0,
+	XPERT98,
+	NUM_XL_CARDS
+};
+
+extern const struct aty_pll_ops aty_pll_ct;
+
+#define DEFAULT_CARD XPERT98
+static int xl_card = DEFAULT_CARD;
+
+static const struct xl_card_cfg_t {
+	int ref_crystal; // 10^4 Hz
+	int mem_type;
+	int mem_size;
+	u32 mem_cntl;
+	u32 ext_mem_cntl;
+	u32 mem_addr_config;
+	u32 bus_cntl;
+	u32 dac_cntl;
+	u32 hw_debug;
+	u32 custom_macro_cntl;
+	u8  dll2_cntl;
+	u8  pll_yclk_cntl;
+} card_cfg[NUM_XL_CARDS] = {
+	// VICTORIA
+	{	2700, SDRAM, 0x800000,
+		0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040,
+		0x82010102, 0x48803800, 0x005E0179,
+		0x50, 0x25
+	},
+	// XPERT98
+	{	1432,  WRAM, 0x800000,
+		0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001,
+		0x8000000A, 0x48833800, 0x007F0779,
+		0x10, 0x19
+	}
+};
+	  
+typedef struct {
+	u8 lcd_reg;
+	u32 val;
+} lcd_tbl_t;
+
+static const lcd_tbl_t lcd_tbl[] = {
+	{ 0x01,	0x000520C0 },
+	{ 0x08,	0x02000408 },
+	{ 0x03,	0x00000F00 },
+	{ 0x00,	0x00000000 },
+	{ 0x02,	0x00000000 },
+	{ 0x04,	0x00000000 },
+	{ 0x05,	0x00000000 },
+	{ 0x06,	0x00000000 },
+	{ 0x33,	0x00000000 },
+	{ 0x34,	0x00000000 },
+	{ 0x35,	0x00000000 },
+	{ 0x36,	0x00000000 },
+	{ 0x37,	0x00000000 }
+};
+
+static inline u32 aty_ld_lcd(u8 lcd_reg, struct fb_info_aty *info)
+{
+	aty_st_8(LCD_INDEX, lcd_reg, info);
+	return aty_ld_le32(LCD_DATA, info);
+}
+
+static inline void aty_st_lcd(u8 lcd_reg, u32 val,
+			      struct fb_info_aty *info)
+{
+	aty_st_8(LCD_INDEX, lcd_reg, info);
+	aty_st_le32(LCD_DATA, val, info);
+}
+
+static void reset_gui(struct fb_info_aty *info)
+{
+	aty_st_8(GEN_TEST_CNTL+1, 0x01, info);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, info);
+	aty_st_8(GEN_TEST_CNTL+1, 0x02, info);
+	mdelay(5);
+}
+
+
+static void reset_sdram(struct fb_info_aty *info)
+{
+	u8 temp;
+
+	temp = aty_ld_8(EXT_MEM_CNTL, info);
+	temp |= 0x02;
+	aty_st_8(EXT_MEM_CNTL, temp, info); // MEM_SDRAM_RESET = 1b
+	temp |= 0x08;
+	aty_st_8(EXT_MEM_CNTL, temp, info); // MEM_CYC_TEST    = 10b
+	temp |= 0x0c;
+	aty_st_8(EXT_MEM_CNTL, temp, info); // MEM_CYC_TEST    = 11b
+	mdelay(5);
+	temp &= 0xf3;
+	aty_st_8(EXT_MEM_CNTL, temp, info); // MEM_CYC_TEST    = 00b
+	temp &= 0xfd;
+	aty_st_8(EXT_MEM_CNTL, temp, info); // MEM_SDRAM_REST  = 0b
+	mdelay(5);
+}
+
+static void init_dll(struct fb_info_aty *info)
+{
+	// enable DLL
+	aty_st_pll(PLL_GEN_CNTL,
+		   aty_ld_pll(PLL_GEN_CNTL, info) & 0x7f,
+		   info);
+
+	// reset DLL
+	aty_st_pll(DLL_CNTL, 0x82, info);
+	aty_st_pll(DLL_CNTL, 0xE2, info);
+	mdelay(5);
+	aty_st_pll(DLL_CNTL, 0x82, info);
+	mdelay(6);
+}
+
+static void reset_clocks(struct fb_info_aty *info, struct pll_ct *pll,
+			 int hsync_enb)
+{
+	reset_gui(info);
+	aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, info);
+	aty_st_pll(SCLK_FB_DIV, pll->sclk_fb_div, info);
+
+	mdelay(15);
+	init_dll(info);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, info);
+	mdelay(5);
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, info);
+	mdelay(6);
+	reset_sdram(info);
+	aty_st_8(CRTC_GEN_CNTL+3,
+		 hsync_enb ? 0x00 : 0x04, info);
+
+	aty_st_pll(SPLL_CNTL2, pll->spll_cntl2, info);
+	aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, info);
+	aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, info);
+}
+
+
+int atyfb_xl_init(struct fb_info_aty *info)
+{
+	int i, err;
+	u32 temp;
+	union aty_pll pll;
+	const struct xl_card_cfg_t * card = &card_cfg[xl_card];
+	
+	aty_st_8(CONFIG_STAT0, 0x85, info);
+	mdelay(10);
+
+	/*
+	 * The following needs to be set before the call
+	 * to var_to_pll() below. They'll be re-set again
+	 * to the same values in aty_init().
+	 */
+	info->ref_clk_per = 100000000UL/card->ref_crystal;
+	info->ram_type = card->mem_type;
+	info->total_vram = card->mem_size;
+	if (xl_card == VICTORIA) {
+		// the MCLK, XCLK are 120MHz on victoria card
+		info->mclk_per = 1000000/120;
+		info->xclk_per = 1000000/120;
+		info->features &= ~M64F_MFB_TIMES_4;
+	}
+	
+	/*
+	 * Calculate mclk and xclk dividers, etc. The passed
+	 * pixclock and bpp values don't matter yet, the vclk
+	 * isn't programmed until later.
+	 */
+	if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll)))
+		return err;
+
+	aty_st_pll(LVDS_CNTL0, 0x00, info);
+	aty_st_pll(DLL2_CNTL, card->dll2_cntl, info);
+	aty_st_pll(V2PLL_CNTL, 0x10, info);
+	aty_st_pll(MPLL_CNTL, MPLL_GAIN, info);
+	aty_st_pll(VPLL_CNTL, VPLL_GAIN, info);
+	aty_st_pll(PLL_VCLK_CNTL, 0x00, info);
+	aty_st_pll(VFC_CNTL, 0x1B, info);
+	aty_st_pll(PLL_REF_DIV, pll.ct.pll_ref_div, info);
+	aty_st_pll(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, info);
+	aty_st_pll(SPLL_CNTL2, 0x03, info);
+	aty_st_pll(PLL_GEN_CNTL, 0x44, info);
+
+	reset_clocks(info, &pll.ct, 0);
+	mdelay(10);
+
+	aty_st_pll(VCLK_POST_DIV, 0x03, info);
+	aty_st_pll(VCLK0_FB_DIV, 0xDA, info);
+	aty_st_pll(VCLK_POST_DIV, 0x0F, info);
+	aty_st_pll(VCLK1_FB_DIV, 0xF5, info);
+	aty_st_pll(VCLK_POST_DIV, 0x3F, info);
+	aty_st_pll(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, info);
+	aty_st_pll(VCLK2_FB_DIV, 0x00, info);
+	aty_st_pll(VCLK_POST_DIV, 0xFF, info);
+	aty_st_pll(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, info);
+	aty_st_pll(VCLK3_FB_DIV, 0x00, info);
+
+	aty_st_8(BUS_CNTL, 0x01, info);
+	aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, info);
+
+	aty_st_le32(CRTC_GEN_CNTL, 0x04000200, info);
+	aty_st_le16(CONFIG_STAT0, 0x0020, info);
+	aty_st_le32(MEM_CNTL, 0x10151A33, info);
+	aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, info);
+	aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, info);
+	aty_st_le32(DAC_CNTL, card->dac_cntl, info);
+	aty_st_le16(GEN_TEST_CNTL, 0x0100, info);
+	aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, info);
+	aty_st_le32(MEM_BUF_CNTL, 0x00382848, info);
+
+	aty_st_le32(HW_DEBUG, card->hw_debug, info);
+	aty_st_le16(MEM_ADDR_CONFIG, 0x0000, info);
+	aty_st_le16(GP_IO+2, 0x0000, info);
+	aty_st_le16(GEN_TEST_CNTL, 0x0000, info);
+	aty_st_le16(EXT_DAC_REGS+2, 0x0000, info);
+	aty_st_le32(CRTC_INT_CNTL, 0x00000000, info);
+	aty_st_le32(TIMER_CONFIG, 0x00000000, info);
+	aty_st_le32(0xEC, 0x00000000, info);
+	aty_st_le32(0xFC, 0x00000000, info);
+
+	for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) {
+		aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, info);
+	}
+
+	aty_st_le16(CONFIG_STAT0, 0x00A4, info);
+	mdelay(10);
+
+	aty_st_8(BUS_CNTL+1, 0xA0, info);
+	mdelay(10);
+	
+	reset_clocks(info, &pll.ct, 1);
+	mdelay(10);
+
+	// something about power management
+	aty_st_8(LCD_INDEX, 0x08, info);
+	aty_st_8(LCD_DATA, 0x0A, info);
+	aty_st_8(LCD_INDEX, 0x08, info);
+	aty_st_8(LCD_DATA+3, 0x02, info);
+	aty_st_8(LCD_INDEX, 0x08, info);
+	aty_st_8(LCD_DATA, 0x0B, info);
+	mdelay(2);
+	
+	// enable display requests, enable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x02, info);
+	// disable display
+	aty_st_8(CRTC_GEN_CNTL, 0x40, info);
+	// disable display requests, disable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, info);
+	mdelay(10);
+
+	aty_st_pll(PLL_YCLK_CNTL, 0x25, info);
+
+	aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, info);
+	aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, info);
+	aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, info);
+	aty_st_8(CUSTOM_MACRO_CNTL+1,
+		 (card->custom_macro_cntl>>8) & 0xff, info);
+
+	aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, info);
+	aty_st_le32(MEM_CNTL, card->mem_cntl, info);
+	aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, info);
+
+	aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, info);
+
+	aty_st_pll(PLL_YCLK_CNTL, 0x01, info);
+	mdelay(15);
+	aty_st_pll(PLL_YCLK_CNTL, card->pll_yclk_cntl, info);
+	mdelay(1);
+	
+	reset_clocks(info, &pll.ct, 0);
+	mdelay(50);
+	reset_clocks(info, &pll.ct, 0);
+	mdelay(50);
+
+	// enable extended register block
+	aty_st_8(BUS_CNTL+3, 0x7B, info);
+	mdelay(1);
+	// disable extended register block
+	aty_st_8(BUS_CNTL+3, 0x73, info);
+
+	aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, info);
+
+	// disable display requests, disable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x04, info);
+	// disable mapping registers in VGA aperture
+	aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, info) & ~0x04, info);
+	mdelay(50);
+	// enable display requests, enable CRTC
+	aty_st_8(CRTC_GEN_CNTL+3, 0x02, info);
+
+	// make GPIO's 14,15,16 all inputs
+	aty_st_8(LCD_INDEX, 0x07, info);
+	aty_st_8(LCD_DATA+3, 0x00, info);
+
+	// enable the display
+	aty_st_8(CRTC_GEN_CNTL, 0x00, info);
+	mdelay(17);
+	// reset the memory controller
+	aty_st_8(GEN_TEST_CNTL+1, 0x02, info);
+	mdelay(15);
+	aty_st_8(GEN_TEST_CNTL+1, 0x00, info);
+	mdelay(30);
+
+	// enable extended register block
+	aty_st_8(BUS_CNTL+3,
+		 (u8)(aty_ld_8(BUS_CNTL+3, info) | 0x08),
+		 info);
+	// set FIFO size to 512 (PIO)
+	aty_st_le32(GUI_CNTL,
+		    aty_ld_le32(GUI_CNTL, info) & ~0x3,
+		    info);
+
+	// enable CRT and disable lcd
+	aty_st_8(LCD_INDEX, 0x01, info);
+	temp = aty_ld_le32(LCD_DATA, info);
+	temp = (temp | 0x01) & ~0x02;
+	aty_st_le32(LCD_DATA, temp, info);
+
+	return 0;
+}
+

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2002-12-14  4:50 Pete Popov
  0 siblings, 0 replies; 77+ messages in thread
From: Pete Popov @ 2002-12-14  4:50 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips

Ralf,

Here's an updated patch for 36 bit address support to replace the patch
I sent you a couple of days ago. This one is "complete" because it takes
care of remap_page_range() as well. It has been tested with a few 36 bit
peripherals on the Alchemy boards. The remap_page_range() fixup was
needed for a RageXL PCI card on the Pb1500 PCI bus and X runs fine on
it.  The patch takes effect only if  CONFIG_64BIT_PHYS_ADDR and
CONFIG_CPU_MIPS32 are both defined.  Otherwise it's a noop. A similar
solution was tested and implemented on PPC, 2.4.x.

Pete

diff -Naur --exclude=CVS linux-2.4-orig/arch/mips/mm/Makefile linux-2.4/arch/mips/mm/Makefile
--- linux-2.4-orig/arch/mips/mm/Makefile	Mon Dec  9 16:57:46 2002
+++ linux-2.4/arch/mips/mm/Makefile	Tue Dec 10 22:14:30 2002
@@ -25,7 +25,7 @@
 obj-$(CONFIG_CPU_R5432)		+= pg-r5432.o c-r5432.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_RM7000)	+= pg-rm7k.o c-rm7k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_R10000)	+= pg-andes.o c-andes.o tlb-r4k.o tlbex-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
+obj-$(CONFIG_CPU_MIPS32)	+= pg-mips32.o c-mips32.o tlb-r4k.o tlbex-mips32.o
 obj-$(CONFIG_CPU_MIPS64)	+= pg-mips32.o c-mips32.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_SB1)		+= pg-sb1.o c-sb1.o tlb-sb1.o tlbex-r4k.o
 
diff -Naur --exclude=CVS linux-2.4-orig/arch/mips/mm/ioremap.c linux-2.4/arch/mips/mm/ioremap.c
--- linux-2.4-orig/arch/mips/mm/ioremap.c	Wed Nov 13 15:04:50 2002
+++ linux-2.4/arch/mips/mm/ioremap.c	Wed Dec 11 22:55:45 2002
@@ -94,6 +94,17 @@
 }
 
 /*
+ * Allow physical addresses to be fixed up to help 36 bit 
+ * peripherals.
+ */
+static phys_t def_fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+	return phys_addr;
+}
+
+phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size) = def_fixup_bigphys_addr;
+
+/*
  * Generic mapping function (not visible outside):
  */
 
@@ -107,7 +118,7 @@
  * caller shouldn't need to know that small detail.
  */
 
-#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL))
+#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL)  && !((phys_t)addr & 0xFFFFFFFF00000000))
 
 void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 {
@@ -116,6 +127,8 @@
 	phys_t last_addr;
 	void * addr;
 
+	phys_addr = fixup_bigphys_addr(phys_addr, size);
+
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
 	if (!size || last_addr < phys_addr)
diff -Naur --exclude=CVS linux-2.4-orig/arch/mips/mm/tlb-r4k.c linux-2.4/arch/mips/mm/tlb-r4k.c
--- linux-2.4-orig/arch/mips/mm/tlb-r4k.c	Thu Dec  5 16:50:28 2002
+++ linux-2.4/arch/mips/mm/tlb-r4k.c	Tue Dec 10 22:14:30 2002
@@ -210,8 +210,14 @@
 	idx = read_c0_index();
 	ptep = pte_offset(pmdp, address);
 	BARRIER;
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+	write_c0_entrylo0(ptep->pte_high);
+	ptep++;
+	write_c0_entrylo1(ptep->pte_high);
+#else
 	write_c0_entrylo0(pte_val(*ptep++) >> 6);
 	write_c0_entrylo1(pte_val(*ptep) >> 6);
+#endif
 	write_c0_entryhi(address | pid);
 	BARRIER;
 	if (idx < 0) {
diff -Naur --exclude=CVS linux-2.4-orig/arch/mips/mm/tlbex-mips32.S linux-2.4/arch/mips/mm/tlbex-mips32.S
--- linux-2.4-orig/arch/mips/mm/tlbex-mips32.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4/arch/mips/mm/tlbex-mips32.S	Tue Dec 10 22:14:30 2002
@@ -0,0 +1,329 @@
+/*
+ * TLB exception handling code for MIPS32 CPUs.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+ *
+ * Multi-cpu abstraction and reworking:
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ *
+ * Pete Popov, ppopov@pacbell.net
+ * Added 36 bit phys address support.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/current.h>
+#include <asm/offset.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+
+/* We really only support 36 bit physical addresses on MIPS32 */
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
+#define PTE_SIZE        8
+#define PTEP_INDX_MSK	0xff0
+#define PTE_INDX_MSK	0xff8
+#define PTE_INDX_SHIFT 9
+#define CONVERT_PTE(pte)
+#define PTE_MAKEWRITE_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, (_PAGE_VALID | _PAGE_DIRTY)>>6; \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#define PTE_MAKEVALID_HIGH(pte, ptr) \
+	lw	pte, 4(ptr); \
+	ori	pte, pte, _PAGE_VALID>>6; \
+	sw	pte, 4(ptr); \
+	lw	pte, 0(ptr);
+
+#else
+
+#define PTE_L		lw
+#define PTE_S		sw
+#define PTE_SRL		srl
+#define P_MTC0		mtc0
+#define PTE_HALF        0
+#define PTE_SIZE	4
+#define PTEP_INDX_MSK	0xff8
+#define PTE_INDX_MSK	0xffc
+#define PTE_INDX_SHIFT	10
+#define CONVERT_PTE(pte) srl pte, pte, 6
+#define PTE_MAKEWRITE_HIGH(pte, ptr)
+#define PTE_MAKEVALID_HIGH(pte, ptr)
+
+#endif  /* CONFIG_64BIT_PHYS_ADDR */
+
+	__INIT
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define GET_PTE_OFF(reg)
+#else
+#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+#endif
+
+/*	
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, MIPS32 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, pgd_current
+	srl	k1, 23
+	sll	k1, 2				# log2(sizeof(pgd_t)
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else 
+	lw	k1, pgd_current			# get pgd pointer
+#endif	
+	nop
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	srl	k0, k0, PGDIR_SHIFT		# get pgd only bits
+
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	GET_PTE_OFF(k0)				# get pte offset
+	and	k0, k0, PTEP_INDX_MSK
+	addu	k1, k1, k0			# add in offset
+
+	PTE_L	k0, PTE_HALF(k1)		# get even pte
+	CONVERT_PTE(k0)
+	P_MTC0	k0, CP0_ENTRYLO0		# load it
+	PTE_L	k1, (PTE_HALF+PTE_SIZE)(k1)	# get odd pte
+	CONVERT_PTE(k1)
+	P_MTC0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	tlbwr					# write random tlb entry
+1:
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+/*
+ * These are here to avoid putting ifdefs in tlb-r4k.c
+ */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_nevada)
+	.set	mips3
+	PANIC("Nevada Exception Vec 0 called")
+	END(except_vec0_nevada)
+
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	PANIC("R4600 Exception Vec 0 called")
+	END(except_vec0_r4600)
+
+	__FINIT
+
+/*
+ * ABUSE of CPP macros 101.
+ *
+ * After this macro runs, the pte faulted on is
+ * in register PTE, a ptr into the table in which
+ * the pte belongs is in PTR.
+ */
+
+#ifdef CONFIG_SMP
+#define GET_PGD(scratch, ptr)        \
+	mfc0    ptr, CP0_CONTEXT;    \
+	la      scratch, pgd_current;\
+	srl     ptr, 23;             \
+	sll     ptr, 2;              \
+	addu    ptr, scratch, ptr;   \
+	lw      ptr, (ptr);          
+#else
+#define GET_PGD(scratch, ptr)    \
+	lw	ptr, pgd_current;
+#endif
+
+#define LOAD_PTE(pte, ptr) \
+	GET_PGD(pte, ptr)          \
+	mfc0	pte, CP0_BADVADDR; \
+	srl	pte, pte, PGDIR_SHIFT; \
+	sll	pte, pte, 2; \
+	addu	ptr, ptr, pte; \
+	mfc0	pte, CP0_BADVADDR; \
+	lw	ptr, (ptr); \
+	srl	pte, pte, PTE_INDX_SHIFT; \
+	and	pte, pte, PTE_INDX_MSK; \
+	addu	ptr, ptr, pte; \
+	PTE_L	pte, (ptr);
+
+	/* This places the even/odd pte pair in the page
+	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+	 * TMP as a scratch register.
+	 */
+#define PTE_RELOAD(ptr, tmp) \
+	ori	ptr, ptr, PTE_SIZE; \
+	xori	ptr, ptr, PTE_SIZE; \
+	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
+	CONVERT_PTE(tmp); \
+	P_MTC0	tmp, CP0_ENTRYLO1; \
+	PTE_L	ptr, PTE_HALF(ptr); \
+	CONVERT_PTE(ptr); \
+	P_MTC0	ptr, CP0_ENTRYLO0;
+
+#define DO_FAULT(write) \
+	.set	noat; \
+	SAVE_ALL; \
+	mfc0	a2, CP0_BADVADDR; \
+	STI; \
+	.set	at; \
+	move	a0, sp; \
+	jal	do_page_fault; \
+	 li	a1, write; \
+	j	ret_from_exception; \
+	 nop; \
+	.set	noat;
+
+	/* Check is PTE is present, if not then jump to LABEL.
+	 * PTR points to the page table where this PTE is located,
+	 * when the macro is done executing PTE will be restored
+	 * with it's original value.
+	 */
+#define PTE_PRESENT(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE valid, store result in PTR. */
+#define PTE_MAKEVALID(pte, ptr) \
+	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+	PTE_S	pte, (ptr);
+
+	/* Check if PTE can be written to, if not branch to LABEL.
+	 * Regardless restore PTE with value from PTR when done.
+	 */
+#define PTE_WRITABLE(pte, ptr, label) \
+	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+	bnez	pte, label; \
+	PTE_L	pte, (ptr);
+
+	/* Make PTE writable, update software status bits as well,
+	 * then store at PTR.
+	 */
+#define PTE_MAKEWRITE(pte, ptr) \
+	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+			   _PAGE_VALID | _PAGE_DIRTY); \
+	PTE_S	pte, (ptr);
+
+	.set	noreorder
+
+#define R5K_HAZARD nop
+
+	.align	5
+	NESTED(handle_tlbl, PT_SIZE, sp)
+	.set	noat
+invalid_tlbl:
+#ifdef TLB_OPTIMIZE
+	/* Test present bit in entry. */
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp
+	PTE_PRESENT(k0, k1, nopage_tlbl)
+	PTE_MAKEVALID_HIGH(k0, k1)
+	PTE_MAKEVALID(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3	
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbl:
+	DO_FAULT(0)
+	END(handle_tlbl)
+
+	.align	5
+	NESTED(handle_tlbs, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+        li      k0,0
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp				# find faulting entry
+	PTE_WRITABLE(k0, k1, nopage_tlbs)
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nopage_tlbs:
+	DO_FAULT(1)
+	END(handle_tlbs)
+
+	.align	5
+	NESTED(handle_mod, PT_SIZE, sp)
+	.set	noat
+#ifdef TLB_OPTIMIZE
+	.set	mips3
+	LOAD_PTE(k0, k1)
+	R5K_HAZARD
+	tlbp					# find faulting entry
+	andi	k0, k0, _PAGE_WRITE
+	beqz	k0, nowrite_mod
+	PTE_L	k0, (k1)
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	PTE_MAKEWRITE(k0, k1)
+	PTE_MAKEWRITE_HIGH(k0, k1)
+	/* Now reload the entry into the tlb. */
+	PTE_RELOAD(k1, k0)
+	nop
+	b	1f
+	 tlbwi
+1:
+	nop
+	.set	mips3
+	eret
+	.set	mips0
+#endif
+
+nowrite_mod:
+	DO_FAULT(1)
+	END(handle_mod)
+
diff -Naur --exclude=CVS linux-2.4-orig/include/asm-mips/page.h linux-2.4/include/asm-mips/page.h
--- linux-2.4-orig/include/asm-mips/page.h	Sat Nov 16 21:39:31 2002
+++ linux-2.4/include/asm-mips/page.h	Fri Dec 13 20:19:10 2002
@@ -71,15 +71,22 @@
  * These are used to make use of C type-checking..
  */
 #ifdef CONFIG_64BIT_PHYS_ADDR
-typedef struct { unsigned long long pte; } pte_t;
+  #ifdef CONFIG_CPU_MIPS32
+    typedef struct { unsigned long pte_low, pte_high; } pte_t;
+    #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+  #else
+    typedef struct { unsigned long long pte_low; } pte_t;
+    #define pte_val(x)    ((x).pte_low)
+  #endif
 #else
-typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pte_low; } pte_t;
+#define pte_val(x)    ((x).pte_low)
 #endif
+
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
-#define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
diff -Naur --exclude=CVS linux-2.4-orig/include/asm-mips/pgtable-2level.h linux-2.4/include/asm-mips/pgtable-2level.h
--- linux-2.4-orig/include/asm-mips/pgtable-2level.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4/include/asm-mips/pgtable-2level.h	Fri Dec 13 20:19:10 2002
@@ -0,0 +1,62 @@
+#ifndef _MIPS_PGTABLE_2LEVEL_H
+#define _MIPS_PGTABLE_2LEVEL_H
+
+/*
+ * traditional mips two-level paging structure:
+ */
+
+#if defined(CONFIG_64BIT_PHYS_ADDR)
+#define PMD_SHIFT	21
+#define PTRS_PER_PTE	512
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	2048
+#define PGD_ORDER	1
+#else
+#define PMD_SHIFT	22
+#define PTRS_PER_PTE	1024
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	1024
+#define PGD_ORDER	0
+#endif
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
+
+static inline int pte_none(pte_t pte)    { return !(pte.pte_low); }
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+static inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+	*ptep = pteval;
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+	if (pte_val(pteval) & _PAGE_GLOBAL) {
+		pte_t *buddy = ptep_buddy(ptep);
+		/*
+		 * Make sure the buddy is global too (if it's !none,
+		 * it better already be global)
+		 */
+		if (pte_none(*buddy))
+			pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
+	}
+#endif
+}
+
+#ifdef CONFIG_CPU_VR41XX
+#define pte_page(x)  (mem_map+((unsigned long)(((x).pte_low >> (PAGE_SHIFT+2)))))
+#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << (PAGE_SHIFT+2)) | pgprot_val(pgprot))
+#else
+#define pte_page(x)  (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT))))
+#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
+#endif
+
+#endif
+
+#endif /* _MIPS_PGTABLE_2LEVEL_H */
diff -Naur --exclude=CVS linux-2.4-orig/include/asm-mips/pgtable-3level.h linux-2.4/include/asm-mips/pgtable-3level.h
--- linux-2.4-orig/include/asm-mips/pgtable-3level.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4/include/asm-mips/pgtable-3level.h	Tue Dec 10 22:14:30 2002
@@ -0,0 +1,63 @@
+#ifndef _MIPS_PGTABLE_3LEVEL_H
+#define _MIPS_PGTABLE_3LEVEL_H
+
+/*
+ * Not really a 3 level page table but we follow most of the x86 PAE code.
+ */
+
+#define PMD_SHIFT	21
+#define PTRS_PER_PTE	512
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	2048
+#define PGD_ORDER	1
+
+#if !defined (_LANGUAGE_ASSEMBLY)
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, &(e), (e).pte_high, (e).pte_low)
+#define pmd_ERROR(e) \
+	printk("%s:%d: bad pmd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %p(%016Lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
+
+/*
+ * MIPS32 Note
+ * pte_low contains the 12 low bits only.  This includes the 6 lsb bits
+ * which contain software control bits, and the next 6 attribute bits 
+ * which are actually written in the entrylo[0,1] registers (G,V,D,Cache Mask).
+ * pte_high contains the 36 bit physical address and the 6 hardware 
+ * attribute bits (G,V,D, Cache Mask). The entry is already fully setup
+ * so in the tlb refill handler we do not need to shift right 6.
+ */
+
+/* Rules for using set_pte: the pte being assigned *must* be
+ * either not present or in a state where the hardware will
+ * not attempt to update the pte.  In places where this is
+ * not possible, use pte_get_and_clear to obtain the old pte
+ * value and then use set_pte to update it.  -ben
+ */
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+	ptep->pte_high = (pte.pte_high & ~0x3f) | ((pte.pte_low>>6) & 0x3f);
+	ptep->pte_low = pte.pte_low;
+}
+
+static inline int pte_same(pte_t a, pte_t b)
+{
+	return a.pte_low == b.pte_low && a.pte_high == b.pte_high;
+}
+
+#define pte_page(x)    (mem_map+(((x).pte_high >> 6)))
+#define pte_none(x)    (!(x).pte_low && !(x).pte_high)
+
+static inline pte_t 
+__mk_pte(unsigned long page_nr, pgprot_t pgprot)
+{
+	pte_t pte;
+
+	pte.pte_high = (page_nr << 6) | (pgprot_val(pgprot) >> 6);
+	pte.pte_low = pgprot_val(pgprot);
+	return pte;
+}
+#endif
+
+#endif /* _MIPS_PGTABLE_3LEVEL_H */
diff -Naur --exclude=CVS linux-2.4-orig/include/asm-mips/pgtable.h linux-2.4/include/asm-mips/pgtable.h
--- linux-2.4-orig/include/asm-mips/pgtable.h	Sat Nov 16 21:39:31 2002
+++ linux-2.4/include/asm-mips/pgtable.h	Fri Dec 13 20:19:10 2002
@@ -13,6 +13,8 @@
 #include <asm/addrspace.h>
 #include <asm/page.h>
 
+#ifndef _LANGUAGE_ASSEMBLY
+
 #include <linux/linkage.h>
 #include <asm/cachectl.h>
 #include <asm/fixmap.h>
@@ -89,11 +91,8 @@
  */
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PMD_SHIFT	21
-#else
-#define PMD_SHIFT	22
-#endif
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 
@@ -102,22 +101,6 @@
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
-/*
- * Entries per page directory level: we use two-level, so
- * we don't really have any PMD directory physically.
- */
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PTRS_PER_PTE	512
-#define PTRS_PER_PMD	1
-#define PTRS_PER_PGD	2048
-#define PGD_ORDER	1
-#else
-#define PTRS_PER_PTE	1024
-#define PTRS_PER_PMD	1
-#define PTRS_PER_PGD	1024
-#define PGD_ORDER	0
-#endif
-
 #define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
 #define FIRST_USER_PGD_NR	0
 
@@ -169,17 +152,13 @@
 #define __S110	PAGE_SHARED
 #define __S111	PAGE_SHARED
 
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define pte_ERROR(e) \
-	printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#include <asm/pgtable-3level.h>
 #else
-#define pte_ERROR(e) \
-	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#include <asm/pgtable-2level.h>
 #endif
-#define pmd_ERROR(e) \
-	printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
-#define pgd_ERROR(e) \
-	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+#if !defined (_LANGUAGE_ASSEMBLY)
 
 extern unsigned long empty_zero_page;
 extern unsigned long zero_page_mask;
@@ -205,40 +184,6 @@
 	pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
 }
 
-static inline int pte_none(pte_t pte)    { return !(pte_val(pte) & ~_PAGE_GLOBAL); }
-static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
-
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-static inline void set_pte(pte_t *ptep, pte_t pteval)
-{
-	*ptep = pteval;
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
-	if (pte_val(pteval) & _PAGE_GLOBAL) {
-		pte_t *buddy = ptep_buddy(ptep);
-		/*
-		 * Make sure the buddy is global too (if it's !none,
-		 * it better already be global)
-		 */
-		if (pte_none(*buddy))
-			pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
-	}
-#endif
-}
-
-static inline void pte_clear(pte_t *ptep)
-{
-#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
-	/* Preserve global status for the pair */
-	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
-		set_pte(ptep, __pte(_PAGE_GLOBAL));
-	else
-#endif
-		set_pte(ptep, __pte(0));
-}
-
 /*
  * (pmds are folded into pgds so this doesn't get actually called,
  * but the define is needed for a generic inline function.)
@@ -281,69 +226,70 @@
 static inline void pgd_clear(pgd_t *pgdp)	{ }
 
 /*
- * Permanent address of a page.  Obviously must never be called on a highmem
- * page.
- */
-#ifdef CONFIG_CPU_VR41XX
-#define pte_page(x)             (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2))))
-#else
-#define pte_page(x)		(mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
-#endif
-
-/*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-static inline int pte_read(pte_t pte)	{ return pte_val(pte) & _PAGE_READ; }
-static inline int pte_write(pte_t pte)	{ return pte_val(pte) & _PAGE_WRITE; }
-static inline int pte_dirty(pte_t pte)	{ return pte_val(pte) & _PAGE_MODIFIED; }
-static inline int pte_young(pte_t pte)	{ return pte_val(pte) & _PAGE_ACCESSED; }
+
+static inline int pte_present(pte_t pte) { return (pte.pte_low) & _PAGE_PRESENT; }
+
+static inline int pte_read(pte_t pte)	{ return (pte).pte_low & _PAGE_READ; }
+static inline int pte_write(pte_t pte)	{ return (pte).pte_low & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte)	{ return (pte).pte_low & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)	{ return (pte).pte_low & _PAGE_ACCESSED; }
+
+static inline void pte_clear(pte_t *ptep)
+{
+	set_pte(ptep, __pte(0));
+}
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	(pte).pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
 	return pte;
 }
 
 static inline pte_t pte_rdprotect(pte_t pte)
 {
-	pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+	(pte).pte_low &= ~(_PAGE_READ | _PAGE_SILENT_READ);
 	return pte;
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	(pte).pte_low &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
 	return pte;
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	(pte).pte_low &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
 	return pte;
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)
 {
-	pte_val(pte) |= _PAGE_WRITE;
-	if (pte_val(pte) & _PAGE_MODIFIED)
-		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	(pte).pte_low |= _PAGE_WRITE;
+	if ((pte).pte_low & _PAGE_MODIFIED) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+	}
 	return pte;
 }
 
 static inline pte_t pte_mkread(pte_t pte)
 {
-	pte_val(pte) |= _PAGE_READ;
-	if (pte_val(pte) & _PAGE_ACCESSED)
-		pte_val(pte) |= _PAGE_SILENT_READ;
+	(pte).pte_low |= _PAGE_READ;
+	if ((pte).pte_low & _PAGE_ACCESSED) {
+		(pte).pte_low |= _PAGE_SILENT_READ;
+	}
 	return pte;
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-	pte_val(pte) |= _PAGE_MODIFIED;
-	if (pte_val(pte) & _PAGE_WRITE)
-		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	(pte).pte_low |= _PAGE_MODIFIED;
+	if ((pte).pte_low & _PAGE_WRITE) {
+		(pte).pte_low |= _PAGE_SILENT_WRITE;
+	}
 	return pte;
 }
 
@@ -366,9 +312,9 @@
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
-	pte_val(pte) |= _PAGE_ACCESSED;
-	if (pte_val(pte) & _PAGE_READ)
-		pte_val(pte) |= _PAGE_SILENT_READ;
+	(pte).pte_low |= _PAGE_ACCESSED;
+	if ((pte).pte_low & _PAGE_READ)
+		(pte).pte_low |= _PAGE_SILENT_READ;
 	return pte;
 }
 
@@ -376,43 +322,24 @@
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-
-#ifdef CONFIG_CPU_VR41XX
-#define mk_pte(page, pgprot)                                            \
-({                                                                      \
-        pte_t   __pte;                                                  \
-                                                                        \
-        pte_val(__pte) = ((phys_t)(page - mem_map) << (PAGE_SHIFT + 2)) | \
-                         pgprot_val(pgprot);                            \
-                                                                        \
-        __pte;                                                          \
-})
-#else
-#define mk_pte(page, pgprot)						\
-({									\
-	pte_t   __pte;							\
-									\
-	pte_val(__pte) = ((phys_t)(page - mem_map) << PAGE_SHIFT) | \
-	                 pgprot_val(pgprot);				\
-									\
-	__pte;								\
-})
-#endif
-
-static inline pte_t mk_pte_phys(phys_t physpage, pgprot_t pgprot)
-{
-#ifdef CONFIG_CPU_VR41XX
-        return __pte((physpage << 2) | pgprot_val(pgprot));
-#else
-	return __pte(physpage | pgprot_val(pgprot));
-#endif
-}
+#define mk_pte(page, pgprot) __mk_pte((page) - mem_map, (pgprot))
+#define mk_pte_phys(physpage, pgprot)	__mk_pte((physpage) >> PAGE_SHIFT, pgprot)
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+	pte.pte_low &= _PAGE_CHG_MASK;
+	pte.pte_low |= pgprot_val(newprot);
+	return pte;
 }
 
+/*
+ * (pmds are folded into pgds so this doesnt get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+
+
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
 
 #define __pgd_offset(address)	pgd_index(address)
@@ -464,7 +391,7 @@
 #define SWP_ENTRY(type,offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
 #endif
 
-#define pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define pte_to_swp_entry(pte)	((swp_entry_t) { (pte).pte_low })
 #define swp_entry_to_pte(x)	((pte_t) { (x).val })
 

@@ -474,6 +401,8 @@
 
 #include <asm-generic/pgtable.h>
 
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
 /*
  * We provide our own get_unmapped area to cope with the virtual aliasing
  * constraints placed on us by the cache architecture.
diff -Naur --exclude=CVS linux-2.4-orig/include/linux/mm.h linux-2.4/include/linux/mm.h
--- linux-2.4-orig/include/linux/mm.h	Sat Nov 16 21:39:31 2002
+++ linux-2.4/include/linux/mm.h	Fri Dec 13 20:19:10 2002
@@ -473,7 +473,7 @@
 
 extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
 extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma);
-extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
+extern int remap_page_range(unsigned long from, phys_t to, unsigned long size, pgprot_t prot);
 extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
 
 extern int vmtruncate(struct inode * inode, loff_t offset);
diff -Naur --exclude=CVS linux-2.4-orig/mm/memory.c linux-2.4/mm/memory.c
--- linux-2.4-orig/mm/memory.c	Wed Nov 13 15:08:45 2002
+++ linux-2.4/mm/memory.c	Fri Dec 13 20:15:39 2002
@@ -824,7 +824,7 @@
  * in null mappings (currently treated as "copy-on-access")
  */
 static inline void remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, pgprot_t prot)
+	phys_t phys_addr, pgprot_t prot)
 {
 	unsigned long end;
 
@@ -848,7 +848,7 @@
 }
 
 static inline int remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, pgprot_t prot)
+	phys_t phys_addr, pgprot_t prot)
 {
 	unsigned long end;
 
@@ -868,8 +868,9 @@
 	return 0;
 }
 
+extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size);
 /*  Note: this is only safe if the mm semaphore is held when called. */
-int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
+int remap_page_range(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot)
 {
 	int error = 0;
 	pgd_t * dir;
@@ -877,6 +878,7 @@
 	unsigned long end = from + size;
 	struct mm_struct *mm = current->mm;
 
+	phys_addr = fixup_bigphys_addr(phys_addr, size);
 	phys_addr -= from;
 	dir = pgd_offset(mm, from);
 	flush_cache_range(mm, beg, end);

^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2002-11-18 23:07 deepak
  2002-11-18 23:20 ` patch Rik van Riel
  0 siblings, 1 reply; 77+ messages in thread
From: deepak @ 2002-11-18 23:07 UTC (permalink / raw)
  To: linux-kernel

how do i uninstall a patch


^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2002-08-26  0:35 Russell Coker
  2002-08-26 17:15 ` patch Stephen Smalley
  2002-08-26 17:37 ` patch Stephen Smalley
  0 siblings, 2 replies; 77+ messages in thread
From: Russell Coker @ 2002-08-26  0:35 UTC (permalink / raw)
  To: SE Linux

[-- Attachment #1: Type: text/plain, Size: 868 bytes --]

This patch adds some new attributes and appropriate use of them.  Also it 
corrects some errors in attribute usage.

Steve, this and the other three patch files comprise about a quarted of the 
difference between your policy and my current tree.  The devfs_t is another 
quarter of the difference.

Of the remaining 1000 lines of patch about half is related to the 
sysadm_devpts_t issue for daemon startup.

I hope you'll accept these patches (or equivalent policy) into your tree and 
that we can come to a decision on what to do with devfs_t (whether to keep it 
or remove it) shortly.  Then it will be a lot easier to sort out the rest of 
the diffs.

-- 
I do not get viruses because I do not use MS software.
If you use Outlook then please do not put my email address in your
address-book so that WHEN you get a virus it won't use my address in the
>From field.

[-- Attachment #2: attrib.diff --]
[-- Type: text/x-diff, Size: 11398 bytes --]

diff -ruN /tmp/selinux/policy/attrib.te ./attrib.te
--- /tmp/selinux/policy/attrib.te	2002-08-21 20:22:42.000000000 +0200
+++ ./attrib.te	2002-08-25 18:08:35.000000000 +0200
@@ -119,6 +119,9 @@
 # to all user domains.
 attribute userdomain;
 
+# attribute for all non-administrative devpts types
+attribute userpty_type;
+
 # The user_crond_domain attribute identifies every user_crond domain, presently
 # user_crond_t and sysadm_crond_t.  It is used in TE rules that should be
 # applied to all user domains.
@@ -178,6 +181,13 @@
 # domains the ability to remove all such files (e.g. init, crond).
 attribute tmpfile;
 
+# The user_tmpfile attribute identifies all types associated with temporary
+# files for unpriv_userdomain domains.
+attribute user_tmpfile;
+
+# for the user_xserver_tmp_t etc
+attribute xserver_tmpfile;
+
 # The tmpfsfile attribute identifies all types defined for tmpfs 
 # type transitions. 
 # It is used in TE rules to grant certain domains the ability to
@@ -239,6 +249,10 @@
 # Identifier for log files or directories that only exist for log files.
 attribute logfile;
 
+# Identifier for lock files (/var/lock/*) or directories that only exist for
+# lock files.
+attribute lockfile;
+
 
 
 ##############################
diff -ruN /tmp/selinux/policy/domains/program/bootloader.te ./domains/program/bootloader.te
--- /tmp/selinux/policy/domains/program/bootloader.te	2002-08-21 20:22:43.000000000 +0200
+++ ./domains/program/bootloader.te	2002-08-25 00:49:03.000000000 +0200
@@ -76,6 +78,11 @@
 allow bootloader_t sysadm_tty_device_t:chr_file rw_file_perms;
 allow bootloader_t sysadm_devpts_t:chr_file rw_file_perms;
 
+ifdef(`dpkg.te', `
+# for making an initrd
+can_exec_read(bootloader_t, { mount_exec_t })
+')
+
 # for reading BIOS data
 allow bootloader_t memory_device_t:chr_file r_file_perms;
 
diff -ruN /tmp/selinux/policy/domains/program/checkpolicy.te ./domains/program/checkpolicy.te
--- /tmp/selinux/policy/domains/program/checkpolicy.te	2002-08-15 21:22:06.000000000 +0200
+++ ./domains/program/checkpolicy.te	2002-08-26 01:03:45.000000000 +0200
@@ -55,5 +55,5 @@
 # so it can be used without privilege to write real binary policy file
 can_exec(user_t, checkpolicy_exec_t)
 
-allow checkpolicy_t privrole:fd use;
+allow checkpolicy_t privfd:fd use;
 
diff -ruN /tmp/selinux/policy/domains/program/dpkg.te ./domains/program/dpkg.te
--- /tmp/selinux/policy/domains/program/dpkg.te	2002-08-21 20:22:44.000000000 +0200
+++ ./domains/program/dpkg.te	2002-08-26 01:04:04.000000000 +0200
@@ -101,7 +101,7 @@
 
 # allow user domains to execute dpkg
 allow userdomain dpkg_exec_t:dir r_dir_perms;
-can_exec(user_t, { dpkg_exec_t apt_exec_t })
+can_exec(userdomain, { dpkg_exec_t apt_exec_t })
 
 # allow everyone to read dpkg database
 r_dir_file({ apt_t userdomain }, { var_lib_dpkg_t var_lib_apt_t var_cache_apt_t })
diff -ruN /tmp/selinux/policy/domains/program/initrc.te ./domains/program/initrc.te
--- /tmp/selinux/policy/domains/program/initrc.te	2002-08-21 20:22:44.000000000 +0200
+++ ./domains/program/initrc.te	2002-08-25 18:09:09.000000000 +0200
@@ -9,7 +9,7 @@
 # initrc_t is the domain of the init rc scripts.
 # initrc_exec_t is the type of the init program.
 #
-type initrc_t, domain, privlog, privowner;
+type initrc_t, domain, privlog, privowner, privmail;
 role system_r types initrc_t;
 every_domain(initrc_t)
 type initrc_exec_t, file_type, sysadmfile, exec_type;
@@ -95,6 +95,10 @@
 allow initrc_t var_log_t:file { setattr rw_file_perms };
 allow initrc_t lastlog_t:file { setattr rw_file_perms };
 
+# remove old locks
+allow initrc_t lockfile:dir rw_dir_perms;
+allow initrc_t lockfile:file { getattr unlink };
+
 # Access /var/lib/random-seed.
 allow initrc_t var_lib_t:file rw_file_perms;
 allow initrc_t var_lib_t:file unlink;
@@ -140,9 +144,11 @@
 allow initrc_t ttyfile:chr_file relabelfrom;
 allow initrc_t tty_device_t:chr_file relabelto;
 
+ifdef(`rpm.te', `
 # Create and read /boot/kernel.h.
 allow initrc_t boot_t:lnk_file r_file_perms;
 file_type_auto_trans(initrc_t, boot_t, boot_runtime_t)
+')
 
 # Delete and re-create /boot/System.map.
 allow initrc_t boot_t:dir { read getattr write remove_name add_name };
diff -ruN /tmp/selinux/policy/domains/program/ipsec.te ./domains/program/ipsec.te
--- /tmp/selinux/policy/domains/program/ipsec.te	2002-08-21 20:22:44.000000000 +0200
+++ ./domains/program/ipsec.te	2002-08-25 19:51:54.000000000 +0200
@@ -25,7 +25,7 @@
 
 type ipsec_mgmt_t, domain, privlog, admin;
 type ipsec_mgmt_exec_t, file_type, sysadmfile, exec_type;
-type ipsec_mgmt_var_run_t, file_type, sysadmfile;
+type ipsec_mgmt_var_run_t, file_type, sysadmfile, pidfile;
 domain_auto_trans(ipsec_mgmt_t, ipsec_exec_t, ipsec_t)
 file_type_auto_trans(ipsec_mgmt_t, var_run_t, ipsec_mgmt_var_run_t)
 
@@ -214,6 +214,7 @@
 
 dontaudit ipsec_mgmt_t devpts_t:dir { getattr read };
 dontaudit ipsec_mgmt_t tty_device_t:chr_file getattr;
+dontaudit ipsec_mgmt_t device_t:dir { getattr read };
 
 allow ipsec_mgmt_t { sysadm_tty_device_t sysadm_devpts_t }:chr_file { read write ioctl };
 allow ipsec_t { sysadm_tty_device_t sysadm_devpts_t }:chr_file { read write };
diff -ruN /tmp/selinux/policy/domains/program/kcheckpass.te ./domains/program/kcheckpass.te
--- /tmp/selinux/policy/domains/program/kcheckpass.te	2002-08-22 16:21:26.000000000 +0200
+++ ./domains/program/kcheckpass.te	2002-08-25 18:27:42.000000000 +0200
@@ -19,7 +19,7 @@
 allow kcheckpass_t sbin_t:dir search;
 allow kcheckpass_t self:fifo_file { read write ioctl };
 allow kcheckpass_t self:unix_stream_socket create_stream_socket_perms;
-allow kcheckpass_t { user_t sysadm_t }:unix_stream_socket { read write ioctl };
+allow kcheckpass_t userdomain:unix_stream_socket { read write ioctl };
 allow kcheckpass_t self:unix_dgram_socket create_socket_perms;
 
 allow kcheckpass_t self:process { fork sigchld };
@@ -32,4 +32,5 @@
 
 dontaudit kcheckpass_t user_home_dir_type:dir search;
 dontaudit kcheckpass_t xdm_t:fd use;
-dontaudit kcheckpass_t user_tmp_t:file read;
+dontaudit kcheckpass_t user_tmpfile:file read;
+dontaudit kcheckpass_t device_t:dir search;
diff -ruN /tmp/selinux/policy/domains/program/ssh.te ./domains/program/ssh.te
--- /tmp/selinux/policy/domains/program/ssh.te	2002-08-21 20:22:46.000000000 +0200
+++ ./domains/program/ssh.te	2002-08-25 18:13:50.000000000 +0200
@@ -83,7 +90,7 @@
 
 # Relabel and access ptys created by sshd
 allow sshd_t sshd_devpts_t:chr_file { setattr getattr relabelfrom relabelto };
-allow sshd_t user_devpts_t:chr_file { setattr relabelto rw_file_perms };
+allow sshd_t { sysadm_devpts_t userpty_type }:chr_file { setattr relabelto rw_file_perms };
 
 #################################
 #
@@ -101,7 +108,7 @@
 
 # Relabel ptys created by sshd
 allow sshd_login_t sshd_devpts_t:chr_file { relabelfrom relabelto };
-allow sshd_login_t user_devpts_t:chr_file { getattr relabelfrom relabelto };
+allow sshd_login_t { sysadm_devpts_t userpty_type }:chr_file { getattr relabelfrom relabelto };
 
 # Obtain the SID for the user
 allow sshd_t security_t:security get_user_sids;
diff -ruN /tmp/selinux/policy/macros/admin_macros.te ./macros/admin_macros.te
--- /tmp/selinux/policy/macros/admin_macros.te	2002-08-21 20:22:47.000000000 +0200
+++ ./macros/admin_macros.te	2002-08-25 18:55:18.000000000 +0200
@@ -82,12 +84,12 @@
 
 # Create files in /tmp/orbit-* and /tmp/.ICE-unix
 # with our derived tmp type rather than user_tmp_t.
-file_type_auto_trans($1_t, user_tmp_t, $1_tmp_t)
+file_type_auto_trans($1_t, user_tmpfile, $1_tmp_t)
 
 ifdef(`xserver.te',
 `# Create files in /tmp/.X11-unix with our X servers derived
 # tmp type rather than user_xserver_tmp_t.
-file_type_auto_trans($1_xserver_t, user_xserver_tmp_t, $1_xserver_tmp_t)')
+file_type_auto_trans($1_xserver_t, xserver_tmpfile, $1_xserver_tmp_t)')
 
 #
 # A user who is authorized for sysadm_t may nonetheless have
diff -ruN /tmp/selinux/policy/macros/user_macros.te ./macros/user_macros.te
--- /tmp/selinux/policy/macros/user_macros.te	2002-08-22 17:15:07.000000000 +0200
+++ ./macros/user_macros.te	2002-08-25 00:31:53.000000000 +0200
@@ -16,23 +16,24 @@
 define(`user_domain',`
 # Use capabilities
 allow $1_t self:capability { net_bind_service dac_override setuid setgid chown sys_tty_config fowner };
+dontaudit $1_t self:capability { sys_nice fsetid };
 
 # Type for home directory.
 ifelse($1, sysadm, `
 type $1_home_dir_t, file_type, sysadmfile, home_dir_type, home_type;
 type $1_home_t, file_type, sysadmfile, home_type;
+type $1_tmp_t, file_type, sysadmfile, tmpfile;
 ', `
 type $1_home_dir_t, file_type, sysadmfile, home_dir_type, user_home_dir_type, home_type, user_home_type;
 type $1_home_t, file_type, sysadmfile, home_type, user_home_type;
 # do not allow privhome access to sysadm_home_dir_t
 file_type_auto_trans(privhome, $1_home_dir_t, $1_home_t)
+type $1_tmp_t, file_type, sysadmfile, tmpfile, user_tmpfile;
 ')
 
 # Create, access, and remove files in home directory.
 file_type_auto_trans($1_t, $1_home_dir_t, $1_home_t)
 
-# Type for temporary files.
-type $1_tmp_t, file_type, sysadmfile, tmpfile;
 # Use the type when creating files in /tmp.
 file_type_auto_trans($1_t, tmp_t, $1_tmp_t)
 # Bind to a Unix domain socket in /tmp.
@@ -44,15 +45,40 @@
 allow $1_t $1_tty_device_t:chr_file { setattr rw_file_perms };
 # Use the type when relabeling terminal devices.
 type_change $1_t tty_device_t:chr_file $1_tty_device_t;
+ifdef(`dpkg.te', `
+# Debian login is from shadow utils and does not allow resetting the perms.
+# have to fix this!
+type_change $1_t ttyfile:chr_file $1_tty_device_t;
+')
 
 # Type and access for pty devices.
+ifelse(`$1', `sysadm', `
 can_create_pty($1)
+', `
+can_create_pty($1, `, userpty_type')
+')
+
 # Use the type when relabeling pty devices.
 ifdef(`rlogind.te',
 `type_change $1_t rlogind_devpts_t:chr_file $1_devpts_t;')
 ifdef(`ssh.te', `
 type_change $1_t sshd_devpts_t:chr_file $1_devpts_t;
-')
+
+# Access /tmp/ssh files.
+allow $1_t sshd_tmp_t:dir rw_dir_perms;
+allow $1_t sshd_tmp_t:file create_file_perms;
+
+# Connect to sshd.
+can_tcp_connect($1_t, sshd_t)
+
+# Connect to ssh proxy.
+can_tcp_connect($1_t, $1_ssh_t)
+
+allow $1_t sshd_t:fd use;
+allow $1_t sshd_t:tcp_socket rw_stream_socket_perms;
+# Use a Unix stream socket inherited from sshd.
+allow $1_t sshd_t:unix_stream_socket rw_stream_socket_perms;
+')dnl end of ssh section
 
 # Type for tmpfs/shm files.
 type $1_tmpfs_t, file_type, sysadmfile, tmpfsfile;
@@ -60,12 +86,6 @@
 file_type_auto_trans($1_t, tmpfs_t, $1_tmpfs_t)
 allow $1_tmpfs_t tmpfs_t:filesystem associate;
 
-# Access /tmp/ssh files.
-ifdef(`ssh.te', `
-allow $1_t sshd_tmp_t:dir rw_dir_perms;
-allow $1_t sshd_tmp_t:file create_file_perms;
-')
-
 # Read and write /var/catman.
 allow $1_t catman_t:dir rw_dir_perms;
 allow $1_t catman_t:notdevfile_class_set create_file_perms;
diff -ruN /tmp/selinux/policy/types/file.te ./types/file.te
--- /tmp/selinux/policy/types/file.te	2002-08-21 20:22:48.000000000 +0200
+++ ./types/file.te	2002-08-25 18:15:48.000000000 +0200
@@ -159,7 +155,7 @@
 type var_run_t, file_type, sysadmfile;
 type var_log_t, file_type, sysadmfile, logfile;
 type faillog_t, file_type, sysadmfile, logfile;
-type var_lock_t, file_type, sysadmfile;
+type var_lock_t, file_type, sysadmfile, lockfile;
 type var_lib_t, file_type, sysadmfile;
 # for /var/{spool,lib}/texmf index files
 type tetex_data_t, file_type, sysadmfile, tmpfile;

^ permalink raw reply	[flat|nested] 77+ messages in thread
* PATCH
@ 2002-07-15 22:29 Pete Popov
  2002-07-16 15:07 ` PATCH Ralf Baechle
  0 siblings, 1 reply; 77+ messages in thread
From: Pete Popov @ 2002-07-15 22:29 UTC (permalink / raw)
  To: linux-mips

Ralf,

__pte is broken when pte_t is a 64bit type.  I did this to fix the 36
bit IO support for the Alchemy boards, but it also affects the 64 bit
mips port.  Apparently it fixed a Xfree problem someone was having.

Pete

--- include/asm-mips/pgtable.h.old	Fri Jul 12 17:25:19 2002
+++ include/asm-mips/pgtable.h	Fri Jul 12 17:25:36 2002
@@ -332,7 +332,9 @@
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-	return __pte(((pte).pte_low & _PAGE_CHG_MASK) | pgprot_val(newprot));
+	pte.pte_low &= _PAGE_CHG_MASK;
+	pte.pte_low |= pgprot_val(newprot);
+	return pte;
 }
 
 /*

^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2002-05-22 15:04 Wilson G. Hein
  2002-05-22 17:44 ` patch Riley Williams
  2002-05-23 11:33 ` patch Wilbert Knol
  0 siblings, 2 replies; 77+ messages in thread
From: Wilson G. Hein @ 2002-05-22 15:04 UTC (permalink / raw)
  To: Linux-Hams Mailing List

Hi,

Trying to patch kerbel 2.4.18 with patch 2.4.19-pre2. Can someone tell me in
what RedHat package the patch command is in. Apparently I don't have it
installed:-)

Wilson, WJ3G


^ permalink raw reply	[flat|nested] 77+ messages in thread
* patch
@ 2001-08-14 15:32 Ryan Senior
  2001-08-15 12:55 ` patch Stephen Smalley
  0 siblings, 1 reply; 77+ messages in thread
From: Ryan Senior @ 2001-08-14 15:32 UTC (permalink / raw)
  To: SELinux

I "applied" the patch, but it didn't apply properly.

The following is what I get:

(Stripping trailing CRs from patch.)
patching file initpolicy.conf
Hunk #1 FAILED at 1775.
Hunk #2 FAILED at 1813.
Hunk #3 FAILED at 2090.
3 out of 3 hunks FAILED -- saving rejects to file initpolicy.conf.rej


I am far from an expert at using patch, in fact aside from patching the
kernel, I haven't used patch much at all.  If you need, I could also
paste in what the .rej file says.

Any assistance is appreciated,

Ryan

--
You have received this message because you are subscribed to the selinux list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch
@ 2001-07-17 12:54 Cemil Degirmenci
  0 siblings, 0 replies; 77+ messages in thread
From: Cemil Degirmenci @ 2001-07-17 12:54 UTC (permalink / raw)
  To: linux-mtd

----- Forwarded message from David Woodhouse <dwmw2@redhat.com> -----

To: cemil@regio.net
From: David Woodhouse <dwmw2@redhat.com>

Index: drivers/mtd/devices/doc2000.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/devices/doc2000.c,v
retrieving revision 1.43
diff -u -r1.43 doc2000.c
--- drivers/mtd/devices/doc2000.c	2001/06/02 14:30:43	1.43
+++ drivers/mtd/devices/doc2000.c	2001/07/17 12:47:52
@@ -84,19 +84,22 @@
 static int _DoC_WaitReady(struct DiskOnChip *doc)
 {
 	unsigned long docptr = doc->virtadr;
-	unsigned short c = 0xffff;
+	unsigned long timeo = jiffies + (HZ * 10);
 
 	DEBUG(MTD_DEBUG_LEVEL3,
 	      "_DoC_WaitReady called for out-of-line wait\n");
 
 	/* Out-of-line routine to wait for chip response */
-	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
-		;
-
-	if (c == 0)
-		DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+	while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+		if (time_after(jiffies, timeo)) {
+			DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
+			return -EIO;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
 
-	return (c == 0);
+	return 0;
 }
 
 static inline int DoC_WaitReady(struct DiskOnChip *doc)
@@ -566,6 +569,7 @@
 
 	this->curfloor = -1;
 	this->curchip = -1;
+	init_MUTEX(&this->lock);
 
 	/* Ident all the chips present. */
 	DoC_ScanChips(this);
@@ -606,6 +610,8 @@
 	if (from >= this->totlen)
 		return -EINVAL;
 
+	down(&this->lock);
+
 	/* Don't allow a single read to cross a 512-byte block boundary */
 	if (from + len > ((from | 0x1ff) + 1))
 		len = ((from | 0x1ff) + 1) - from;
@@ -724,6 +730,8 @@
 	    DoC_WaitReady(this);
 	}
 
+	up(&this->lock);
+
 	return ret;
 }
 
@@ -751,6 +759,8 @@
 	if (to >= this->totlen)
 		return -EINVAL;
 
+	down(&this->lock);
+
 	/* Don't allow a single write to cross a 512-byte block boundary */
 	if (to + len > ((to | 0x1ff) + 1))
 		len = ((to | 0x1ff) + 1) - to;
@@ -813,6 +823,7 @@
 			printk("Error programming flash\n");
 			/* Error in programming */
 			*retlen = 0;
+			up(&this->lock);
 			return -EIO;
 		}
 
@@ -865,6 +876,7 @@
 		printk("Error programming flash\n");
 		/* Error in programming */
 		*retlen = 0;
+		up(&this->lock);
 		return -EIO;
 	}
 
@@ -874,6 +886,7 @@
 	if (eccbuf) {
 		unsigned char x[8];
 		size_t dummy;
+		int ret;
 
 		/* Write the ECC data to flash */
 		for (di=0; di<6; di++)
@@ -882,9 +895,11 @@
 		x[6]=0x55;
 		x[7]=0x55;
 		
-		return doc_write_oob(mtd, to, 8, &dummy, x);
+		ret = doc_write_oob(mtd, to, 8, &dummy, x);
+		up(&this->lock);
+		return ret;
 	}
-
+	up(&this->lock);
 	return 0;
 }
 
@@ -892,10 +907,12 @@
 			size_t * retlen, u_char * buf)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
-	int len256 = 0;
+	int len256 = 0, ret;
 	unsigned long docptr;
 	struct Nand *mychip;
 
+	down(&this->lock);
+
 	docptr = this->virtadr;
 
 	mychip = &this->chips[ofs >> this->chipshift];
@@ -939,12 +956,15 @@
 	/* Reading the full OOB data drops us off of the end of the page,
          * causing the flash device to go into busy mode, so we need
          * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
-	return DoC_WaitReady(this);
+	
+	ret = DoC_WaitReady(this);
+	up(&this->lock);
+	return ret;
 
 }
 
-static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-			 size_t * retlen, const u_char * buf)
+static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
+				size_t * retlen, const u_char * buf)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
 	int len256 = 0;
@@ -1032,8 +1052,20 @@
 	return 0;
 
 }
+
+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
+			 size_t * retlen, const u_char * buf)
+{
+	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
+	int ret;
+
+	down(&this->lock);
+	ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
+	up(&this->lock);
+	return ret;
+}
 
-int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
 	__u32 ofs = instr->addr;
@@ -1041,6 +1073,8 @@
 	unsigned long docptr;
 	struct Nand *mychip;
 
+	down(&this->lock);
+
 	if (len != mtd->erasesize)
 		printk(KERN_WARNING "Erase not right size (%x != %x)n",
 		       len, mtd->erasesize);
@@ -1078,6 +1112,7 @@
 	if (instr->callback)
 		instr->callback(instr);
 
+	up(&this->lock);
 	return 0;
 }
 
Index: include/linux/mtd/doc2000.h
===================================================================
RCS file: /home/cvs/mtd/include/linux/mtd/doc2000.h,v
retrieving revision 1.13
diff -u -r1.13 doc2000.h
--- include/linux/mtd/doc2000.h	2001/05/29 12:03:45	1.13
+++ include/linux/mtd/doc2000.h	2001/07/17 12:47:52
@@ -134,6 +134,7 @@
 	int numchips;
 	struct Nand *chips;
 	struct mtd_info *nextdoc;
+	struct semaphore lock;
 };
 
 int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);


----- End forwarded message -----

-- 
Cemil Degirmenci                //   http://cemil.debian-linux.de
Am Eisenberg 13                 //   Tel.       06638-9180010   
36341 Lauterbach                //   Mobil.     0177-2541153
Germany                         //   E-Mail     cemil@security-focus.de

^ permalink raw reply	[flat|nested] 77+ messages in thread
* Patch
@ 1999-05-20 11:54 nicolas.boussekeyt
  0 siblings, 0 replies; 77+ messages in thread
From: nicolas.boussekeyt @ 1999-05-20 11:54 UTC (permalink / raw)
  To: linuxppc-dev, linuxppc-user


I want used the patch find ftp.ppc.kernel.org to my powerbook.
How does i used  this patch in the src of the kernel ?

                                         Nicolas BOUSSEKEYT
                                         ALCATEL Fibre Optique
                                        Tel : 03 21 79 49 00
                                        Web : http://www.alcatel.fr

[[ This message was sent via the linuxppc-dev mailing list.  Replies are ]]
[[ not  forced  back  to the list, so be sure to Cc linuxppc-dev if your ]]
[[ reply is of general interest. Please check http://lists.linuxppc.org/ ]]
[[ and http://www.linuxppc.org/ for useful information before posting.   ]]

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2024-06-18 16:40 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-11  0:01 PATCH Pete Popov
2004-10-11  0:32 ` PATCH Maciej W. Rozycki
2004-10-11  0:47   ` PATCH Pete Popov
2004-10-11  7:55   ` PATCH Pete Popov
2004-10-11 10:32     ` PATCH Christoph Hellwig
2004-10-11 17:07       ` PATCH Pete Popov
2004-10-11 13:53     ` PATCH Atsushi Nemoto
2004-10-11 16:33       ` PATCH Pete Popov
2004-10-11 18:04         ` PATCH Pete Popov
  -- strict thread matches above, loose matches on Subject: below --
2024-06-18 16:19 Patch Solegaiter
2024-06-18 16:40 ` Patch bluez.test.bot
2020-06-23 23:14 Patch Joe Slater
     [not found] <06c7632e-9e21-7428-bfa3-4ec122f637fd@synopsys.com>
2016-12-27 16:41 ` Patch Joao Pinto
2016-12-27 16:42 ` Patch Joao Pinto
2013-11-22 16:35 Patch Arthur Schwalbenberg
2013-11-22 17:36 ` Patch Levente Kurusa
2013-11-25  8:58   ` Patch Daniel Vetter
2013-11-25  8:58     ` Patch Daniel Vetter
2013-01-23 22:12 Patch for ip setting on bridge interface and vlan Kevin Yung
2013-01-23 22:51 ` Patch Kevin Yung
2010-05-04 16:48 patch Kristoffer Ericson
2009-01-29 10:11 PATCH gabriele.paoloni
2004-10-10 23:43 PATCH Pete Popov
2004-10-10 17:17 PATCH Pete Popov
2004-10-10 18:01 ` PATCH Geert Uytterhoeven
2004-10-10 19:11   ` PATCH Maciej W. Rozycki
2004-10-10 22:50     ` PATCH Pete Popov
2004-10-11  0:25       ` PATCH Maciej W. Rozycki
2004-10-11  0:39         ` PATCH Pete Popov
2004-10-10 19:33   ` PATCH Matt Porter
2004-10-10 22:52     ` PATCH Pete Popov
2004-10-10 23:41     ` PATCH Pete Popov
2004-10-10  7:17 PATCH Pete Popov
2004-10-10  5:31 PATCH Pete Popov
2004-02-28 22:06 Patch Tommy McCabe
2004-02-22  0:44 PATCH Pete Popov
2004-02-22 16:08 ` PATCH Kronos
2004-02-22 19:03   ` PATCH Pete Popov
2003-12-01  5:58 patch Diyab
2003-12-01 14:36 ` patch Stephen Smalley
2003-11-03 22:45 Patch Frank Borich
2003-11-03 23:00 ` Patch Patrick Mansfield
     [not found] <OE58jbP3SIGYF2rEF6f00001796@hotmail.com>
2003-02-10 16:09 ` Patch Aman
2003-02-10 17:24   ` Patch Matt Porter
2002-12-25 17:36 Patch Mailhebuau Christophe
     [not found] ` <1040837764.2777.8.camel-SH3sQJamR4OeZLLa646FqQ@public.gmane.org>
2002-12-25 19:10   ` Patch Gregory Gulik
2002-12-26  5:12   ` Patch Theodore Morse
2002-12-14  4:52 PATCH Pete Popov
2002-12-17 22:29 ` PATCH Greg Lindahl
2002-12-17 22:40   ` PATCH Pete Popov
2002-12-17 23:24     ` PATCH Alan Cox
2002-12-17 22:51       ` PATCH Pete Popov
2002-12-17 22:59         ` PATCH Greg Lindahl
2002-12-20 20:43 ` PATCH James Simmons
2002-12-20 20:59   ` PATCH Pete Popov
2002-12-21 20:39     ` PATCH James Simmons
2002-12-14  4:50 PATCH Pete Popov
2002-11-18 23:07 patch deepak
2002-11-18 23:20 ` patch Rik van Riel
2002-11-19  7:33   ` patch Duncan Sands
2002-08-26  0:35 patch Russell Coker
2002-08-26 17:15 ` patch Stephen Smalley
2002-08-26 17:37 ` patch Stephen Smalley
2002-07-15 22:29 PATCH Pete Popov
2002-07-16 15:07 ` PATCH Ralf Baechle
2002-07-16 15:15   ` PATCH Pete Popov
2002-07-16 17:43     ` PATCH Joe George
2002-07-16 18:00       ` PATCH Pete Popov
2002-07-17  0:29         ` PATCH Vivien Chappelier
2002-05-22 15:04 patch Wilson G. Hein
2002-05-22 17:44 ` patch Riley Williams
2002-05-23 11:33 ` patch Wilbert Knol
2002-05-23 16:01   ` patch Richard Adams
2002-05-24 14:14   ` patch Tomi Manninen
2001-08-14 15:32 patch Ryan Senior
2001-08-15 12:55 ` patch Stephen Smalley
2001-07-17 12:54 Patch Cemil Degirmenci
1999-05-20 11:54 Patch nicolas.boussekeyt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.