Linux Kernel Patch v2.2, patch-2.2.8 (05/33)

15 views
Skip to first unread message

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part05

#!/bin/sh
# this is part 05 of a 33 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 05; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&
X .word _arm6_7_flush_tlb_all @ 44
X .word _arm6_7_flush_tlb_area @ 48
X .word _arm7_set_pmd @ 52
- .word _arm6_7_reset @ 56
- .word _arm6_7_flush_cache @ 60
-
+ .word _arm6_7_set_pte @ 56
+ .word _arm6_7_reset @ 60
X .word _arm6_7_flush_cache @ 64
+
X .word _arm6_7_flush_cache @ 68
+ .word _arm6_7_flush_cache @ 72
diff -u --recursive --new-file v2.2.7/linux/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S
--- v2.2.7/linux/arch/arm/mm/proc-sa110.S Tue Dec 22 14:16:53 1998
+++ linux/arch/arm/mm/proc-sa110.S Sat May 8 11:07:16 1999
@@ -8,6 +8,7 @@
X */
X #include <linux/linkage.h>
X #include <asm/assembler.h>
+#include <asm/hardware.h>
X #include "../lib/constants.h"
X
X /* This is the maximum size of an area which will be flushed. If the area
@@ -21,7 +22,6 @@
X
X /*
X * Function: sa110_flush_cache_all (void)
- *
X * Purpose : Flush all cache lines
X */
X .align 5
@@ -33,7 +33,7 @@
X ands r1, r1, #1
X eor r1, r1, #1
X str r1, [r3]
- ldr ip, =0xdf000000
+ ldr ip, =FLUSH_BASE
X addne ip, ip, #32768
X add r1, ip, #16384 @ only necessary for 16k
X 1: ldr r3, [ip], #32
@@ -47,11 +47,9 @@
X
X /*
X * Function: sa110_flush_cache_area (unsigned long address, int end, int flags)
- *
X * Params : address Area start address
X * : end Area end address
X * : flags b0 = I cache as well
- *
X * Purpose : clean & flush all cache lines associated with this area of memory
X */
X .align 5
@@ -74,10 +72,8 @@
X
X /*
X * Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
- *
X * Params : address Area start address
X * : end Area end address
- *
X * Purpose : ensure all dirty cachelines in the specified area have been
X * written out to memory (for DMA)
X */
@@ -99,13 +95,10 @@
X
X /*
X * Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
- *
X * Params : address Area start address
X * : end Area end address
- *
X * Purpose : throw away all D-cached data in specified region without
- * an obligation to write it ack.
- *
+ * an obligation to write it back.
X * Note : Must clean the D-cached entries around the boundaries if the
X * start and/or end address are not cache aligned.
X */
@@ -124,9 +117,7 @@
X
X /*
X * Function: sa110_flush_cache_entry (unsigned long address)
- *
X * Params : address Address of cache line to flush
- *
X * Purpose : clean & flush an entry
X */
X .align 5
@@ -138,24 +129,23 @@
X mov pc, lr
X
X /*
- * Function: sa110_flush_cache_pte (unsigned long address)
- *
+ * Function: sa110_clean_cache_area(unsigned long start, unsigned long size)
X * Params : address Address of cache line to clean
- *
X * Purpose : Ensure that physical memory reflects cache at this location
X * for page table purposes.
X */
-_sa110_flush_cache_pte:
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
+_sa110_clean_cache_area:
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
+ add r0, r0, #32
+ subs r1, r1, #32
+ bhi 1b
X mov pc, lr
X
X /*
X * Function: sa110_flush_ram_page (unsigned long page)
- *
X * Params : address Area start address
X * : size size of area
X * : flags b0 = I cache as well
- *
X * Purpose : clean & flush all cache lines associated with this area of memory
X */
X .align 5
@@ -176,7 +166,6 @@
X
X /*
X * Function: sa110_flush_tlb_all (void)
- *
X * Purpose : flush all TLB entries in all caches
X */
X .align 5
@@ -188,11 +177,9 @@
X
X /*
X * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
- *
X * Params : address Area start address
X * : end Area end address
X * : flags b0 = I cache as well
- *
X * Purpose : flush a TLB entry
X */
X .align 5
@@ -212,22 +199,21 @@
X
X .align 5
X _sa110_flush_icache_area:
- mov r3, #0
X 1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
X add r0, r0, #32
- cmp r0, r1
- blt 1b
+ subs r1, r1, #32
+ bhi 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
X mcr p15, 0, r0, c7, c5, 0 @ flush I cache
X mov pc, lr
X /*
X * Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next)
- *
X * Params : prev Old task structure
X * : next New task structure for process to run
- *
+ * Returns : prev
X * Purpose : Perform a task switch, saving the old processes state, and restoring
X * the new.
- *
X * Notes : We don't fiddle with the FP registers here - we postpone this until
X * the new task actually uses FP. This way, we don't swap FP for tasks
X * that do not require it.
@@ -237,20 +223,30 @@
X stmfd sp!, {r4 - r9, fp, lr} @ Store most regs on stack
X mrs ip, cpsr
X stmfd sp!, {ip} @ Save cpsr_SVC
+ ldr r2, [r0, #TSS_MEMMAP] @ Get old page tables
X str sp, [r0, #TSS_SAVE] @ Save sp_SVC
X ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldr r0, [r1, #TSK_ADDR_LIMIT]
- teq r0, #0
- moveq r0, #DOM_KERNELDOMAIN
- movne r0, #DOM_USERDOMAIN
- mcr p15, 0, r0, c3, c0 @ Set segment
- ldr r0, [r1, #TSS_MEMMAP] @ Page table pointer
+ ldr r4, [r1, #TSK_ADDR_LIMIT]
+ teq r4, #0
+ moveq r4, #DOM_KERNELDOMAIN
+ movne r4, #DOM_USERDOMAIN
+ mcr p15, 0, r4, c3, c0 @ Set segment
+ ldr r4, [r1, #TSS_MEMMAP] @ Page table pointer
+/*
+ * Flushing the cache is nightmarishly slow, so we take any excuse
+ * to get out of it. If the old page table is the same as the new,
+ * this is a CLONE_VM relative of the old task and there is no need
+ * to flush. The overhead of the tests isn't even on the radar
+ * compared to the cost of the flush itself.
+ */
+ teq r4, r2
+ beq 2f
X ldr r3, =Lclean_switch
X ldr r2, [r3]
X ands r2, r2, #1
X eor r2, r2, #1
X str r2, [r3]
- ldr r2, =0xdf000000
+ ldr r2, =FLUSH_BASE
X addne r2, r2, #32768
X add r1, r2, #16384 @ only necessary for 16k
X 1: ldr r3, [r2], #32
@@ -259,19 +255,16 @@
X mov r1, #0
X mcr p15, 0, r1, c7, c5, 0 @ flush I cache
X mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
X mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
- ldmfd sp!, {ip}
+2: ldmfd sp!, {ip}
X msr spsr, ip @ Save tasks CPSR into SPSR for this return
X ldmfd sp!, {r4 - r9, fp, pc}^ @ Load all regs saved previously
X
X /*
X * Function: sa110_data_abort ()
- *
X * Params : r0 = address of aborted instruction
- *
X * Purpose : obtain information about current aborted instruction
- *
X * Returns : r0 = address of abort
X * : r1 = FSR
X * : r2 != 0 if writing
@@ -288,12 +281,10 @@
X mov pc, lr
X
X /*
- * Function: sa110_set_pmd ()
- *
+ * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd)
X * Params : r0 = Address to set
X * : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
+ * Purpose : Set a PMD and flush it out
X */
X .align 5
X _sa110_set_pmd: str r1, [r0]
@@ -301,23 +292,51 @@
X mov pc, lr
X
X /*
+ * Function: sa110_set_pte(pte_t *ptep, pte_t pte)
+ * Params : r0 = Address to set
+ * : r1 = value to set
+ * Purpose : Set a PTE and flush it out
+ */
+ .align 5
+_sa110_set_pte: str r1, [r0], #-1024 @ linux version
+
+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+ bic r2, r1, #0xff0
+ bic r2, r2, #3
+ orr r2, r2, #HPTE_TYPE_SMALL
+
+ tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
+ orrne r2, r2, #HPTE_AP_READ
+
+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+ orreq r2, r2, #HPTE_AP_WRITE
+
+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+ str r2, [r0] @ hardware version
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
+ mov pc, lr
+
+/*
X * Function: sa110_check_bugs (void)
X * : sa110_proc_init (void)
X * : sa110_proc_fin (void)
- *
X * Notes : This processor does not require these
X */
X _sa110_check_bugs:
X mrs ip, cpsr
X bic ip, ip, #F_BIT
X msr cpsr, ip
+
X _sa110_proc_init:
X _sa110_proc_fin:
X mov pc, lr
X
X /*
X * Function: sa110_reset
- *
X * Notes : This sets up everything for a reset
X */
X _sa110_reset: mrs r1, cpsr
@@ -350,14 +369,15 @@
X .word _sa110_flush_cache_all @ 24
X .word _sa110_flush_cache_area @ 28
X .word _sa110_flush_cache_entry @ 32
- .word _sa110_flush_cache_pte @ 36
+ .word _sa110_clean_cache_area @ 36
X .word _sa110_flush_ram_page @ 40
X .word _sa110_flush_tlb_all @ 44
X .word _sa110_flush_tlb_area @ 48
X
X .word _sa110_set_pmd @ 52
- .word _sa110_reset @ 56
- .word _sa110_flush_icache_area @ 60
+ .word _sa110_set_pte @ 56
+ .word _sa110_reset @ 60
+ .word _sa110_flush_icache_area @ 64
X
- .word _sa110_cache_wback_area @ 64
- .word _sa110_cache_purge_area @ 68
+ .word _sa110_cache_wback_area @ 68
+ .word _sa110_cache_purge_area @ 72
diff -u --recursive --new-file v2.2.7/linux/arch/arm/mm/small_page.c linux/arch/arm/mm/small_page.c
--- v2.2.7/linux/arch/arm/mm/small_page.c Wed Sep 9 14:51:05 1998
+++ linux/arch/arm/mm/small_page.c Sat May 8 11:06:57 1999
@@ -5,6 +5,8 @@
X *
X * Changelog:
X * 26/01/1996 RMK Cleaned up various areas to make little more generic
+ * 07/02/1999 RMK Support added for 16K and 32K page sizes
+ * containing 8K blocks
X */
X
X #include <linux/signal.h>
@@ -19,21 +21,32 @@
X #include <linux/swap.h>
X #include <linux/smp.h>
X
-#define SMALL_ALLOC_SHIFT (10)
+#if PAGE_SIZE == 4096
+/* 2K blocks */
+#define SMALL_ALLOC_SHIFT (11)
+#define NAME(x) x##_2k
+#elif PAGE_SIZE == 32768 || PAGE_SIZE == 16384
+/* 8K blocks */
+#define SMALL_ALLOC_SHIFT (13)
+#define NAME(x) x##_8k
+#endif
+
X #define SMALL_ALLOC_SIZE (1 << SMALL_ALLOC_SHIFT)
X #define NR_BLOCKS (PAGE_SIZE / SMALL_ALLOC_SIZE)
+#define BLOCK_MASK ((1 << NR_BLOCKS) - 1)
X
-#if NR_BLOCKS != 4
-#error I only support 4 blocks per page!
-#endif
-
-#define USED(pg) ((atomic_read(&(pg)->count) >> 8) & 15)
+#define USED(pg) ((atomic_read(&(pg)->count) >> 8) & BLOCK_MASK)
X #define SET_USED(pg,off) (atomic_read(&(pg)->count) |= 256 << off)
X #define CLEAR_USED(pg,off) (atomic_read(&(pg)->count) &= ~(256 << off))
+#define ALL_USED BLOCK_MASK
X #define IS_FREE(pg,off) (!(atomic_read(&(pg)->count) & (256 << off)))
-#define PAGE_PTR(page,block) ((struct free_small_page *)((page) + \
+#define SM_PAGE_PTR(page,block) ((struct free_small_page *)((page) + \
X ((block) << SMALL_ALLOC_SHIFT)))
X
+#if NR_BLOCKS != 2 && NR_BLOCKS != 4
+#error I only support 2 or 4 blocks per page
+#endif
+
X struct free_small_page {
X unsigned long next;
X unsigned long prev;
@@ -52,6 +65,7 @@
X 1, /* 0001 */
X 0, /* 0010 */
X 2, /* 0011 */
+#if NR_BLOCKS == 4
X 0, /* 0100 */
X 1, /* 0101 */
X 0, /* 0110 */
@@ -64,6 +78,7 @@
X 1, /* 1101 */
X 0, /* 1110 */
X 4 /* 1111 */
+#endif
X };
X
X static inline void clear_page_links(unsigned long page)
@@ -72,7 +87,7 @@
X int i;
X
X for (i = 0; i < NR_BLOCKS; i++) {
- fsp = PAGE_PTR(page, i);
+ fsp = SM_PAGE_PTR(page, i);
X fsp->next = fsp->prev = 0;
X }
X }
@@ -90,7 +105,7 @@
X for (i = 0; i < NR_BLOCKS; i++) {
X if (mask & (1 << i))
X continue;
- fsp = PAGE_PTR(page, i);
+ fsp = SM_PAGE_PTR(page, i);
X fsp->prev = prev;
X }
X }
@@ -108,12 +123,12 @@
X for (i = 0; i < NR_BLOCKS; i++) {
X if (mask & (1 << i))
X continue;
- fsp = PAGE_PTR(page, i);
+ fsp = SM_PAGE_PTR(page, i);
X fsp->next = next;
X }
X }
X
-unsigned long get_small_page(int priority)
+unsigned long NAME(get_page)(int priority)
X {
X struct free_small_page *fsp;
X unsigned long new_page;
@@ -129,8 +144,8 @@
X page = mem_map + MAP_NR(small_page_ptr);
X offset = offsets[USED(page)];
X SET_USED(page, offset);
- new_page = (unsigned long)PAGE_PTR(small_page_ptr, offset);
- if (USED(page) == 15) {
+ new_page = (unsigned long)SM_PAGE_PTR(small_page_ptr, offset);
+ if (USED(page) == ALL_USED) {
X fsp = (struct free_small_page *)new_page;
X set_page_links_prev (fsp->next, 0);
X small_page_ptr = fsp->next;
@@ -156,30 +171,31 @@
X goto again;
X }
X
-void free_small_page(unsigned long spage)
+void NAME(free_page)(unsigned long spage)
X {
X struct free_small_page *ofsp, *cfsp;
X unsigned long flags;
X struct page *page;
X int offset, oldoffset;
X
+ if (!spage)
+ goto none;
+
X offset = (spage >> SMALL_ALLOC_SHIFT) & (NR_BLOCKS - 1);
X spage -= offset << SMALL_ALLOC_SHIFT;
X
X page = mem_map + MAP_NR(spage);
- if (!PageReserved(page) || !USED(page)) {
- printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
- return;
- }
- if (IS_FREE(page, offset)) {
- printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
- return;
- }
+ if (!PageReserved(page) || !USED(page))
+ goto non_small;
+
+ if (IS_FREE(page, offset))
+ goto free;
+
X save_flags_cli (flags);
X oldoffset = offsets[USED(page)];
X CLEAR_USED(page, offset);
- ofsp = PAGE_PTR(spage, oldoffset);
- cfsp = PAGE_PTR(spage, offset);
+ ofsp = SM_PAGE_PTR(spage, oldoffset);
+ cfsp = SM_PAGE_PTR(spage, offset);
X
X if (oldoffset == NR_BLOCKS) { /* going from totally used to mostly used */
X cfsp->prev = 0;
@@ -197,4 +213,13 @@
X } else
X *cfsp = *ofsp;
X restore_flags(flags);
+ return;
+
+non_small:
+ printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
+ return;
+free:
+ printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
+none:
+ return;
X }
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- v2.2.7/linux/arch/i386/kernel/entry.S Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/entry.S Fri Apr 30 08:13:37 1999
@@ -154,7 +154,9 @@
X .globl ret_from_fork
X ret_from_fork:
X #ifdef __SMP__
+ pushl %ebx
X call SYMBOL_NAME(schedule_tail)
+ addl $4, %esp
X #endif /* __SMP__ */
X GET_CURRENT(%ebx)
X jmp ret_from_sys_call
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.2.7/linux/arch/i386/kernel/i386_ksyms.c Tue Mar 23 14:35:46 1999
+++ linux/arch/i386/kernel/i386_ksyms.c Mon May 10 10:32:45 1999
@@ -39,6 +39,7 @@
X EXPORT_SYMBOL(local_irq_count);
X EXPORT_SYMBOL(enable_irq);
X EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(disable_irq_nosync);
X EXPORT_SYMBOL(kernel_thread);
X
X EXPORT_SYMBOL_NOVERS(__down_failed);
@@ -91,7 +92,7 @@
X EXPORT_SYMBOL(__global_sti);
X EXPORT_SYMBOL(__global_save_flags);
X EXPORT_SYMBOL(__global_restore_flags);
-EXPORT_SYMBOL(mtrr_hook);
+EXPORT_SYMBOL(smp_call_function);
X #endif
X
X #ifdef CONFIG_MCA
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.2.7/linux/arch/i386/kernel/io_apic.c Fri Apr 16 14:47:30 1999
+++ linux/arch/i386/kernel/io_apic.c Thu May 6 16:07:03 1999
@@ -1049,7 +1049,7 @@
X * and do not need to be masked.
X */
X ack_APIC_irq();
- status = desc->status & ~IRQ_REPLAY;
+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
X status |= IRQ_PENDING;
X
X /*
@@ -1060,8 +1060,9 @@
X if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
X action = desc->action;
X status &= ~IRQ_PENDING;
+ status |= IRQ_INPROGRESS;
X }
- desc->status = status | IRQ_INPROGRESS;
+ desc->status = status;
X spin_unlock(&irq_controller_lock);
X
X /*
@@ -1103,7 +1104,7 @@
X * So this all has to be within the spinlock.
X */
X mask_IO_APIC_irq(irq);
- status = desc->status & ~IRQ_REPLAY;
+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
X
X /*
X * If the IRQ is disabled for whatever reason, we must
@@ -1112,8 +1113,9 @@
X action = NULL;
X if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
X action = desc->action;
+ status |= IRQ_INPROGRESS;
X }
- desc->status = status | IRQ_INPROGRESS;
+ desc->status = status;
X
X ack_APIC_irq();
X spin_unlock(&irq_controller_lock);
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.2.7/linux/arch/i386/kernel/irq.c Fri Apr 16 14:47:30 1999
+++ linux/arch/i386/kernel/irq.c Mon May 10 10:32:45 1999
@@ -203,7 +203,7 @@
X
X void make_8259A_irq(unsigned int irq)
X {
- disable_irq(irq);
+ disable_irq_nosync(irq);
X io_apic_irqs &= ~(1<<irq);
X irq_desc[irq].handler = &i8259A_irq_type;
X enable_irq(irq);
@@ -239,11 +239,13 @@
X {
X unsigned int status;
X mask_and_ack_8259A(irq);
- status = desc->status & ~IRQ_REPLAY;
+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
X action = NULL;
- if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
X action = desc->action;
- desc->status = status | IRQ_INPROGRESS;
+ status |= IRQ_INPROGRESS;
+ }
+ desc->status = status;
X }
X spin_unlock(&irq_controller_lock);
X
@@ -320,7 +322,7 @@
X BUILD_SMP_INTERRUPT(reschedule_interrupt)
X BUILD_SMP_INTERRUPT(invalidate_interrupt)
X BUILD_SMP_INTERRUPT(stop_cpu_interrupt)
-BUILD_SMP_INTERRUPT(mtrr_interrupt)
+BUILD_SMP_INTERRUPT(call_function_interrupt)
X BUILD_SMP_INTERRUPT(spurious_interrupt)
X
X /*
@@ -747,7 +749,7 @@
X * hardware disable after having gotten the irq
X * controller lock.
X */
-void disable_irq(unsigned int irq)
+void disable_irq_nosync(unsigned int irq)
X {
X unsigned long flags;
X
@@ -757,9 +759,21 @@
X irq_desc[irq].handler->disable(irq);
X }
X spin_unlock_irqrestore(&irq_controller_lock, flags);
+}
+
+/*
+ * Synchronous version of the above, making sure the IRQ is
+ * no longer running on any other IRQ..
+ */
+void disable_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
X
- if (irq_desc[irq].status & IRQ_INPROGRESS)
- synchronize_irq();
+ if (!local_irq_count[smp_processor_id()]) {
+ do {
+ barrier();
+ } while (irq_desc[irq].status & IRQ_INPROGRESS);
+ }
X }
X
X void enable_irq(unsigned int irq)
@@ -769,7 +783,7 @@
X spin_lock_irqsave(&irq_controller_lock, flags);
X switch (irq_desc[irq].depth) {
X case 1:
- irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS);
+ irq_desc[irq].status &= ~IRQ_DISABLED;
X irq_desc[irq].handler->enable(irq);
X /* fall throught */
X default:
@@ -864,7 +878,7 @@
X
X if (!shared) {
X irq_desc[irq].depth = 0;
- irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS);
+ irq_desc[irq].status &= ~IRQ_DISABLED;
X irq_desc[irq].handler->startup(irq);
X }
X spin_unlock_irqrestore(&irq_controller_lock,flags);
@@ -936,7 +950,7 @@
X *
X * This depends on the fact that any interrupt that
X * comes in on to an unassigned handler will get stuck
- * with "IRQ_INPROGRESS" asserted and the interrupt
+ * with "IRQ_WAITING" cleared and the interrupt
X * disabled.
X */
X unsigned long probe_irq_on(void)
@@ -950,8 +964,7 @@
X spin_lock_irq(&irq_controller_lock);
X for (i = NR_IRQS-1; i > 0; i--) {
X if (!irq_desc[i].action) {
- unsigned int status = irq_desc[i].status | IRQ_AUTODETECT;
- irq_desc[i].status = status & ~IRQ_INPROGRESS;
+ irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING;
X irq_desc[i].handler->startup(i);
X }
X }
@@ -974,7 +987,7 @@
X continue;
X
X /* It triggered already - consider it spurious. */
- if (status & IRQ_INPROGRESS) {
+ if (!(status & IRQ_WAITING)) {
X irq_desc[i].status = status & ~IRQ_AUTODETECT;
X irq_desc[i].handler->shutdown(i);
X }
@@ -1000,7 +1013,7 @@
X if (!(status & IRQ_AUTODETECT))
X continue;
X
- if (status & IRQ_INPROGRESS) {
+ if (!(status & IRQ_WAITING)) {
X if (!nr_irqs)
X irq_found = i;
X nr_irqs++;
@@ -1081,8 +1094,8 @@
X /* self generated IPI for local APIC timer */
X set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
X
- /* IPI for MTRR control */
- set_intr_gate(MTRR_CHANGE_VECTOR, mtrr_interrupt);
+ /* IPI for generic function call */
+ set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
X
X /* IPI vector for APIC spurious interrupts */
X set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.2.7/linux/arch/i386/kernel/irq.h Fri Apr 16 14:47:30 1999
+++ linux/arch/i386/kernel/irq.h Tue May 11 10:37:06 1999
@@ -26,6 +26,7 @@
X #define IRQ_PENDING 4 /* IRQ pending - replay on enable */
X #define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */
X #define IRQ_AUTODETECT 16 /* IRQ is being autodetected */
+#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
X
X /*
X * This is the "IRQ descriptor", which contains various information
@@ -64,7 +65,7 @@
X #define INVALIDATE_TLB_VECTOR 0x31
X #define STOP_CPU_VECTOR 0x40
X #define LOCAL_TIMER_VECTOR 0x41
-#define MTRR_CHANGE_VECTOR 0x50
+#define CALL_FUNCTION_VECTOR 0x50
X
X /*
X * First APIC vector available to drivers: (vectors 0x51-0xfe)
@@ -98,7 +99,6 @@
X extern int i8259A_irq_pending(unsigned int irq);
X extern void ack_APIC_irq(void);
X extern void FASTCALL(send_IPI_self(int vector));
-extern void smp_send_mtrr(void);
X extern void init_VISWS_APIC_irqs(void);
X extern void setup_IO_APIC(void);
X extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c
--- v2.2.7/linux/arch/i386/kernel/mca.c Fri Apr 16 14:47:30 1999
+++ linux/arch/i386/kernel/mca.c Mon May 10 13:00:10 1999
@@ -92,7 +92,7 @@
X * is set to zero.
X */
X
-static struct MCA_info* mca_info = 0;
+static struct MCA_info* mca_info = NULL;
X
X /* MCA registers */
X
@@ -160,7 +160,10 @@
X
X /* id = 0x0000 usually indicates hardware failure,
X * however, ZP Gu (z...@castle.net> reports that his 9556
- * has 0x0000 as id and everything still works.
+ * has 0x0000 as id and everything still works. There
+ * also seem to be an adapter with id = 0x0000; the
+ * NCR Parallel Bus Memory Card. Until this is confirmed,
+ * however, this code will stay.
X */
X
X mca_info->slot[slot].status = MCA_ADAPTER_ERROR;
@@ -222,7 +225,13 @@
X
X /* Allocate MCA_info structure (at address divisible by 8) */
X
- mca_info = kmalloc(sizeof(struct MCA_info), GFP_ATOMIC);
+ mca_info = kmalloc(sizeof(struct MCA_info), GFP_KERNEL);
+
+ if(mca_info == NULL) {
+ printk("Failed to allocate memory for mca_info!");
+ restore_flags(flags);
+ return;
+ }
X
X /* Make sure adapter setup is off */
X
@@ -382,7 +391,7 @@
X
X int mca_find_adapter(int id, int start)
X {
- if(mca_info == 0 || id == 0 || id == 0xffff) {
+ if(mca_info == NULL || id == 0xffff) {
X return MCA_NOTFOUND;
X }
X
@@ -412,7 +421,7 @@
X
X int mca_find_unused_adapter(int id, int start)
X {
- if(mca_info == 0 || id == 0 || id == 0xffff) {
+ if(mca_info == NULL || id == 0xffff) {
X return MCA_NOTFOUND;
X }
X
@@ -443,7 +452,7 @@
X
X unsigned char mca_read_stored_pos(int slot, int reg)
X {
- if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0) return 0;
+ if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
X if(reg < 0 || reg >= 8) return 0;
X return mca_info->slot[slot].pos[reg];
X } /* mca_read_stored_pos() */
@@ -455,7 +464,7 @@
X unsigned int byte = 0;
X unsigned long flags;
X
- if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == 0) return 0;
+ if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
X if(reg < 0 || reg >= 8) return 0;
X
X save_flags(flags);
@@ -527,7 +536,7 @@
X return;
X if(reg < 0 || reg >= 8)
X return;
- if(mca_info == 0)
+ if(mca_info == NULL)
X return;
X
X save_flags(flags);
@@ -554,7 +563,7 @@
X
X void mca_set_adapter_name(int slot, char* name)
X {
- if(mca_info == 0) return;
+ if(mca_info == NULL) return;
X
X if(slot >= 0 && slot < MCA_NUMADAPTERS) {
X if(name != NULL) {
@@ -570,7 +579,7 @@
X
X void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* dev)
X {
- if(mca_info == 0) return;
+ if(mca_info == NULL) return;
X
X if(slot >= 0 && slot < MCA_NUMADAPTERS) {
X mca_info->slot[slot].procfn = procfn;
@@ -597,7 +606,7 @@
X
X char *mca_get_adapter_name(int slot)
X {
- if(mca_info == 0) return 0;
+ if(mca_info == NULL) return 0;
X
X if(slot >= 0 && slot < MCA_NUMADAPTERS) {
X return mca_info->slot[slot].name;
@@ -608,7 +617,7 @@
X
X int mca_isadapter(int slot)
X {
- if(mca_info == 0) return 0;
+ if(mca_info == NULL) return 0;
X
X if(slot >= 0 && slot < MCA_NUMADAPTERS) {
X return ((mca_info->slot[slot].status == MCA_ADAPTER_NORMAL)
@@ -620,7 +629,7 @@
X
X int mca_isenabled(int slot)
X {
- if(mca_info == 0) return 0;
+ if(mca_info == NULL) return 0;
X
X if(slot >= 0 && slot < MCA_NUMADAPTERS) {
X return (mca_info->slot[slot].status == MCA_ADAPTER_NORMAL);
@@ -637,7 +646,7 @@
X {
X int i, j, len = 0;
X
- if(MCA_bus && mca_info != 0)
+ if(MCA_bus && mca_info != NULL)
X {
X /* Format POS registers of eight MCA slots */
X
@@ -676,10 +685,10 @@
X
X __initfunc(void mca_do_proc_init(void))
X {
- int i = 0;
- struct proc_dir_entry* node = 0;
+ int i;
+ struct proc_dir_entry* node = NULL;
X
- if(mca_info == 0) return; /* Should never happen */
+ if(mca_info == NULL) return; /* Should never happen */
X
X proc_register(&proc_mca, &(struct proc_dir_entry) {
X PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO,
@@ -696,8 +705,12 @@
X mca_info->slot[i].dev = 0;
X
X if(!mca_isadapter(i)) continue;
- node = kmalloc(sizeof(struct proc_dir_entry), GFP_ATOMIC);
+ node = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
X
+ if(node == NULL) {
+ printk("Failed to allocate memory for MCA proc-entries!");
+ return;
+ }
X if(i < MCA_MAX_SLOT_NR) {
X node->low_ino = PROC_MCA_SLOT + i;
X node->namelen = sprintf(mca_info->slot[i].procname,
@@ -727,7 +740,7 @@
X
X /* This really shouldn't happen... */
X
- if(mca_info == 0) {
+ if(mca_info == NULL) {
X *buf = 0;
X return 0;
X }
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.2.7/linux/arch/i386/kernel/mtrr.c Mon Dec 28 15:00:52 1998
+++ linux/arch/i386/kernel/mtrr.c Mon May 10 10:32:45 1999
@@ -132,6 +132,70 @@
X Fixed harmless compiler warning in include/asm-i386/mtrr.h
X Fixed version numbering and history for v1.23 -> v1.24.
X v1.26
+ 19990118 Richard Gooch <rgo...@atnf.csiro.au>
+ PLACEHOLDER.
+ v1.27
+ 19990123 Richard Gooch <rgo...@atnf.csiro.au>
+ Changed locking to spin with reschedule.
+ Made use of new <smp_call_function>.
+ v1.28
+ 19990201 Zoltan Boszormenyi <zbo...@mol.hu>
+ Extended the driver to be able to use Cyrix style ARRs.
+ 19990204 Richard Gooch <rgo...@atnf.csiro.au>
+ Restructured Cyrix support.
+ v1.29
+ 19990204 Zoltan Boszormenyi <zbo...@mol.hu>
+ Refined ARR support: enable MAPEN in set_mtrr_prepare()
+ and disable MAPEN in set_mtrr_done().
+ 19990205 Richard Gooch <rgo...@atnf.csiro.au>
+ Minor cleanups.
+ v1.30
+ 19990208 Zoltan Boszormenyi <zbo...@mol.hu>
+ Protect plain 6x86s (and other processors without the
+ Page Global Enable feature) against accessing CR4 in
+ set_mtrr_prepare() and set_mtrr_done().
+ 19990210 Richard Gooch <rgo...@atnf.csiro.au>
+ Turned <set_mtrr_up> and <get_mtrr> into function pointers.
+ v1.31
+ 19990212 Zoltan Boszormenyi <zbo...@mol.hu>
+ Major rewrite of cyrix_arr_init(): do not touch ARRs,
+ leave them as the BIOS have set them up.
+ Enable usage of all 8 ARRs.
+ Avoid multiplications by 3 everywhere and other
+ code clean ups/speed ups.
+ 19990213 Zoltan Boszormenyi <zbo...@mol.hu>
+ Set up other Cyrix processors identical to the boot cpu.
+ Since Cyrix don't support Intel APIC, this is l'art pour l'art.
+ Weigh ARRs by size:
+ If size <= 32M is given, set up ARR# we were given.
+ If size > 32M is given, set up ARR7 only if it is free,
+ fail otherwise.
+ 19990214 Zoltan Boszormenyi <zbo...@mol.hu>
+ Also check for size >= 256K if we are to set up ARR7,
+ mtrr_add() returns the value it gets from set_mtrr()
+ 19990218 Zoltan Boszormenyi <zbo...@mol.hu>
+ Remove Cyrix "coma bug" workaround from here.
+ Moved to linux/arch/i386/kernel/setup.c and
+ linux/include/asm-i386/bugs.h
+ 19990228 Richard Gooch <rgo...@atnf.csiro.au>
+ Added #ifdef CONFIG_DEVFS_FS
+ Added MTRRIOC_KILL_ENTRY ioctl(2)
+ Trap for counter underflow in <mtrr_file_del>.
+ Trap for 4 MiB aligned regions for PPro, stepping <= 7.
+ 19990301 Richard Gooch <rgo...@atnf.csiro.au>
+ Created <get_free_region> hook.
+ 19990305 Richard Gooch <rgo...@atnf.csiro.au>
+ Temporarily disable AMD support now MTRR capability flag is set.
+ v1.32
+ 19990308 Zoltan Boszormenyi <zbo...@mol.hu>
+ Adjust my changes (19990212-19990218) to Richard Gooch's
+ latest changes. (19990228-19990305)
+ v1.33
+ 19990309 Richard Gooch <rgo...@atnf.csiro.au>
+ Fixed typo in <printk> message.
+ 19990310 Richard Gooch <rgo...@atnf.csiro.au>
+ Support K6-II/III based on Alan Cox's <al...@redhat.com> patches.
+ v1.34
X */
X #include <linux/types.h>
X #include <linux/errno.h>
@@ -163,11 +227,12 @@
X #include <asm/segment.h>
X #include <asm/bitops.h>
X #include <asm/atomic.h>
+#include <asm/msr.h>
X
X #include <asm/hardirq.h>
X #include "irq.h"
X
-#define MTRR_VERSION "1.26 (19981001)"
+#define MTRR_VERSION "1.34 (19990310)"
X
X #define TRUE 1
X #define FALSE 0
@@ -197,7 +262,7 @@
X # define MTRR_CHANGE_MASK_DEFTYPE 0x04
X #endif
X
-/* In the processor's MTRR interface, the MTRR type is always held in
+/* In the Intel processor's MTRR interface, the MTRR type is always held in
X an 8 bit field: */
X typedef u8 mtrr_type;
X
@@ -207,9 +272,12 @@
X #ifdef __SMP__
X # define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
X #else
-# define set_mtrr(reg,base,size,type) set_mtrr_up (reg, base, size, type,TRUE)
+# define set_mtrr(reg,base,size,type) (*set_mtrr_up) (reg, base, size, type, \
+ TRUE)
X #endif
X
+#define spin_lock_reschedule(lock) while (!spin_trylock(lock)) schedule ();
+
X #ifndef CONFIG_PROC_FS
X # define compute_ascii() while (0)
X #endif
@@ -233,49 +301,30 @@
X unsigned long deftype_lo;
X unsigned long deftype_hi;
X unsigned long cr4val;
+ unsigned long ccr3;
X };
X
-/*
- * Access to machine-specific registers (available on 586 and better only)
- * Note: the rd* operations modify the parameters directly (without using
- * pointer indirection), this allows gcc to optimize better
- */
-#define rdmsr(msr,val1,val2) \
- __asm__ __volatile__("rdmsr" \
- : "=a" (val1), "=d" (val2) \
- : "c" (msr))
-
-#define wrmsr(msr,val1,val2) \
- __asm__ __volatile__("wrmsr" \
- : /* no outputs */ \
- : "c" (msr), "a" (val1), "d" (val2))
-
-#define rdtsc(low,high) \
- __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
-
-#define rdpmc(counter,low,high) \
- __asm__ __volatile__("rdpmc" \
- : "=a" (low), "=d" (high) \
- : "c" (counter))
-
X
-/* Put the processor into a state where MTRRs can be safely set. */
-static void set_mtrr_prepare(struct set_mtrr_context *ctxt)
+/* Put the processor into a state where MTRRs can be safely set */
+static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
X {
X unsigned long tmp;
X
- /* disable interrupts locally */
+ /* Disable interrupts locally */
X __save_flags (ctxt->flags); __cli ();
X
- /* save value of CR4 and clear Page Global Enable (bit 7) */
- asm volatile ("movl %%cr4, %0\n\t"
- "movl %0, %1\n\t"
- "andb $0x7f, %b1\n\t"
- "movl %1, %%cr4\n\t"
- : "=r" (ctxt->cr4val), "=q" (tmp) : : "memory");
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) return;
X
- /* disable and flush caches. Note that wbinvd flushes the TLBs as
- a side-effect. */
+ /* Save value of CR4 and clear Page Global Enable (bit 7) */
+ if (boot_cpu_data.x86_capability & X86_FEATURE_PGE)
+ asm volatile ("movl %%cr4, %0\n\t"
+ "movl %0, %1\n\t"
+ "andb $0x7f, %b1\n\t"
+ "movl %1, %%cr4\n\t"
+ : "=r" (ctxt->cr4val), "=q" (tmp) : : "memory");
+
+ /* Disable and flush caches. Note that wbinvd flushes the TLBs as
+ a side-effect */
X asm volatile ("movl %%cr0, %0\n\t"
X "orl $0x40000000, %0\n\t"
X "wbinvd\n\t"
@@ -283,64 +332,108 @@
X "wbinvd\n\t"
X : "=r" (tmp) : : "memory");
X
- /* disable MTRRs, and set the default type to uncached. */
- rdmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:
+ /* Disable MTRRs, and set the default type to uncached */
+ rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+ wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
+ break;
+ case X86_VENDOR_CYRIX:
+ tmp = getCx86 (CX86_CCR3);
+ setCx86 (CX86_CCR3, (tmp & 0x0f) | 0x10);
+ ctxt->ccr3 = tmp;
+ break;
+ }
X } /* End Function set_mtrr_prepare */
X
-
-/* Restore the processor after a set_mtrr_prepare */
-static void set_mtrr_done(struct set_mtrr_context *ctxt)
+/* Restore the processor after a set_mtrr_prepare */
+static void set_mtrr_done (struct set_mtrr_context *ctxt)
X {
X unsigned long tmp;
X
- /* flush caches and TLBs */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ {
+ __restore_flags (ctxt->flags);
+ return;
+ }
+
+ /* Flush caches and TLBs */
X asm volatile ("wbinvd" : : : "memory" );
X
- /* restore MTRRdefType */
- wrmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+ /* Restore MTRRdefType */
+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:
+ wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+ break;
+ case X86_VENDOR_CYRIX:
+ setCx86 (CX86_CCR3, ctxt->ccr3);
+ break;
+ }
X
- /* enable caches */
+ /* Enable caches */
X asm volatile ("movl %%cr0, %0\n\t"
X "andl $0xbfffffff, %0\n\t"
X "movl %0, %%cr0\n\t"
X : "=r" (tmp) : : "memory");
X
- /* restore value of CR4 */
- asm volatile ("movl %0, %%cr4"
- : : "r" (ctxt->cr4val) : "memory");
+ /* Restore value of CR4 */
+ if (boot_cpu_data.x86_capability & X86_FEATURE_PGE)
+ asm volatile ("movl %0, %%cr4"
+ : : "r" (ctxt->cr4val) : "memory");
X
- /* re-enable interrupts locally (if enabled previously) */
+ /* Re-enable interrupts locally (if enabled previously) */
X __restore_flags (ctxt->flags);
X } /* End Function set_mtrr_done */
X
-
-/* this function returns the number of variable MTRRs */
+/* This function returns the number of variable MTRRs */
X static unsigned int get_num_var_ranges (void)
X {
X unsigned long config, dummy;
X
- rdmsr(MTRRcap_MSR, config, dummy);
- return (config & 0xff);
+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:
+ rdmsr (MTRRcap_MSR, config, dummy);
+ return (config & 0xff);
+ /*break;*/
+ case X86_VENDOR_CYRIX:
+ /* Cyrix have 8 ARRs */
+ return 8;
+ /*break;*/
+ case X86_VENDOR_AMD:
+ return 2;
+ /*break;*/
+ }
+ return 0;
X } /* End Function get_num_var_ranges */
X
-
-/* non-zero if we have the write-combining memory type. */
+/* Returns non-zero if we have the write-combining memory type */
X static int have_wrcomb (void)
X {
X unsigned long config, dummy;
X
- rdmsr(MTRRcap_MSR, config, dummy);
- return (config & (1<<10));
-}
-
+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:
+ rdmsr (MTRRcap_MSR, config, dummy);
+ return (config & (1<<10));
+ /*break;*/
+ case X86_VENDOR_CYRIX:
+ case X86_VENDOR_AMD:
+ return 1;
+ /*break;*/
+ }
+ return 0;
+} /* End Function have_wrcomb */
X
-static void get_mtrr (unsigned int reg, unsigned long *base,
- unsigned long *size, mtrr_type *type)
+static void intel_get_mtrr (unsigned int reg, unsigned long *base,
+ unsigned long *size, mtrr_type *type)
X {
X unsigned long dummy, mask_lo, base_lo;
X
- rdmsr(MTRRphysMask_MSR(reg), mask_lo, dummy);
+ rdmsr (MTRRphysMask_MSR(reg), mask_lo, dummy);
X if ((mask_lo & 0x800) == 0) {
X /* Invalid (i.e. free) range. */
X *base = 0;
@@ -364,11 +457,104 @@
X
X *base = (base_lo & 0xfffff000UL);
X *type = (base_lo & 0xff);
-} /* End Function get_mtrr */
+} /* End Function intel_get_mtrr */
+
+static void cyrix_get_arr (unsigned int reg, unsigned long *base,
+ unsigned long *size, mtrr_type *type)
+{
+ unsigned long flags;
+ unsigned char arr, ccr3, rcr, shift;
+
+ arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
X
+ /* Save flags and disable interrupts */
+ __save_flags (flags); __cli ();
X
-static void set_mtrr_up (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type, int do_safe)
+ ccr3 = getCx86 (CX86_CCR3);
+ setCx86 (CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
+ ((unsigned char *) base)[3] = getCx86 (arr);
+ ((unsigned char *) base)[2] = getCx86 (arr+1);
+ ((unsigned char *) base)[1] = getCx86 (arr+2);
+ rcr = getCx86(CX86_RCR_BASE + reg);
+ setCx86 (CX86_CCR3, ccr3); /* disable MAPEN */
+
+ /* Enable interrupts if it was enabled previously */
+ __restore_flags (flags);
+
+ shift = ((unsigned char *) base)[1] & 0x0f;
+ *base &= 0xfffff000UL;
+
+ /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
+ * Note: shift==0xf means 4G, this is unsupported.
+ */
+ if (shift)
+ *size = (reg < 7 ? 0x800UL : 0x20000UL) << shift;
+ else
+ *size = 0;
+
+ /* Bit 0 is Cache Enable on ARR7, Cache Disable on ARR0-ARR6 */
+ if (reg < 7) {
+ switch (rcr) {
+ case 1: *type = MTRR_TYPE_UNCACHABLE; break;
+ case 8: *type = MTRR_TYPE_WRBACK; break;
+ case 9: *type = MTRR_TYPE_WRCOMB; break;
+ case 24:
+ default: *type = MTRR_TYPE_WRTHROUGH; break;
+ }
+ } else {
+ switch (rcr) {
+ case 0: *type = MTRR_TYPE_UNCACHABLE; break;
+ case 8: *type = MTRR_TYPE_WRCOMB; break;
+ case 9: *type = MTRR_TYPE_WRBACK; break;
+ case 25:
+ default: *type = MTRR_TYPE_WRTHROUGH; break;
+ }
+ }
+} /* End Function cyrix_get_arr */
+
+static void amd_get_mtrr (unsigned int reg, unsigned long *base,
+ unsigned long *size, mtrr_type *type)
+{
+ unsigned long low, high;
+
+ rdmsr (0xC0000085, low, high);
+ /* Upper dword is region 1, lower is region 0 */
+ if (reg == 1) low = high;
+ /* The base masks off on the right alignment */
+ *base = low & 0xFFFE0000;
+ *type = 0;
+ if (low & 1) *type = MTRR_TYPE_UNCACHABLE;
+ if (low & 2) *type = MTRR_TYPE_WRCOMB;
+ if ( !(low & 3) )
+ {
+ *size = 0;
+ return;
+ }
+ /*
+ * This needs a little explaining. The size is stored as an
+ * inverted mask of bits of 128K granularity 15 bits long offset
+ * 2 bits
+ *
+ * So to get a size we do invert the mask and add 1 to the lowest
+ * mask bit (4 as its 2 bits in). This gives us a size we then shift
+ * to turn into 128K blocks
+ *
+ * eg 111 1111 1111 1100 is 512K
+ *
+ * invert 000 0000 0000 0011
+ * +1 000 0000 0000 0100
+ * *128K ...
+ */
+ low = (~low) & 0x1FFFC;
+ *size = (low + 4) << 15;
+ return;
+} /* End Function amd_get_mtrr */
+
+static void (*get_mtrr) (unsigned int reg, unsigned long *base,
+ unsigned long *size, mtrr_type *type) = NULL;
+
+static void intel_set_mtrr_up (unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type, int do_safe)
X /* [SUMMARY] Set variable MTRR register on the local CPU.
X <reg> The register to set.
X <base> The base address of the region.
@@ -376,6 +562,7 @@
X <type> The type of the region.
X <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
X be done externally.
+ [RETURNS] Nothing.
X */
X {
X struct set_mtrr_context ctxt;
@@ -393,8 +580,92 @@
X wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0);
X }
X if (do_safe) set_mtrr_done (&ctxt);
-} /* End Function set_mtrr_up */
+} /* End Function intel_set_mtrr_up */
+
+static void cyrix_set_arr_up (unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type, int do_safe)
+{
+ struct set_mtrr_context ctxt;
+ unsigned char arr, arr_type, arr_size;
+
+ arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
+
+ /* count down from 32M (ARR0-ARR6) or from 2G (ARR7) */
+ size >>= (reg < 7 ? 12 : 18);
+ size &= 0x7fff; /* make sure arr_size <= 14 */
+ for(arr_size = 0; size; arr_size++, size >>= 1);
+
+ if (reg<7) {
+ switch (type) {
+ case MTRR_TYPE_UNCACHABLE: arr_type = 1; break;
+ case MTRR_TYPE_WRCOMB: arr_type = 9; break;
+ case MTRR_TYPE_WRTHROUGH: arr_type = 24; break;
+ default: arr_type = 8; break;
+ }
+ } else {
+ switch (type) {
+ case MTRR_TYPE_UNCACHABLE: arr_type = 0; break;
+ case MTRR_TYPE_WRCOMB: arr_type = 8; break;
+ case MTRR_TYPE_WRTHROUGH: arr_type = 25; break;
+ default: arr_type = 9; break;
+ }
+ }
+
+ if (do_safe) set_mtrr_prepare (&ctxt);
+ setCx86(arr, ((unsigned char *) &base)[3]);
+ setCx86(arr+1, ((unsigned char *) &base)[2]);
+ setCx86(arr+2, (((unsigned char *) &base)[1]) | arr_size);
+ setCx86(CX86_RCR_BASE + reg, arr_type);
+ if (do_safe) set_mtrr_done (&ctxt);
+} /* End Function cyrix_set_arr_up */
+
+static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type, int do_safe)
+/* [SUMMARY] Set variable MTRR register on the local CPU.
+ <reg> The register to set.
+ <base> The base address of the region.
+ <size> The size of the region. If this is 0 the region is disabled.
+ <type> The type of the region.
+ <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
+ be done externally.
+ [RETURNS] Nothing.
+*/
+{
+ u32 low, high;
+ struct set_mtrr_context ctxt;
+
+ if (do_safe) set_mtrr_prepare (&ctxt);
+ /*
+ * Low is MTRR0 , High MTRR 1
+ */
+ rdmsr (0xC0000085, low, high);
+ /*
+ * Blank to disable
+ */
+ if (size == 0)
+ *(reg ? &high : &low) = 0;
+ else
+ /* Set the register to the base (already shifted for us), the
+ type (off by one) and an inverted bitmask of the size
+
+ The size is the only odd bit. We are fed say 512K
+ We invert this and we get 111 1111 1111 1011 but
+ if you subtract one and invert you get the desired
+ 111 1111 1111 1100 mask
+ */
+ *(reg ? &high : &low)=(((~(size-1))>>15)&0x0001FFFC)|base|(type+1);
+ /*
+ * The writeback rule is quite specific. See the manual. Its
+ * disable local interrupts, write back the cache, set the mtrr
+ */
+ __asm__ __volatile__ ("wbinvd" : : : "memory");
+ wrmsr (0xC0000085, low, high);
+ if (do_safe) set_mtrr_done (&ctxt);
+} /* End Function amd_set_mtrr_up */
X
+static void (*set_mtrr_up) (unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type,
+ int do_safe) = NULL;
X
X #ifdef __SMP__
X
@@ -407,7 +678,7 @@
X };
X
X
-/* Get the MSR pair relating to a var range. */
+/* Get the MSR pair relating to a var range */
X __initfunc(static void get_mtrr_var_range (unsigned int index,
X struct mtrr_var_range *vr))
X {
@@ -416,8 +687,8 @@
X } /* End Function get_mtrr_var_range */
X
X
-/* Set the MSR pair relating to a var range. Returns TRUE if
- changes are made. */
+/* Set the MSR pair relating to a var range. Returns TRUE if
+ changes are made */
X __initfunc(static int set_mtrr_var_range_testing (unsigned int index,
X struct mtrr_var_range *vr))
X {
@@ -441,8 +712,7 @@
X }
X
X return changed;
-}
-
+} /* End Function set_mtrr_var_range_testing */
X
X __initfunc(static void get_fixed_ranges(mtrr_type *frs))
X {
@@ -456,8 +726,7 @@
X
X for (i = 0; i < 8; i++)
X rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]);
-}
-
+} /* End Function get_fixed_ranges */
X
X __initfunc(static int set_fixed_ranges_testing(mtrr_type *frs))
X {
@@ -487,10 +756,8 @@
X changed = TRUE;
X }
X }
-
X return changed;
-}
-
+} /* End Function set_fixed_ranges_testing */
X
X struct mtrr_state
X {
@@ -502,7 +769,7 @@
X };
X
X
-/* Grab all of the MTRR state for this CPU into *state. */
+/* Grab all of the MTRR state for this CPU into *state */
X __initfunc(static void get_mtrr_state(struct mtrr_state *state))
X {
X unsigned int nvrs, i;
@@ -511,22 +778,22 @@
X
X nvrs = state->num_var_ranges = get_num_var_ranges();
X vrs = state->var_ranges
- = kmalloc(nvrs * sizeof(struct mtrr_var_range), GFP_KERNEL);
+ = kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
X if (vrs == NULL)
X nvrs = state->num_var_ranges = 0;
X
X for (i = 0; i < nvrs; i++)
- get_mtrr_var_range(i, &vrs[i]);
+ get_mtrr_var_range (i, &vrs[i]);
X
- get_fixed_ranges(state->fixed_ranges);
+ get_fixed_ranges (state->fixed_ranges);
X
- rdmsr(MTRRdefType_MSR, lo, dummy);
+ rdmsr (MTRRdefType_MSR, lo, dummy);
X state->def_type = (lo & 0xff);
X state->enabled = (lo & 0xc00) >> 10;
X } /* End Function get_mtrr_state */
X
X
-/* Free resources associated with a struct mtrr_state */
+/* Free resources associated with a struct mtrr_state */
X __initfunc(static void finalize_mtrr_state(struct mtrr_state *state))
X {
X if (state->var_ranges) kfree (state->var_ranges);
@@ -546,14 +813,14 @@
X unsigned long change_mask = 0;
X
X for (i = 0; i < state->num_var_ranges; i++)
- if (set_mtrr_var_range_testing(i, &state->var_ranges[i]))
+ if ( set_mtrr_var_range_testing (i, &state->var_ranges[i]) )
X change_mask |= MTRR_CHANGE_MASK_VARIABLE;
X
- if (set_fixed_ranges_testing(state->fixed_ranges))
+ if ( set_fixed_ranges_testing(state->fixed_ranges) )
X change_mask |= MTRR_CHANGE_MASK_FIXED;
X
- /* set_mtrr_restore restores the old value of MTRRdefType,
- so to set it we fiddle with the saved value. */
+ /* Set_mtrr_restore restores the old value of MTRRdefType,
+ so to set it we fiddle with the saved value */
X if ((ctxt->deftype_lo & 0xff) != state->def_type
X || ((ctxt->deftype_lo & 0xc00) >> 10) != state->enabled)
X {
@@ -566,76 +833,63 @@
X
X
X static atomic_t undone_count;
-static void (*handler_func) (struct set_mtrr_context *ctxt, void *info);
-static void *handler_info;
X static volatile int wait_barrier_execute = FALSE;
X static volatile int wait_barrier_cache_enable = FALSE;
X
-static void sync_handler (void)
+struct set_mtrr_data
+{
+ unsigned long smp_base;
+ unsigned long smp_size;
+ unsigned int smp_reg;
+ mtrr_type smp_type;
+};
+
+static void ipi_handler (void *info)
X /* [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
X [RETURNS] Nothing.
X */
X {
+ struct set_mtrr_data *data = info;
X struct set_mtrr_context ctxt;
X
X set_mtrr_prepare (&ctxt);
- /* Notify master CPU that I'm at the barrier and then wait */
+ /* Notify master that I've flushed and disabled my cache */
X atomic_dec (&undone_count);
X while (wait_barrier_execute) barrier ();
X /* The master has cleared me to execute */
- (*handler_func) (&ctxt, handler_info);
+ (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
+ data->smp_type, FALSE);
X /* Notify master CPU that I've executed the function */
X atomic_dec (&undone_count);
X /* Wait for master to clear me to enable cache and return */
X while (wait_barrier_cache_enable) barrier ();
X set_mtrr_done (&ctxt);
-} /* End Function sync_handler */
+} /* End Function ipi_handler */
X
-static void do_all_cpus (void (*handler) (struct set_mtrr_context *ctxt,
- void *info),
- void *info, int local)
-/* [SUMMARY] Execute a function on all CPUs, with caches flushed and disabled.
- [PURPOSE] This function will synchronise all CPUs, flush and disable caches
- on all CPUs, then call a specified function. When the specified function
- finishes on all CPUs, caches are enabled on all CPUs.
- <handler> The function to execute.
- <info> An arbitrary information pointer which is passed to <<handler>>.
- <local> If TRUE <<handler>> is executed locally.
- [RETURNS] Nothing.
-*/
+static void set_mtrr_smp (unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type)
X {
- unsigned long timeout;
+ struct set_mtrr_data data;
X struct set_mtrr_context ctxt;
X
- mtrr_hook = sync_handler;
- handler_func = handler;
- handler_info = info;
+ data.smp_reg = reg;
+ data.smp_base = base;
+ data.smp_size = size;
+ data.smp_type = type;
X wait_barrier_execute = TRUE;
X wait_barrier_cache_enable = TRUE;
- /* Send a message to all other CPUs and wait for them to enter the
- barrier */
X atomic_set (&undone_count, smp_num_cpus - 1);
- smp_send_mtrr();
- /* Wait for it to be done */
- timeout = jiffies + JIFFIE_TIMEOUT;
- while ( (atomic_read (&undone_count) > 0) &&
- time_before(jiffies, timeout) )
- barrier ();
- if (atomic_read (&undone_count) > 0)
- {
+ /* Flush and disable the local CPU's cache and start the ball rolling on
+ other CPUs */
+ set_mtrr_prepare (&ctxt);
+ if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
X panic ("mtrr: timed out waiting for other CPUs\n");
- }
- mtrr_hook = NULL;
- /* All other CPUs should be waiting for the barrier, with their caches
- already flushed and disabled. Prepare for function completion
- notification */
+ /* Wait for all other CPUs to flush and disable their caches */
+ while (atomic_read (&undone_count) > 0) barrier ();
+ /* Set up for completion wait and then release other CPUs to change MTRRs*/
X atomic_set (&undone_count, smp_num_cpus - 1);
- /* Flush and disable the local CPU's cache and release the barier, which
- should cause the other CPUs to execute the function. Also execute it
- locally if required */
- set_mtrr_prepare (&ctxt);
X wait_barrier_execute = FALSE;
- if (local) (*handler) (&ctxt, info);
+ (*set_mtrr_up) (reg, base, size, type, FALSE);
X /* Now wait for other CPUs to complete the function */
X while (atomic_read (&undone_count) > 0) barrier ();
X /* Now all CPUs should have finished the function. Release the barrier to
@@ -643,41 +897,10 @@
X then enable the local cache and return */
X wait_barrier_cache_enable = FALSE;
X set_mtrr_done (&ctxt);
- handler_func = NULL;
- handler_info = NULL;
-} /* End Function do_all_cpus */
-
-
-struct set_mtrr_data
-{
- unsigned long smp_base;
- unsigned long smp_size;
- unsigned int smp_reg;
- mtrr_type smp_type;
-};
-
-static void set_mtrr_handler (struct set_mtrr_context *ctxt, void *info)
-{
- struct set_mtrr_data *data = info;
-
- set_mtrr_up (data->smp_reg, data->smp_base, data->smp_size, data->smp_type,
- FALSE);
-} /* End Function set_mtrr_handler */
-
-static void set_mtrr_smp (unsigned int reg, unsigned long base,
- unsigned long size, mtrr_type type)
-{
- struct set_mtrr_data data;
-
- data.smp_reg = reg;
- data.smp_base = base;
- data.smp_size = size;
- data.smp_type = type;
- do_all_cpus (set_mtrr_handler, &data, TRUE);
X } /* End Function set_mtrr_smp */
X
X
-/* Some BIOS's are fucked and don't set all MTRRs the same! */
+/* Some BIOS's are fucked and don't set all MTRRs the same! */
X __initfunc(static void mtrr_state_warn (unsigned long mask))
X {
X if (!mask) return;
@@ -720,6 +943,58 @@
X #endif
X } /* End Function init_table */
X
+static int generic_get_free_region (unsigned long base, unsigned long size)
+/* [SUMMARY] Get a free MTRR.
+ <base> The starting (base) address of the region.
+ <size> The size (in bytes) of the region.
+ [RETURNS] The index of the region on success, else -1 on error.
+*/
+{
+ int i, max;
+ mtrr_type ltype;
+ unsigned long lbase, lsize;
+
+ max = get_num_var_ranges ();
+ for (i = 0; i < max; ++i)
+ {
+ (*get_mtrr) (i, &lbase, &lsize, &ltype);
+ if (lsize < 1) return i;
+ }
+ return -ENOSPC;
+} /* End Function generic_get_free_region */
+
+static int cyrix_get_free_region (unsigned long base, unsigned long size)
+/* [SUMMARY] Get a free ARR.
+ <base> The starting (base) address of the region.
+ <size> The size (in bytes) of the region.
+ [RETURNS] The index of the region on success, else -1 on error.
+*/
+{
+ int i;
+ mtrr_type ltype;
+ unsigned long lbase, lsize;
+
+ /* If we are to set up a region >32M then look at ARR7 immediately */
+ if (size > 0x2000000UL) {
+ cyrix_get_arr (7, &lbase, &lsize, &ltype);
+ if (lsize < 1) return 7;
+ /* else try ARR0-ARR6 first */
+ } else {
+ for (i = 0; i < 7; i++)
+ {
+ cyrix_get_arr (i, &lbase, &lsize, &ltype);
+ if (lsize < 1) return i;
+ }
+ /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
+ cyrix_get_arr (i, &lbase, &lsize, &ltype);
+ if ((lsize < 1) && (size >= 0x40000)) return i;
+ }
+ return -ENOSPC;
+} /* End Function cyrix_get_free_region */
+
+static int (*get_free_region) (unsigned long base,
+ unsigned long size) = generic_get_free_region;
+
X int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
X char increment)
X /* [SUMMARY] Add an MTRR entry.
@@ -738,28 +1013,57 @@
X unsigned long lbase, lsize, last;
X
X if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return -ENODEV;
- if ( (base & 0xfff) || (size & 0xfff) )
- {
- printk ("mtrr: size and base must be multiples of 4kB\n");
- printk ("mtrr: size: %lx base: %lx\n", size, base);
- return -EINVAL;
- }
- if (base + size < 0x100000)
- {
- printk ("mtrr: cannot set region below 1 MByte (0x%lx,0x%lx)\n",
- base, size);
- return -EINVAL;
- }
- /* Check upper bits of base and last are equal and lower bits are 0 for
- base and 1 for last */
- last = base + size - 1;
- for (lbase = base; !(lbase & 1) && (last & 1);
- lbase = lbase >> 1, last = last >> 1);
- if (lbase != last)
+ switch (boot_cpu_data.x86_vendor)
X {
- printk ("mtrr: base(0x%lx) is not aligned on a size(0x%lx) boundary\n",
- base, size);
+ case X86_VENDOR_INTEL:
+ /* For Intel PPro stepping <= 7, must be 4 MiB aligned */
+ if ( (boot_cpu_data.x86 == 6) && (boot_cpu_data.x86_model == 1) &&
+ (boot_cpu_data.x86_mask <= 7) && ( base & ( (1 << 22) - 1 ) ) )
+ {
+ printk ("mtrr: base(0x%lx) is not 4 MiB aligned\n", base);
+ return -EINVAL;
+ }
+ /* Fall through */
+ case X86_VENDOR_CYRIX:
+ if ( (base & 0xfff) || (size & 0xfff) )
+ {
+ printk ("mtrr: size and base must be multiples of 4 kiB\n");
+ printk ("mtrr: size: %lx base: %lx\n", size, base);
+ return -EINVAL;
+ }
+ if (base + size < 0x100000)
+ {
+ printk ("mtrr: cannot set region below 1 MiB (0x%lx,0x%lx)\n",
+ base, size);
+ return -EINVAL;
+ }
+ /* Check upper bits of base and last are equal and lower bits are 0
+ for base and 1 for last */
+ last = base + size - 1;
+ for (lbase = base; !(lbase & 1) && (last & 1);
+ lbase = lbase >> 1, last = last >> 1);
+ if (lbase != last)
+ {
+ printk ("mtrr: base(0x%lx) is not aligned on a size(0x%lx) boundary\n",
+ base, size);
+ return -EINVAL;
+ }
+ break;
+ case X86_VENDOR_AMD:
+ /* Apply the K6 block alignment and size rules
+ In order
+ o Uncached or gathering only
+ o 128K or bigger block
+ o Power of 2 block
+ o base suitably aligned to the power
+ */
+ if (type > MTRR_TYPE_WRCOMB || size < (1 << 17) ||
+ (size & ~(size-1))-size || (base & (size-1)))
+ return -EINVAL;
+ break;
+ default:
X return -EINVAL;
+ /*break;*/
X }
X if (type >= MTRR_NUM_TYPES)
X {
@@ -775,10 +1079,10 @@
X increment = increment ? 1 : 0;
X max = get_num_var_ranges ();
X /* Search for existing MTRR */
- spin_lock (&main_lock);
+ spin_lock_reschedule (&main_lock);
X for (i = 0; i < max; ++i)
X {
- get_mtrr (i, &lbase, &lsize, &ltype);
+ (*get_mtrr) (i, &lbase, &lsize, &ltype);
X if (base >= lbase + lsize) continue;
X if ( (base < lbase) && (base + size <= lbase) ) continue;
X /* At this point we know there is some kind of overlap/enclosure */
@@ -804,19 +1108,18 @@
X return i;
X }
X /* Search for an empty MTRR */
- for (i = 0; i < max; ++i)
+ i = (*get_free_region) (base, size);
+ if (i < 0)
X {
- get_mtrr (i, &lbase, &lsize, &ltype);
- if (lsize > 0) continue;
- set_mtrr (i, base, size, type);
- usage_table[i] = 1;
- compute_ascii ();
X spin_unlock (&main_lock);
+ printk ("mtrr: no more MTRRs available\n");
X return i;
X }
+ set_mtrr (i, base, size, type);
+ usage_table[i] = 1;
+ compute_ascii ();
X spin_unlock (&main_lock);
- printk ("mtrr: no more MTRRs available\n");
- return -ENOSPC;
+ return i;
X } /* End Function mtrr_add */
X
X int mtrr_del (int reg, unsigned long base, unsigned long size)
@@ -836,13 +1139,13 @@
X
X if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return -ENODEV;
X max = get_num_var_ranges ();
- spin_lock (&main_lock);
+ spin_lock_reschedule (&main_lock);
X if (reg < 0)
X {
X /* Search for existing MTRR */
SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi
echo 'End of part 05'
echo 'File patch-2.2.8 is continued in part 06'
echo 06 > _shar_seq_.tmp
exit 0
--
Thomas Koenig, Thomas...@ciw.uni-karlsruhe.de, ig...@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part06

#!/bin/sh
# this is part 06 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 06; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

X for (i = 0; i < max; ++i)
X {
- get_mtrr (i, &lbase, &lsize, &ltype);
+ (*get_mtrr) (i, &lbase, &lsize, &ltype);

X if ( (lbase == base) && (lsize == size) )
X {
X reg = i;
@@ -862,7 +1165,7 @@
X printk ("mtrr: register: %d too big\n", reg);
X return -EINVAL;
X }
- get_mtrr (reg, &lbase, &lsize, &ltype);
+ (*get_mtrr) (reg, &lbase, &lsize, &ltype);
X if (lsize < 1)
X {
X spin_unlock (&main_lock);
@@ -913,7 +1216,9 @@
X
X reg = mtrr_del (-1, base, size);
X if (reg < 0) return reg;
- if (fcount != NULL) --fcount[reg];
+ if (fcount == NULL) return reg;
+ if (fcount[reg] < 1) return -EINVAL;
+ --fcount[reg];
X return reg;
X } /* End Function mtrr_file_del */
X
@@ -1019,11 +1324,18 @@
X err = mtrr_file_del (sentry.base, sentry.size, file);
X if (err < 0) return err;
X break;
+ case MTRRIOC_KILL_ENTRY:
+ if ( !suser () ) return -EPERM;
+ if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
+ return -EFAULT;
+ err = mtrr_del (-1, sentry.base, sentry.size);
+ if (err < 0) return err;
+ break;
X case MTRRIOC_GET_ENTRY:
X if ( copy_from_user (&gentry, (void *) arg, sizeof gentry) )
X return -EFAULT;
X if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
- get_mtrr (gentry.regnum, &gentry.base, &gentry.size, &type);
+ (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
X gentry.type = type;
X if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
X return -EFAULT;
@@ -1115,7 +1427,7 @@


X max = get_num_var_ranges ();

X for (i = 0; i < max; i++)
X {
- get_mtrr (i, &base, &size, &type);
+ (*get_mtrr) (i, &base, &size, &type);
X if (size < 1) usage_table[i] = 0;
X else
X {
@@ -1148,23 +1460,165 @@


X
X #ifdef __SMP__
X

+typedef struct {
+ unsigned long base;
+ unsigned long size;
+ mtrr_type type;
+} arr_state_t;
+
+arr_state_t arr_state[8] __initdata = {
+ {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL},
+ {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}
+};
+
+unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
+
+__initfunc(static void cyrix_arr_init_secondary(void))


+{
+ struct set_mtrr_context ctxt;

+ int i;
+
+ set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
+
+ /* the CCRs are not contiguous */
+ for(i=0; i<4; i++) setCx86(CX86_CCR0 + i, ccr_state[i]);
+ for( ; i<7; i++) setCx86(CX86_CCR4 + i, ccr_state[i]);
+ for(i=0; i<8; i++)
+ cyrix_set_arr_up(i,
+ arr_state[i].base, arr_state[i].size, arr_state[i].type, FALSE);
+
+ set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
+} /* End Function cyrix_arr_init_secondary */
+
+#endif
+
+/*
+ * On Cyrix 6x86(MX) and M II the ARR3 is special: it has connection
+ * with the SMM (System Management Mode) mode. So we need the following:
+ * Check whether SMI_LOCK (CCR3 bit 0) is set
+ * if it is set, write a warning message: ARR3 cannot be changed!
+ * (it cannot be changed until the next processor reset)
+ * if it is reset, then we can change it, set all the needed bits:
+ * - disable access to SMM memory through ARR3 range (CCR1 bit 7 reset)
+ * - disable access to SMM memory (CCR1 bit 2 reset)
+ * - disable SMM mode (CCR1 bit 1 reset)
+ * - disable write protection of ARR3 (CCR6 bit 1 reset)
+ * - (maybe) disable ARR3
+ * Just to be sure, we enable ARR usage by the processor (CCR5 bit 5 set)
+ */
+__initfunc(static void cyrix_arr_init(void))


+{
+ struct set_mtrr_context ctxt;

+ unsigned char ccr[7];
+ int ccrc[7] = { 0, 0, 0, 0, 0, 0, 0 };
+#ifdef __SMP__
+ int i;
+#endif
+
+ set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
+
+ /* Save all CCRs locally */
+ ccr[0] = getCx86 (CX86_CCR0);
+ ccr[1] = getCx86 (CX86_CCR1);
+ ccr[2] = getCx86 (CX86_CCR2);
+ ccr[3] = ctxt.ccr3;
+ ccr[4] = getCx86 (CX86_CCR4);
+ ccr[5] = getCx86 (CX86_CCR5);
+ ccr[6] = getCx86 (CX86_CCR6);
+
+ if (ccr[3] & 1)
+ ccrc[3] = 1;
+ else {
+ /* Disable SMM mode (bit 1), access to SMM memory (bit 2) and
+ * access to SMM memory through ARR3 (bit 7).
+ */
+/*
+ if (ccr[1] & 0x80) { ccr[1] &= 0x7f; ccrc[1] |= 0x80; }
+ if (ccr[1] & 0x04) { ccr[1] &= 0xfb; ccrc[1] |= 0x04; }
+ if (ccr[1] & 0x02) { ccr[1] &= 0xfd; ccrc[1] |= 0x02; }
+*/
+ if (ccr[6] & 0x02) {
+ ccr[6] &= 0xfd; ccrc[6] = 1; /* Disable write protection of ARR3. */
+ setCx86 (CX86_CCR6, ccr[6]);
+ }
+ /* Disable ARR3. */
+ /* cyrix_set_arr_up (3, 0, 0, 0, FALSE); */
+ }
+ /* If we changed CCR1 in memory, change it in the processor, too. */
+ if (ccrc[1]) setCx86 (CX86_CCR1, ccr[1]);
+
+ /* Enable ARR usage by the processor */
+ if (!(ccr[5] & 0x20)) {
+ ccr[5] |= 0x20; ccrc[5] = 1;
+ setCx86 (CX86_CCR5, ccr[5]);
+ }
+
+#ifdef __SMP__
+ for(i=0; i<7; i++) ccr_state[i] = ccr[i];
+ for(i=0; i<8; i++)
+ cyrix_get_arr(i,
+ &arr_state[i].base, &arr_state[i].size, &arr_state[i].type);
+#endif
+
+ set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
+
+ if ( ccrc[5] ) printk ("mtrr: ARR usage was not enabled, enabled manually\n");
+ if ( ccrc[3] ) printk ("mtrr: ARR3 cannot be changed\n");
+/*
+ if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n");
+ if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n");
+ if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n");
+*/
+ if ( ccrc[6] ) printk ("mtrr: ARR3 was write protected, unprotected\n");
+} /* End Function cyrix_arr_init */
+
+__initfunc(static void mtrr_setup (void))
+{
+ printk ("mtrr: v%s Richard Gooch (rgo...@atnf.csiro.au)\n", MTRR_VERSION);


+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:

+ get_mtrr = intel_get_mtrr;
+ set_mtrr_up = intel_set_mtrr_up;


+ break;
+ case X86_VENDOR_CYRIX:

+ printk ("mtrr: Using Cyrix style ARRs\n");
+ get_mtrr = cyrix_get_arr;
+ set_mtrr_up = cyrix_set_arr_up;
+ get_free_region = cyrix_get_free_region;


+ break;
+ case X86_VENDOR_AMD:

+ get_mtrr = amd_get_mtrr;
+ set_mtrr_up = amd_set_mtrr_up;
+ break;
+ }
+} /* End Function mtrr_setup */
+
+#ifdef __SMP__
+
X static volatile unsigned long smp_changes_mask __initdata = 0;
X static struct mtrr_state smp_mtrr_state __initdata = {0, 0};
X
X __initfunc(void mtrr_init_boot_cpu (void))
X {
X if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return;
- printk("mtrr: v%s Richard Gooch (rgo...@atnf.csiro.au)\n", MTRR_VERSION);
-
- get_mtrr_state (&smp_mtrr_state);
+ mtrr_setup ();


+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:

+ get_mtrr_state (&smp_mtrr_state);


+ break;
+ case X86_VENDOR_CYRIX:

+ cyrix_arr_init ();
+ break;
+ }
X } /* End Function mtrr_init_boot_cpu */
X
-__initfunc(void mtrr_init_secondary_cpu (void))
+__initfunc(static void intel_mtrr_init_secondary_cpu (void))
X {
X unsigned long mask, count;


X struct set_mtrr_context ctxt;
X

- if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return;
X /* Note that this is not ideal, since the cache is only flushed/disabled
X for this CPU while the MTRRs are changed, but changing this requires
X more invasive changes to the way the kernel boots */
@@ -1177,21 +1631,52 @@
X if (mask & 0x01) set_bit (count, &smp_changes_mask);
X mask >>= 1;
X }
-} /* End Function mtrr_init_secondary_cpu */
+} /* End Function intel_mtrr_init_secondary_cpu */
X
+__initfunc(void mtrr_init_secondary_cpu (void))
+{
+ if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return;


+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:

+ intel_mtrr_init_secondary_cpu ();


+ break;
+ case X86_VENDOR_CYRIX:

+ /* This is _completely theoretical_!
+ * I assume here that one day Cyrix will support Intel APIC.
+ * In reality on non-Intel CPUs we won't even get to this routine.
+ * Hopefully no one will plug two Cyrix processors in a dual P5 board.
+ * :-)
+ */
+ cyrix_arr_init_secondary ();
+ break;
+ default:
+ printk ("mtrr: SMP support incomplete for this vendor\n");
+ break;
+ }
+} /* End Function mtrr_init_secondary_cpu */


X #endif /* __SMP__ */
X

X __initfunc(int mtrr_init(void))
X {
X if ( !(boot_cpu_data.x86_capability & X86_FEATURE_MTRR) ) return 0;
-# ifndef __SMP__
- printk("mtrr: v%s Richard Gooch (rgo...@atnf.csiro.au)\n", MTRR_VERSION);
-# endif
-
X # ifdef __SMP__
- finalize_mtrr_state (&smp_mtrr_state);
- mtrr_state_warn (smp_changes_mask);
-# endif /* __SMP__ */


+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_INTEL:

+ finalize_mtrr_state (&smp_mtrr_state);
+ mtrr_state_warn (smp_changes_mask);
+ break;
+ }
+# else /* __SMP__ */
+ mtrr_setup ();
+ switch (boot_cpu_data.x86_vendor)
+ {
+ case X86_VENDOR_CYRIX:
+ cyrix_arr_init ();
+ break;
+ }
+# endif /* !__SMP__ */
X
X # ifdef CONFIG_PROC_FS
X proc_register (&proc_root, &proc_root_mtrr);
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.2.7/linux/arch/i386/kernel/process.c Tue Mar 23 14:35:46 1999
+++ linux/arch/i386/kernel/process.c Fri Apr 30 08:13:37 1999
@@ -111,6 +111,8 @@
X /* endless idle loop with no priority at all */
X current->priority = 0;
X current->counter = -100;
+ init_idle();
+
X for (;;) {
X if (work)
X start_idle = jiffies;
@@ -139,6 +141,8 @@
X /* endless idle loop with no priority at all */
X current->priority = 0;
X current->counter = -100;
+ init_idle();
+
X while(1) {
X if (current_cpu_data.hlt_works_ok && !hlt_counter &&
X !current->need_resched)
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.2.7/linux/arch/i386/kernel/setup.c Tue Mar 23 14:35:46 1999
+++ linux/arch/i386/kernel/setup.c Mon May 10 10:32:45 1999
@@ -5,6 +5,10 @@
X *
X * Enhanced CPU type detection by Mike Jagdis, Patrick St. Jean
X * and Martin Mares, November 1997.
+ *
+ * Force Cyrix 6x86(MX) and M II processors to report MTRR capability
+ * and fix against Cyrix "coma bug" by
+ * Zoltan Boszormenyi <zbo...@mol.hu> February 1999.
X */
X
X /*
@@ -39,6 +43,7 @@
X #include <asm/io.h>
X #include <asm/smp.h>
X #include <asm/cobalt.h>
+#include <asm/msr.h>
X
X /*
X * Machine setup..
@@ -57,6 +62,7 @@
X unsigned int machine_id = 0;
X unsigned int machine_submodel_id = 0;
X unsigned int BIOS_revision = 0;
+unsigned int mca_pentium_flag = 0;
X
X /*
X * Setup options
@@ -244,11 +250,6 @@
X unsigned long memory_start, memory_end;
X char c = ' ', *to = command_line, *from = COMMAND_LINE;
X int len = 0;
- static unsigned char smptrap=0;
-
- if (smptrap)
- return;
- smptrap=1;
X
X #ifdef CONFIG_VISWS
X visws_get_board_type_and_rev();
@@ -381,16 +382,6 @@
X
X }
X

-#define rdmsr(msr,val1,val2) \
- __asm__ __volatile__("rdmsr" \
- : "=a" (val1), "=d" (val2) \
- : "c" (msr))
-
-#define wrmsr(msr,val1,val2) \
- __asm__ __volatile__("wrmsr" \
- : /* no outputs */ \
- : "c" (msr), "a" (val1), "d" (val2))
-

X __initfunc(static int get_model_name(struct cpuinfo_x86 *c))
X {
X unsigned int n, dummy, *v;
@@ -408,6 +399,14 @@
X cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
X cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
X c->x86_model_id[48] = 0;
+ /* Set MTRR capability flag if appropriate */
+ if(boot_cpu_data.x86 !=5)
+ return 1;
+ if((boot_cpu_data.x86_model == 9) ||
+ ((boot_cpu_data.x86_model == 8) &&
+ (boot_cpu_data.x86_mask >= 8)))
+ c->x86_capability |= X86_FEATURE_MTRR;
+
X return 1;
X }
X
@@ -587,6 +586,10 @@
X (c->x86_model)++;
X } else /* 686 */
X p = Cx86_cb+1;
+ /* Emulate MTRRs using Cyrix's ARRs. */
+ c->x86_capability |= X86_FEATURE_MTRR;
+ /* 6x86's contain this bug */
+ c->coma_bug = 1;
X break;
X
X case 4: /* MediaGX/GXm */
@@ -611,11 +614,14 @@
X
X case 5: /* 6x86MX/M II */
X if (dir1 > 7) dir0_msn++; /* M II */
+ else c->coma_bug = 1; /* 6x86MX, it has the bug. */
X tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;
X Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];
X p = Cx86_cb+tmp;
X if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))
X (c->x86_model)++;
+ /* Emulate MTRRs using Cyrix's ARRs. */
+ c->x86_capability |= X86_FEATURE_MTRR;
X break;
X
X case 0xf: /* Cyrix 486 without DEVID registers */
@@ -869,7 +875,7 @@
X int sep_bug;
X static char *x86_cap_flags[] = {
X "fpu", "vme", "de", "pse", "tsc", "msr", "6", "mce",
- "cx8", "9", "10", "sep", "12", "pge", "14", "cmov",
+ "cx8", "9", "10", "sep", "mtrr", "pge", "14", "cmov",
X "16", "17", "psn", "19", "20", "21", "22", "mmx",
X "24", "kni", "26", "27", "28", "29", "30", "31"
X };
@@ -917,7 +923,6 @@
X } else if (c->x86_vendor == X86_VENDOR_INTEL) {
X x86_cap_flags[6] = "pae";
X x86_cap_flags[9] = "apic";
- x86_cap_flags[12] = "mtrr";
X x86_cap_flags[14] = "mca";
X x86_cap_flags[16] = "pat";
X x86_cap_flags[17] = "pse36";
@@ -936,6 +941,7 @@
X "hlt_bug\t\t: %s\n"
X "sep_bug\t\t: %s\n"
X "f00f_bug\t: %s\n"
+ "coma_bug\t: %s\n"
X "fpu\t\t: %s\n"
X "fpu_exception\t: %s\n"
X "cpuid level\t: %d\n"
@@ -945,6 +951,7 @@
X c->hlt_works_ok ? "no" : "yes",
X sep_bug ? "yes" : "no",
X c->f00f_bug ? "yes" : "no",
+ c->coma_bug ? "yes" : "no",
X c->hard_math ? "yes" : "no",
X (c->hard_math && ignore_irq13) ? "yes" : "no",
X c->cpuid_level,
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.7/linux/arch/i386/kernel/smp.c Wed Apr 28 11:37:29 1999
+++ linux/arch/i386/kernel/smp.c Mon May 10 10:32:45 1999
@@ -40,10 +40,12 @@
X #include <linux/smp_lock.h>
X #include <linux/init.h>
X #include <asm/mtrr.h>
+#include <asm/msr.h>
X
X #include "irq.h"
X
-extern unsigned long start_kernel;
+#define JIFFIE_TIMEOUT 100
+
X extern void update_one_process( struct task_struct *p,
X unsigned long ticks, unsigned long user,
X unsigned long system, int cpu);
@@ -147,16 +149,7 @@
X */
X #define APIC_DEFAULT_PHYS_BASE 0xfee00000
X
-/*
- * Reads and clears the Pentium Timestamp-Counter
- */
-#define READ_TSC(x) __asm__ __volatile__ ( "rdtsc" \
- :"=a" (((unsigned long*)&(x))[0]), \
- "=d" (((unsigned long*)&(x))[1]))
-
-#define CLEAR_TSC \
- __asm__ __volatile__ ("\t.byte 0x0f, 0x30;\n"::\
- "a"(0x00001000), "d"(0x00001000), "c"(0x10):"memory")
+#define CLEAR_TSC wrmsr(0x10, 0x00001000, 0x00001000)
X
X /*
X * Setup routine for controlling SMP activation
@@ -899,6 +892,7 @@
X * Everything has been set up for the secondary
X * CPUs - they just need to reload everything
X * from the task structure
+ * This function must not return.
X */
X void __init initialize_secondary(void)
X {
@@ -940,7 +934,6 @@
X /*
X * We need an idle process for each processor.
X */
-
X kernel_thread(start_secondary, NULL, CLONE_PID);
X cpucount++;
X
@@ -951,6 +944,8 @@
X idle->processor = i;
X __cpu_logical_map[cpucount] = i;
X cpu_number_map[i] = cpucount;
+ idle->has_cpu = 1; /* we schedule the first task manually */
+ idle->tss.eip = (unsigned long) start_secondary;
X
X /* start_eip had better be page-aligned! */
X start_eip = setup_trampoline();
@@ -1183,6 +1178,7 @@
X /* Must be done before other processors booted */
X mtrr_init_boot_cpu ();
X #endif
+ init_idle();
X /*
X * Initialize the logical to physical CPU number mapping
X * and the per-CPU profiling counter/multiplier
@@ -1657,15 +1653,84 @@
X send_IPI_allbutself(STOP_CPU_VECTOR);
X }
X
-/*
- * this function sends an 'reload MTRR state' IPI to all other CPUs
- * in the system. it goes straight through, completion processing
- * is done on the mttr.c level.
+/* Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
X */
-
-void smp_send_mtrr(void)
+struct smp_call_function_struct {
+ void (*func) (void *info);
+ void *info;
+ atomic_t unstarted_count;
+ atomic_t unfinished_count;
+ int wait;
+};
+static volatile struct smp_call_function_struct *smp_call_function_data = NULL;
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int retry,
+ int wait)
+/* [SUMMARY] Run a function on all other CPUs.
+ <func> The function to run. This must be fast and non-blocking.
+ <info> An arbitrary pointer to pass to the function.
+ <retry> If true, keep retrying until ready.
+ <wait> If true, wait until function has completed on other CPUs.
+ [RETURNS] 0 on success, else a negative status code. Does not return until
+ remote CPUs are nearly ready to execute <<func>> or are or have executed.
+*/
X {
- send_IPI_allbutself(MTRR_CHANGE_VECTOR);
+ unsigned long timeout;
+ struct smp_call_function_struct data;
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+
+ if (retry) {
+ while (1) {
+ if (smp_call_function_data) {
+ schedule (); /* Give a mate a go */
+ continue;
+ }
+ spin_lock (&lock);
+ if (smp_call_function_data) {
+ spin_unlock (&lock); /* Bad luck */
+ continue;
+ }
+ /* Mine, all mine! */
+ break;
+ }
+ }
+ else {
+ if (smp_call_function_data) return -EBUSY;
+ spin_lock (&lock);
+ if (smp_call_function_data) {
+ spin_unlock (&lock);
+ return -EBUSY;
+ }
+ }
+ smp_call_function_data = &data;
+ spin_unlock (&lock);
+ data.func = func;
+ data.info = info;
+ atomic_set (&data.unstarted_count, smp_num_cpus - 1);
+ data.wait = wait;
+ if (wait) atomic_set (&data.unfinished_count, smp_num_cpus - 1);
+ /* Send a message to all other CPUs and wait for them to respond */
+ send_IPI_allbutself (CALL_FUNCTION_VECTOR);
+ /* Wait for response */
+ timeout = jiffies + JIFFIE_TIMEOUT;
+ while ( (atomic_read (&data.unstarted_count) > 0) &&
+ time_before (jiffies, timeout) )
+ barrier ();
+ if (atomic_read (&data.unstarted_count) > 0) {
+ smp_call_function_data = NULL;
+ return -ETIMEDOUT;
+ }
+ if (wait)
+ while (atomic_read (&data.unfinished_count) > 0)
+ barrier ();
+ smp_call_function_data = NULL;
+ return 0;
X }
X
X /*
@@ -1781,6 +1846,7 @@
X local_flush_tlb();
X
X ack_APIC_irq();
+
X }
X
X static void stop_this_cpu (void)
@@ -1803,12 +1869,19 @@
X stop_this_cpu();
X }
X
-void (*mtrr_hook) (void) = NULL;
-
-asmlinkage void smp_mtrr_interrupt(void)
+asmlinkage void smp_call_function_interrupt(void)
X {
- ack_APIC_irq();
- if (mtrr_hook) (*mtrr_hook)();
+ void (*func) (void *info) = smp_call_function_data->func;
+ void *info = smp_call_function_data->info;
+ int wait = smp_call_function_data->wait;
+
+ ack_APIC_irq ();
+ /* Notify initiating CPU that I've grabbed the data and am about to
+ execute the function */
+ atomic_dec (&smp_call_function_data->unstarted_count);
+ /* At this point the structure may be out of scope unless wait==1 */
+ (*func) (info);
+ if (wait) atomic_dec (&smp_call_function_data->unfinished_count);
X }
X
X /*
@@ -1949,7 +2022,7 @@
X /*
X * We wrapped around just now. Let's start:
X */
- READ_TSC(t1);
+ rdtscll(t1);
X tt1=apic_read(APIC_TMCCT);
X
X #define LOOPS (HZ/10)
@@ -1960,7 +2033,7 @@
X wait_8254_wraparound ();
X
X tt2=apic_read(APIC_TMCCT);
- READ_TSC(t2);
+ rdtscll(t2);
X
X /*
X * The APIC bus clock counter is 32 bits only, it
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v2.2.7/linux/arch/i386/kernel/time.c Tue Mar 23 14:35:46 1999
+++ linux/arch/i386/kernel/time.c Thu Apr 29 11:53:41 1999
@@ -47,6 +47,7 @@
X #include <asm/io.h>
X #include <asm/irq.h>
X #include <asm/delay.h>
+#include <asm/msr.h>
X
X #include <linux/mc146818rtc.h>
X #include <linux/timex.h>
@@ -83,8 +84,8 @@
X register unsigned long edx asm("dx");
X
X /* Read the Time Stamp Counter */
- __asm__("rdtsc"
- :"=a" (eax), "=d" (edx));
+
+ rdtsc(eax,edx);
X
X /* .. relative to previous jiffy (32 bits is enough) */
X eax -= last_tsc_low; /* tsc_low delta */
@@ -443,7 +444,8 @@
X */
X
X /* read Pentium cycle counter */
- __asm__("rdtsc" : "=a" (last_tsc_low) : : "edx");
+
+ rdtscl(last_tsc_low);
X
X outb_p(0x00, 0x43); /* latch the count ASAP */
X
@@ -566,12 +568,12 @@
X unsigned long endlow, endhigh;
X unsigned long count;
X
- __asm__ __volatile__("rdtsc":"=a" (startlow),"=d" (starthigh));
+ rdtsc(startlow,starthigh);
X count = 0;
X do {
X count++;
X } while ((inb(0x61) & 0x20) == 0);
- __asm__ __volatile__("rdtsc":"=a" (endlow),"=d" (endhigh));
+ rdtsc(endlow,endhigh);
X
X last_tsc_low = endlow;
X
diff -u --recursive --new-file v2.2.7/linux/arch/i386/kernel/visws_apic.c linux/arch/i386/kernel/visws_apic.c
--- v2.2.7/linux/arch/i386/kernel/visws_apic.c Wed Jan 20 23:14:04 1999
+++ linux/arch/i386/kernel/visws_apic.c Thu May 6 16:12:23 1999
@@ -201,11 +201,13 @@


X {
X unsigned int status;

X /* XXX APIC EOI? */


- status = desc->status & ~IRQ_REPLAY;
+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
X action = NULL;
- if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
X action = desc->action;
- desc->status = status | IRQ_INPROGRESS;
+ status |= IRQ_INPROGRESS;
+ }
+ desc->status = status;
X }
X spin_unlock(&irq_controller_lock);
X

diff -u --recursive --new-file v2.2.7/linux/arch/m68k/Makefile linux/arch/m68k/Makefile
--- v2.2.7/linux/arch/m68k/Makefile Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/Makefile Tue May 11 09:57:14 1999
@@ -56,6 +56,11 @@
X CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES)
X LIBS += arch/m68k/lib/lib.a
X
+ifdef CONFIG_Q40
+CORE_FILES := $(CORE_FILES) arch/m68k/q40/q40.o
+SUBDIRS := $(SUBDIRS) arch/m68k/q40
+endif
+
X ifdef CONFIG_AMIGA
X CORE_FILES := $(CORE_FILES) arch/m68k/amiga/amiga.o
X SUBDIRS := $(SUBDIRS) arch/m68k/amiga
@@ -81,6 +86,11 @@
X SUBDIRS := $(SUBDIRS) arch/m68k/apollo
X endif
X
+ifdef CONFIG_MVME147
+CORE_FILES := $(CORE_FILES) arch/m68k/mvme147/mvme147.o
+SUBDIRS := $(SUBDIRS) arch/m68k/mvme147
+endif
+
X ifdef CONFIG_MVME16x
X CORE_FILES := $(CORE_FILES) arch/m68k/mvme16x/mvme16x.o
X SUBDIRS := $(SUBDIRS) arch/m68k/mvme16x
@@ -89,6 +99,11 @@
X ifdef CONFIG_BVME6000
X CORE_FILES := $(CORE_FILES) arch/m68k/bvme6000/bvme6000.o
X SUBDIRS := $(SUBDIRS) arch/m68k/bvme6000
+endif
+
+ifdef CONFIG_SUN3X
+CORE_FILES := $(CORE_FILES) arch/m68k/sun3x/sun3x.o
+SUBDIRS := $(SUBDIRS) arch/m68k/sun3x
X endif
X
X ifdef CONFIG_M68040
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/bvme6000/config.c linux/arch/m68k/bvme6000/config.c
--- v2.2.7/linux/arch/m68k/bvme6000/config.c Tue Dec 22 14:16:54 1998
+++ linux/arch/m68k/bvme6000/config.c Tue May 11 09:57:14 1999
@@ -417,10 +417,10 @@
X static void scc_delay (void)
X {
X int n;
- char i;
+ volatile int trash;
X
X for (n = 0; n < 20; n++)
- i = *(volatile char *)0;
+ trash = n;
X }
X
X static void scc_write (char ch)
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.2.7/linux/arch/m68k/config.in Tue Feb 23 15:21:32 1999
+++ linux/arch/m68k/config.in Tue May 11 09:57:14 1999
@@ -37,6 +37,7 @@
X bool 'Apollo support' CONFIG_APOLLO
X bool 'VME (Motorola and BVM) support' CONFIG_VME
X if [ "$CONFIG_VME" = "y" ]; then
+ bool 'MVME147 support' CONFIG_MVME147
X bool 'MVME162, 166 and 167 support' CONFIG_MVME16x
X bool 'BVME4000 and BVME6000 support' CONFIG_BVME6000
X fi
@@ -44,10 +45,13 @@
X if [ "$CONFIG_HP300" = "y" ]; then
X bool 'DIO bus support' CONFIG_DIO
X fi
+bool 'Sun3x support' CONFIG_SUN3X
+
X define_bool CONFIG_SUN3 n
X if [ "$CONFIG_PCI" = "y" ]; then
X bool 'Backward-compatible /proc/pci' CONFIG_PCI_OLD_PROC
X fi
+bool 'Q40/Q60 support' CONFIG_Q40
X
X comment 'Processor type'
X bool '68020 support' CONFIG_M68020
@@ -94,6 +98,29 @@
X fi
X fi
X bool '/proc/hardware support' CONFIG_PROC_HARDWARE
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Parallel port support (EXPERIMENTAL, disables old lp driver!)' CONFIG_PARPORT
+ if [ "$CONFIG_PARPORT" != "n" ]; then
+ if [ "$CONFIG_AMIGA" != "n" ]; then
+ dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
+ if [ "$CONFIG_ZORRO" != "n" ]; then
+ dep_tristate ' Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT
+ fi
+ fi
+ if [ "$CONFIG_Q40" != "n" ]; then
+ tristate ' Q40 Parallel port' CONFIG_PARPORT
+ if [ "$CONFIG_PARPORT" != "n" ]; then
+ define_bool CONFIG_PARPORT_PC y
+ fi
+ fi
+ fi
+ if [ "$CONFIG_ATARI" == "y" ]; then
+ dep_tristate ' Atari builtin port' CONFIG_PARPORT_ATARI $CONFIG_PARPORT
+ fi
+fi
+
+
X endmenu
X
X source drivers/block/Config.in
@@ -147,6 +174,7 @@
X bool 'A4091 SCSI support' CONFIG_A4091_SCSI
X bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
X bool 'Blizzard PowerUP 603e+ SCSI' CONFIG_BLZ603EPLUS_SCSI
+ dep_tristate 'BSC Oktagon SCSI support' CONFIG_OKTAGON_SCSI $CONFIG_SCSI
X bool 'Cyberstorm Mk III SCSI support' CONFIG_CYBERSTORMIII_SCSI
X # bool 'GVP Turbo 040/060 SCSI support' CONFIG_GVP_TURBO_SCSI
X fi
@@ -167,6 +195,10 @@
X fi
X #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
X
+if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME147" = "y" ]; then
+ bool 'WD33C93 SCSI driver for MVME147' CONFIG_MVME147_SCSI
+fi
+
X if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME16x" = "y" ]; then
X bool 'NCR53C710 SCSI driver for MVME16x' CONFIG_MVME16x_SCSI
X fi
@@ -175,6 +207,10 @@
X bool 'NCR53C710 SCSI driver for BVME6000' CONFIG_BVME6000_SCSI
X fi
X
+if [ "$CONFIG_SUN3X" = "y" ]; then
+ bool 'ESP SCSI driver' CONFIG_SUN3X_ESP
+fi
+
X endmenu
X
X fi
@@ -219,6 +255,9 @@
X # bool 'Macintosh (AV) onboard MACE ethernet' CONFIG_MACMACE
X bool 'Macintosh (Quadra) onboard SONIC ethernet' CONFIG_MACSONIC
X fi
+if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME147" = "y" ]; then
+ tristate 'MVME147 (Lance) Ethernet support' CONFIG_MVME147_NET
+fi
X if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME16x" = "y" ]; then
X tristate 'MVME16x Ethernet support' CONFIG_MVME16x_NET
X fi
@@ -232,9 +271,17 @@
X tristate 'PAMsNet support' CONFIG_ATARI_PAMSNET
X fi
X fi
+if [ "$CONFIG_SUN3X" = "y" ]; then
+ bool 'Sun3x Lance support' CONFIG_SUNLANCE
+fi
X if [ "$CONFIG_HP300" = "y" ]; then
X bool 'HP on-board LANCE support' CONFIG_HPLANCE
X fi
+if [ "$CONFIG_Q40" = "y" ]; then
+ if [ ! "$CONFIG_PARPORT" = "n" ]; then
+ dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT
+ fi
+fi
X fi
X endmenu
X
@@ -243,6 +290,23 @@
X mainmenu_option next_comment
X comment 'Character devices'
X
+if [ "$CONFIG_Q40" = "y" ]; then
+ tristate 'Q40 Standard/generic serial support' CONFIG_SERIAL
+fi
+
+if [ "$CONFIG_SERIAL" = "y" ]; then
+ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
+ bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
+fi
+
+if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
+ bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
+ bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
+# bool ' Autodetect IRQ - do not yet enable !!' CONFIG_SERIAL_DETECT_IRQ
+ bool ' Support special multiport boards' CONFIG_SERIAL_MULTIPORT
+ bool ' Support the Bell Technologies HUB6 card' CONFIG_HUB6
+fi
+
X if [ "$CONFIG_VME" = "n" ]; then
X define_bool CONFIG_VT y
X if [ "$CONFIG_VT" = "y" ]; then
@@ -254,10 +318,17 @@
X define_bool CONFIG_NVRAM y
X fi
X
-tristate 'Parallel printer support' CONFIG_M68K_PRINTER
-if [ "$CONFIG_ZORRO" = "y" ]; then
- dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_M68K_PRINTER
-fi
+if [ "$CONFIG_PARPORT" = "n" ]; then
+ tristate 'Parallel printer support' CONFIG_M68K_PRINTER
+ if [ "$CONFIG_ZORRO" = "y" ]; then
+ dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_M68K_PRINTER
+ fi
+else
+ dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
+ if [ "$CONFIG_PRINTER" != "n" ]; then
+ bool ' Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
+ fi
+fi
X if [ "$CONFIG_AMIGA" = "y" ]; then
X tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
X fi
@@ -280,13 +351,17 @@
X fi
X if [ "$CONFIG_AMIGA" = "y" ]; then
X tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
- bool 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET
+ if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
+ tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
+ fi
X fi
-if [ "$CONFIG_ZORRO" = "y" ]; then
- tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
- dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
- dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
- tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+if [ "$CONFIG_PARPORT" = "n" ]; then
+ if [ "$CONFIG_ZORRO" = "y" ]; then
+ tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
+ dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
+ dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
+ tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+ fi
X fi
X if [ "$CONFIG_MAC" = "y" ]; then
X bool 'Mac SCC serial support' CONFIG_MAC_SCC
@@ -294,18 +369,32 @@
X if [ "$CONFIG_HP300" = "y" -a "$CONFIG_DIO" = "y" ]; then
X tristate 'HP DCA serial support' CONFIG_HPDCA
X fi
+if [ "$CONFIG_SUN3X" = "y" ]; then
+ bool 'Sun3x builtin serial support' CONFIG_SUN3X_ZS
+ if [ "$CONFIG_SUN3X_ZS" = "y" ]; then
+ bool 'Sun keyboard support' CONFIG_SUN_KEYBOARD
+ bool 'Sun mouse support' CONFIG_SUN_MOUSE
+ define_bool CONFIG_SBUS y
+ define_bool CONFIG_SBUSCHAR y
+ define_bool CONFIG_SUN_SERIAL y
+ fi
+fi
X if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" -o \
- "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" ]; then
+ "$CONFIG_MAC" = "y" -o "$CONFIG_HP300" = "y" -o \
+ "$CONFIG_SUN3X" = "y" ]; then
X if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
X "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
X "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
X "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
- "$CONFIG_HPDCA" = "y" ]; then
+ "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" ]; then
X bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
X fi
X fi
X if [ "$CONFIG_VME" = "y" ]; then
X define_bool CONFIG_SERIAL_CONSOLE y
+ if [ "$CONFIG_MVME147" = "y" ]; then
+ bool 'SCC support for MVME147 serial ports' CONFIG_MVME147_SCC
+ fi
X if [ "$CONFIG_MVME16x" = "y" ]; then
X bool 'CD2401 support for MVME166/7 serial ports' CONFIG_SERIAL167
X bool 'SCC support for MVME162 serial ports' CONFIG_MVME162_SCC
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S
--- v2.2.7/linux/arch/m68k/kernel/entry.S Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/entry.S Tue May 11 09:57:14 1999
@@ -164,8 +164,17 @@
X
X movel %sp,%sp@-
X movel %d0,%sp@- | put vector # on stack
+#if defined(MACH_Q40_ONLY) && defined(CONFIG_BLK_DEV_FD)
+ btstb #4,0xff000000 | Q40 floppy needs very special treatment ...
+ jbeq 1f
+ btstb #3,0xff000004
+ jbeq 1f
+ jbsr SYMBOL_NAME(floppy_hardint)
+ jbra 3f
+1:
+#endif
X jbsr SYMBOL_NAME(process_int)| process the IRQ
- addql #8,%sp | pop parameters off stack
+3: addql #8,%sp | pop parameters off stack
X
X SYMBOL_NAME_LABEL(ret_from_interrupt)
X subql #1,SYMBOL_NAME(local_irq_count)
@@ -295,6 +304,8 @@
X 2: fmovemx %fp0-%fp7,%a0@(TASK_TSS+TSS_FPREG)
X fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_TSS+TSS_FPCNTL)
X 3:
+ /* Return previous task in %d1 */
+ movel %curptr,%d1
X
X /* switch to new task (a1 contains new task) */
X movel %a1,%curptr
@@ -320,7 +331,14 @@
X movec %d0,%cacr
X
X /* switch the root pointer */
+#ifdef CPU_M68030_ONLY
+ .chip 68030
+ pmovefd %a1@(TASK_TSS+TSS_CRP),%crp
+ .chip 68k
+ pflush #0,#4
+#else
X pmove %a1@(TASK_TSS+TSS_CRP),%crp
+#endif
X #endif
X
X #if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/head.S linux/arch/m68k/kernel/head.S
--- v2.2.7/linux/arch/m68k/kernel/head.S Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/head.S Tue May 11 09:57:14 1999
@@ -23,6 +23,7 @@
X ** 98/04/25 Phil Blundell: added HP300 support
X ** 1998/08/30 David Kilzer: Added support for fbcon_font_desc structures
X ** for linux-2.1.115
+** 9/02/11 Richard Zidlicky: added Q40 support (initial vesion 99/01/01)
X **
X ** This file is subject to the terms and conditions of the GNU General Public
X ** License. See the file README.legal in the main directory of this archive
@@ -303,6 +304,12 @@
X .globl SYMBOL_NAME(availmem)
X .globl SYMBOL_NAME(m68k_pgtable_cachemode)
X .globl SYMBOL_NAME(m68k_supervisor_cachemode)
+#ifdef CONFIG_MVME16x
+.globl SYMBOL_NAME(mvme_bdid_ptr)
+#endif
+#ifdef CONFIG_Q40
+.globl SYMBOL_NAME(q40_mem_cptr)
+#endif
X
X CPUTYPE_040 = 1 /* indicates an 040 */
X CPUTYPE_060 = 2 /* indicates an 060 */
@@ -512,13 +519,15 @@
X #endif
X .endm
X
-
X #define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab
X #define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab
X #define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab
+#define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab
X #define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
X #define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
X #define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
+#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
+#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
X
X #define is_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
X #define is_not_040_or_060(lab) btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
@@ -552,9 +561,11 @@
X .long BOOTINFOV_MAGIC
X .long MACH_AMIGA, AMIGA_BOOTI_VERSION
X .long MACH_ATARI, ATARI_BOOTI_VERSION
+ .long MACH_MVME147, MVME147_BOOTI_VERSION
X .long MACH_MVME16x, MVME16x_BOOTI_VERSION
X .long MACH_BVME6000, BVME6000_BOOTI_VERSION
X .long MACH_MAC, MAC_BOOTI_VERSION
+ .long MACH_Q40, Q40_BOOTI_VERSION
X .long 0
X 1: jra SYMBOL_NAME(__start)
X
@@ -859,7 +870,12 @@
X /*
X * 040: Map the 16Meg range physical 0x0 upto logical 0x8000.0000
X */
- mmu_map #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
+ mmu_map #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
+ /*
+ * Map the Zorro III I/O space with transparent translation
+ * for frame buffer memory etc.
+ */
+ mmu_map_tt #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE_S
X
X jbra L(mmu_init_done)
X
@@ -867,7 +883,8 @@
X /*
X * 030: Map the 32Meg range physical 0x0 upto logical 0x8000.0000
X */
- mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
+ mmu_map #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
+ mmu_map_tt #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE030
X
X jbra L(mmu_init_done)
X
@@ -926,6 +943,25 @@
X L(mmu_init_not_atari):
X #endif
X
+#ifdef CONFIG_Q40
+ is_not_q40(L(notq40))
+ /*
+ * add transparent mapping for 0xff00 0000 - 0xffff ffff
+ * non-cached serialized etc..
+ * this includes master chip, DAC, RTC and ISA ports
+ * 0xfe000000-0xfeffffff is for screen and ROM
+ */
+
+ putc 'Q'
+
+ mmu_map_tt #0,#0xfe000000,#0x01000000,#_PAGE_CACHE040W
+ mmu_map_tt #1,#0xff000000,#0x01000000,#_PAGE_NOCACHE_S
+
+ jbra L(mmu_init_done)
+
+L(notq40):
+#endif
+
X #ifdef CONFIG_HP300
X is_not_hp300(L(nothp300))
X
@@ -940,6 +976,24 @@
X
X #endif
X
+#ifdef CONFIG_MVME147
+
+ is_not_mvme147(L(not147))
+
+ /*
+ * On MVME147 we have already created kernel page tables for
+ * 4MB of RAM at address 0, so now need to do a transparent
+ * mapping of the top of memory space. Make it 0.5GByte for now,
+ * so we can access on-board i/o areas.
+ */
+
+ mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE030
+
+ jbra L(mmu_init_done)
+
+L(not147):
+#endif /* CONFIG_MVME147 */
+
X #ifdef CONFIG_MVME16x
X
X is_not_mvme16x(L(not16x))
@@ -965,7 +1019,7 @@
X * 0xffe00000->0xffe1ffff.
X */
X
- mmu_map_tt 1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
+ mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
X
X jbra L(mmu_init_done)
X
@@ -985,7 +1039,7 @@
X * clash with User code virtual address space.
X */
X
- mmu_map_tt 1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
+ mmu_map_tt #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
X
X jbra L(mmu_init_done)
X
@@ -1052,13 +1106,23 @@
X mmu_map_eq #0x50000000,#0x02000000,%d3
X mmu_map_eq #0x60000000,#0x00400000,%d3
X mmu_map_eq #0x9c000000,#0x00400000,%d3
- mmu_map_tt 1,#0xf8000000,#0x08000000,%d3
+ mmu_map_tt #1,#0xf8000000,#0x08000000,%d3
X
X jbra L(mmu_init_done)
X
X L(mmu_init_not_mac):
X #endif
X
+#ifdef CONFIG_SUN3X
+ is_not_sun3x(L(notsun3x))
+
+ /* setup tt1 for I/O */
+ mmu_map_tt #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
+
+L(notsun3x):
+ jbra L(mmu_init_done)
+#endif
+
X L(mmu_init_done):
X
X putc 'G'
@@ -1214,6 +1278,14 @@
X 1:
X #endif
X
+#ifdef CONFIG_SUN3X
+ is_not_sun3x(1f)
+
+ /* enable copro */
+ oriw #0x4000,0x61000000
+1:
+#endif
+
X /*
X * Fixup the addresses for the kernel pointer table and availmem.
X * Convert them from physical addresses to virtual addresses.
@@ -1780,7 +1852,7 @@
X /* Extract the highest bit set
X */
X bfffo ARG3{#0,#32},%d1
- cmpw #8,%d0
+ cmpw #8,%d1
X jcc L(do_map)
X
X /* And get the mask
@@ -2155,7 +2227,9 @@
X /* Temporary allocate a page table and insert it into the ptr table
X */
X movel %a1@,%d0
- addl #PTR_TABLE_SIZE*4,%a1@
+ /* The 512 should be PAGE_TABLE_SIZE*4, but that violates the
+ alignment restriction for pointer tables on the '0[46]0. */
+ addl #512,%a1@
X orw #_PAGE_TABLE+_PAGE_ACCESSED,%d0
X movel %d0,%a0@
X dputs " (new)"
@@ -2703,6 +2777,31 @@
X L(serial_init_not_mac):
X #endif /* CONFIG_MAC */
X
+#ifdef CONFIG_Q40
+ is_not_q40(2f)
+/* debug output goes into SRAM, so we don't do it unless requested
+ - check for '%LX$' signature in SRAM */
+ lea %pc@(SYMBOL_NAME(q40_mem_cptr)),%a1
+ move.l #0xff020010,%a1@ /* must be inited - also used by debug=mem */
+ move.l #0xff020000,%a1
+ cmp.b #'%',%a1@
+ bne 2f /*nodbg*/
+ addq.w #4,%a1
+ cmp.b #'L',%a1@
+ bne 2f /*nodbg*/
+ addq.w #4,%a1
+ cmp.b #'X',%a1@
+ bne 2f /*nodbg*/
+ addq.w #4,%a1
+ cmp.b #'$',%a1@
+ bne 2f /*nodbg*/
+ /* signature OK */
+ lea %pc@(L(q40_do_debug)),%a1
+ tas %a1@
+/*nodbg: q40_do_debug is 0 by default*/
+2:
+#endif
+
X L(serial_init_done):
X func_return serial_init
X
@@ -2792,6 +2891,15 @@
X 4:
X #endif /* CONFIG_ATARI */
X
+#ifdef CONFIG_MVME147
+ is_not_mvme147(2f)
+1: btst #2,M147_SCC_CTRL_A
+ jeq 1b
+ moveb %d0,M147_SCC_DATA_A
+ jbra L(serial_putc_done)
+2:
+#endif
+
X #ifdef CONFIG_MVME16x
X is_not_mvme16x(2f)
X /*
@@ -2805,7 +2913,7 @@
X moveml %sp@+,%d0-%d7/%a2-%a6
X jbra L(serial_putc_done)
X 2:
-#endif CONFIG_MVME162 | CONFIG_MVME167
+#endif CONFIG_MVME16x
X
X #ifdef CONFIG_BVME6000
X is_not_bvme6000(2f)
@@ -2819,6 +2927,18 @@
X 2:
X #endif
X
+#ifdef CONFIG_Q40
+ is_not_q40(2f)
+ tst.l %pc@(L(q40_do_debug)) /* only debug if requested */
+ beq 2f
+ lea %pc@(SYMBOL_NAME(q40_mem_cptr)),%a1
+ move.l %a1@,%a0
+ move.b %d0,%a0@
+ addq.l #4,%a0
+ move.l %a0,%a1@
+2:
+#endif
+
X L(serial_putc_done):
X func_return serial_putc
X
@@ -3472,6 +3592,10 @@
X L(temp_mmap_mem):
X .long 0
X
+#if defined (CONFIG_MVME147)
+M147_SCC_CTRL_A = 0xfffe3002
+M147_SCC_DATA_A = 0xfffe3003
+#endif
X
X #if defined (CONFIG_BVME6000)
X BVME_SCC_CTRL_A = 0xffb0000b
@@ -3508,4 +3632,10 @@
X #if defined(CONFIG_MVME16x)
X SYMBOL_NAME_LABEL(mvme_bdid_ptr)
X .long 0
+#endif
+#if defined(CONFIG_Q40)
+SYMBOL_NAME_LABEL(q40_mem_cptr)
+ .long 0
+L(q40_do_debug):
+ .long 0
X #endif
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/ints.c linux/arch/m68k/kernel/ints.c
--- v2.2.7/linux/arch/m68k/kernel/ints.c Tue Jun 23 10:01:21 1998
+++ linux/arch/m68k/kernel/ints.c Tue May 11 09:57:14 1999
@@ -38,6 +38,10 @@
X #include <asm/page.h>
X #include <asm/machdep.h>
X
+#ifdef CONFIG_Q40
+#include <asm/q40ints.h>
+#endif
+
X /* table for system interrupt handlers */
X static irq_handler_t irq_list[SYS_IRQS];
X
@@ -177,14 +181,24 @@
X
X /*
X * Do we need these probe functions on the m68k?
+ *
+ * ... may be usefull with ISA devices


X */
X unsigned long probe_irq_on (void)

X {
+#ifdef CONFIG_Q40
+ if (MACH_IS_Q40)
+ return q40_probe_irq_on();
+#endif
X return 0;
X }
X
X int probe_irq_off (unsigned long irqs)
X {
+#ifdef CONFIG_Q40
+ if (MACH_IS_Q40)
+ return q40_probe_irq_off(irqs);
+#endif
X return 0;
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/m68k_defs.h linux/arch/m68k/kernel/m68k_defs.h
--- v2.2.7/linux/arch/m68k/kernel/m68k_defs.h Thu Jan 7 15:11:36 1999
+++ linux/arch/m68k/kernel/m68k_defs.h Tue May 11 09:57:14 1999
@@ -3,6 +3,47 @@
X */
X
X #define TS_MAGICKEY 0x5a5a5a5a
-#define TS_TSS 482
-#define TS_ESP0 502
-#define TS_FPU 506
+#define TASK_STATE 0
+#define TASK_FLAGS 4
+#define TASK_SIGPENDING 8
+#define TASK_NEEDRESCHED 20
+#define TASK_TSS 470
+#define TASK_MM 622
+#define TSS_KSP 0
+#define TSS_USP 4
+#define TSS_SR 8
+#define TSS_FS 10
+#define TSS_CRP 12
+#define TSS_ESP0 20
+#define TSS_FPREG 24
+#define TSS_FPCNTL 120
+#define TSS_FPSTATE 132
+#define PT_D0 32
+#define PT_ORIG_D0 36
+#define PT_SR 44
+#define PT_VECTOR 50
+#define IRQ_HANDLER 0
+#define IRQ_DEVID 8
+#define IRQ_NEXT 16
+#define STAT_IRQ 120
+#define BIR_TAG 0
+#define BIR_SIZE 2
+#define BIR_DATA 4
+#define FBCON_FONT_DESC_IDX 0
+#define FBCON_FONT_DESC_NAME 4
+#define FBCON_FONT_DESC_WIDTH 8
+#define FBCON_FONT_DESC_HEIGHT 12
+#define FBCON_FONT_DESC_DATA 16
+#define FBCON_FONT_DESC_PREF 20
+#define CUSTOMBASE -2132807680
+#define C_INTENAR 28
+#define C_INTREQR 30
+#define C_INTENA 154
+#define C_INTREQ 156
+#define C_SERDATR 24
+#define C_SERDAT 48
+#define C_SERPER 50
+#define CIAABASE -2134908927
+#define CIABBASE -2134913024
+#define C_PRA 0
+#define ZTWOBASE -2147483648
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c
--- v2.2.7/linux/arch/m68k/kernel/m68k_ksyms.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/m68k_ksyms.c Tue May 11 09:57:14 1999
@@ -18,6 +18,7 @@
X #include <asm/checksum.h>
X #include <asm/hardirq.h>
X #include <asm/softirq.h>
+#include <asm/m68kserial.h>
X
X asmlinkage long long __ashrdi3 (long long, int);
X extern char m68k_debug_device[];
@@ -54,6 +55,8 @@
X EXPORT_SYMBOL(disable_irq);
X EXPORT_SYMBOL(kernel_set_cachemode);
X EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(register_serial);
+EXPORT_SYMBOL(unregister_serial);
X
X /* Networking helper routines. */
X EXPORT_SYMBOL(csum_partial_copy);
@@ -69,4 +72,5 @@
X
X EXPORT_SYMBOL_NOVERS(__down_failed);
X EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
+EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
X EXPORT_SYMBOL_NOVERS(__up_wakeup);
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.2.7/linux/arch/m68k/kernel/process.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/process.c Tue May 11 09:57:14 1999
@@ -169,15 +169,7 @@
X
X asmlinkage int m68k_vfork(struct pt_regs *regs)
X {
- int child;
- struct semaphore sem = MUTEX_LOCKED;
-
- child = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs);
-
- if (child > 0)
- down(&sem);
-
- return child;
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs);
X }
X
X asmlinkage int m68k_clone(struct pt_regs *regs)
@@ -190,7 +182,7 @@
X newsp = regs->d2;
X if (!newsp)
X newsp = rdusp();
- return do_fork(clone_flags & ~CLONE_VFORK, newsp, regs);
+ return do_fork(clone_flags, newsp, regs);
X }
X
X int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/ptrace.c linux/arch/m68k/kernel/ptrace.c
--- v2.2.7/linux/arch/m68k/kernel/ptrace.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/ptrace.c Tue May 11 09:57:14 1999
@@ -312,6 +312,7 @@
X asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
X {
X struct task_struct *child;
+ unsigned long flags;
X int ret;
X
X lock_kernel();
@@ -343,21 +344,22 @@
X (current->uid != child->uid) ||
X (current->gid != child->egid) ||
X (current->gid != child->sgid) ||
+ (!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
X (current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
X goto out;
X /* the same process cannot be attached many times */
X if (child->flags & PF_PTRACED)
X goto out;
X child->flags |= PF_PTRACED;
- if (child->p_pptr != current) {
- unsigned long flags;
X
- write_lock_irqsave(&tasklist_lock, flags);
+ write_lock_irqsave(&tasklist_lock, flags);
+ if (child->p_pptr != current) {
X REMOVE_LINKS(child);
X child->p_pptr = current;
X SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
X }
+ write_unlock_irqrestore(&tasklist_lock, flags);
+
X send_sig(SIGSTOP, child, 1);
X ret = 0;
X goto out;
@@ -502,7 +504,6 @@
X }
X
X case PTRACE_DETACH: { /* detach a process that was attached. */
- unsigned long flags;
X long tmp;
X
X ret = -EIO;
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/setup.c linux/arch/m68k/kernel/setup.c
--- v2.2.7/linux/arch/m68k/kernel/setup.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/kernel/setup.c Tue May 11 09:57:14 1999
@@ -77,10 +77,26 @@
X int (*mach_set_clock_mmss) (unsigned long) = NULL;
X void (*mach_reset)( void );
X long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
-#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY)
+#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) || defined(CONFIG_BLK_DEV_FD)
X void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
X void (*mach_floppy_eject) (void) = NULL;
X #endif
+struct serial_struct;
+#ifdef CONFIG_SERIAL
+long serial_rs_init(void);
+int serial_register_serial(struct serial_struct *);
+void serial_unregister_serial(int);
+long ser_console_init(long, long );
+#endif
+#if defined(CONFIG_USERIAL)||defined(CONFIG_BVME6000_SCC)||defined(CONFIG_MVME162_SCC)||defined(CONFIG_HPDCA)||defined(CONFIG_WHIPPET_SERIAL)||defined(CONFIG_MULTIFACE_III_TTY)||defined(CONFIG_GVPIOEXT)||defined(CONFIG_AMIGA_BUILTIN_SERIAL)||defined(CONFIG_MAC_SCC)||defined(CONFIG_ATARI_MIDI)||defined(CONFIG_ATARI_SCC)||defined(CONFIG_ATARI_MFPSER)
+#define M68K_SERIAL
+#endif
+#ifdef M68K_SERIAL
+long m68k_rs_init(void);
+int m68k_register_serial(struct serial_struct *);
+void m68k_unregister_serial(int);
+long m68k_serial_console_init(long, long );
+#endif
X #ifdef CONFIG_HEARTBEAT
X void (*mach_heartbeat) (int) = NULL;
X #endif
@@ -97,15 +113,19 @@
X extern int amiga_parse_bootinfo(const struct bi_record *);
X extern int atari_parse_bootinfo(const struct bi_record *);
X extern int mac_parse_bootinfo(const struct bi_record *);
+extern int q40_parse_bootinfo(const struct bi_record *);
X
X extern void config_amiga(void);
X extern void config_atari(void);
X extern void config_mac(void);
X extern void config_sun3(void);
X extern void config_apollo(void);
+extern void config_mvme147(void);
X extern void config_mvme16x(void);
X extern void config_bvme6000(void);
X extern void config_hp300(void);
+extern void config_q40(void);
+extern void config_sun3x(void);
X
X #define MASK_256K 0xfffc0000
X
@@ -149,6 +169,8 @@
X unknown = atari_parse_bootinfo(record);
X else if (MACH_IS_MAC)
X unknown = mac_parse_bootinfo(record);
+ else if (MACH_IS_Q40)
+ unknown = q40_parse_bootinfo(record);
X else
X unknown = 1;
X }
@@ -258,6 +280,11 @@
X config_apollo();
X break;
X #endif
+#ifdef CONFIG_MVME147
+ case MACH_MVME147:
+ config_mvme147();
+ break;
+#endif
X #ifdef CONFIG_MVME16x
X case MACH_MVME16x:
X config_mvme16x();
@@ -273,6 +300,16 @@
X config_hp300();
X break;
X #endif
+#ifdef CONFIG_Q40
+ case MACH_Q40:
+ config_q40();
+ break;
+#endif
+#ifdef CONFIG_SUN3X
+ case MACH_SUN3X:
+ config_sun3x();
+ break;
+#endif
X default:
X panic ("No configuration setup");
X }
@@ -384,7 +421,52 @@
X return(len);
X }
X
-#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY)
+#if defined(CONFIG_SERIAL) || defined(M68K_SERIAL)
+int rs_init(void)
+{
+#ifdef CONFIG_SERIAL
+ if (MACH_IS_Q40)
+ return serial_rs_init();
+#endif
+#ifdef M68K_SERIAL
+ return m68k_rs_init();
+#endif
+}
+int register_serial(struct serial_struct *p)
+{
+#ifdef CONFIG_SERIAL
+ if (MACH_IS_Q40)
+ return serial_register_serial(p);
+#endif
+#ifdef M68K_SERIAL
+ return m68k_register_serial(p);
+#endif
+}
+void unregister_serial(int i)
+{
+#ifdef CONFIG_SERIAL
+ if (MACH_IS_Q40)
+ serial_unregister_serial(i);
+#endif
+#ifdef M68K_SERIAL
+ m68k_unregister_serial(i);
+#endif
+}
+#ifdef CONFIG_SERIAL_CONSOLE
+long serial_console_init(long kmem_start, long kmem_end)
+{
+#ifdef CONFIG_SERIAL
+ if (MACH_IS_Q40)
+ return ser_console_init(kmem_start, kmem_end);
+#endif
+#if defined(M68K_SERIAL) && defined(CONFIG_SERIAL_CONSOLE)
+ return m68k_serial_console_init(kmem_start, kmem_end);
+#endif
+}
+#endif
+#endif
+
+#if defined(CONFIG_AMIGA_FLOPPY) || defined(CONFIG_ATARI_FLOPPY) || defined(CONFIG_BLK_DEV_FD)
X __initfunc(void floppy_setup(char *str, int *ints))
X {
X if (mach_floppy_setup)
@@ -399,7 +481,7 @@
X #endif
X
X /* for "kbd-reset" cmdline param */
-void __init kbd_reset_setup(char *str, int *ints)
+__initfunc(void kbd_reset_setup(char *str, int *ints))
X {
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/kernel/time.c linux/arch/m68k/kernel/time.c
--- v2.2.7/linux/arch/m68k/kernel/time.c Tue Mar 23 14:35:46 1999
+++ linux/arch/m68k/kernel/time.c Tue May 11 09:57:14 1999
@@ -200,5 +200,5 @@
X time_status |= STA_UNSYNC;
X time_maxerror = NTP_PHASE_LIMIT;
X time_esterror = NTP_PHASE_LIMIT;
- sti();
+ write_unlock_irq(&xtime_lock);
X }
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/lib/semaphore.S linux/arch/m68k/lib/semaphore.S
--- v2.2.7/linux/arch/m68k/lib/semaphore.S Sat May 24 09:10:22 1997
+++ linux/arch/m68k/lib/semaphore.S Tue May 11 09:57:14 1999
@@ -32,6 +32,16 @@
X movel (%sp)+,%a0
X rts
X
+ENTRY(__down_failed_trylock)
+ movel %a0,-(%sp)
+ movel %d1,-(%sp)
+ movel %a1,-(%sp)
+ jbsr SYMBOL_NAME(__down_trylock)
+ movel (%sp)+,%a1
+ movel (%sp)+,%d1
+ movel (%sp)+,%a0
+ rts
+
X ENTRY(__up_wakeup)
X moveml %a0/%d0/%d1,-(%sp)
X movel %a1,-(%sp)
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mm/init.c linux/arch/m68k/mm/init.c
--- v2.2.7/linux/arch/m68k/mm/init.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/mm/init.c Tue May 11 09:57:14 1999
@@ -123,7 +123,7 @@
X unsigned long mm_cachebits = 0;
X #endif
X
-static pte_t *__init kernel_page_table(unsigned long *memavailp)
+__initfunc(static pte_t * kernel_page_table(unsigned long *memavailp))
X {
X pte_t *ptablep;
X
@@ -140,15 +140,19 @@
X
X static pmd_t *last_pgtable __initdata = NULL;
X
-static pmd_t *__init kernel_ptr_table(unsigned long *memavailp)
+__initfunc(static pmd_t * kernel_ptr_table(unsigned long *memavailp))
X {
X if (!last_pgtable) {
X unsigned long pmd, last;
X int i;
X
+ /* Find the last ptr table that was used in head.S and
+ * reuse the remaining space in that page for further
+ * ptr tables.
+ */
X last = (unsigned long)kernel_pg_dir;
X for (i = 0; i < PTRS_PER_PGD; i++) {
- if (!pgd_val(kernel_pg_dir[i]))
+ if (!pgd_present(kernel_pg_dir[i]))
X continue;
X pmd = pgd_page(kernel_pg_dir[i]);
X if (pmd > last)
@@ -175,8 +179,8 @@
X return last_pgtable;
X }
X
-static unsigned long __init
-map_chunk (unsigned long addr, long size, unsigned long *memavailp)
+__initfunc(static unsigned long
+map_chunk (unsigned long addr, long size, unsigned long *memavailp))
X {
X #define PTRTREESIZE (256*1024)
X #define ROOTTREESIZE (32*1024*1024)
@@ -282,8 +286,8 @@
X * paging_init() continues the virtual memory environment setup which
X * was begun by the code in arch/head.S.
X */
-unsigned long __init paging_init(unsigned long start_mem,
- unsigned long end_mem)
+__initfunc(unsigned long paging_init(unsigned long start_mem,
+ unsigned long end_mem))
X {
X int chunk;
X unsigned long mem_avail = 0;
@@ -392,7 +396,7 @@
X return PAGE_ALIGN(free_area_init(start_mem, end_mem));
X }
X
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
X {
X int codepages = 0;
X int datapages = 0;
@@ -443,7 +447,7 @@
X /* insert pointer tables allocated so far into the tablelist */
X init_pointer_table((unsigned long)kernel_pg_dir);
X for (i = 0; i < PTRS_PER_PGD; i++) {
- if (pgd_val(kernel_pg_dir[i]))
+ if (pgd_present(kernel_pg_dir[i]))
X init_pointer_table(pgd_page(kernel_pg_dir[i]));
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mm/kmap.c linux/arch/m68k/mm/kmap.c
--- v2.2.7/linux/arch/m68k/mm/kmap.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/mm/kmap.c Tue May 11 09:57:14 1999
@@ -116,6 +116,14 @@
X if (!size || size > physaddr + size)
X return NULL;
X
+#ifdef CONFIG_AMIGA
+ if (MACH_IS_AMIGA) {
+ if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
+ && (cacheflag == IOMAP_NOCACHE_SER))
+ return (void *)physaddr;
+ }
+#endif
+
X #ifdef DEBUG
X printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
X #endif
@@ -174,7 +182,7 @@
X }
X }
X
- while (size > 0) {
+ while ((long)size > 0) {
X #ifdef DEBUG
X if (!(virtaddr & (PTRTREESIZE-1)))
X printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
@@ -187,7 +195,7 @@
X }
X
X if (CPU_IS_020_OR_030) {
- pmd_dir->pmd[(virtaddr/PTRTREESIZE)&-16] = physaddr;
+ pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
X physaddr += PTRTREESIZE;
X virtaddr += PTRTREESIZE;
X size -= PTRTREESIZE;
@@ -217,7 +225,14 @@
X */
X void iounmap(void *addr)
X {
+#ifdef CONFIG_AMIGA
+ if ((!MACH_IS_AMIGA) ||
+ (((unsigned long)addr < 0x40000000) ||
+ ((unsigned long)addr > 0x60000000)))
+ free_io_area(addr);
+#else
X free_io_area(addr);
+#endif
X }
X
X /*
@@ -232,7 +247,7 @@
X pmd_t *pmd_dir;
X pte_t *pte_dir;
X
- while (size > 0) {
+ while ((long)size > 0) {
X pgd_dir = pgd_offset_k(virtaddr);
X if (pgd_bad(*pgd_dir)) {
X printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
@@ -242,7 +257,7 @@
X pmd_dir = pmd_offset(pgd_dir, virtaddr);
X
X if (CPU_IS_020_OR_030) {
- int pmd_off = (virtaddr/PTRTREESIZE) & -16;
+ int pmd_off = (virtaddr/PTRTREESIZE) & 15;
X
X if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
X pmd_dir->pmd[pmd_off] = 0;
@@ -308,7 +323,7 @@
X }
X }
X
- while (size > 0) {
+ while ((long)size > 0) {
X pgd_dir = pgd_offset_k(virtaddr);
X if (pgd_bad(*pgd_dir)) {
X printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
@@ -318,7 +333,7 @@
X pmd_dir = pmd_offset(pgd_dir, virtaddr);
X
X if (CPU_IS_020_OR_030) {
- int pmd_off = (virtaddr/PTRTREESIZE) & -16;
+ int pmd_off = (virtaddr/PTRTREESIZE) & 15;
X
X if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
X pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.2.7/linux/arch/m68k/mm/memory.c Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/mm/memory.c Tue May 11 09:57:14 1999
@@ -11,6 +11,7 @@
X #include <linux/types.h>
X #include <linux/malloc.h>
X #include <linux/init.h>
+#include <linux/pagemap.h>
X
X #include <asm/setup.h>
X #include <asm/segment.h>
@@ -93,12 +94,11 @@
X static ptable_desc ptable_list = { &ptable_list, &ptable_list };
X
X #define PD_MARKBITS(dp) (*(unsigned char *)&(dp)->offset)
-#define PD_PAGE(dp) (PAGE_OFFSET + ((dp)->map_nr << PAGE_SHIFT))
X #define PAGE_PD(page) ((ptable_desc *)&mem_map[MAP_NR(page)])
X
X #define PTABLE_SIZE (PTRS_PER_PMD * sizeof(pmd_t))
X
-void __init init_pointer_table(unsigned long ptable)
+__initfunc(void init_pointer_table(unsigned long ptable))
X {
X ptable_desc *dp;
X unsigned long page = ptable & PAGE_MASK;
@@ -166,7 +166,7 @@
X (dp->next = last->next)->prev = dp;
X (dp->prev = last)->next = dp;
X }
- return (pmd_t *) (PD_PAGE(dp) + off);
+ return (pmd_t *) (page_address(dp) + off);
X }
X
X int free_pointer_table (pmd_t *ptable)
@@ -215,8 +215,8 @@
X /* function code match? */
X base = (regval >> 4) & 7;
X mask = ~(regval & 7);
- if ((SUPER_DATA & mask) != (base & mask))
- return( 0 );
+ if (((SUPER_DATA ^ base) & mask) != 0)
+ return 0;
X }
X else {
X /* must not be user-only */
@@ -226,8 +226,8 @@
X
X /* address match? */
X base = regval & 0xff000000;
- mask = ~((regval << 8) & 0xff000000);
- return( (vaddr & mask) == (base & mask) );
+ mask = ~(regval << 8) & 0xff000000;
+ return ((vaddr ^ base) & mask) == 0;
X }
X
X #ifndef CONFIG_SINGLE_MEMORY_CHUNK
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mvme147/147ints.c linux/arch/m68k/mvme147/147ints.c
--- v2.2.7/linux/arch/m68k/mvme147/147ints.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/mvme147/147ints.c Tue May 11 09:57:14 1999


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 06'
echo 'File patch-2.2.8 is continued in part 07'
echo 07 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part07

#!/bin/sh
# this is part 07 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 07; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

@@ -0,0 +1,142 @@
+/*
+ * arch/m68k/mvme147/147ints.c
+ *
+ * Copyright (C) 1997 Richard Hirst [ric...@sleepie.demon.co.uk]
+ *
+ * based on amiints.c -- Amiga Linux interrupt handling code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+
+static void mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp);
+
+/*
+ * This should ideally be 4 elements only, for speed.
+ */
+
+static struct {
+ void (*handler)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ void *dev_id;
+ const char *devname;
+ unsigned count;
+} irq_tab[256];
+
+/*
+ * void mvme147_init_IRQ (void)
+ *
+ * Parameters: None
+ *
+ * Returns: Nothing
+ *
+ * This function is called during kernel startup to initialize
+ * the mvme147 IRQ handling routines.
+ */
+
+void mvme147_init_IRQ (void)
+{
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ irq_tab[i].handler = mvme147_defhand;
+ irq_tab[i].flags = IRQ_FLG_STD;
+ irq_tab[i].dev_id = NULL;
+ irq_tab[i].devname = NULL;
+ irq_tab[i].count = 0;
+ }
+}
+
+int mvme147_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *devname, void *dev_id)
+{
+ if (irq > 255) {
+ printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+ return -ENXIO;
+ }
+ if (!(irq_tab[irq].flags & IRQ_FLG_STD)) {
+ if (irq_tab[irq].flags & IRQ_FLG_LOCK) {
+ printk("%s: IRQ %d from %s is not replaceable\n",
+ __FUNCTION__, irq, irq_tab[irq].devname);
+ return -EBUSY;
+ }
+ if (flags & IRQ_FLG_REPLACE) {
+ printk("%s: %s can't replace IRQ %d from %s\n",
+ __FUNCTION__, devname, irq, irq_tab[irq].devname);


+ return -EBUSY;
+ }
+ }

+ irq_tab[irq].handler = handler;
+ irq_tab[irq].flags = flags;
+ irq_tab[irq].dev_id = dev_id;
+ irq_tab[irq].devname = devname;
+ return 0;
+}
+
+void mvme147_free_irq(unsigned int irq, void *dev_id)
+{
+ if (irq > 255) {
+ printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
+ return;
+ }
+ if (irq_tab[irq].dev_id != dev_id)
+ printk("%s: Removing probably wrong IRQ %d from %s\n",
+ __FUNCTION__, irq, irq_tab[irq].devname);
+
+ irq_tab[irq].handler = mvme147_defhand;
+ irq_tab[irq].flags = IRQ_FLG_STD;
+ irq_tab[irq].dev_id = NULL;
+ irq_tab[irq].devname = NULL;
+}
+
+void mvme147_process_int (unsigned long vec, struct pt_regs *fp)
+{
+ if (vec > 255)
+ printk ("mvme147_process_int: Illegal vector %ld\n", vec);
+ else
+ {
+ irq_tab[vec].count++;
+ irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp);
+ }
+}
+
+int mvme147_get_irq_list (char *buf)
+{
+ int i, len = 0;
+
+ for (i = 0; i < 256; i++) {
+ if (irq_tab[i].count)
+ len += sprintf (buf+len, "Vec 0x%02x: %8d %s\n",
+ i, irq_tab[i].count,
+ irq_tab[i].devname ? irq_tab[i].devname : "free");
+ }
+ return len;
+}
+
+
+static void mvme147_defhand (int irq, void *dev_id, struct pt_regs *fp)
+{
+ printk ("Unknown interrupt 0x%02x\n", irq);
+}
+
+void mvme147_enable_irq (unsigned int irq)
+{
+}
+
+
+void mvme147_disable_irq (unsigned int irq)
+{
+}
+
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mvme147/Makefile linux/arch/m68k/mvme147/Makefile
--- v2.2.7/linux/arch/m68k/mvme147/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/mvme147/Makefile Tue May 11 09:57:14 1999
@@ -0,0 +1,14 @@
+#
+# Makefile for Linux arch/m68k/mvme147 source directory
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+O_TARGET := mvme147.o
+O_OBJS := config.o 147ints.o
+
+
+include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mvme147/config.c linux/arch/m68k/mvme147/config.c
--- v2.2.7/linux/arch/m68k/mvme147/config.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/mvme147/config.c Tue May 11 09:57:14 1999
@@ -0,0 +1,240 @@
+/*
+ * arch/m68k/mvme147/config.c
+ *
+ * Copyright (C) 1996 Dave Frascone [ch...@mindspring.com]
+ * Cloned from Richard Hirst [ric...@sleepie.demon.co.uk]
+ *
+ * Based on:
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/major.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/mvme147hw.h>
+
+
+extern void mvme147_process_int (int level, struct pt_regs *regs);
+extern void mvme147_init_IRQ (void);
+extern void mvme147_free_irq (unsigned int, void *);
+extern int mvme147_get_irq_list (char *);
+extern void mvme147_enable_irq (unsigned int);
+extern void mvme147_disable_irq (unsigned int);
+static void mvme147_get_model(char *model);
+static int mvme147_get_hardware_list(char *buffer);
+extern int mvme147_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void mvme147_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int mvme147_keyb_init(void);
+extern int mvme147_kbdrate (struct kbd_repeat *);
+extern unsigned long mvme147_gettimeoffset (void);
+extern void mvme147_gettod (int *year, int *mon, int *day, int *hour,
+ int *min, int *sec);
+extern int mvme147_hwclk (int, struct hwclk_time *);
+extern int mvme147_set_clock_mmss (unsigned long);
+extern void mvme147_check_partition (struct gendisk *hd, unsigned int dev);
+extern void mvme147_reset (void);
+extern void mvme147_waitbut(void);
+
+
+static int bcd2int (unsigned char b);
+
+/* Save tick handler routine pointer, will point to do_timer() in
+ * kernel/sched.c, called via mvme147_process_int() */
+
+void (*tick_handler)(int, void *, struct pt_regs *);
+
+
+int mvme147_kbdrate (struct kbd_repeat *k)


+{
+ return 0;
+}

+
+void mvme147_reset()
+{
+ printk ("\r\n\nCalled mvme147_reset\r\n");
+ m147_pcc->watchdog = 0x0a; /* Clear timer */
+ m147_pcc->watchdog = 0xa5; /* Enable watchdog - 100ms to reset */
+ while (1)
+ ;
+}
+
+static void mvme147_get_model(char *model)
+{
+ sprintf(model, "Motorola MVME147");
+}
+
+
+static int mvme147_get_hardware_list(char *buffer)
+{
+ *buffer = '\0';


+
+ return 0;
+}

+
+
+__initfunc(void config_mvme147(void))
+{
+ mach_sched_init = mvme147_sched_init;
+ mach_keyb_init = mvme147_keyb_init;
+ mach_kbdrate = mvme147_kbdrate;
+ mach_init_IRQ = mvme147_init_IRQ;
+ mach_gettimeoffset = mvme147_gettimeoffset;
+ mach_gettod = mvme147_gettod;
+ mach_hwclk = mvme147_hwclk;
+ mach_set_clock_mmss = mvme147_set_clock_mmss;
+ mach_reset = mvme147_reset;
+ mach_free_irq = mvme147_free_irq;
+ mach_process_int = mvme147_process_int;
+ mach_get_irq_list = mvme147_get_irq_list;
+ mach_request_irq = mvme147_request_irq;
+ enable_irq = mvme147_enable_irq;
+ disable_irq = mvme147_disable_irq;
+ mach_get_model = mvme147_get_model;
+ mach_get_hardware_list = mvme147_get_hardware_list;
+}
+
+
+/* Using pcc tick timer 1 */
+
+static void mvme147_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+{
+ m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
+ m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
+ tick_handler(irq, dev_id, fp);
+}
+
+
+void mvme147_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+{
+ tick_handler = timer_routine;
+ request_irq (PCC_IRQ_TIMER1, mvme147_timer_int,
+ IRQ_FLG_REPLACE, "timer 1", NULL);
+
+ /* Init the clock with a value */
+ /* our clock goes off every 6.25us */
+ m147_pcc->t1_preload = PCC_TIMER_PRELOAD;
+ m147_pcc->t1_cntrl = 0x0; /* clear timer */
+ m147_pcc->t1_cntrl = 0x3; /* start timer */
+ m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; /* clear pending ints */
+ m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
+}
+
+/* This is always executed with interrupts disabled. */
+/* XXX There are race hazards in this code XXX */
+unsigned long mvme147_gettimeoffset (void)
+{
+ volatile unsigned short *cp = (volatile unsigned short *)0xfffe1012;
+ unsigned short n;
+
+ n = *cp;
+ while (n != *cp)
+ n = *cp;
+
+ n -= PCC_TIMER_PRELOAD;
+ return (unsigned long)n * 25 / 4;
+}
+
+extern void mvme147_gettod (int *year, int *mon, int *day, int *hour,
+ int *min, int *sec)
+{
+ m147_rtc->ctrl = RTC_READ;
+ *year = bcd2int (m147_rtc->bcd_year);
+ *mon = bcd2int (m147_rtc->bcd_mth);
+ *day = bcd2int (m147_rtc->bcd_dom);
+ *hour = bcd2int (m147_rtc->bcd_hr);
+ *min = bcd2int (m147_rtc->bcd_min);
+ *sec = bcd2int (m147_rtc->bcd_sec);
+ m147_rtc->ctrl = 0;
+}
+
+static int bcd2int (unsigned char b)
+{
+ return ((b>>4)*10 + (b&15));
+}
+
+int mvme147_hwclk(int op, struct hwclk_time *t)


+{
+ return 0;
+}

+
+int mvme147_set_clock_mmss (unsigned long nowtime)


+{
+ return 0;
+}

+
+int mvme147_keyb_init (void)


+{
+ return 0;
+}

+
+/*------------------- Serial console stuff ------------------------*/
+
+void m147_scc_write(struct console *co, const char *str, unsigned cnt);
+
+
+void mvme147_init_console_port (struct console *co, int cflag)
+{
+ co->write = m147_scc_write;
+}
+
+
+static void scc_delay (void)
+{
+ int n;
+ volatile int trash;
+
+ for (n = 0; n < 20; n++)
+ trash = n;
+}
+
+static void scc_write (char ch)
+{
+ volatile char *p = (volatile char *)M147_SCC_A_ADDR;
+
+ do {
+ scc_delay();
+ }
+ while (!(*p & 4));
+ scc_delay();
+ *p = 8;
+ scc_delay();
+ *p = ch;
+}
+
+
+void m147_scc_write (struct console *co, const char *str, unsigned count)


+{
+ unsigned long flags;
+

+ save_flags(flags);
+ cli();
+
+ while (count--)
+ {
+ if (*str == '\n')
+ scc_write ('\r');
+ scc_write (*str++);
+ }
+ restore_flags(flags);
+}
+
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/mvme16x/config.c linux/arch/m68k/mvme16x/config.c
--- v2.2.7/linux/arch/m68k/mvme16x/config.c Tue Jun 23 10:01:21 1998
+++ linux/arch/m68k/mvme16x/config.c Tue May 11 09:57:14 1999
@@ -335,10 +335,10 @@


X static void scc_delay (void)
X {
X int n;
- char i;
+ volatile int trash;
X
X for (n = 0; n < 20; n++)
- i = *(volatile char *)0;
+ trash = n;
X }
X
X static void scc_write (char ch)

diff -u --recursive --new-file v2.2.7/linux/arch/m68k/q40/Makefile linux/arch/m68k/q40/Makefile
--- v2.2.7/linux/arch/m68k/q40/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/q40/Makefile Tue May 11 09:57:14 1999
@@ -0,0 +1,14 @@
+#
+# Makefile for Linux arch/m68k/q40 source directory
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := q40.o
+O_OBJS := config.o q40ints.o
+
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/q40/README linux/arch/m68k/q40/README
--- v2.2.7/linux/arch/m68k/q40/README Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/q40/README Tue May 11 09:57:14 1999
@@ -0,0 +1,121 @@
+Linux for the Q40
+=================
+
+You may try http://www.geocities.com/SiliconValley/Bay/2602/ for
+some up to date information. Booter and other tools will be also
+available from this place and ftp.uni-erlangen.de/linux/680x0/q40/
+and mirrors.
+
+Hints to documentation usually refer to the linux source tree in
+/usr/src/linux unless URL given.
+
+It seems IRQ unmasking can't be safely done on a Q40. Autoprobing is
+not yet implemented - do not try it! (See below)
+
+For a list of kernel commandline options read the documentation for the
+particular device drivers.
+
+The floppy imposes a very high interrupt load on the CPU, approx 30K/s.
+When something blocks interrupts (HD) it will loose some of them, so far
+this is not known to have caused any data loss. On hihgly loaded systems
+it can make the floppy very slow. Other Q40 OS' simply poll the floppy
+for this reason - something that can't be done in Linux.
+Only possible cure is getting a 82072 contoler with fifo instead of
+the 8272A
+
+drivers used by the Q40, appart from the very obvious (console etc.):
+ drivers/char/q40_keyb.c # use PC keymaps for national keyboards
+ serial.c # normal PC driver - any speed
+ lp.c # printer driver
+ char/joystick/* # most of this should work
+ block/q40ide.c # startup for ide
+ ide* # see Documentation/ide.txt
+ floppy.c # normal PC driver, DMA emu in asm/floppy.h
+ # and arch/m68k/kernel/entry.S
+ # see drivers/block/README.fd
+ video/q40fb.c
+ misc/parport_pc.c
+
+Various other PC drivers can be enabled simply by adding them to
+arch/m68k/config.in, especially 8 bit devices should be without any
+problems. For cards using 16bit io/mem more care is required, like
+checking byteorder issues, hacking memcpy_*_io etc.
+
+
+Debugging
+=========
+
+Upon startup the kernel will usually output "ABCQGHIJ" into the SRAM,
+preceded by the booter signature. This is a trace just in case something
+went wrong during earliest setup stages.
+*Changed* to preserve SRAM contents by default, this is only done when
+requested - SRAM must start with '%LX$' signature to do this. '-d' option
+to 'lxx' loader enables this.
+
+SRAM can also be used as additional console device, use debug=mem.
+This will save kernel startup msgs into SRAM, the screen will display
+only the penguin - and shell prompt if it gets that far..
+
+Serial console works and can also be used for debugging, provided serial
+initialisation works.
+
+Most problems seem to be caused by fawlty or badly configured io-cards or
+harddrives anyway..there are so many things that can go wrong here.
+Make sure to configure the parallel port as SPP for first testing..the
+Q40 may have trouble with parallel interrupts.
+
+
+Q40 Hardware Description
+========================
+
+This is just an overview, see asm-m68k/* for details ask if you have any
+questions.
+
+The Q40 consists of a 68040@40 MHz, 1MB video RAM, up to 32MB RAM, AT-style
+keyboard interface, 1 Programmable LED, 2 8bit DACs and up to 1MB ROM, 1MB
+shadow ROM.
+
+Most interfacing like floppy, hd, serial, parallel ports is done via ISA
+slots. The ISA io and mem range is mapped (sparse&byteswapped!) into separate
+regions of the memory.
+The main interrupt register IIRQ_REG will indicate whether an IRQ was internal
+or from some ISA devices, EIRQ_REG can distinguish up to 8 ISA IRQs.
+
+The Q40 custom chip is programmable to provide 2 periodic timers:
+ - 50 or 200 Hz - level 2, !!THIS CANT BE DISABLED!!
+ - 10 or 20 KHz - level 4 (and possibly 6 - hardware decoding..)
+
+Linux uses the 200 Hz interrupt for timer and beep by default.
+
+
+Interrupts
+==========
+
+q40 master chip handles only level triggered interrupts :-((
+further limitation is no disabling etc. Unless someone finds
+some ingenious clue this means autoprobing will never work.
+Parallel port interrupts cause most trouble..
+
+IRQ sharing is not yet implemented.
+
+
+Keyboard
+========
+
+q40 receives AT make/break codes from the keyboard, these are translated to
+the PC scancodes x86 Linux uses. So by theory every national keyboard should
+work just by loading the apropriate x86 keytable - see any national-HOWTO.
+
+Unfortunately the AT->PC translation isn't quite trivial and even worse, my
+documentation of it is absolutely minimal - thus some exotic keys may not
+behave exactly as expected.
+
+There is still hope that it can be fixed completely though. If you encounter
+problems, email me idealy this:
+ - exact keypress/release sequence
+ - 'showkey -s' run on q40, non-X session
+ - 'showkey -s' run on a PC, non-X session
+ - AT codes as displayed by the q40 debuging ROM
+btw if the showkey output from PC and Q40 doesn't differ then you have some
+classic configuration problem - don't send me anything in this case
+
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/q40/config.c linux/arch/m68k/q40/config.c
--- v2.2.7/linux/arch/m68k/q40/config.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/q40/config.c Tue May 11 09:57:14 1999
@@ -0,0 +1,425 @@
+/*
+ * arch/m68k/q40/config.c
+ *
+ * originally based on:
+ *
+ * linux/bvme/config.c
+ *
+ * Copyright (C) 1993 Hamish Macdonald
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/kd.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/major.h>
+
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/q40_master.h>
+#include <asm/keyboard.h>
+
+extern void fd_floppy_eject(void);
+extern void fd_floppy_setup(char *str, int *ints);
+
+extern void q40_process_int (int level, struct pt_regs *regs);
+extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
+extern void q40_init_IRQ (void);
+extern void q40_free_irq (unsigned int, void *);
+extern int q40_get_irq_list (char *);
+extern void q40_enable_irq (unsigned int);
+extern void q40_disable_irq (unsigned int);
+static void q40_get_model(char *model);
+static int q40_get_hardware_list(char *buffer);
+extern int q40_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id);
+extern void q40_sched_init(void (*handler)(int, void *, struct pt_regs *));
+extern int q40_keyb_init(void);
+extern int q40_kbdrate (struct kbd_repeat *);
+extern unsigned long q40_gettimeoffset (void);
+extern void q40_gettod (int *year, int *mon, int *day, int *hour,
+ int *min, int *sec);
+extern int q40_hwclk (int, struct hwclk_time *);
+extern int q40_set_clock_mmss (unsigned long);
+extern void q40_reset (void);
+extern void q40_waitbut(void);
+void q40_set_vectors (void);
+extern void (*kd_mksound)(unsigned int, unsigned int);
+void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ );
+
+extern char *saved_command_line;
+extern char m68k_debug_device[];
+static void q40_mem_console_write(struct console *co, const char *b,
+ unsigned int count);
+
+static int ql_ticks=0;
+static int sound_ticks=0;
+
+static unsigned char bcd2bin (unsigned char b);
+static unsigned char bin2bcd (unsigned char b);
+
+static int q40_wait_key(struct console *co){return 0;}
+static struct console q40_console_driver = {
+ "debug",
+ NULL, /* write */
+ NULL, /* read */
+ NULL, /* device */
+ q40_wait_key, /* wait_key */
+ NULL, /* unblank */
+ NULL, /* setup */
+ CON_PRINTBUFFER,
+ -1,
+ 0,
+ NULL
+};
+
+
+/* Save tick handler routine pointer, will point to do_timer() in
+ * kernel/sched.c */
+
+/* static void (*tick_handler)(int, void *, struct pt_regs *); */
+
+
+/* early debugging function:*/
+extern char *q40_mem_cptr; /*=(char *)0xff020000;*/
+static int _cpleft;
+
+static void q40_mem_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ char *p=(char *)s;
+
+ if (count<_cpleft)
+ while (count-- >0){
+ *q40_mem_cptr=*p++;
+ q40_mem_cptr+=4;
+ _cpleft--;
+ }
+}
+#if 0
+void printq40(char *str)
+{
+ int l=strlen(str);
+ char *p=q40_mem_cptr;
+
+ while (l-- >0 && _cpleft-- >0)
+ {
+ *p=*str++;
+ p+=4;
+ }
+ q40_mem_cptr=p;
+}
+#endif
+
+#if 0
+int q40_kbdrate (struct kbd_repeat *k)


+{
+ return 0;
+}

+#endif
+
+void q40_reset()
+{
+
+ printk ("\n\n*******************************************\n"
+ "Called q40_reset : press the RESET button!! \n");
+ printk( "*******************************************\n");
+
+ while(1)
+ ;
+}
+
+static void q40_get_model(char *model)
+{
+ sprintf(model, "Q40");
+}
+
+
+/* No hardware options on Q40? */
+
+static int q40_get_hardware_list(char *buffer)
+{
+ *buffer = '\0';
+ return 0;
+}
+
+
+__initfunc(void config_q40(void))
+{
+ mach_sched_init = q40_sched_init; /* ok */
+ /*mach_kbdrate = q40_kbdrate;*/ /* unneeded ?*/
+ mach_keyb_init = q40_keyb_init; /* OK */
+ mach_init_IRQ = q40_init_IRQ;
+ mach_gettimeoffset = q40_gettimeoffset;
+ mach_gettod = q40_gettod;
+ mach_hwclk = q40_hwclk;
+ mach_set_clock_mmss = q40_set_clock_mmss;
+/* mach_mksound = q40_mksound; */
+ mach_reset = q40_reset; /* use reset button instead !*/
+ mach_free_irq = q40_free_irq;
+ mach_process_int = q40_process_int;
+ mach_get_irq_list = q40_get_irq_list;
+ mach_request_irq = q40_request_irq;
+ enable_irq = q40_enable_irq;
+ disable_irq = q40_disable_irq;
+ mach_default_handler = &q40_sys_default_handler;
+ mach_get_model = q40_get_model; /* no use..*/
+ mach_get_hardware_list = q40_get_hardware_list; /* no use */
+ kd_mksound = q40_mksound;
+ /*mach_kbd_leds = q40kbd_leds;*/
+#ifdef CONFIG_MAGIC_SYSRQ
+ mach_sysrq_key = 0x54;
+#endif
+ conswitchp = &dummy_con;
+#ifdef CONFIG_BLK_DEV_FD
+ mach_floppy_setup = fd_floppy_setup;
+ mach_floppy_eject = fd_floppy_eject;
+ /**/
+#endif
+
+ mach_max_dma_address = 0; /* no DMA at all */
+
+
+/* userfull for early debuging stages writes kernel messages into SRAM */
+
+ if (!strncmp( m68k_debug_device,"mem",3 ))
+ {
+ /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/
+ _cpleft=2000-((long)q40_mem_cptr-0xff020000)/4;
+ q40_console_driver.write = q40_mem_console_write;
+ register_console(&q40_console_driver);
+ }
+}
+
+
+int q40_parse_bootinfo(const struct bi_record *rec)
+{
+ return 1; /* unknown */
+}
+
+#define DAC_LEFT ((unsigned char *)0xff008000)
+#define DAC_RIGHT ((unsigned char *)0xff008004)
+void q40_mksound(unsigned int hz, unsigned int ticks)
+{
+ /* for now ignore hz, except that hz==0 switches off sound */
+ /* simply alternate the ampl 0-255-0-.. at 200Hz */
+ if (hz==0)
+ {
+ if (sound_ticks)
+ sound_ticks=1; /* atomic - no irq spinlock used */
+
+ *DAC_LEFT=0;
+ *DAC_RIGHT=0;
+
+ return;
+ }
+ /* sound itself is done in q40_timer_int */
+ if (sound_ticks == 0) sound_ticks=1000; /* pretty long beep */
+ sound_ticks=ticks<<1;
+}
+
+static void (*q40_timer_routine)(int, void *, struct pt_regs *);
+
+static void q40_timer_int (int irq, void *dev_id, struct pt_regs *fp)
+{
+#if (HZ==10000)
+ master_outb(-1,SAMPLE_CLEAR_REG);
+#else /* must be 50 or 100 */
+ master_outb(-1,FRAME_CLEAR_REG);
+#endif
+
+#if (HZ==100)
+ ql_ticks = ql_ticks ? 0 : 1;
+ if (sound_ticks)
+ {
+ unsigned char sval=(sound_ticks & 1) ? 0 : 255;
+ sound_ticks--;
+ *DAC_LEFT=sval;
+ *DAC_RIGHT=sval;
+ }
+ if (ql_ticks) return;
+#endif
+ q40_timer_routine(irq, dev_id, fp);
+}
+
+
+void q40_sched_init (void (*timer_routine)(int, void *, struct pt_regs *))
+{
+ int timer_irq;
+
+ q40_timer_routine = timer_routine;
+
+#if (HZ==10000)
+ timer_irq=Q40_IRQ_TIMER;
+#else
+ timer_irq=Q40_IRQ_FRAME;
+#endif
+
+ /*printk("registering sched/timer IRQ %d\n", timer_irq);*/
+
+ if (request_irq(timer_irq, q40_timer_int, 0,
+ "timer", q40_timer_int))
+ panic ("Couldn't register timer int");
+
+#if (HZ==10000)
+ master_outb(SAMPLE_LOW,SAMPLE_RATE_REG);
+ master_outb(-1,SAMPLE_CLEAR_REG);
+ master_outb(1,SAMPLE_ENABLE_REG);
+#else
+ master_outb(-1,FRAME_CLEAR_REG); /* not necessary ? */
+#if (HZ==100)
+ master_outb( 1,FRAME_RATE_REG);
+#endif
+#endif
+}
+
+
+unsigned long q40_gettimeoffset (void)
+{
+#if (HZ==100)
+ return 5000*(ql_ticks!=0);
+#else
+ return 0;
+#endif
+}
+
+extern void q40_gettod (int *year, int *mon, int *day, int *hour,
+ int *min, int *sec)
+{
+ RTC_CTRL |= RTC_READ;
+ *year = bcd2bin (RTC_YEAR);
+ *mon = bcd2bin (RTC_MNTH)-1;
+ *day = bcd2bin (RTC_DATE);
+ *hour = bcd2bin (RTC_HOUR);
+ *min = bcd2bin (RTC_MINS);
+ *sec = bcd2bin (RTC_SECS);
+ RTC_CTRL &= ~(RTC_READ);
+
+}
+
+static unsigned char bcd2bin (unsigned char b)
+{
+ return ((b>>4)*10 + (b&15));
+}
+
+static unsigned char bin2bcd (unsigned char b)
+{
+ return (((b/10)*16) + (b%10));
+}
+
+
+/*
+ * Looks like op is non-zero for setting the clock, and zero for
+ * reading the clock.
+ *
+ * struct hwclk_time {
+ * unsigned sec; 0..59
+ * unsigned min; 0..59
+ * unsigned hour; 0..23
+ * unsigned day; 1..31
+ * unsigned mon; 0..11
+ * unsigned year; 00...
+ * int wday; 0..6, 0 is Sunday, -1 means unknown/don't set
+ * };
+ */
+
+int q40_hwclk(int op, struct hwclk_time *t)
+{
+ if (op)
+ { /* Write.... */
+ RTC_CTRL |= RTC_WRITE;
+
+ RTC_SECS = bin2bcd(t->sec);
+ RTC_MINS = bin2bcd(t->min);
+ RTC_HOUR = bin2bcd(t->hour);
+ RTC_DATE = bin2bcd(t->day);
+ RTC_MNTH = bin2bcd(t->mon + 1);
+ RTC_YEAR = bin2bcd(t->year%100);
+ if (t->wday >= 0)
+ RTC_DOW = bin2bcd(t->wday+1);
+
+ RTC_CTRL &= ~(RTC_WRITE);
+ }
+ else
+ { /* Read.... */
+ RTC_CTRL |= RTC_READ;
+
+ t->year = bcd2bin (RTC_YEAR);
+ t->mon = bcd2bin (RTC_MNTH)-1;
+ t->day = bcd2bin (RTC_DATE);
+ t->hour = bcd2bin (RTC_HOUR);
+ t->min = bcd2bin (RTC_MINS);
+ t->sec = bcd2bin (RTC_SECS);
+
+ RTC_CTRL &= ~(RTC_READ);
+
+ if (t->year < 70)
+ t->year += 100;
+ t->wday = bcd2bin(RTC_DOW)-1;
+
+ }


+
+ return 0;
+}

+
+/*
+ * Set the minutes and seconds from seconds value 'nowtime'. Fail if
+ * clock is out by > 30 minutes. Logic lifted from atari code.
+ * Algorithm is to wait for the 10ms register to change, and then to
+ * wait a short while, and then set it.
+ */
+
+int q40_set_clock_mmss (unsigned long nowtime)
+{
+ int retval = 0;
+ short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+
+ int rtc_minutes;
+
+
+ rtc_minutes = bcd2bin (RTC_MINS);
+
+ if ((rtc_minutes < real_minutes
+ ? real_minutes - rtc_minutes
+ : rtc_minutes - real_minutes) < 30)
+ {
+ RTC_CTRL |= RTC_WRITE;
+ RTC_MINS = bin2bcd(real_minutes);
+ RTC_SECS = bin2bcd(real_seconds);
+ RTC_CTRL &= ~(RTC_WRITE);
+ }
+ else
+ retval = -1;
+
+
+ return retval;
+}
+
+extern void q40kbd_init_hw(void);
+
+int q40_keyb_init (void)
+{
+ q40kbd_init_hw();
+ return 0;
+}
+
+#if 0
+/* dummy to cause */
+void q40_slow_io()
+{
+ return;
+}
+#endif
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/q40/q40ints.c linux/arch/m68k/q40/q40ints.c
--- v2.2.7/linux/arch/m68k/q40/q40ints.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/q40/q40ints.c Tue May 11 09:57:14 1999
@@ -0,0 +1,347 @@
+/*
+ * arch/m68k/q40/q40ints.c
+ *
+ * Copyright (C) 1999 Richard Zidlicky
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * losely based on bvme6000ints.c
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+
+#include <asm/q40_master.h>
+#include <asm/q40ints.h>
+
+/*
+ * Q40 IRQs are defined as follows:
+ * 3,4,5,6,7,10,11,14,15 : ISA dev IRQs
+ * 16-31: reserved
+ * 32 : keyboard int
+ * 33 : frame int (50 Hz periodic timer)
+ * 34 : sample int (10/20 KHz periodic timer)
+ *
+*/
+
+extern int ints_inited;
+
+
+void q40_irq2_handler (int, void *, struct pt_regs *fp);
+
+
+extern void (*q40_sys_default_handler[]) (int, void *, struct pt_regs *); /* added just for debugging */
+
+static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp);
+static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs);
+
+/*
+ * This should ideally be 4 elements only, for speed.
+ */
+
+#define DEVNAME_SIZE 24
+
+static struct {
+ void (*handler)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ void *dev_id;
+ char devname[DEVNAME_SIZE];
+ unsigned count;
+} irq_tab[Q40_IRQ_MAX+1];
+
+/*
+ * void q40_init_IRQ (void)
+ *
+ * Parameters: None
+ *
+ * Returns: Nothing
+ *
+ * This function is called during kernel startup to initialize
+ * the q40 IRQ handling routines.
+ */
+
+void q40_init_IRQ (void)
+{
+ int i;
+
+ for (i = 0; i <= Q40_IRQ_MAX; i++) {
+ irq_tab[i].handler = q40_defhand;
+ irq_tab[i].flags = IRQ_FLG_STD;
+ irq_tab[i].dev_id = NULL;
+ irq_tab[i].devname[0] = 0;
+ irq_tab[i].count = 0;
+ }
+
+ /* setup handler for ISA ints */
+ sys_request_irq(IRQ2,q40_irq2_handler, IRQ_FLG_LOCK, "q40 ISA and master chip", NULL);
+
+ /* now enable some ints.. */
+
+#if 0 /* has been abandoned */
+ master_outb(1,SER_ENABLE_REG);
+#endif
+ master_outb(1,EXT_ENABLE_REG);
+
+ /* would be spurious ints by now, q40kbd_init_hw() does that */
+ master_outb(0,KEY_IRQ_ENABLE_REG);
+}
+
+int q40_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *devname, void *dev_id)
+{
+ /*printk("q40_request_irq %d, %s\n",irq,devname);*/
+
+ if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) {
+ printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+ return -ENXIO;
+ }
+
+ /* test for ISA ints not implemented by HW */
+ if (irq<15)
+ {
+ switch (irq){
+ case 1: case 2: case 8: case 9:
+ case 12: case 13:
+ printk("%s: ISA IRQ %d from %s not implemented by HW\n", __FUNCTION__, irq, devname);
+ return -ENXIO;
+ default:
+ }
+ }
+
+ if (irq<Q40_IRQ_TIMER)
+ {
+ if (irq==11) {
+ printk("warning IRQ 10 and 11 not distinguishable\n");
+ irq=10;
+ }
+ if (!(irq_tab[irq].flags & IRQ_FLG_STD))
+ {
+ if (irq_tab[irq].flags & IRQ_FLG_LOCK)
+ {
+ printk("%s: IRQ %d from %s is not replaceable\n",
+ __FUNCTION__, irq, irq_tab[irq].devname);
+ return -EBUSY;
+ }
+ if (flags & IRQ_FLG_REPLACE)
+ {
+ printk("%s: %s can't replace IRQ %d from %s\n",
+ __FUNCTION__, devname, irq, irq_tab[irq].devname);


+ return -EBUSY;
+ }
+ }

+ /*printk("IRQ %d set to handler %p\n",irq,handler);*/
+ irq_tab[irq].handler = handler;
+ irq_tab[irq].flags = flags;
+ irq_tab[irq].dev_id = dev_id;
+ strncpy(irq_tab[irq].devname,devname,DEVNAME_SIZE);
+ return 0;
+ }
+ else {
+ /* Q40_IRQ_TIMER :somewhat special actions required here ..*/
+ sys_request_irq(4,handler,flags,devname,dev_id);
+ sys_request_irq(6,handler,flags,devname,dev_id);
+ return 0;
+ }
+}
+
+void q40_free_irq(unsigned int irq, void *dev_id)
+{
+ if (irq > Q40_IRQ_MAX || (irq>15 && irq<32)) {
+ printk("%s: Incorrect IRQ %d, dev_id %x \n", __FUNCTION__, irq, (unsigned)dev_id);
+ return;
+ }
+
+ /* test for ISA ints not implemented by HW */
+ if (irq<15) {
+ switch (irq){
+ case 1: case 2: case 8: case 9:
+ case 12: case 13:
+ printk("%s: ISA IRQ %d from %x illegal\n", __FUNCTION__, irq, (unsigned)dev_id);
+ return;
+ default:
+ }
+ }
+
+ if (irq<Q40_IRQ_TIMER){
+ if (irq==11) irq=10;
+ if (irq_tab[irq].dev_id != dev_id)
+ printk("%s: Removing probably wrong IRQ %d from %s\n",
+ __FUNCTION__, irq, irq_tab[irq].devname);
+
+ irq_tab[irq].handler = q40_defhand;
+ irq_tab[irq].flags = IRQ_FLG_STD;
+ irq_tab[irq].dev_id = NULL;
+ /* irq_tab[irq].devname = NULL; */
+ } else { /* == Q40_IRQ_TIMER */
+ sys_free_irq(4,dev_id);
+ sys_free_irq(6,dev_id);
+ }
+}
+
+#if 1
+void q40_process_int (int level, struct pt_regs *fp)
+{
+ printk("unexpected interrupt %x\n",level);
+}
+#endif
+
+/*
+ * tables to translate bits into IRQ numbers
+ * it is a good idea to order the entries by priority
+ *
+*/
+
+struct IRQ_TABLE{ unsigned mask; int irq ;};
+
+static struct IRQ_TABLE iirqs[]={
+ {IRQ_FRAME_MASK,Q40_IRQ_FRAME},
+ {IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
+ {0,0}};
+static struct IRQ_TABLE eirqs[]={
+ {IRQ3_MASK,3}, /* ser 1 */
+ {IRQ4_MASK,4}, /* ser 2 */
+ {IRQ14_MASK,14}, /* IDE 1 */
+ {IRQ15_MASK,15}, /* IDE 2 */
+ {IRQ6_MASK,6}, /* floppy */
+ {IRQ7_MASK,7}, /* par */
+
+ {IRQ5_MASK,5},
+ {IRQ10_MASK,10},
+
+
+
+
+ {0,0}};
+
+/* complaiun only this many times about spurious ints : */
+static int ccleirq=60; /* ISA dev IRQ's*/
+static int cclirq=60; /* internal */
+
+/* FIX: add IRQ_INPROGRESS,mask,unmask,probing.... */
+
+void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
+{
+ /* got level 2 interrupt, dispatch to ISA or keyboard IRQs */
+
+ unsigned mir=master_inb(IIRQ_REG);
+ unsigned mer;
+ int irq,i;
+
+ /*
+ * more than 1 bit might be set, must handle atmost 1 int source,
+ * - handle only those with explicitly set handler
+ */
+
+ if ((mir&IRQ_SER_MASK) || (mir&IRQ_EXT_MASK))
+ {
+
+ /* some ISA dev caused the int */
+
+ mer=master_inb(EIRQ_REG);
+
+ for (i=0; eirqs[i].mask; i++)
+ {
+ if (mer&(eirqs[i].mask))
+ {
+ irq=eirqs[i].irq;
+ irq_tab[irq].count++;
+ if (irq_tab[irq].handler == q40_defhand )
+ continue; /* ignore uninited INTs :-( */
+
+ irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
+ return;
+ }
+ }
+ if (ccleirq>0)
+ printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
+ }
+ else
+ {
+ /* internal */
+
+ for (i=0; iirqs[i].mask; i++)
+ {
+ if (mir&(iirqs[i].mask))
+ {
+ irq=iirqs[i].irq;
+ irq_tab[irq].count++;
+ if (irq_tab[irq].handler == q40_defhand )
+ continue; /* ignore uninited INTs :-( */
+
+ irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
+ return;
+ }
+ }
+ if (cclirq>0)
+ printk("internal level 2 interrupt from unknown source ? IIRQ_REG=%x\n",mir),cclirq--;
+ }
+}
+
+int q40_get_irq_list (char *buf)
+{
+ int i, len = 0;
+
+ for (i = 0; i <= Q40_IRQ_MAX; i++) {
+ if (irq_tab[i].count)
+ len += sprintf (buf+len, "Vec 0x%02x: %8d %s%s\n",
+ i, irq_tab[i].count,
+ irq_tab[i].devname[0] ? irq_tab[i].devname : "?",
+ irq_tab[i].handler == q40_defhand ?
+ " (now unassigned)" : "");
+ }
+ return len;
+}
+
+
+static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
+{
+#if 0
+ printk ("Unknown q40 interrupt 0x%02x\n", irq);
+#endif
+}
+static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
+{
+#if 0
+ if (ints_inited)
+#endif
+ printk ("Uninitialised interrupt level %d\n", lev);
+#if 0
+ else
+ printk ("Interrupt before interrupt initialisation\n");
+#endif
+}
+
+ void (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
+ sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
+ sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
+ };
+
+void q40_enable_irq (unsigned int irq)
+{
+}
+
+
+void q40_disable_irq (unsigned int irq)
+{
+}
+
+unsigned long q40_probe_irq_on (void)
+{
+ printk("sorry, irq probing not yet implemented - reconfigure the driver to avoid this\n");
+ return 0;
+}
+int q40_probe_irq_off (unsigned long irqs)
+{
+ return -1;
+}
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/Makefile linux/arch/m68k/sun3x/Makefile
--- v2.2.7/linux/arch/m68k/sun3x/Makefile Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/Makefile Tue May 11 09:57:14 1999
@@ -0,0 +1,14 @@
+#
+# Makefile for Linux arch/m68k/sun3x source directory
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := sun3x.o
+O_OBJS := config.o time.o dvma.o sbus.o
+OX_OBJS :=
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/config.c linux/arch/m68k/sun3x/config.c
--- v2.2.7/linux/arch/m68k/sun3x/config.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/config.c Tue May 11 09:57:14 1999
@@ -0,0 +1,128 @@
+/*
+ * Setup kernel for a Sun3x machine
+ *
+ * (C) 1999 Thomas Bogendoerfer (tsbo...@alpha.franken.de)
+ *
+ * based on code from Oliver Jowett <oli...@jowett.manawatu.gen.nz>
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/sun3x.h>
+
+#include "time.h"
+
+static volatile unsigned char *sun3x_intreg = (unsigned char *)SUN3X_INTREG;
+extern int serial_console;
+
+void sun3x_halt(void)
+{
+ /* Disable interrupts */
+ cli();
+
+ /* we can't drop back to PROM, so we loop here */
+ for (;;);
+}
+
+void sun3x_reboot(void)
+{
+ /* This never returns, don't bother saving things */
+ cli();
+
+ /* no idea, whether this works */
+ asm ("reset");
+}
+
+__initfunc(int sun3x_keyb_init(void))


+{
+ return 0;
+}

+
+int sun3x_kbdrate(struct kbd_repeat *r)


+{
+ return 0;
+}

+
+void sun3x_kbd_leds(unsigned int i)
+{
+
+}
+
+static void sun3x_badint (int irq, void *dev_id, struct pt_regs *fp)
+{
+ printk ("received spurious interrupt %d\n",irq);
+ num_spurious += 1;
+}
+
+void (*sun3x_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+ sun3x_badint, sun3x_badint, sun3x_badint, sun3x_badint,
+ sun3x_badint, sun3x_badint, sun3x_badint, sun3x_badint
+};
+
+void sun3x_enable_irq(unsigned int irq)
+{
+ *sun3x_intreg |= (1 << irq);
+}
+
+void sun3x_disable_irq(unsigned int irq)
+{
+ *sun3x_intreg &= ~(1 << irq);
+}
+
+__initfunc(void sun3x_init_IRQ(void))
+{
+ /* disable all interrupts initially */
+ *sun3x_intreg = 1; /* master enable only */
+}
+
+int sun3x_get_irq_list(char *buf)


+{
+ return 0;
+}

+
+/*
+ * Setup the sun3x configuration info
+ */
+__initfunc(void config_sun3x(void))
+{
+ mach_get_irq_list = sun3x_get_irq_list;
+ mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
+
+ mach_keyb_init = sun3x_keyb_init;
+ mach_kbdrate = sun3x_kbdrate;
+ mach_kbd_leds = sun3x_kbd_leds;
+
+ mach_sched_init = sun3x_sched_init;
+ mach_init_IRQ = sun3x_init_IRQ;
+ enable_irq = sun3x_enable_irq;
+ disable_irq = sun3x_disable_irq;
+ mach_request_irq = sys_request_irq;
+ mach_free_irq = sys_free_irq;
+ mach_default_handler = &sun3x_default_handler;
+ mach_gettimeoffset = sun3x_gettimeoffset;
+ mach_reset = sun3x_reboot;
+
+ mach_gettod = sun3x_gettod;
+
+ switch (*(unsigned char *)SUN3X_EEPROM_CONS) {
+ case 0x10:
+ serial_console = 1;
+ conswitchp = NULL;
+ break;
+ case 0x11:
+ serial_console = 2;
+ conswitchp = NULL;
+ break;
+ default:
+ serial_console = 0;
+ conswitchp = &dummy_con;


+ break;
+ }
+
+}

diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/dvma.c linux/arch/m68k/sun3x/dvma.c
--- v2.2.7/linux/arch/m68k/sun3x/dvma.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/dvma.c Tue May 11 09:57:14 1999
@@ -0,0 +1,162 @@
+/*
+ * Virtual DMA allocation
+ *
+ * (C) 1999 Thomas Bogendoerfer (tsbo...@alpha.franken.de)
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/mm.h>
+
+#include <asm/sun3x.h>
+#include <asm/dvma.h>
+#include <asm/io.h>
+#include <asm/page.h>
+
+/* IOMMU support */
+
+#define IOMMU_ENTRIES 2048
+#define IOMMU_ADDR_MASK 0x03ffe000
+#define IOMMU_CACHE_INHIBIT 0x00000040
+#define IOMMU_FULL_BLOCK 0x00000020
+#define IOMMU_MODIFIED 0x00000010
+#define IOMMU_USED 0x00000008
+#define IOMMU_WRITE_PROTECT 0x00000004
+#define IOMMU_DT_MASK 0x00000003
+#define IOMMU_DT_INVALID 0x00000000
+#define IOMMU_DT_VALID 0x00000001
+#define IOMMU_DT_BAD 0x00000002
+
+#define DVMA_PAGE_SHIFT 13
+#define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT)
+#define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1))
+
+
+static volatile unsigned long *iommu_pte = (unsigned long *)SUN3X_IOMMU;
+static unsigned long iommu_use[IOMMU_ENTRIES];
+static unsigned long iommu_bitmap[IOMMU_ENTRIES/32];
+
+
+#define dvma_entry_paddr(index) (iommu_pte[index] & IOMMU_ADDR_MASK)
+#define dvma_entry_vaddr(index,paddr) ((index << DVMA_PAGE_SHIFT) | \
+ (paddr & (DVMA_PAGE_SIZE-1)))
+#define dvma_entry_set(index,addr) (iommu_pte[index] = \
+ (addr & IOMMU_ADDR_MASK) | \
+ IOMMU_DT_VALID)
+#define dvma_entry_clr(index) (iommu_pte[index] = IOMMU_DT_INVALID)
+#define dvma_entry_use(index) (iommu_use[index])
+#define dvma_entry_inc(index) (iommu_use[index]++)
+#define dvma_entry_dec(index) (iommu_use[index]--)
+#define dvma_entry_hash(addr) ((addr >> DVMA_PAGE_SHIFT) ^ \
+ ((addr & 0x03c00000) >> \
+ (DVMA_PAGE_SHIFT+4)))
+#define dvma_map iommu_bitmap
+#define dvma_map_size (IOMMU_ENTRIES/2)
+#define dvma_slow_offset (IOMMU_ENTRIES/2)
+#define dvma_is_slow(addr) ((addr) & \
+ (dvma_slow_offset << DVMA_PAGE_SHIFT))
+
+static int fixed_dvma;
+
+void __init dvma_init(void)
+{
+ unsigned long tmp;
+
+ if ((unsigned long)high_memory < (IOMMU_ENTRIES << DVMA_PAGE_SHIFT)) {
+ printk ("Sun3x fixed DVMA mapping\n");
+ fixed_dvma = 1;
+ for (tmp = 0; tmp < (unsigned long)high_memory; tmp += DVMA_PAGE_SIZE)
+ dvma_entry_set (tmp >> DVMA_PAGE_SHIFT, virt_to_phys((void *)tmp));
+ fixed_dvma = 1;
+ } else {
+ printk ("Sun3x variable DVMA mapping\n");
+ for (tmp = 0; tmp < IOMMU_ENTRIES; tmp++)
+ dvma_entry_clr (tmp);
+ fixed_dvma = 0;
+ }
+}
+
+unsigned long dvma_slow_alloc (unsigned long paddr, int npages)
+{
+ int scan, base;
+
+ scan = 0;
+ for (;;) {
+ scan = find_next_zero_bit(dvma_map, dvma_map_size, scan);
+ if ((base = scan) + npages > dvma_map_size) {
+ printk ("dvma_slow_alloc failed for %d pages\n",npages);
+ return 0;
+ }
+ for (;;) {
+ if (scan >= base + npages) goto found;
+ if (test_bit(scan, dvma_map)) break;
+ scan++;
+ }
+ }
+
+found:
+ for (scan = base; scan < base+npages; scan++) {
+ dvma_entry_set(scan+dvma_slow_offset, paddr);
+ paddr += DVMA_PAGE_SIZE;
+ set_bit(scan, dvma_map);
+ }
+ return (dvma_entry_vaddr((base+dvma_slow_offset),paddr));
+}
+
+unsigned long dvma_alloc (unsigned long paddr, unsigned long size)
+{
+ int index;
+ int pages = ((paddr & ~DVMA_PAGE_MASK) + size + (DVMA_PAGE_SIZE-1)) >>
+ DVMA_PAGE_SHIFT;
+
+ if (fixed_dvma)
+ return ((unsigned long)phys_to_virt (paddr));
+
+ if (pages > 1) /* multi page, allocate from slow pool */
+ return dvma_slow_alloc (paddr, pages);
+
+ index = dvma_entry_hash (paddr);
+
+ if (dvma_entry_use(index)) {
+ if (dvma_entry_paddr(index) == (paddr & DVMA_PAGE_MASK)) {
+ dvma_entry_inc(index);
+ return dvma_entry_vaddr(index,paddr);
+ }
+ /* collision, allocate from slow pool */
+ return dvma_slow_alloc (paddr, pages);
+ }
+
+ dvma_entry_set(index,paddr);
+ dvma_entry_inc(index);
+ return dvma_entry_vaddr(index,paddr);
+}
+
+void dvma_free (unsigned long dvma_addr, unsigned long size)
+{
+ int npages;
+ int index;
+
+ if (fixed_dvma)
+ return;
+
+ if (!dvma_is_slow(dvma_addr)) {
+ index = (dvma_addr >> DVMA_PAGE_SHIFT);
+ if (dvma_entry_use(index) == 0) {
+ printk ("dvma_free: %lx entry already free\n",dvma_addr);
+ return;
+ }
+ dvma_entry_dec(index);
+ if (dvma_entry_use(index) == 0)
+ dvma_entry_clr(index);
+ return;
+ }
+
+ /* free in slow pool */
+ npages = ((dvma_addr & ~DVMA_PAGE_MASK) + size + (DVMA_PAGE_SIZE-1)) >>
+ DVMA_PAGE_SHIFT;
+ for (index = (dvma_addr >> DVMA_PAGE_SHIFT); npages--; index++) {
+ dvma_entry_clr(index);
+ clear_bit (index,dvma_map);
+ }
+}
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/sbus.c linux/arch/m68k/sun3x/sbus.c
--- v2.2.7/linux/arch/m68k/sun3x/sbus.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/sbus.c Tue May 11 09:57:14 1999
@@ -0,0 +1,44 @@
+/*
+ * SBus helper functions
+ *
+ * Sun3x don't have a sbus, but many of the used devices are also
+ * used on Sparc machines with sbus. To avoid having a lot of
+ * duplicate code, we provide necessary glue stuff to make using
+ * of the sbus driver code possible.
+ *
+ * (C) 1999 Thomas Bogendoerfer (tsbo...@alpha.franken.de)
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+__initfunc(void sbus_init(void))
+{
+
+}
+
+void *sparc_alloc_io (u32 address, void *virtual, int len, char *name,
+ u32 bus_type, int rdonly)
+{
+ return (void *)address;
+}
+
+int prom_getintdefault(int node, char *property, int deflt)
+{
+ return deflt;
+}
+
+int prom_getbool (int node, char *prop)
+{
+ return 1;
+}
+
+void prom_printf(char *fmt, ...)
+{
+
+}
+
+void prom_halt (void)
+{
+
+}
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/time.c linux/arch/m68k/sun3x/time.c
--- v2.2.7/linux/arch/m68k/sun3x/time.c Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/time.c Tue May 11 09:57:14 1999
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/m68k/sun3x/time.c
+ *
+ * Sun3x-specific time handling
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/sun3x.h>
+
+#include "time.h"
+
+#define M_CONTROL 0xf8
+#define M_SEC 0xf9
+#define M_MIN 0xfa
+#define M_HOUR 0xfb
+#define M_DAY 0xfc
+#define M_DATE 0xfd
+#define M_MONTH 0xfe
+#define M_YEAR 0xff
+
+#define C_WRITE 0x80
+#define C_READ 0x40
+#define C_SIGN 0x20
+#define C_CALIB 0x1f
+
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+
+/* Read the Mostek */
+void sun3x_gettod (int *yearp, int *monp, int *dayp,
+ int *hourp, int *minp, int *secp)
+{
+ volatile unsigned char *eeprom = (unsigned char *)SUN3X_EEPROM;
+
+ /* Stop updates */
+ *(eeprom + M_CONTROL) |= C_READ;
+
+ /* Read values */
+ *yearp = BCD_TO_BIN(*(eeprom + M_YEAR));
+ *monp = BCD_TO_BIN(*(eeprom + M_MONTH));
+ *dayp = BCD_TO_BIN(*(eeprom + M_DATE));
+ *hourp = BCD_TO_BIN(*(eeprom + M_HOUR));
+ *minp = BCD_TO_BIN(*(eeprom + M_MIN));
+ *secp = BCD_TO_BIN(*(eeprom + M_SEC));
+
+ /* Restart updates */
+ *(eeprom + M_CONTROL) &= ~C_READ;
+}
+
+/* Not much we can do here */
+unsigned long sun3x_gettimeoffset (void)
+{
+ return 0L;
+}
+
+static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
+{
+ void (*vector)(int, void *, struct pt_regs *) = dev_id;
+
+ /* Clear the pending interrupt - pulse the enable line low */
+ disable_irq(5);
+ enable_irq(5);
+
+ vector(irq, NULL, regs);
+}
+
+__initfunc(void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *)))
+{
+ sys_request_irq(5, sun3x_timer_tick, IRQ_FLG_STD, "timer tick", vector);
+
+ /* Pulse enable low to get the clock started */
+ disable_irq(5);
+ enable_irq(5);
+}
diff -u --recursive --new-file v2.2.7/linux/arch/m68k/sun3x/time.h linux/arch/m68k/sun3x/time.h
--- v2.2.7/linux/arch/m68k/sun3x/time.h Wed Dec 31 16:00:00 1969
+++ linux/arch/m68k/sun3x/time.h Tue May 11 09:57:14 1999
@@ -0,0 +1,9 @@
+#ifndef SUN3X_TIME_H
+#define SUN3X_TIME_H
+
+void sun3x_gettod (int *yearp, int *monp, int *dayp,
+ int *hourp, int *minp, int *secp);
+unsigned long sun3x_gettimeoffset (void);
+void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *));
+
+#endif
diff -u --recursive --new-file v2.2.7/linux/arch/mips/kernel/irixioctl.c linux/arch/mips/kernel/irixioctl.c
--- v2.2.7/linux/arch/mips/kernel/irixioctl.c Fri Oct 23 22:01:19 1998
+++ linux/arch/mips/kernel/irixioctl.c Sat May 8 11:14:01 1999
@@ -33,13 +33,15 @@
X {
X struct file *filp;
X
- if(fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+ file = fcheck(fd);
+ if(!file)
X return ((struct tty_struct *) 0);
X if(filp->private_data) {
X struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
X
- if(ttyp->magic == TTY_MAGIC)
+ if(ttyp->magic == TTY_MAGIC) {
X return ttyp;
+ }
X }
X return ((struct tty_struct *) 0);
X }
diff -u --recursive --new-file v2.2.7/linux/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- v2.2.7/linux/arch/mips/kernel/sysirix.c Tue Mar 23 14:35:46 1999
+++ linux/arch/mips/kernel/sysirix.c Sat May 8 11:14:01 1999
@@ -23,6 +23,7 @@
X #include <linux/smp.h>
X #include <linux/smp_lock.h>
X #include <linux/utsname.h>
+#include <linux/file.h>
X
X #include <asm/ptrace.h>
X #include <asm/page.h>
@@ -734,6 +735,7 @@
X int error, i;
X
X /* We don't support this feature yet. */
+ lock_kernel();
X if(fs_type) {
X error = -EINVAL;
X goto out;
@@ -776,7 +778,6 @@
X
X asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
X {
- struct dentry *dentry;
X struct inode *inode;
X struct statfs kbuf;
X mm_segment_t old_fs;
@@ -787,25 +788,22 @@
X error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
X if (error)
X goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (!(file = fget(fd))) {
X error = -EBADF;
X goto out;
X }
- if (!(dentry = file->f_dentry)) {
+
+ if (!(inode = file->f_dentry->d_inode)) {
X error = -ENOENT;
- goto out;
- }
- if (!(inode = dentry->d_inode)) {
- error = -ENOENT;
- goto out;
+ goto out_f;
X }
X if (!inode->i_sb) {
X error = -ENODEV;
- goto out;
+ goto out_f;
X }
X if (!inode->i_sb->s_op->statfs) {
X error = -ENOSYS;
- goto out;
+ goto out_f;
X }
X
X old_fs = get_fs(); set_fs(get_ds());
@@ -813,7 +811,7 @@
X sizeof(struct statfs));
X set_fs(old_fs);
X if (error)
- goto out;
+ goto out_f;
X
X __put_user(kbuf.f_type, &buf->f_type);
X __put_user(kbuf.f_bsize, &buf->f_bsize);
@@ -826,9 +824,9 @@
X __put_user(0, &buf->f_fname[i]);
X __put_user(0, &buf->f_fpack[i]);
X }
- error = 0;
X
- dput(dentry);
+out_f:
+ fput(file);
X out:
X unlock_kernel();
X return error;
@@ -1110,7 +1108,7 @@
X
X lock_kernel();
X if(!(flags & MAP_ANONYMOUS)) {
- if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if(!(file = fget(fd))) {
X retval = -EBADF;
X goto out;
X }
@@ -1130,6 +1128,8 @@
X flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
X
X retval = do_mmap(file, addr, len, prot, flags, offset);
+ if (file)
+ fput(file);
X
X out:
X unlock_kernel();
@@ -1568,7 +1568,6 @@
X
X asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
X {
- struct dentry *dentry;
X struct inode *inode;
X mm_segment_t old_fs;
X struct statfs kbuf;
@@ -1582,21 +1581,21 @@
X error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
X if (error)
X goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (!(file = fget(fd))) {
X error = -EBADF;
X goto out;
X }
- if (!(dentry = file->f_dentry)) {
+ if (!(inode = file->f_dentry->d_inode)) {
X error = -ENOENT;
- goto out;
+ goto out_f;
X }
- if (!(inode = dentry->d_inode)) {
- error = -ENOENT;
- goto out;
+ if (!inode->i_sb) {
+ error = -ENODEV;
+ goto out_f;
X }
X if (!inode->i_sb->s_op->statfs) {
X error = -ENOSYS;
- goto out;
+ goto out_f;
X }
X
X old_fs = get_fs(); set_fs(get_ds());
@@ -1604,7 +1603,7 @@
X sizeof(struct statfs));
X set_fs(old_fs);
X if (error)
- goto out;
+ goto out_f;
X
X __put_user(kbuf.f_bsize, &buf->f_bsize);
X __put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1626,9 +1625,8 @@
X for(i = 0; i < 32; i++)
X __put_user(0, &buf->f_fstr[i]);
X
- error = 0;
-
- dput(dentry);
+out_f:
+ fput(file);
X out:
X unlock_kernel();
X return error;
@@ -1726,7 +1724,7 @@
X }
X
X if(!(flags & MAP_ANONYMOUS)) {
- if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if(!(file = fcheck(fd))) {
X error = -EBADF;
X goto out;
X }
@@ -1812,6 +1810,7 @@
X struct statfs kbuf;
X int error, i;
X
+ lock_kernel();
X printk("[%s:%ld] Wheee.. irix_statvfs(%s,%p)\n",
X current->comm, current->pid, fname, buf);
X error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
@@ -1864,7 +1863,6 @@
X
X asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
X {
- struct dentry *dentry;
X struct inode *inode;
X mm_segment_t old_fs;
X struct statfs kbuf;
@@ -1878,21 +1876,21 @@
X error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
X if (error)
X goto out;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+ if (!(file = fget(fd))) {
X error = -EBADF;
X goto out;
X }
- if (!(dentry = file->f_dentry)) {
+ if (!(inode = file->f_dentry->d_inode)) {
X error = -ENOENT;
- goto out;
+ goto out_f;
X }
- if (!(inode = dentry->d_inode)) {
- error = -ENOENT;
- goto out;
+ if (!inode->i_sb) {
+ error = -ENODEV;
+ goto out_f;
X }
X if (!inode->i_sb->s_op->statfs) {
X error = -ENOSYS;
- goto out;
+ goto out_f;
X }
X
X old_fs = get_fs(); set_fs(get_ds());
@@ -1900,7 +1898,7 @@
X sizeof(struct statfs));
X set_fs(old_fs);
X if (error)
- goto out;
+ goto out_f;
X
X __put_user(kbuf.f_bsize, &buf->f_bsize);
X __put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1921,10 +1919,8 @@
X __put_user(kbuf.f_namelen, &buf->f_namemax);
X for(i = 0; i < 32; i++)
X __put_user(0, &buf->f_fstr[i]);
-
- error = 0;
-
- dput(dentry);
+out_f:
+ fput(file);
X out:
X unlock_kernel();
X return error;
@@ -1994,7 +1990,6 @@
X unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
X int retval;
X
- lock_kernel();
X #ifdef DEBUG_GETDENTS
X printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
X reclen, namlen, buf->count);
@@ -2020,14 +2015,12 @@
X retval = 0;
X
X out:
- unlock_kernel();
X return retval;
X }
X
X asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
X {
X struct file *file;
- struct dentry *dentry;
X struct inode *inode;
X struct irix_dirent32 *lastdirent;
X struct irix_dirent32_callback buf;
@@ -2039,46 +2032,56 @@
X current->pid, fd, dirent, count, eob);
X #endif
X error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+ file = fget(fd);
+ if (!file)
X goto out;
X
- dentry = file->f_dentry;
- if (!dentry)
- goto out;
+ inode = file->f_dentry->d_inode;
+ if (!inode)
+ goto out_putf;
X
X inode = dentry->d_inode;
X if (!inode)
- goto out;
+ goto out_putf;
X
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out;
-
- error = -EFAULT;
- if(!access_ok(VERIFY_WRITE, dirent, count) ||
- !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
- goto out;
-
- __put_user(0, eob);
X buf.current_dir = (struct irix_dirent32 *) dirent;
X buf.previous = NULL;
X buf.count = count;
X buf.error = 0;
X
+ error = -ENOTDIR;
+ if (!file->f_op || !file->f_op->readdir)
+ goto out_putf;
+
+ /*
+ * Get the inode's semaphore to prevent changes
+ * to the directory while we read it.
+ */
+ down(&inode->i_sem);
X error = file->f_op->readdir(file, &buf, irix_filldir32);
+ up(&inode->i_sem);
X if (error < 0)
- goto out;
+ goto out_putf;
+ error = buf.error;
X lastdirent = buf.previous;
- if (!lastdirent) {
- error = buf.error;
- goto out;
+ if (lastdirent) {
+ put_user(file->f_pos, &lastdirent->d_off);
+ error = count - buf.count;
X }
- lastdirent->d_off = (u32) file->f_pos;
+
+ if (put_user(0, eob) < 0) {
+ error = EFAULT;
+ goto out_putf;
+ }
+
+
X #ifdef DEBUG_GETDENTS
X printk("eob=%d returning %d\n", *eob, count - buf.count);
X #endif
X error = count - buf.count;
X
+out_putf:
+ fput(file);
X out:
X unlock_kernel();
X return error;
@@ -2110,7 +2113,6 @@
X unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
X int retval;
X
- lock_kernel();
X buf->error = -EINVAL; /* only used if we fail.. */
X if (reclen > buf->count) {
X retval = -EINVAL;
@@ -2131,14 +2133,12 @@
X
X retval = 0;
X out:
- unlock_kernel();
X return retval;
X }
X
X asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
X {
X struct file *file;
- struct dentry *dentry;
X struct inode *inode;
X struct irix_dirent64 *lastdirent;
X struct irix_dirent64_callback buf;
@@ -2150,40 +2150,38 @@
X current->pid, fd, dirent, cnt);
X #endif
X error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- goto out;
-
- dentry = file->f_dentry;
- if (!dentry)
+ if (!(file = fget(fd)))
X goto out;
X
- inode = dentry->d_inode;
+ inode = file->f_dentry->d_inode;
X if (!inode)
- goto out;
+ goto out_f;
X
X error = -ENOTDIR;
X if (!file->f_op || !file->f_op->readdir)


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 07'
echo 'File patch-2.2.8 is continued in part 08'
echo 08 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part08

#!/bin/sh
# this is part 08 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 08; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

- goto out;
+ goto out_f;
X

X error = -EFAULT;
X if(!access_ok(VERIFY_WRITE, dirent, cnt))


- goto out;
+ goto out_f;
X

X error = -EINVAL;
X if(cnt < (sizeof(struct irix_dirent64) + 255))


- goto out;
+ goto out_f;
X

X buf.curr = (struct irix_dirent64 *) dirent;
X buf.previous = NULL;
X buf.count = cnt;
X buf.error = 0;
+ down(&inode->i_sem);
X error = file->f_op->readdir(file, &buf, irix_filldir64);


+ up(&inode->i_sem);
X if (error < 0)
- goto out;

+ goto out_f;
X lastdirent = buf.previous;
X if (!lastdirent) {
X error = buf.error;
- goto out;
+ goto out_f;
X }
X lastdirent->d_off = (u64) file->f_pos;
X #ifdef DEBUG_GETDENTS
@@ -2191,6 +2189,8 @@
X #endif
X error = cnt - buf.count;
X

+out_f:
+ fput(file);
X out:
X unlock_kernel();
X return error;

@@ -2199,7 +2199,6 @@
X asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)


X {
X struct file *file;
- struct dentry *dentry;
X struct inode *inode;

X struct irix_dirent64 *lastdirent;
X struct irix_dirent64_callback buf;

@@ -2211,42 +2210,40 @@


X current->pid, fd, dirent, cnt);
X #endif
X error = -EBADF;
- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
- goto out;
-
- dentry = file->f_dentry;
- if (!dentry)
+ if (!(file = fget(fd)))
X goto out;
X
- inode = dentry->d_inode;
+ inode = file->f_dentry->d_inode;
X if (!inode)
- goto out;
+ goto out_f;
X
X error = -ENOTDIR;
X if (!file->f_op || !file->f_op->readdir)
- goto out;
+ goto out_f;
X

X error = -EFAULT;
X if(!access_ok(VERIFY_WRITE, dirent, cnt) ||
X !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
- goto out;
+ goto out_f;
X
X error = -EINVAL;
X if(cnt < (sizeof(struct irix_dirent64) + 255))


- goto out;
+ goto out_f;
X

X *eob = 0;
X buf.curr = (struct irix_dirent64 *) dirent;
X buf.previous = NULL;
X buf.count = cnt;
X buf.error = 0;
+ down(&inode->i_sem);
X error = file->f_op->readdir(file, &buf, irix_filldir64);


+ up(&inode->i_sem);
X if (error < 0)
- goto out;

+ goto out_f;
X lastdirent = buf.previous;
X if (!lastdirent) {
X error = buf.error;
- goto out;
+ goto out_f;
X }
X lastdirent->d_off = (u64) file->f_pos;
X #ifdef DEBUG_GETDENTS
@@ -2254,6 +2251,8 @@
X #endif
X error = cnt - buf.count;
X

+out_f:
+ fput(file);
X out:
X unlock_kernel();
X return error;

diff -u --recursive --new-file v2.2.7/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v2.2.7/linux/arch/ppc/boot/Makefile Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/boot/Makefile Thu Apr 29 12:39:01 1999
@@ -14,7 +14,7 @@
X .s.o:
X $(AS) -o $*.o $<
X .c.o:
- $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $<
+ $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $<
X .S.s:
X $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
X .S.o:
@@ -57,7 +57,7 @@
X -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \
X -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \
X -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \
- -DKERNELBASE=$(KERNELBASE) -c -o misc.o misc.c
+ -c -o misc.o misc.c
X $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
X $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
X --add-section=initrd=ramdisk.image.gz \
@@ -84,7 +84,7 @@
X #
X $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
X -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux image` \
- -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` -DKERNELBASE=$(KERNELBASE) \
+ -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \
X -c -o misc.o misc.c
X $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
X $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
@@ -95,7 +95,7 @@
X dd if=zImage of=/dev/fd0H1440 bs=64b
X
X mkprep : mkprep.c
- $(HOSTCC) -DKERNELBASE=$(KERNELBASE) -o mkprep mkprep.c
+ $(HOSTCC) -o mkprep mkprep.c
X
X znetboot : zImage
X cp zImage $(TFTPIMAGE)
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/boot/head.S linux/arch/ppc/boot/head.S
--- v2.2.7/linux/arch/ppc/boot/head.S Fri Apr 16 14:47:30 1999
+++ linux/arch/ppc/boot/head.S Thu Apr 29 12:39:01 1999
@@ -6,7 +6,7 @@
X .text
X
X /*
- * $Id: head.S,v 1.29 1999/03/08 23:41:17 cort Exp $
+ * $Id: head.S,v 1.31 1999/04/22 06:32:00 davem Exp $
X *
X * Boot loader philosophy:
X * ROM loads us to some arbitrary location
@@ -23,11 +23,7 @@
X start_:
X mr r11,r3 /* Save pointer to residual/board data */
X mr r25,r5 /* Save OFW pointer */
-
- mfmsr r3 /* Turn off interrupts */
- li r4,0
- ori r4,r4,MSR_EE
- andc r3,r3,r4
+ li r3,MSR_IP /* Establish default MSR value */
X mtmsr r3
X
X /* check if we need to relocate ourselves to the link addr or were we
@@ -136,6 +132,20 @@
X lis r10,0xdeadc0de@h
X ori r10,r10,0xdeadc0de@l
X stw r10,0(r9)
+/*
+ * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2
+ * so disable BATs before setting this to avoid a clash
+ */
+ li r8,0
+ mtspr DBAT0U,r8
+ mtspr DBAT1U,r8
+ mtspr DBAT2U,r8
+ mtspr DBAT3U,r8
+ mtspr IBAT0U,r8
+ mtspr IBAT1U,r8
+ mtspr IBAT2U,r8
+ mtspr IBAT3U,r8
+
X blr
X hang:
X b hang
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/boot/kbd.c linux/arch/ppc/boot/kbd.c
--- v2.2.7/linux/arch/ppc/boot/kbd.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/boot/kbd.c Thu Apr 29 12:39:01 1999
@@ -127,6 +127,11 @@
X unsigned char c;
X int i;
X
+ /* flush input queue */
+ while ((inb(KBSTATP) & KBINRDY))
+ {
+ (void)inb(KBDATAP);
+ }
X /* Send self-test */
X while (inb(KBSTATP) & KBOUTRDY) ;
X outb(KBSTATP,0xAA);
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/boot/misc.c linux/arch/ppc/boot/misc.c
--- v2.2.7/linux/arch/ppc/boot/misc.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/boot/misc.c Tue May 11 08:24:32 1999
@@ -1,7 +1,7 @@
X /*
X * misc.c
X *
- * $Id: misc.c,v 1.61 1999/03/08 23:51:02 cort Exp $
+ * $Id: misc.c,v 1.64 1999/04/30 05:52:46 cort Exp $
X *
X * Adapted for PowerPC by Gary Thomas
X *
@@ -33,14 +33,16 @@
X char *end_avail;
X extern char _end[];
X
-#if defined(CONFIG_SERIAL_CONSOLE)
-char cmd_preset[] = "console=ttyS0,9600n8";
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
X #else
-char cmd_preset[] = "";
+#define CMDLINE "";
X #endif
-char cmd_buf[256];
-char *cmd_line = cmd_buf;
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
X
+int keyb_present = 1; /* keyboard controller is present by default */
X RESIDUAL hold_resid_buf;
X RESIDUAL *hold_residual = &hold_resid_buf;
X unsigned long initrd_start = 0, initrd_end = 0;
@@ -58,7 +60,8 @@
X void * memcpy(void * __dest, __const void * __src,
X int __n);
X void gunzip(void *, int, unsigned char *, int *);
-int _cvt(unsigned long val, char *buf, long radix, char *digits);
+static int _cvt(unsigned long val, char *buf, long radix, char *digits);
+unsigned char inb(int);
X
X void pause()
X {
@@ -93,11 +96,14 @@
X
X tstc(void)
X {
- return (
X #if defined(CONFIG_SERIAL_CONSOLE)
- NS16550_tstc(com_port) ||
+ if (keyb_present)
+ return (CRT_tstc() || NS16550_tstc(com_port));
+ else
+ NS16550_tstc(com_port);
+#else
+ return (CRT_tstc() );
X #endif /* CONFIG_SERIAL_CONSOLE */
- CRT_tstc());
X }
X
X getc(void)
@@ -106,7 +112,8 @@
X #if defined(CONFIG_SERIAL_CONSOLE)
X if (NS16550_tstc(com_port)) return (NS16550_getc(com_port));
X #endif /* CONFIG_SERIAL_CONSOLE */
- if (CRT_tstc()) return (CRT_getc());
+ if (keyb_present)
+ if (CRT_tstc()) return (CRT_getc());
X }
X }
X
@@ -188,6 +195,8 @@
X }
X }
X
+ cursor(x, y);
+
X orig_x = x;
X orig_y = y;
X }
@@ -317,6 +326,8 @@
X int dev_handle;
X int mem_info[2];
X int res, size;
+ unsigned char board_type;
+ unsigned char base_mod;
X
X lines = 25;
X cols = 80;
@@ -333,14 +344,31 @@
X flush_instruction_cache();
X _put_HID0(_get_HID0() & ~0x0000C000);
X _put_MSR((orig_MSR = _get_MSR()) & ~0x0030);
- vga_init(0xC0000000);
X
X #if defined(CONFIG_SERIAL_CONSOLE)
- com_port = (struct NS16550 *)NS16550_init(1);
+ com_port = (struct NS16550 *)NS16550_init(0);
X #endif /* CONFIG_SERIAL_CONSOLE */
+ vga_init(0xC0000000);
X
X if (residual)
X {
+ /* Is this Motorola PPCBug? */
+ if ((1 & residual->VitalProductData.FirmwareSupports) &&
+ (1 == residual->VitalProductData.FirmwareSupplier)) {
+ board_type = inb(0x800) & 0xF0;
+
+ /* If this is genesis 2 board then check for no
+ * keyboard controller and more than one processor.
+ */
+ if (board_type == 0xe0) {
+ base_mod = inb(0x803);
+ /* if a MVME2300/2400 or a Sitka then no keyboard */
+ if((base_mod == 0x9) || (base_mod == 0xF9) ||
+ (base_mod == 0xE1)) {
+ keyb_present = 0; /* no keyboard */
+ }
+ }
+ }
X memcpy(hold_residual,residual,sizeof(RESIDUAL));
X } else {
X /* Assume 32M in the absence of more info... */
@@ -429,7 +457,7 @@
X avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
X puts("zimage at: "); puthex((unsigned long)zimage_start);
X puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n");
- if ( (unsigned long)zimage_start <= 0x008000000 )
+ if ( (unsigned long)zimage_start <= 0x00800000 )
X {
X memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size );
X zimage_start = (char *)avail_ram;
@@ -444,6 +472,7 @@
X {
X puts("initrd at: "); puthex(initrd_start);
X puts(" "); puthex(initrd_end); puts("\n");
+#ifdef OMIT
X avail_ram = (char *)PAGE_ALIGN(
X (unsigned long)zimage_size+(unsigned long)zimage_start);
X memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE );
@@ -451,6 +480,7 @@
X initrd_end = initrd_start + INITRD_SIZE;
X puts("relocated to: "); puthex(initrd_start);
X puts(" "); puthex(initrd_end); puts("\n");
+#endif
X }
X
X avail_ram = (char *)0x00400000;
@@ -458,9 +488,8 @@
X puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" ");
X puthex((unsigned long)end_avail); puts("\n");
X
-#if !defined(CONFIG_SERIAL_CONSOLE)
- CRT_tstc(); /* Forces keyboard to be initialized */
-#endif
+ if (keyb_present)
+ CRT_tstc(); /* Forces keyboard to be initialized */
X
X puts("\nLinux/PPC load: ");
X timer = 0;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/boot/mkprep.c linux/arch/ppc/boot/mkprep.c
--- v2.2.7/linux/arch/ppc/boot/mkprep.c Mon Oct 5 13:13:36 1998
+++ linux/arch/ppc/boot/mkprep.c Thu Apr 29 12:39:01 1999
@@ -14,15 +14,8 @@
X * Modified for x86 hosted builds by Matt Porter <por...@neta.com>
X */
X
-#ifdef linux
-#include <linux/types.h>
-/*#include <asm/stat.h>*/
-/*#include <asm/byteorder.h>*/ /* the byte swap funcs don't work here -- Cort */
-#else
X #include <unistd.h>
-#endif
X #include <sys/stat.h>
-
X #include <stdio.h>
X #include <errno.h>
X
@@ -168,10 +161,10 @@
X /* set entry point and boot image size skipping over elf header */
X #ifdef __i386__
X *entry = 0x400/*+65536*/;
- *length = info.st_size+0x400;
+ *length = info.st_size-elfhdr_size+0x400;
X #else
X *entry = cpu_to_le32(0x400/*+65536*/);
- *length = cpu_to_le32(info.st_size+0x400);
+ *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
X #endif /* __i386__ */
X
X /* sets magic number for msdos partition (used by linux) */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.2.7/linux/arch/ppc/common_defconfig Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/common_defconfig Tue May 11 08:24:32 1999
@@ -1,5 +1,5 @@
X #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
X #
X
X #
@@ -42,13 +42,13 @@
X CONFIG_MAC_KEYBOARD=y
X CONFIG_MAC_FLOPPY=y
X CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
X CONFIG_ADBMOUSE=y
-CONFIG_BLK_DEV_IDE_PMAC=y
X CONFIG_PROC_DEVICETREE=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
X # CONFIG_TOTALMP is not set
X CONFIG_BOOTX_TEXT=y
+# CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
X
X #
X # Plug and Play support
@@ -60,6 +60,10 @@
X #
X # CONFIG_BLK_DEV_FD is not set
X CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
X # CONFIG_BLK_DEV_HD_IDE is not set
X CONFIG_BLK_DEV_IDEDISK=y
X CONFIG_BLK_DEV_IDECD=y
@@ -70,8 +74,14 @@
X # CONFIG_BLK_DEV_RZ1000 is not set
X # CONFIG_BLK_DEV_IDEPCI is not set
X # CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDE_PMAC=y
+# CONFIG_BLK_DEV_IDEDMA_PMAC is not set
X # CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
X # CONFIG_BLK_DEV_NBD is not set
X # CONFIG_BLK_DEV_MD is not set
X CONFIG_BLK_DEV_RAM=y
@@ -101,10 +111,17 @@
X # CONFIG_IP_MROUTE is not set
X CONFIG_IP_ALIAS=y
X # CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
X CONFIG_INET_RARP=y
-CONFIG_IP_NOSR=y
X CONFIG_SKB_LARGE=y
X # CONFIG_IPV6 is not set
+
+#
+#
+#
X # CONFIG_IPX is not set
X CONFIG_ATALK=m
X # CONFIG_X25 is not set
@@ -126,12 +143,20 @@
X # SCSI support
X #
X CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
X CONFIG_BLK_DEV_SD=y
X CONFIG_CHR_DEV_ST=y
X CONFIG_BLK_DEV_SR=y
X CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
X CONFIG_SCSI_CONSTANTS=y
X # CONFIG_SCSI_LOGGING is not set
X
@@ -159,10 +184,15 @@
X # CONFIG_SCSI_FUTURE_DOMAIN is not set
X # CONFIG_SCSI_GDTH is not set
X # CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_G_NCR5380_PORT is not set
+# CONFIG_SCSI_G_NCR5380_MEM is not set
X # CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
X # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
X # CONFIG_SCSI_NCR53C7xx is not set
X CONFIG_SCSI_NCR53C8XX=y
+# CONFIG_SCSI_SYM53C8XX is not set
X CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
X CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
X CONFIG_SCSI_NCR53C8XX_SYNC=20
@@ -175,6 +205,7 @@
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set
X # CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set
@@ -205,7 +236,7 @@
X # CONFIG_ACENIC is not set
X # CONFIG_NET_ISA is not set
X CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
X # CONFIG_AC3200 is not set
X # CONFIG_APRICOT is not set
X # CONFIG_CS89x0 is not set
@@ -229,6 +260,10 @@
X # CONFIG_COPS is not set
X # CONFIG_IPDDP is not set
X CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
X # CONFIG_SLIP is not set
X # CONFIG_NET_RADIO is not set
X # CONFIG_TR is not set
@@ -256,22 +291,37 @@
X # Console drivers
X #
X CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_PM2 is not set
X CONFIG_FB_OF=y
X CONFIG_FB_CONTROL=y
X CONFIG_FB_PLATINUM=y
X CONFIG_FB_VALKYRIE=y
-CONFIG_FB_ATY=y
+# CONFIG_FB_ATY is not set
X CONFIG_FB_IMSTT=y
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
X CONFIG_FBCON_CFB8=y
X CONFIG_FBCON_CFB16=y
X CONFIG_FBCON_CFB24=y
X CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA is not set
X # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
X CONFIG_FBCON_FONTS=y
X # CONFIG_FONT_8x8 is not set
@@ -287,12 +337,22 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
+CONFIG_SERIAL=m
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
X # CONFIG_NVRAM is not set
@@ -307,11 +367,20 @@
X # Joystick support
X #
X # CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
X
X #
X # Ftape, the floppy tape device driver
X #
X # CONFIG_FTAPE is not set
+# CONFIG_FT_NORMAL_DEBUG is not set
+# CONFIG_FT_FULL_DEBUG is not set
+# CONFIG_FT_NO_TRACE is not set
+# CONFIG_FT_NO_TRACE_AT_ALL is not set
+# CONFIG_FT_STD_FDC is not set
+# CONFIG_FT_MACH2 is not set
+# CONFIG_FT_PROBE_FC10 is not set
+# CONFIG_FT_ALT_FDC is not set
X
X #
X # Filesystems
@@ -402,3 +471,10 @@
X # CONFIG_SOUND_MSNDCLAS is not set
X # CONFIG_SOUND_MSNDPIN is not set
X # CONFIG_SOUND_OSS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.2.7/linux/arch/ppc/config.in Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/config.in Tue May 11 08:24:32 1999
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.84 1999/02/23 08:08:38 davem Exp $
+# $Id: config.in,v 1.92 1999/04/30 05:41:43 cort Exp $
X # For a description of the syntax of this configuration file,
X # see the Configure script.
X #
@@ -19,12 +19,10 @@
X APUS CONFIG_APUS \
X MBX CONFIG_MBX" PowerMac
X
+bool 'Symmetric multi-processing support' CONFIG_SMP
X if [ "$CONFIG_ALL_PPC" != "y" ];then
X define_bool CONFIG_MACH_SPECIFIC y
X fi
-
-bool 'Symmetric multi-processing support' CONFIG_SMP
-
X endmenu
X
X if [ "$CONFIG_MBX" = "y" ];then
@@ -82,13 +80,20 @@
X bool 'Support for PowerMac keyboard' CONFIG_MAC_KEYBOARD
X bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY
X bool 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL
+if [ "$CONFIG_MAC_SERIAL" = "y" ]; then


+ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE

+fi
X bool 'Support for PowerMac ADB mouse' CONFIG_ADBMOUSE
-bool 'Support for PowerMac IDE devices (must also enable IDE)' CONFIG_BLK_DEV_IDE_PMAC
X bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
-bool 'Include kgdb kernel debugger' CONFIG_KGDB
-bool 'Include xmon kernel debugger' CONFIG_XMON
X bool 'Support for TotalImpact TotalMP' CONFIG_TOTALMP
X bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT
+bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP
+if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then
+ bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL y
+ if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
+ string 'Initial kernel command string' CONFIG_CMDLINE console=ttyS0,9600 console=tty0 root=/dev/sda2
+ fi
+fi
X
X if [ "$CONFIG_APUS" = "y" ]; then
X define_bool CONFIG_FB_CONSOLE y
@@ -176,4 +181,12 @@
X source drivers/sound/Config.in
X fi
X
+endmenu
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Include kgdb kernel debugger' CONFIG_KGDB
+bool 'Include xmon kernel debugger' CONFIG_XMON
X endmenu
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.2.7/linux/arch/ppc/defconfig Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/defconfig Tue May 11 08:24:32 1999
@@ -8,13 +8,12 @@
X CONFIG_PPC=y
X CONFIG_6xx=y
X # CONFIG_8xx is not set
-CONFIG_PMAC=y
+# CONFIG_PMAC is not set
X # CONFIG_PREP is not set
X # CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
+CONFIG_ALL_PPC=y
X # CONFIG_APUS is not set
X # CONFIG_MBX is not set
-CONFIG_MACH_SPECIFIC=y
X # CONFIG_SMP is not set
X
X #
@@ -36,20 +35,20 @@
X CONFIG_BINFMT_MISC=m
X # CONFIG_BINFMT_JAVA is not set
X # CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_VGA_CONSOLE=y
X CONFIG_FB=y
X CONFIG_FB_COMPAT_XPMAC=y
X CONFIG_PMAC_PBOOK=y
X CONFIG_MAC_KEYBOARD=y
X CONFIG_MAC_FLOPPY=y
X CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
X CONFIG_ADBMOUSE=y
-CONFIG_BLK_DEV_IDE_PMAC=y
X CONFIG_PROC_DEVICETREE=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
X # CONFIG_TOTALMP is not set
X CONFIG_BOOTX_TEXT=y
+# CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
X
X #
X # Plug and Play support
@@ -76,15 +75,13 @@
X # CONFIG_BLK_DEV_IDEPCI is not set
X # CONFIG_BLK_DEV_SL82C105 is not set
X CONFIG_BLK_DEV_IDE_PMAC=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_PMAC_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_IDEDMA_PMAC is not set
X # CONFIG_IDE_CHIPSETS is not set
X
X #
X # Additional Block Devices
X #
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
X # CONFIG_BLK_DEV_NBD is not set
X # CONFIG_BLK_DEV_MD is not set
X CONFIG_BLK_DEV_RAM=y
@@ -119,7 +116,6 @@
X # (it is safe to leave these untouched)
X #
X CONFIG_INET_RARP=y
-CONFIG_IP_NOSR=y
X CONFIG_SKB_LARGE=y
X # CONFIG_IPV6 is not set
X
@@ -155,12 +151,12 @@
X CONFIG_CHR_DEV_ST=y
X CONFIG_BLK_DEV_SR=y
X CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_SG=y
X
X #
X # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
X #
-# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_MULTI_LUN=y
X CONFIG_SCSI_CONSTANTS=y
X # CONFIG_SCSI_LOGGING is not set
X
@@ -188,16 +184,28 @@
X # CONFIG_SCSI_FUTURE_DOMAIN is not set
X # CONFIG_SCSI_GDTH is not set
X # CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_G_NCR5380_PORT is not set
+# CONFIG_SCSI_G_NCR5380_MEM is not set
X # CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
X # CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
X # CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_NCR53C8XX=y
+# CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
X # CONFIG_SCSI_PAS16 is not set
X # CONFIG_SCSI_PCI2000 is not set
X # CONFIG_SCSI_PCI2220I is not set
X # CONFIG_SCSI_PSI240I is not set
X # CONFIG_SCSI_QLOGIC_FAS is not set
X # CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
X # CONFIG_SCSI_SEAGATE is not set
X # CONFIG_SCSI_DC390T is not set
X # CONFIG_SCSI_T128 is not set
@@ -228,7 +236,7 @@
X # CONFIG_ACENIC is not set
X # CONFIG_NET_ISA is not set
X CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
+CONFIG_PCNET32=y
X # CONFIG_AC3200 is not set
X # CONFIG_APRICOT is not set
X # CONFIG_CS89x0 is not set
@@ -275,7 +283,7 @@
X # CONFIG_ISDN is not set
X
X #
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+# Old CD-ROM drivers (not SCSI, not IDE)
X #
X # CONFIG_CD_NO_IDESCSI is not set
X
@@ -283,22 +291,37 @@
X # Console drivers
X #
X CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_PM2 is not set
X CONFIG_FB_OF=y
X CONFIG_FB_CONTROL=y
X CONFIG_FB_PLATINUM=y
X CONFIG_FB_VALKYRIE=y
-CONFIG_FB_ATY=y
+# CONFIG_FB_ATY is not set
X CONFIG_FB_IMSTT=y
X CONFIG_FB_CT65550=y
X # CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
X # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
X CONFIG_FBCON_CFB8=y
X CONFIG_FBCON_CFB16=y
X CONFIG_FBCON_CFB24=y
X CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA is not set
X # CONFIG_FBCON_FONTWIDTH8_ONLY is not set
X CONFIG_FBCON_FONTS=y
X # CONFIG_FONT_8x8 is not set
@@ -314,15 +337,25 @@
X #
X CONFIG_VT=y
X CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
+CONFIG_SERIAL=m
X # CONFIG_SERIAL_EXTENDED is not set
X # CONFIG_SERIAL_NONSTANDARD is not set
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
X # CONFIG_QIC02_TAPE is not set
X # CONFIG_WATCHDOG is not set
-CONFIG_NVRAM=y
+# CONFIG_NVRAM is not set
X # CONFIG_RTC is not set
X
X #
@@ -334,11 +367,20 @@
X # Joystick support
X #
X # CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
X
X #
X # Ftape, the floppy tape device driver
X #
X # CONFIG_FTAPE is not set
+# CONFIG_FT_NORMAL_DEBUG is not set
+# CONFIG_FT_FULL_DEBUG is not set
+# CONFIG_FT_NO_TRACE is not set
+# CONFIG_FT_NO_TRACE_AT_ALL is not set
+# CONFIG_FT_STD_FDC is not set
+# CONFIG_FT_MACH2 is not set
+# CONFIG_FT_PROBE_FC10 is not set
+# CONFIG_FT_ALT_FDC is not set
X
X #
X # Filesystems
@@ -429,3 +471,10 @@
X # CONFIG_SOUND_MSNDCLAS is not set
X # CONFIG_SOUND_MSNDPIN is not set
X # CONFIG_SOUND_OSS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.2.7/linux/arch/ppc/kernel/Makefile Mon Dec 28 15:00:52 1998
+++ linux/arch/ppc/kernel/Makefile Thu Apr 29 12:39:01 1999
@@ -27,7 +27,7 @@
X endif
X
X ifeq ($(CONFIG_MBX),y)
-O_OBJS += mbx_setup.o mbx_pci.o softemu8xx.o
+O_OBJS += mbx_setup.o mbx_pci.o softemu8xx.o i8259.o ppc8xx_pic.o
X else
X ifeq ($(CONFIG_APUS),y)
X O_OBJS += apus_setup.o prom.o openpic.o
@@ -36,7 +36,8 @@
X O_OBJS += prep_time.o pmac_time.o chrp_time.o \
X pmac_setup.o pmac_support.o \
X prep_pci.o pmac_pci.o chrp_pci.o \
- residual.o prom.o openpic.o feature.o
+ residual.o prom.o openpic.o feature.o \
+ prep_nvram.o open_pic.o i8259.o pmac_pic.o indirect_pci.o
X OX_OBJS += chrp_setup.o prep_setup.o
X endif
X endif
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/align.c linux/arch/ppc/kernel/align.c
--- v2.2.7/linux/arch/ppc/kernel/align.c Mon Oct 5 13:13:36 1998
+++ linux/arch/ppc/kernel/align.c Thu Apr 29 12:39:01 1999
@@ -194,13 +194,8 @@
X return -EFAULT; /* bad address */
X }
X
-#ifdef __SMP__
- if ((flags & F) && (regs->msr & MSR_FP) )
- smp_giveup_fpu(current);
-#else
- if ((flags & F) && last_task_used_math == current)
- giveup_fpu();
-#endif
+ if ((flags & F) && (regs->msr & MSR_FP))
+ giveup_fpu(current);
X if (flags & M)
X return 0; /* too hard for now */
X
@@ -254,27 +249,16 @@
X data.d = current->tss.fpr[reg];
X break;
X /* these require some floating point conversions... */
- /* note that giveup_fpu enables the FPU for the kernel */
X /* we'd like to use the assignment, but we have to compile
X * the kernel with -msoft-float so it doesn't use the
X * fp regs for copying 8-byte objects. */
X case LD+F+S:
-#ifdef __SMP__
- if (regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- giveup_fpu();
-#endif
+ enable_kernel_fp();
X cvt_fd(&data.f, &current->tss.fpr[reg], &current->tss.fpscr);
X /* current->tss.fpr[reg] = data.f; */
X break;
X case ST+F+S:
-#ifdef __SMP__
- if (regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- giveup_fpu();
-#endif
+ enable_kernel_fp();
X cvt_df(&current->tss.fpr[reg], &data.f, &current->tss.fpscr);
X /* data.f = current->tss.fpr[reg]; */
X break;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- v2.2.7/linux/arch/ppc/kernel/apus_setup.c Tue Dec 22 14:16:54 1998
+++ linux/arch/ppc/kernel/apus_setup.c Thu Apr 29 12:39:01 1999
@@ -14,12 +14,50 @@
X #include <linux/sched.h>
X #include <linux/kd.h>
X #include <linux/init.h>
+#include <linux/hdreg.h>
+
+/* Get the IDE stuff from the 68k file */
+#define ide_init_hwif_ports m68k_ide_init_hwif_ports
+#define ide_default_irq m68k_ide_default_irq
+#define ide_default_io_base m68k_ide_default_io_base
+#define ide_check_region m68k_ide_check_region
+#define ide_request_region m68k_ide_request_region
+#define ide_release_region m68k_ide_release_region
+#define ide_fix_driveid m68k_ide_fix_driveid
+#include <asm-m68k/ide.h>
+#undef ide_init_hwif_ports
+#define ide_default_irq
+#define ide_default_io_base
+#define ide_check_region
+#define ide_request_region
+#define ide_release_region
+#define ide_fix_driveid
+
X
X #include <asm/setup.h>
X #include <asm/amigahw.h>
X #include <asm/amigappc.h>
X #include <asm/pgtable.h>
X #include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ide.h>
+
+#include "time.h"
+#include "local_irq.h"
+
+unsigned long apus_get_rtc_time(void);
+int apus_set_rtc_time(unsigned long nowtime);
+
+/* APUS defs */
+extern int parse_bootinfo(const struct bi_record *);
+extern char _end[];
+#ifdef CONFIG_APUS
+struct mem_info ramdisk;
+unsigned long isa_io_base;
+unsigned long isa_mem_base;
+unsigned long pci_dram_offset;
+#endif
+/* END APUS defs */
X
X unsigned long m68k_machtype;
X char debug_device[6] = "";
@@ -72,6 +110,8 @@
X int i;
X char *p, *q;
X
+ m68k_machtype = MACH_AMIGA;
+
X /* Parse the command line for arch-specific options.
X * For the m68k, this is currently only "debug=xxx" to enable printing
X * certain kernel messages to some machine-specific device. */
@@ -408,4 +448,195 @@
X "icbi 0,%0 \n\t"
X "isync \n\t"
X : : "r" (addr));
+}
+
+void
+apus_restart(char *cmd)
+{
+ cli();
+
+ APUS_WRITE(APUS_REG_LOCK,
+ REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2);
+ APUS_WRITE(APUS_REG_LOCK,
+ REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK3);
+ APUS_WRITE(APUS_REG_LOCK,
+ REGLOCK_BLACKMAGICK2|REGLOCK_BLACKMAGICK3);
+ APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET);
+ APUS_WRITE(APUS_REG_RESET, REGRESET_AMIGARESET);
+ for(;;);
+}
+
+void
+apus_power_off(void)


+{
+ for (;;);
+}

+
+void
+apus_halt(void)
+{
+ apus_restart(NULL);
+}
+
+void
+apus_do_IRQ(struct pt_regs *regs,
+ int cpu,
+ int isfake)
+{
+ int old_level, new_level;
+
+ /* I don't think we need SMP code here - Corey */
+
+ old_level = ~(regs->mq) & IPLEMU_IPLMASK;
+ new_level = (~(regs->mq) >> 3) & IPLEMU_IPLMASK;
+ if (new_level != 0)
+ {
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
+ APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
+ | (~(new_level) & IPLEMU_IPLMASK)));
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+
+ process_int (VEC_SPUR+new_level, regs);
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
+ APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
+ | (~(old_level) & IPLEMU_IPLMASK)));
+ }
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */
+void
+apus_ide_insw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_insw(port, buf, ns);
+}
+
+void
+apus_ide_outsw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_outsw(port, buf, ns);
+}
+
+int
+apus_ide_default_irq(ide_ioreg_t base)
+{
+ m68k_ide_default_irq(base);
+}
+
+ide_ioreg_t
+apus_ide_default_io_base(int index)
+{
+ m68k_ide_default_io_base(index);
+}
+
+int
+apus_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+ return m68k_ide_check_region(from, extent);
+}
+
+void
+apus_ide_request_region(ide_ioreg_t from,
+ unsigned int extent,
+ const char *name)
+{
+ m68k_ide_request_region(from, extent, name);
+}
+
+void
+apus_ide_release_region(ide_ioreg_t from,
+ unsigned int extent)
+{
+ m68k_ide_release_region(from, extent);
+}
+
+void
+apus_ide_fix_driveid(struct hd_driveid *id)
+{
+ m68k_ide_fix_driveid(id);
+}
+
+__initfunc(void
+apus_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq))
+{
+ m68k_ide_init_hwif_ports(p, base, irq);
+}
+#endif
+
+__initfunc(void
+apus_local_init_IRQ(void))
+{
+ ppc_md.mask_irq = amiga_disable_irq;
+ ppc_md.unmask_irq = amiga_enable_irq;
+ apus_init_IRQ();
+}
+
+__initfunc(void
+apus_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7))
+{
+ /* Parse bootinfo. The bootinfo is located right after
+ the kernel bss */
+ parse_bootinfo((const struct bi_record *)&_end);
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* Take care of initrd if we have one. Use data from
+ bootinfo to avoid the need to initialize PPC
+ registers when kernel is booted via a PPC reset. */
+ if ( ramdisk.addr ) {
+ initrd_start = (unsigned long) __va(ramdisk.addr);
+ initrd_end = (unsigned long)
+ __va(ramdisk.size + ramdisk.addr);
+ }
+ /* Make sure code below is not executed. */
+ r4 = 0;
+ r6 = 0;
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ ISA_DMA_THRESHOLD = 0x00ffffff;
+
+ ppc_md.setup_arch = apus_setup_arch;
+ ppc_md.setup_residual = NULL;
+ ppc_md.get_cpuinfo = apus_get_cpuinfo;
+ ppc_md.irq_cannonicalize = NULL;
+ ppc_md.init_IRQ = apus_init_IRQ;
+ ppc_md.do_IRQ = apus_do_IRQ;
+ ppc_md.get_irq_source = NULL;
+ ppc_md.init = NULL;
+
+ ppc_md.restart = apus_restart;
+ ppc_md.power_off = apus_power_off;
+ ppc_md.halt = apus_halt;
+
+ ppc_md.time_init = NULL;
+ ppc_md.set_rtc_time = apus_set_rtc_time;
+ ppc_md.get_rtc_time = apus_get_rtc_time;
+ ppc_md.calibrate_decr = apus_calibrate_decr;
+
+ /* These should not be used for the APUS yet, since it uses
+ the M68K keyboard now. */
+ ppc_md.kbd_setkeycode = NULL;
+ ppc_md.kbd_getkeycode = NULL;
+ ppc_md.kbd_translate = NULL;
+ ppc_md.kbd_unexpected_up = NULL;
+ ppc_md.kbd_leds = NULL;
+ ppc_md.kbd_init_hw = NULL;
+ ppc_md.kbd_sysrq_xlate = NULL;
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+ ppc_ide_md.insw = apus_ide_insw;
+ ppc_ide_md.outsw = apus_ide_outsw;
+ ppc_ide_md.default_irq = apus_ide_default_irq;
+ ppc_ide_md.default_io_base = apus_ide_default_io_base;
+ ppc_ide_md.check_region = apus_ide_check_region;
+ ppc_ide_md.request_region = apus_ide_request_region;
+ ppc_ide_md.release_region = apus_ide_release_region;
+ ppc_ide_md.fix_driveid = apus_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports;
+
+ ppc_ide_md.io_base = _IO_BASE;
+#endif
X }
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- v2.2.7/linux/arch/ppc/kernel/chrp_pci.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/chrp_pci.c Tue May 11 08:24:32 1999
@@ -15,10 +15,14 @@
X #include <asm/hydra.h>
X #include <asm/prom.h>
X #include <asm/gg2.h>
+#include <asm/ide.h>
+#include <asm/machdep.h>
+
+#include "pci.h"
X
X /* LongTrail */
X #define pci_config_addr(bus, dev, offset) \
- (GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
+(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
X
X volatile struct Hydra *Hydra = NULL;
X
@@ -30,159 +34,78 @@
X int gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char *val)
X {
- if (bus > 7) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7) {
+ *val = 0xff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset));
+ return PCIBIOS_SUCCESSFUL;
X }
X
X int gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short *val)
X {
- if (bus > 7) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7) {
+ *val = 0xffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset));
+ return PCIBIOS_SUCCESSFUL;
X }
X
X
X int gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int *val)
X {
- if (bus > 7) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset));
+ return PCIBIOS_SUCCESSFUL;
X }
X
X int gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char val)
X {
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val);
+ return PCIBIOS_SUCCESSFUL;
X }
X
X int gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short val)
X {
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val);
+ return PCIBIOS_SUCCESSFUL;
X }
X
X int gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int val)
X {
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-extern volatile unsigned int *pci_config_address;
-extern volatile unsigned char *pci_config_data;
-
-#define DEV_FN_MAX (31<<3)
-
-int raven_pcibios_read_config_byte(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned char *val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
- *val = in_8(pci_config_data+(offset&3));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int raven_pcibios_read_config_word(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned short *val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset&1)return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
- *val = in_le16((volatile unsigned short *)
- (pci_config_data+(offset&3)));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int raven_pcibios_read_config_dword(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned int *val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset&3)return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
- *val = in_le32((volatile unsigned int *)(pci_config_data));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int raven_pcibios_write_config_byte(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned char val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
- out_8(pci_config_data+(offset&3),val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int raven_pcibios_write_config_word(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned short val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset&1)return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|((offset&~3)<<24));
- out_le16((volatile unsigned short *)(pci_config_data+(offset&3)),val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int raven_pcibios_write_config_dword(unsigned char bus,
- unsigned char dev_fn,
- unsigned char offset,
- unsigned int val)
-{
- if (dev_fn >= DEV_FN_MAX) return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset&3)return PCIBIOS_BAD_REGISTER_NUMBER;
- out_be32(pci_config_address,
- 0x80|(bus<<8)|(dev_fn<<16)|(offset<<24));
- out_le32((volatile unsigned int *)pci_config_data,val);
- return PCIBIOS_SUCCESSFUL;
+ if (bus > 7)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val);
+ return PCIBIOS_SUCCESSFUL;
X }
X
X #define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000))
X #define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000))
-#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
+#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \
X | (((o) & ~3) << 24))
-
+unsigned int python_busnr = 1;
+
X int python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char *val)
X {
- if (bus > 2) {
+ if (bus > python_busnr) {
X *val = 0xff;
X return PCIBIOS_DEVICE_NOT_FOUND;
X }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X *val = in_8((unsigned char *)python_config_data(bus) + (offset&3));
X return PCIBIOS_SUCCESSFUL;
X }
@@ -190,11 +113,11 @@
X int python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short *val)
X {
- if (bus > 2) {
+ if (bus > python_busnr) {
X *val = 0xffff;
X return PCIBIOS_DEVICE_NOT_FOUND;
X }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3)));
X return PCIBIOS_SUCCESSFUL;
X }
@@ -203,11 +126,11 @@
X int python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int *val)
X {
- if (bus > 2) {
+ if (bus > python_busnr) {
X *val = 0xffffffff;
X return PCIBIOS_DEVICE_NOT_FOUND;
X }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X *val = in_le32((unsigned *)python_config_data(bus));
X return PCIBIOS_SUCCESSFUL;
X }
@@ -215,9 +138,9 @@
X int python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char val)
X {
- if (bus > 2)
+ if (bus > python_busnr)
X return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val);
X return PCIBIOS_SUCCESSFUL;
X }
@@ -225,9 +148,9 @@
X int python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short val)
X {
- if (bus > 2)
+ if (bus > python_busnr)
X return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3),
X val);
X return PCIBIOS_SUCCESSFUL;
@@ -236,9 +159,9 @@
X int python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int val)
X {
- if (bus > 2)
+ if (bus > python_busnr)
X return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset) );
+ out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
X out_le32((unsigned *)python_config_data(bus) + (offset&3), val);
X return PCIBIOS_SUCCESSFUL;
X }
@@ -264,7 +187,8 @@
X /* all others are 1 (= default) */
X };
X
-__initfunc(int hydra_init(void))
+int __init
+hydra_init(void)
X {
X struct device_node *np;
X
@@ -287,4 +211,97 @@
X OpenPIC_InitSenses = hydra_openpic_initsenses;
X OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses);
X return 1;
+}
+
+void __init
+chrp_pcibios_fixup(void)
+{
+ struct pci_dev *dev;
+
+ /* some of IBM chrps have > 1 bus */
+ if ( !strncmp("IBM", get_property(find_path_device("/"),
+ "name", NULL),3) )
+ {
+ pci_scan_peer_bridge(1);
+ pci_scan_peer_bridge(2);
+ }
+
+ /* PCI interrupts are controlled by the OpenPIC */
+ for( dev=pci_devices ; dev; dev=dev->next )
+ {
+ if ( dev->irq )
+ dev->irq = openpic_to_irq( dev->irq );
+ /* adjust the io_port for the NCR cards for busses other than 0 -- Cort */
+ if ( (dev->bus->number > 0) && (dev->vendor == PCI_VENDOR_ID_NCR) )
+ dev->base_address[0] += (dev->bus->number*0x08000000);
+ /* these need to be absolute addrs for OF and Matrox FB -- Cort */
+ if ( dev->vendor == PCI_VENDOR_ID_MATROX )
+ {
+ if ( dev->base_address[0] < isa_mem_base )
+ dev->base_address[0] += isa_mem_base;
+ if ( dev->base_address[1] < isa_mem_base )
+ dev->base_address[1] += isa_mem_base;
+ }
+ /* the F50 identifies the amd as a trident */
+ if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) &&
+ (dev->class == PCI_CLASS_NETWORK_ETHERNET) )
+ {
+ dev->vendor = PCI_VENDOR_ID_AMD;
+ pcibios_write_config_word(dev->bus->number, dev->devfn,
+ PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ }
+ }
+}
+
+decl_config_access_method(grackle);
+decl_config_access_method(indirect);
+
+void __init
+chrp_setup_pci_ptrs(void)
+{
+ struct device_node *py;
+
+ if ( !strncmp("MOT",
+ get_property(find_path_device("/"), "model", NULL),3) )
+ {
+ pci_dram_offset = 0;
+ isa_mem_base = 0xf7000000;
+ isa_io_base = 0xfe000000;
+ set_config_access_method(grackle);
+ }
+ else
+ {
+ if ( (py = find_compatible_devices( "pci", "IBM,python" )) )
+ {
+ /* find out how many pythons */
+ while ( (py = py->next) ) python_busnr++;
+ set_config_access_method(python);
+ /*
+ * We base these values on the machine type but should
+ * try to read them from the python controller itself.
+ * -- Cort
+ */
+ if ( !strncmp("IBM,7025-F50", get_property(find_path_device("/"), "name", NULL),12) )
+ {
+ pci_dram_offset = 0x80000000;
+ isa_mem_base = 0xa0000000;
+ isa_io_base = 0x88000000;
+ } else if ( !strncmp("IBM,7043-260",
+ get_property(find_path_device("/"), "name", NULL),12) )
+ {
+ pci_dram_offset = 0x80000000;
+ isa_mem_base = 0xc0000000;
+ isa_io_base = 0xf8000000;
+ }
+ }
+ else
+ {
+ pci_dram_offset = 0;
+ isa_mem_base = 0xf7000000;
+ isa_io_base = 0xf8000000;
+ set_config_access_method(gg2);
+ }
+ }
+
+ ppc_md.pcibios_fixup = chrp_pcibios_fixup;
X }
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.2.7/linux/arch/ppc/kernel/chrp_setup.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/chrp_setup.c Tue May 11 08:24:32 1999
@@ -41,8 +41,50 @@
X #include <asm/prom.h>
X #include <asm/gg2.h>
X #include <asm/pci-bridge.h>
-
-extern void hydra_init(void);
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/adb.h>
+#include <asm/hydra.h>
+
+#include "time.h"
+#include "local_irq.h"
+#include "i8259.h"
+#include "open_pic.h"
+
+/* Fixme - need to move these into their own .c and .h file */
+extern void i8259_mask_and_ack_irq(unsigned int irq_nr);
+extern void i8259_set_irq_mask(unsigned int irq_nr);
+extern void i8259_mask_irq(unsigned int irq_nr);
+extern void i8259_unmask_irq(unsigned int irq_nr);
+extern void i8259_init(void);
+
+/* Fixme - remove this when it is fixed. - Corey */
+extern volatile unsigned char *chrp_int_ack_special;
+
+unsigned long chrp_get_rtc_time(void);
+int chrp_set_rtc_time(unsigned long nowtime);
+void chrp_calibrate_decr(void);
+void chrp_time_init(void);
+
+void chrp_setup_pci_ptrs(void);
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);
+extern unsigned char pckbd_sysrq_xlate[128];
+extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int mackbd_getkeycode(unsigned int scancode);
+extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char mackbd_unexpected_up(unsigned char keycode);
+extern void mackbd_leds(unsigned char leds);
+extern void mackbd_init_hw(void);
+extern unsigned char mackbd_sysrq_xlate[128];
X
X /* for the mac fs */
X kdev_t boot_dev;
@@ -61,17 +103,17 @@
X #endif
X
X static const char *gg2_memtypes[4] = {
- "FPM", "SDRAM", "EDO", "BEDO"
+ "FPM", "SDRAM", "EDO", "BEDO"
X };
X static const char *gg2_cachesizes[4] = {
- "256 KB", "512 KB", "1 MB", "Reserved"
+ "256 KB", "512 KB", "1 MB", "Reserved"
X };
X static const char *gg2_cachetypes[4] = {
- "Asynchronous", "Reserved", "Flow-Through Synchronous",
- "Pipelined Synchronous"
+ "Asynchronous", "Reserved", "Flow-Through Synchronous",
+ "Pipelined Synchronous"
X };
X static const char *gg2_cachemodes[4] = {
- "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
+ "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
X };
X
X int
@@ -84,7 +126,7 @@
X
X root = find_path_device("/");
X if (root)
- model = get_property(root, "model", NULL);
+ model = get_property(root, "model", NULL);
X len = sprintf(buffer,"machine\t\t: CHRP %s\n", model);
X
X /* longtrail (goldengate) stuff */
@@ -137,7 +179,7 @@
X return len;
X }
X
- /*
+/*
X * Fixes for the National Semiconductor PC78308VUL SuperI/O
X *
X * Some versions of Open Firmware incorrectly initialize the IRQ settings
@@ -146,56 +188,56 @@
X
X __initfunc(static inline void sio_write(u8 val, u8 index))
X {
- outb(index, 0x15c);
- outb(val, 0x15d);
+ outb(index, 0x15c);
+ outb(val, 0x15d);
X }
X
X __initfunc(static inline u8 sio_read(u8 index))
X {
- outb(index, 0x15c);
- return inb(0x15d);
+ outb(index, 0x15c);
+ return inb(0x15d);
X }
X
X __initfunc(static void sio_fixup_irq(const char *name, u8 device, u8 level,
X u8 type))
X {
- u8 level0, type0, active;
+ u8 level0, type0, active;
X
- /* select logical device */
- sio_write(device, 0x07);
- active = sio_read(0x30);
- level0 = sio_read(0x70);
- type0 = sio_read(0x71);
- printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
- !active ? "in" : "");
- if (level0 == level && type0 == type && active)
- printk("OK\n");
- else {
- printk("remapping to level %d, type %d, active\n", level, type);
- sio_write(0x01, 0x30);
- sio_write(level, 0x70);
- sio_write(type, 0x71);
- }
+ /* select logical device */
+ sio_write(device, 0x07);
+ active = sio_read(0x30);
+ level0 = sio_read(0x70);
+ type0 = sio_read(0x71);
+ printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
+ !active ? "in" : "");
+ if (level0 == level && type0 == type && active)
+ printk("OK\n");
+ else {
+ printk("remapping to level %d, type %d, active\n", level, type);
+ sio_write(0x01, 0x30);
+ sio_write(level, 0x70);
+ sio_write(type, 0x71);
+ }
X
X }
X
X __initfunc(static void sio_init(void))
X {
- /* logical device 0 (KBC/Keyboard) */
- sio_fixup_irq("keyboard", 0, 1, 2);
- /* select logical device 1 (KBC/Mouse) */
- sio_fixup_irq("mouse", 1, 12, 2);
+ /* logical device 0 (KBC/Keyboard) */
+ sio_fixup_irq("keyboard", 0, 1, 2);
+ /* select logical device 1 (KBC/Mouse) */
+ sio_fixup_irq("mouse", 1, 12, 2);
X }
X
X
X __initfunc(void
-chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
+ chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
X {
X extern char cmd_line[];
X
X /* init to some ~sane value until calibrate_delay() runs */
X loops_per_sec = 50000000;
-
+
X #ifdef CONFIG_BLK_DEV_INITRD
X /* this is fine for chrp */
X initrd_below_start_ok = 1;
@@ -243,27 +285,210 @@
X if ( !strncmp("MOT", get_property(find_path_device("/"),
X "model", NULL),3) )
X *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
+ /*
+ * The f50 has a lot of IO space - we need to map some in that
+ * isn't covered by the BAT mappings in MMU_init() -- Cort
+ */
+ if ( !strncmp("F5", get_property(find_path_device("/"),
+ "ibm,model-class", NULL),2) )
+ {
+#if 0
+ /*
+ * This ugly hack allows us to force ioremap() to
+ * create a 1-to-1 mapping for us, even though
+ * the address is < ioremap_base. This is necessary
+ * since we want our PCI IO space to have contiguous
+ * virtual addresses and I think it's worse to have
+ * calls to map_page() here.
+ * -- Cort
+ */
+ unsigned long hold = ioremap_base;
+ ioremap_base = 0;
+ __ioremap(0x90000000, 0x10000000, _PAGE_NO_CACHE);
+ ioremap_base = hold;
+#endif
+ }
X }
X
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+void
+chrp_restart(char *cmd)
+{
+#if 0
+ extern unsigned int rtas_entry, rtas_data, rtas_size;
+ printk("RTAS system-reboot returned %d\n",
+ call_rtas("system-reboot", 0, 1, NULL));
+ printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
+ rtas_entry,rtas_data,rtas_size);
+ for (;;);
+#else
+ printk("System Halted\n");
+ while(1);
+#endif
+}
X
-unsigned int chrp_ide_irq = 0;
-int chrp_ide_ports_known = 0;
-ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
-ide_ioreg_t chrp_idedma_regbase;
+void
+chrp_power_off(void)
+{
+ /* RTAS doesn't seem to work on Longtrail.
+ For now, do it the same way as the PReP. */
+#if 0
+ extern unsigned int rtas_entry, rtas_data, rtas_size;
+ printk("RTAS power-off returned %d\n",
+ call_rtas("power-off", 2, 1, NULL, 0, 0));
+ printk("rtas_entry: %08lx rtas_data: %08lx rtas_size: %08lx\n",
+ rtas_entry,rtas_data,rtas_size);
+ for (;;);
+#else
+ chrp_restart(NULL);
+#endif
+}
X
-void chrp_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+void
+chrp_halt(void)
X {
- ide_ioreg_t port = base;
- int i = 8;
+ chrp_restart(NULL);
+}
X
- while (i--)
- *p++ = port++;
- *p++ = port;
- if (irq != NULL)
- *irq = chrp_ide_irq;
+u_int
+chrp_irq_cannonicalize(u_int irq)
+{
+ if (irq == 2)
+ {
+ return 9;
+ }
+ else
+ {
+ return irq;
+ }
+}
+
+void
+chrp_do_IRQ(struct pt_regs *regs,
+ int cpu,
+ int isfake)
+{
+ int irq;
+ unsigned long bits = 0;
+ int openpic_eoi_done = 0;
+
+#ifdef __SMP__
+ {
+ unsigned int loops = 1000000;
+ while (test_bit(0, &global_irq_lock)) {
+ if (smp_processor_id() == global_irq_holder) {
+ printk("uh oh, interrupt while we hold global irq lock!\n");
+#ifdef CONFIG_XMON
+ xmon(0);
+#endif
+ break;
+ }
+ if (loops-- == 0) {
+ printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
+#ifdef CONFIG_XMON
+ xmon(0);
+#endif
+ }
+ }
+ }
+#endif /* __SMP__ */
+
+ irq = openpic_irq(0);
+ if (irq == IRQ_8259_CASCADE)
+ {
+ /*
+ * This magic address generates a PCI IACK cycle.
+ *
+ * This should go in the above mask/ack code soon. -- Cort
+ */
+ if ( chrp_int_ack_special )
+ irq = *chrp_int_ack_special;
+ else
+ irq = i8259_irq(0);
+ /*
+ * Acknowledge as soon as possible to allow i8259
+ * interrupt nesting */
+ openpic_eoi(0);
+ openpic_eoi_done = 1;
+ }
+ if (irq == OPENPIC_VEC_SPURIOUS)
+ {
+ /*
+ * Spurious interrupts should never be
+ * acknowledged
+ */
+ ppc_spurious_interrupts++;


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 08'
echo 'File patch-2.2.8 is continued in part 09'
echo 09 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part09

#!/bin/sh
# this is part 09 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 09; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

+ openpic_eoi_done = 1;
+ goto out;
+ }
+ bits = 1UL << irq;
+
+ if (irq < 0)
+ {
+ printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+ irq, regs->nip);
+ ppc_spurious_interrupts++;
+ }
+ else
+ {
+ ppc_irq_dispatch_handler( regs, irq );
+ }
+out:
+ if (!openpic_eoi_done)
+ openpic_eoi(0);
X }
X
+__initfunc(void
+ chrp_init_IRQ(void))
+{
+ struct device_node *np;
+ int i;
+
+ if ( !(np = find_devices("pci") ) )
+ printk("Cannot find pci to get ack address\n");
+ else
+ {
+ chrp_int_ack_special = (volatile unsigned char *)
+ (*(unsigned long *)get_property(np,
+ "8259-interrupt-acknowledge", NULL));
+ }
+ for ( i = 16 ; i < NR_IRQS ; i++ )
+ irq_desc[i].ctl = &open_pic;
+ /* openpic knows that it's at irq 16 offset
+ * so we don't need to set it in the pic structure


+ * -- Cort
+ */

+ openpic_init(1);
+ for ( i = 0 ; i < 16 ; i++ )
+ irq_desc[i].ctl = &i8259_pic;
+ i8259_init();
+#ifdef CONFIG_XMON
+ request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
+ xmon_irq, 0, "NMI", 0);
+#endif /* CONFIG_XMON */
+#ifdef __SMP__
+ request_irq(openpic_to_irq(OPENPIC_VEC_IPI),
+ openpic_ipi_action, 0, "IPI0", 0);


+#endif /* __SMP__ */
+}
+

+__initfunc(void
+ chrp_init2(void))
+{
+ adb_init();
+
+ /* Should this be here? - Corey */
+ pmac_nvram_init();


+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */

+unsigned int chrp_ide_irq = 0;
+int chrp_ide_ports_known = 0;
+ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
+ide_ioreg_t chrp_idedma_regbase;
+
X void chrp_ide_probe(void) {
X
X struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
@@ -281,9 +506,167 @@
X }
X }
X
+void
+chrp_ide_insw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_insw(port+_IO_BASE, buf, ns);
+}
+
+void
+chrp_ide_outsw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_outsw(port+_IO_BASE, buf, ns);
+}
+
+int
+chrp_ide_default_irq(ide_ioreg_t base)
+{
+ if (chrp_ide_ports_known == 0)
+ chrp_ide_probe();
+ return chrp_ide_irq;
+}
+
+ide_ioreg_t
+chrp_ide_default_io_base(int index)
+{
+ if (chrp_ide_ports_known == 0)
+ chrp_ide_probe();
+ return chrp_ide_regbase[index];
+}
+
+int
+chrp_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+ return check_region(from, extent);
+}
+
+void
+chrp_ide_request_region(ide_ioreg_t from,


+ unsigned int extent,
+ const char *name)
+{

+ request_region(from, extent, name);
+}
+
+void
+chrp_ide_release_region(ide_ioreg_t from,


+ unsigned int extent)
+{

+ release_region(from, extent);
+}
+
+void
+chrp_ide_fix_driveid(struct hd_driveid *id)
+{
+ ppc_generic_ide_fix_driveid(id);
+}
+
+void chrp_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
+{
+ ide_ioreg_t port = base;
+ int i = 8;
+
+ while (i--)
+ *p++ = port++;
+ *p++ = port;
+ if (irq != NULL)
+ *irq = chrp_ide_irq;
+}
+
X EXPORT_SYMBOL(chrp_ide_irq);
X EXPORT_SYMBOL(chrp_ide_ports_known);
X EXPORT_SYMBOL(chrp_ide_regbase);
X EXPORT_SYMBOL(chrp_ide_probe);
X
X #endif
+
+__initfunc(void
+ chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,


+ unsigned long r6, unsigned long r7))
+{

+ chrp_setup_pci_ptrs();
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* take care of initrd if we have one */
+ if ( r3 )
+ {
+ initrd_start = r3 + KERNELBASE;
+ initrd_end = r3 + r4 + KERNELBASE;
+ }


+#endif /* CONFIG_BLK_DEV_INITRD */
+

+ /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+
+ ppc_md.setup_arch = chrp_setup_arch;
+ ppc_md.setup_residual = NULL;
+ ppc_md.get_cpuinfo = chrp_get_cpuinfo;
+ ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
+ ppc_md.init_IRQ = chrp_init_IRQ;
+ ppc_md.do_IRQ = chrp_do_IRQ;
+
+ ppc_md.init = chrp_init2;
+
+ ppc_md.restart = chrp_restart;
+ ppc_md.power_off = chrp_power_off;
+ ppc_md.halt = chrp_halt;
+
+ ppc_md.time_init = chrp_time_init;
+ ppc_md.set_rtc_time = chrp_set_rtc_time;
+ ppc_md.get_rtc_time = chrp_get_rtc_time;
+ ppc_md.calibrate_decr = chrp_calibrate_decr;
+
+#ifdef CONFIG_VT
+#ifdef CONFIG_MAC_KEYBOAD
+ if ( adb_hardware == ADB_NONE )
+ {
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
+#endif
+ }
+ else
+ {
+ ppc_md.kbd_setkeycode = mackbd_setkeycode;
+ ppc_md.kbd_getkeycode = mackbd_getkeycode;
+ ppc_md.kbd_translate = mackbd_translate;
+ ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
+ ppc_md.kbd_leds = mackbd_leds;
+ ppc_md.kbd_init_hw = mackbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = mackbd_sysrq_xlate;
+#endif
+ }
+#else
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
+#endif
+#endif
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+ ppc_ide_md.insw = chrp_ide_insw;
+ ppc_ide_md.outsw = chrp_ide_outsw;
+ ppc_ide_md.default_irq = chrp_ide_default_irq;
+ ppc_ide_md.default_io_base = chrp_ide_default_io_base;
+ ppc_ide_md.check_region = chrp_ide_check_region;
+ ppc_ide_md.request_region = chrp_ide_request_region;
+ ppc_ide_md.release_region = chrp_ide_release_region;
+ ppc_ide_md.fix_driveid = chrp_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;


+
+ ppc_ide_md.io_base = _IO_BASE;
+#endif

+}
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.2.7/linux/arch/ppc/kernel/head.S Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/head.S Tue May 11 08:24:32 1999


@@ -1,7 +1,7 @@
X /*

X * arch/ppc/kernel/head.S
X *
- * $Id: head.S,v 1.121 1999/03/16 10:40:29 cort Exp $
+ * $Id: head.S,v 1.130 1999/05/09 19:16:43 cort Exp $
X *
X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)
@@ -91,7 +91,7 @@
X #define tlbia \
X li r4,128; \
X mtctr r4; \
- lis r4,0xC000; \
+ lis r4,KERNELBASE@h; \
X 0: tlbie r4; \
X addi r4,r4,0x1000; \
X bdnz 0b
@@ -415,7 +415,7 @@
X * this, we leave this much untouched space on the stack on exception
X * entry.
X */
-#define STACK_UNDERHEAD 64
+#define STACK_UNDERHEAD 0
X
X /*
X * Exception entry code. This code runs with address translation
@@ -1495,27 +1495,25 @@
X * On SMP we know the fpu is free, since we give it up every
X * switch. -- Cort
X */
+ mfmsr r5
+ ori r5,r5,MSR_FP
+ SYNC
+ mtmsr r5 /* enable use of fpu now */
+ SYNC
+/*
+ * For SMP, we don't do lazy FPU switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another. Instead we call giveup_fpu in switch_to.
+ */
+#ifndef __SMP__
X #ifndef CONFIG_APUS
X lis r6,-KERNELBASE@h
X #else
X lis r6,CYBERBASEp@h
X lwz r6,0(r6)
X #endif
-
X addis r3,r6,last_task_used_math@ha
X lwz r4,last_task_used_math@l(r3)
- mfmsr r5
- ori r5,r5,MSR_FP
- SYNC
- mtmsr r5 /* enable use of fpu now */
-/*
- * All the saving of last_task_used_math is handled
- * by a switch_to() call to smp_giveup_fpu() in SMP so
- * last_task_used_math is not used.
- * -- Cort
- */
-#ifndef __SMP__
- SYNC
X cmpi 0,r4,0
X beq 1f
X add r4,r4,r6
@@ -1529,15 +1527,17 @@
X li r20,MSR_FP|MSR_FE0|MSR_FE1
X andc r4,r4,r20 /* disable FP for previous task */
X stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:


X #endif /* __SMP__ */

-1: ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1 /* enable use of FP after return */
+ /* enable use of FP after return */
+ ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1
X mfspr r5,SPRG3 /* current task's TSS (phys) */
X lfd fr0,TSS_FPSCR-4(r5)
X mtfsf 0xff,fr0
X REST_32FPRS(0, r5)
+#ifndef __SMP__
X subi r4,r5,TSS
X sub r4,r4,r6
-#ifndef __SMP__
X stw r4,last_task_used_math@l(r3)


X #endif /* __SMP__ */

X /* restore registers and return */
@@ -1574,48 +1574,44 @@
X .align 4
X
X /*
- * Disable FP for the task which had the FPU previously,
- * and save its floating-point registers in its thread_struct.
+ * giveup_fpu(tsk)
+ * Disable FP for the task given as the argument,
+ * and save the floating-point registers in its thread_struct.
X * Enables the FPU for use in the kernel on return.
X */
-/* smp_giveup_fpu() takes an arg to tell it where to save the fpu
- * regs since last_task_used_math can't be trusted (many many race
- * conditions). -- Cort
- */
- .globl smp_giveup_fpu
-smp_giveup_fpu:
- mr r4,r3
- b 12f
X .globl giveup_fpu
X giveup_fpu:
- lis r3,last_task_used_math@ha
- lwz r4,last_task_used_math@l(r3)
-12:
X mfmsr r5
X ori r5,r5,MSR_FP
X SYNC
X mtmsr r5 /* enable use of fpu now */
X SYNC
- cmpi 0,r4,0
+ cmpi 0,r3,0
X beqlr- /* if no previous owner, done */
- addi r4,r4,TSS /* want TSS of last_task_used_math */
+ addi r3,r3,TSS /* want TSS of task */
+ lwz r5,PT_REGS(r3)
+ cmpi 0,r5,0
+ SAVE_32FPRS(0, r3)
+ mffs fr0
+ stfd fr0,TSS_FPSCR-4(r3)
+ beq 1f
+ lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+ li r3,MSR_FP|MSR_FE0|MSR_FE1
+ andc r4,r4,r3 /* disable FP for previous task */
+ stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
X #ifndef __SMP__
X li r5,0
- stw r5,last_task_used_math@l(r3)
+ lis r4,last_task_used_math@ha
+ stw r5,last_task_used_math@l(r4)


X #endif /* __SMP__ */

- SAVE_32FPRS(0, r4)
- mffs fr0
- stfd fr0,TSS_FPSCR-4(r4)
- lwz r5,PT_REGS(r4)
- lwz r3,_MSR-STACK_FRAME_OVERHEAD(r5)
- li r4,MSR_FP|MSR_FE0|MSR_FE1
- andc r3,r3,r4 /* disable FP for previous task */
- stw r3,_MSR-STACK_FRAME_OVERHEAD(r5)
+ blr
+
X #else /* CONFIG_8xx */
X .globl giveup_fpu
X giveup_fpu:
-#endif /* CONFIG_8xx */
X blr
+#endif /* CONFIG_8xx */
X
X /*
X * This code is jumped to from the startup code to copy
@@ -2049,8 +2045,9 @@
X stw r0,GPR0(r1)
X lwz r0,0(r1)
X stw r0,GPR1(r1)
- SAVE_10GPRS(2, r1)
- SAVE_10GPRS(12, r1)
+ /* r3-r13 are caller saved -- Cort */
+ SAVE_GPR(2, r1)
+ SAVE_8GPRS(14, r1)
X SAVE_10GPRS(22, r1)
X mflr r20 /* Return to switch caller */
X mfmsr r22
@@ -2073,6 +2070,8 @@
X mtspr SPRG3,r0 /* Update current TSS phys addr */
X SYNC
X lwz r1,KSP(r4) /* Load new stack pointer */
+ /* save the old current 'last' for return value */
+ mr r3,r2
X addi r2,r4,-TSS /* Update current */
X #ifndef CONFIG_8xx
X /* Set up segment registers for new task */
@@ -2080,39 +2079,62 @@
X addis r5,r5,0x6000 /* Set Ks, Ku bits */
X li r0,12 /* TASK_SIZE / SEGMENT_SIZE */
X mtctr r0
- li r3,0
-3: mtsrin r5,r3
+ li r9,0
+3: mtsrin r5,r9
X addi r5,r5,1 /* next VSID */
- addis r3,r3,0x1000 /* address of next segment */
+ addis r9,r9,0x1000 /* address of next segment */
X bdnz 3b
X #else
X /* On the MPC8xx, we place the physical address of the new task
X * page directory loaded into the MMU base register, and set the
X * ASID compare register with the new "context".
X */
- lwz r3,MM-TSS(r4) /* Get virtual address of mm */
- lwz r3,PGD(r3) /* get new->mm->pgd */
- addis r3,r3,-KERNELBASE@h /* convert to phys addr */
- mtspr M_TWB, r3 /* Update MMU base address */
+ lwz r9,MM-TSS(r4) /* Get virtual address of mm */
+ lwz r9,PGD(r9) /* get new->mm->pgd */
+ addis r9,r9,-KERNELBASE@h /* convert to phys addr */
+ mtspr M_TWB, r9 /* Update MMU base address */
X mtspr M_CASID, r5 /* Update context */
X tlbia
X #endif
X SYNC
-
-/* FALL THROUGH into int_return */
-#ifdef __SMP__
- /* call schedule_tail if this is the first time for a child process */
- lwz r5,TSS_SMP_FORK_RET(r4)
- cmpi 0,r5,0
- beq+ int_return
- li r3,0
- stw r3,TSS_SMP_FORK_RET(r4)
- bl schedule_tail
-#endif /* __SMP__ */
+2: lwz r9,_MSR(r1) /* Returning to user mode? */
+ andi. r9,r9,MSR_PR
+ beq+ 10f /* if not, don't adjust kernel stack */
+8: addi r4,r1,INT_FRAME_SIZE+STACK_UNDERHEAD /* size of frame */
+ stw r4,TSS+KSP(r2) /* save kernel stack pointer */
+ tophys(r9,r1,r9)
+ mtspr SPRG2,r9 /* phys exception stack pointer */
+10: lwz r2,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r2
+ mtlr r0
+ lwz r2,_XER(r1)
+ lwz r0,_CCR(r1)
+ mtspr XER,r2
+ mtcrf 0xFF,r0
+ /* r3-r13 are destroyed -- Cort */
+ REST_GPR(14, r1)
+ REST_8GPRS(15, r1)
+ REST_8GPRS(23, r1)
+ REST_GPR(31, r1)
+ lwz r2,_NIP(r1) /* Restore environment */
+ lwz r0,_MSR(r1)
+ mtspr SRR0,r2
+ mtspr SRR1,r0
+ lwz r0,GPR0(r1)
+ lwz r2,GPR2(r1)
+ lwz r1,GPR1(r1)
+ SYNC
+ rfi
X
X /*
X * Trap exit.
X */
+#ifdef __SMP__
+ .globl ret_from_smpfork
+ret_from_smpfork:
+ bl schedule_tail
+#endif
X .globl ret_from_syscall
X ret_from_syscall:
X .globl int_return
@@ -2127,8 +2149,8 @@
X lwz r5,_MSR(r1)
X and. r5,r5,r4
X beq 2f
-3: lis r4,n_lost_interrupts@ha
- lwz r4,n_lost_interrupts@l(r4)
+3: lis r4,ppc_n_lost_interrupts@ha
+ lwz r4,ppc_n_lost_interrupts@l(r4)
X cmpi 0,r4,0
X beq+ 1f
X addi r3,r1,STACK_FRAME_OVERHEAD
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/i8259.c linux/arch/ppc/kernel/i8259.c
--- v2.2.7/linux/arch/ppc/kernel/i8259.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/i8259.c Tue May 11 08:24:32 1999
@@ -0,0 +1,130 @@
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include "i8259.h"
+
+unsigned char cached_8259[2] = { 0xff, 0xff };
+#define cached_A1 (cached_8259[0])
+#define cached_21 (cached_8259[1])
+
+int i8259_irq(int cpu)
+{
+ int irq;
+
+ /*
+ * Perform an interrupt acknowledge cycle on controller 1
+ */
+ outb(0x0C, 0x20);
+ irq = inb(0x20) & 7;

+ if (irq == 2)
+ {

+ /*
+ * Interrupt is cascaded so perform interrupt
+ * acknowledge on controller 2
+ */
+ outb(0x0C, 0xA0);
+ irq = (inb(0xA0) & 7) + 8;
+ }
+ else if (irq==7)
+ {
+ /*
+ * This may be a spurious interrupt
+ *
+ * Read the interrupt status register. If the most
+ * significant bit is not set then there is no valid
+ * interrupt
+ */
+ outb(0x0b, 0x20);
+ if(~inb(0x20)&0x80)
+ return -1;


+ }
+ return irq;
+}
+

+static void i8259_mask_and_ack_irq(unsigned int irq_nr)
+{
+ if ( irq_nr >= i8259_pic.irq_offset )
+ irq_nr -= i8259_pic.irq_offset;
+
+ if (irq_nr > 7) {
+ cached_A1 |= 1 << (irq_nr-8);
+ inb(0xA1); /* DUMMY */
+ outb(cached_A1,0xA1);
+ outb(0x20,0xA0); /* Non-specific EOI */
+ outb(0x20,0x20); /* Non-specific EOI to cascade */
+ } else {
+ cached_21 |= 1 << irq_nr;
+ inb(0x21); /* DUMMY */
+ outb(cached_21,0x21);
+ outb(0x20,0x20); /* Non-specific EOI */
+ }
+}
+
+static void i8259_set_irq_mask(int irq_nr)
+{
+ outb(cached_A1,0xA1);
+ outb(cached_21,0x21);
+}
+
+static void i8259_mask_irq(unsigned int irq_nr)
+{
+ if ( irq_nr >= i8259_pic.irq_offset )
+ irq_nr -= i8259_pic.irq_offset;
+ if ( irq_nr < 8 )
+ cached_21 |= 1 << irq_nr;
+ else
+ cached_A1 |= 1 << (irq_nr-8);
+ i8259_set_irq_mask(irq_nr);
+}
+
+static void i8259_unmask_irq(unsigned int irq_nr)
+{
+
+ if ( irq_nr >= i8259_pic.irq_offset )
+ irq_nr -= i8259_pic.irq_offset;
+ if ( irq_nr < 8 )
+ cached_21 &= ~(1 << irq_nr);
+ else
+ cached_A1 &= ~(1 << (irq_nr-8));
+ i8259_set_irq_mask(irq_nr);
+}
+
+struct hw_interrupt_type i8259_pic = {
+ " i8259 ",
+ NULL,
+ NULL,
+ NULL,
+ i8259_unmask_irq,
+ i8259_mask_irq,
+ i8259_mask_and_ack_irq,
+ 0
+};
+
+static void
+no_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+}
+
+void __init i8259_init(void)
+{
+ /* init master interrupt controller */
+ outb(0x11, 0x20); /* Start init sequence */
+ outb(0x00, 0x21); /* Vector base */
+ outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
+ outb(0x01, 0x21); /* Select 8086 mode */
+ outb(0xFF, 0x21); /* Mask all */
+ /* init slave interrupt controller */
+ outb(0x11, 0xA0); /* Start init sequence */
+ outb(0x08, 0xA1); /* Vector base */
+ outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
+ outb(0x01, 0xA1); /* Select 8086 mode */
+ outb(0xFF, 0xA1); /* Mask all */
+ outb(cached_A1, 0xA1);
+ outb(cached_21, 0x21);
+ request_irq( i8259_pic.irq_offset + 2, no_action, SA_INTERRUPT,
+ "82c59 secondary cascade", NULL );
+ enable_irq(i8259_pic.irq_offset + 2); /* Enable cascade interrupt */
+}
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/i8259.h linux/arch/ppc/kernel/i8259.h
--- v2.2.7/linux/arch/ppc/kernel/i8259.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/i8259.h Tue May 11 08:24:32 1999
@@ -0,0 +1,12 @@
+
+#ifndef _PPC_KERNEL_i8259_H
+#define _PPC_KERNEL_i8259_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type i8259_pic;
+
+void i8259_init(void);
+int i8259_irq(int);
+
+#endif /* _PPC_KERNEL_i8259_H */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- v2.2.7/linux/arch/ppc/kernel/idle.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/idle.c Thu Apr 29 12:39:01 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: idle.c,v 1.60 1999/02/12 07:06:26 cort Exp $
+ * $Id: idle.c,v 1.61 1999/03/18 04:15:45 cort Exp $
X *
X * Idle daemon for PowerPC. Idle daemon will handle any action
X * that needs to be taken when the system becomes idle.
@@ -303,7 +303,14 @@
X hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE);
X hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM;
X asm("mtspr 1008,%0" : : "r" (hid0));
- msr |= MSR_POW;
+
+ /* set the POW bit in the MSR, and enable interrupts
+ * so we wake up sometime! */
+ _nmask_and_or_msr(0, MSR_POW | MSR_EE);
+
+ /* Disable interrupts again so restore_flags will
+ * work. */
+ _nmask_and_or_msr(MSR_EE, 0);
X }
X restore_flags(msr);
X default:
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/indirect_pci.c linux/arch/ppc/kernel/indirect_pci.c
--- v2.2.7/linux/arch/ppc/kernel/indirect_pci.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/indirect_pci.c Tue May 11 08:24:32 1999
@@ -0,0 +1,121 @@
+/*
+ * Support for indirect PCI bridges.
+ *
+ * Copyright (C) 1998 Gabriel Paubert.
+ *
+ * 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/pci.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+unsigned int * pci_config_address;
+unsigned char * pci_config_data;
+
+int indirect_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char *val)
+{
+ unsigned flags;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ *val= in_8(pci_config_data + (offset&3));
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short *val)
+{
+ unsigned flags;
+
+ if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ *val= in_le16((unsigned short *)(pci_config_data + (offset&3)));
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int *val)
+{
+ unsigned flags;
+
+ if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ *val= in_le32((unsigned *)pci_config_data);
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char val)
+{
+ unsigned flags;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ out_8(pci_config_data + (offset&3), val);
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short val)
+{
+ unsigned flags;
+
+ if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ out_le16((unsigned short *)(pci_config_data + (offset&3)), val);
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int indirect_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int val)
+{
+ unsigned flags;
+
+ if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ save_flags(flags); cli();
+
+ out_be32(pci_config_address,
+ ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80);
+
+ out_le32((unsigned *)pci_config_data, val);
+
+ restore_flags(flags);
+ return PCIBIOS_SUCCESSFUL;
+}
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.2.7/linux/arch/ppc/kernel/irq.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/irq.c Thu Apr 29 12:39:01 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: irq.c,v 1.102 1999/02/03 01:36:59 paulus Exp $
+ * $Id: irq.c,v 1.105 1999/03/25 19:51:51 cort Exp $
X *
X * arch/ppc/kernel/irq.c
X *
@@ -58,44 +58,15 @@


X #include <asm/amigahw.h>
X #include <asm/amigappc.h>

X #include <asm/ptrace.h>
-#ifdef CONFIG_8xx
-#include <asm/8xx_immap.h>
-#include <asm/mbx.h>
-#endif
X
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+#include "local_irq.h"
+
X extern volatile unsigned long ipi_count;
-static void dispatch_handler(struct pt_regs *regs, int irq);
X void enable_irq(unsigned int irq_nr);
X void disable_irq(unsigned int irq_nr);
X
-static void i8259_mask_and_ack_irq(unsigned int irq_nr);
-static void i8259_mask_irq(unsigned int irq_nr);
-static void i8259_unmask_irq(unsigned int irq_nr);
-#ifdef CONFIG_8xx
-static void mbx_mask_and_ack(unsigned int irq_nr);
-static void mbx_mask_irq(unsigned int irq_nr);
-static void mbx_unmask_irq(unsigned int irq_nr);
-static void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs);
-#else /* CONFIG_8xx */
-static volatile unsigned char *chrp_int_ack_special;
-extern void process_int(unsigned long vec, struct pt_regs *fp);
-extern void apus_init_IRQ(void);
-extern void amiga_disable_irq(unsigned int irq);
-extern void amiga_enable_irq(unsigned int irq);
-static void pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base);
-static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs);
-static void pmac_mask_irq(unsigned int irq_nr);
-static void pmac_unmask_irq(unsigned int irq_nr);
-static void pmac_mask_and_ack_irq(unsigned int irq_nr);
-static void chrp_mask_and_ack_irq(unsigned int irq_nr);
-static void chrp_unmask_irq(unsigned int irq_nr);
-static void chrp_mask_irq(unsigned int irq_nr);
-#ifdef __SMP__
-static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
-extern void smp_message_recv(void);
-#endif /* __SMP__ */
-#endif /* CONFIG_8xx */
+/* Fixme - Need to figure out a way to get rid of this - Corey */
+volatile unsigned char *chrp_int_ack_special;
X
X #ifdef CONFIG_APUS
X /* Rename a few functions. Requires the CONFIG_APUS protection. */
@@ -105,39 +76,19 @@
X #define VEC_SPUR (24)
X #endif
X
+#define MAXCOUNT 10000000
+
X #define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
-unsigned char cached_8259[2] = { 0xff, 0xff };
-#define cached_A1 (cached_8259[0])
-#define cached_21 (cached_8259[1])
-
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-int max_irqs;
-int max_real_irqs;
-static int spurious_interrupts = 0;
-static unsigned int cached_irq_mask[NR_MASK_WORDS];
-unsigned int lost_interrupts[NR_MASK_WORDS];
-atomic_t n_lost_interrupts;
-
-#ifndef CONFIG_8xx
-#define GATWICK_IRQ_POOL_SIZE 10
-static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
-/* pmac */
-struct pmac_irq_hw {
- unsigned int flag;
- unsigned int enable;
- unsigned int ack;
- unsigned int level;
-};
-
-/* these addresses are obtained from the device tree now -- Cort */
-volatile struct pmac_irq_hw *pmac_irq_hw[4] __pmac = {
- (struct pmac_irq_hw *) 0xf3000020,
- (struct pmac_irq_hw *) 0xf3000010,
- (struct pmac_irq_hw *) 0xf4000020,
- (struct pmac_irq_hw *) 0xf4000010,
-};
-#endif /* CONFIG_8xx */
+
+int ppc_spurious_interrupts = 0;
+
+unsigned int ppc_local_bh_count[NR_CPUS];
+unsigned int ppc_local_irq_count[NR_CPUS];
+struct irqaction *ppc_irq_action[NR_IRQS];
+unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
+unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
+atomic_t ppc_n_lost_interrupts;
+
X
X /* nasty hack for shared irq's since we need to do kmalloc calls but
X * can't very early in the boot when we need to do a request irq.
@@ -174,82 +125,7 @@
X kfree(ptr);
X }
X
-struct hw_interrupt_type {
- const char * typename;
- void (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*handle)(unsigned int irq, struct pt_regs * regs);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
- void (*mask_and_ack)(unsigned int irq);
- int irq_offset;
-};
-
-#define mask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->disable) irq_desc[irq].ctl->disable(irq);})
-#define unmask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->enable) irq_desc[irq].ctl->enable(irq);})
-#define mask_and_ack_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->mask_and_ack) irq_desc[irq].ctl->mask_and_ack(irq);})
-
-struct irqdesc {
- struct irqaction *action;
- struct hw_interrupt_type *ctl;
-};
-static struct irqdesc irq_desc[NR_IRQS] = {{0, 0}, };
-
-static struct hw_interrupt_type i8259_pic = {
- " i8259 ",
- NULL,
- NULL,
- NULL,
- i8259_unmask_irq,
- i8259_mask_irq,
- i8259_mask_and_ack_irq,
- 0
-};
-#ifndef CONFIG_8xx
-static struct hw_interrupt_type pmac_pic = {
- " PMAC-PIC ",
- NULL,
- NULL,
- NULL,
- pmac_unmask_irq,
- pmac_mask_irq,
- pmac_mask_and_ack_irq,
- 0
-};
-
-static struct hw_interrupt_type gatwick_pic = {
- " GATWICK ",
- NULL,
- NULL,
- NULL,
- pmac_unmask_irq,
- pmac_mask_irq,
- pmac_mask_and_ack_irq,
- 0
-};
-
-static struct hw_interrupt_type open_pic = {
- " OpenPIC ",
- NULL,
- NULL,
- NULL,
- chrp_unmask_irq,
- chrp_mask_irq,
- chrp_mask_and_ack_irq,
- 0
-};
-#else
-static struct hw_interrupt_type ppc8xx_pic = {
- " 8xx SIU ",
- NULL,
- NULL,
- NULL,
- mbx_unmask_irq,
- mbx_mask_irq,
- mbx_mask_and_ack,
- 0
-};
-#endif /* CONFIG_8xx */
+struct irqdesc irq_desc[NR_IRQS] = {{0, 0}, };
X
X int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
X unsigned long irqflags, const char * devname, void *dev_id)
@@ -357,19 +233,17 @@
X }
X #ifdef __SMP__
X /* should this be per processor send/receive? */
- len += sprintf(buf+len, "IPI: %10lu", ipi_count);
- for ( i = 0 ; i <= smp_num_cpus-1; i++ )
- len += sprintf(buf+len," ");
- len += sprintf(buf+len, " interprocessor messages received\n");
+ len += sprintf(buf+len, "IPI: %10lu\n", ipi_count);
X #endif
- len += sprintf(buf+len, "BAD: %10u",spurious_interrupts);
- for ( i = 0 ; i <= smp_num_cpus-1; i++ )
- len += sprintf(buf+len," ");
- len += sprintf(buf+len, " spurious or short\n");
+ len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);


X return len;
X }
X

-static void dispatch_handler(struct pt_regs *regs, int irq)
+/*
+ * Eventually, this should take an array of interrupts and an array size
+ * so it can dispatch multiple interrupts.
+ */
+void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
X {
X int status;
X struct irqaction *action;
@@ -390,209 +264,18 @@
X __cli();
X unmask_irq(irq);
X } else {
- spurious_interrupts++;
+ ppc_spurious_interrupts++;
X disable_irq( irq );
X }
X }
X
-#define MAXCOUNT 100000000
X asmlinkage void do_IRQ(struct pt_regs *regs, int isfake)
X {
- int irq;
- unsigned long bits = 0;
X int cpu = smp_processor_id();
- int openpic_eoi_done = 0;
-
- hardirq_enter(cpu);
-#ifndef CONFIG_8xx
-#ifdef __SMP__
- /* IPI's are a hack on the powersurge -- Cort */
- if ( (_machine == _MACH_Pmac) && (cpu != 0) )
- {
- if (!isfake)
- {
-#ifdef CONFIG_XMON
- static int xmon_2nd;
- if (xmon_2nd)
- xmon(regs);
-#endif
- smp_message_recv();
- goto out;
- }
- /* could be here due to a do_fake_interrupt call but we don't
- mess with the controller from the second cpu -- Cort */


- goto out;
- }
-

- {
- unsigned int loops = MAXCOUNT;
- while (test_bit(0, &global_irq_lock)) {
- if (smp_processor_id() == global_irq_holder) {
- printk("uh oh, interrupt while we hold global irq lock!\n");
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- break;
- }
- if (loops-- == 0) {
- printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- }
- }
- }
-#endif /* __SMP__ */
-
- switch ( _machine )
- {
- case _MACH_Pmac:
- for (irq = max_real_irqs - 1; irq > 0; irq -= 32) {
- int i = irq >> 5;
- bits = ld_le32(&pmac_irq_hw[i]->flag)
- | lost_interrupts[i];
- if (bits == 0)
- continue;
- irq -= cntlzw(bits);
- break;
- }
- break;
- case _MACH_chrp:
- irq = openpic_irq(0);
- if (irq == IRQ_8259_CASCADE)
- {
- /*
- * This magic address generates a PCI IACK cycle.
- *
- * This should go in the above mask/ack code soon. -- Cort
- */
- irq = *chrp_int_ack_special;
- /*
- * Acknowledge as soon as possible to allow i8259
- * interrupt nesting
- */
- openpic_eoi(0);
- openpic_eoi_done = 1;
- }
- if (irq == OPENPIC_VEC_SPURIOUS)
- {
- /*
- * Spurious interrupts should never be
- * acknowledged
- */
- spurious_interrupts++;
- openpic_eoi_done = 1;
- }
- bits = 1UL << irq;
- break;
- case _MACH_prep:
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- outb(0x0C, 0xA0);
- irq = (inb(0xA0) & 7) + 8;
- bits |= 1UL << irq;
-#if 0
- /* It's possible to loose intrs here
- * if we get 2 intrs in the upper 8
- * bits. We eoi irq 2 and handle one of
- * the upper intrs but then ignore it
- * since we've already eoi-d 2. So,
- * we must keep track of lost intrs.
- * -- Cort
- */
- while (1)
- {
- int i;
- outb(0x0C, 0xA0);
- i = inb(0xA0);
- if ( !(i & 128) )
- break;
- irq &= 7;
- irq += 8;
- bits |= 1UL << irq;
- }
-#endif
- }
- else
- bits = 1UL << irq;
-
- break;
-#ifdef CONFIG_APUS
- case _MACH_apus:
- {
- int old_level, new_level;
-
- old_level = ~(regs->mq) & IPLEMU_IPLMASK;
- new_level = (~(regs->mq) >> 3) & IPLEMU_IPLMASK;
-
- if (new_level == 0)
- {
- goto apus_out;
- }
-
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
- | (~(new_level) & IPLEMU_IPLMASK)));
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
-
- process_int (VEC_SPUR+new_level, regs);
-
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
- | (~(old_level) & IPLEMU_IPLMASK)));
-apus_out:
- hardirq_exit(cpu);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
- goto out2;
- }
-#endif
- }
X
- if (irq < 0)
- {
- printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
- irq, regs->nip);
- spurious_interrupts++;


- goto out;
- }
-

-#else /* CONFIG_8xx */
- /* For MPC8xx, read the SIVEC register and shift the bits down
- * to get the irq number.
- */
- bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
- irq = bits >> 26;
- irq += ppc8xx_pic.irq_offset;
- bits = 1UL << irq;
-#endif /* CONFIG_8xx */
-#if 0
- /*
- * this allows for > 1 interrupt at a time so we can
- * clear out any 'double' interrupts on prep and
- * finish up the lost interrupts.
- * It doesn't currently work for irqs > 31 so I'm leaving
- * it commented out for now.
- * -- Cort
- */
- for ( i = 0 ; i < sizeof(bits)*8 ; i++ )
- if ( bits & (1UL<<i) )
- dispatch_handler( regs, i );
-#else
- dispatch_handler( regs, irq );
-#endif
-
-#ifndef CONFIG_8xx
-out:
- if (_machine == _MACH_chrp && !openpic_eoi_done)
- openpic_eoi(0);
-#endif /* CONFIG_8xx */
- hardirq_exit(cpu);
-#ifdef CONFIG_APUS
-out2:
-#endif
+ hardirq_enter(cpu);
+ ppc_md.do_IRQ(regs, cpu, isfake);
+ hardirq_exit(cpu);
X }
X

X unsigned long probe_irq_on (void)

@@ -605,461 +288,16 @@


X return 0;
X }
X

-static void i8259_mask_and_ack_irq(unsigned int irq_nr)
-{
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
- if (irq_nr > 7) {
- cached_A1 |= 1 << (irq_nr-8);
- inb(0xA1); /* DUMMY */
- outb(cached_A1,0xA1);
- outb(0x62,0x20); /* Specific EOI to cascade */
- /*outb(0x20,0xA0);*/
- outb(0x60|(irq_nr-8), 0xA0); /* specific eoi */
- } else {
- cached_21 |= 1 << irq_nr;
- inb(0x21); /* DUMMY */
- outb(cached_21,0x21);
- /*outb(0x20,0x20);*/
- outb(0x60|irq_nr,0x20); /* specific eoi */
- }
-}
-
-static void i8259_set_irq_mask(int irq_nr)
-{
- outb(cached_A1,0xA1);
- outb(cached_21,0x21);
-}
-
-static void i8259_mask_irq(unsigned int irq_nr)
-{
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
- if ( irq_nr < 8 )
- cached_21 |= 1 << irq_nr;
- else
- cached_A1 |= 1 << (irq_nr-8);
- i8259_set_irq_mask(irq_nr);
-}
-
-static void i8259_unmask_irq(unsigned int irq_nr)
-{
-
- if ( irq_nr >= i8259_pic.irq_offset )
- irq_nr -= i8259_pic.irq_offset;
- if ( irq_nr < 8 )
- cached_21 &= ~(1 << irq_nr);
- else
- cached_A1 &= ~(1 << (irq_nr-8));
- i8259_set_irq_mask(irq_nr);
-}
-
-#ifndef CONFIG_8xx
-static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int irq, bits;
-
- for (irq = max_irqs - 1; irq > max_real_irqs; irq -= 32) {
- int i = irq >> 5;
- bits = ld_le32(&pmac_irq_hw[i]->flag)
- | lost_interrupts[i];
- if (bits == 0)
- continue;
- irq -= cntlzw(bits);
- break;
- }
- /* The previous version of this code allowed for this case, we
- * don't. Put this here to check for it.
- * -- Cort
- */
- if ( irq_desc[irq].ctl != &gatwick_pic )
- printk("gatwick irq not from gatwick pic\n");
- else
- dispatch_handler( regs, irq );
-}
-
-void pmac_mask_and_ack_irq(unsigned int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- clear_bit(irq_nr, cached_irq_mask);
- if (test_and_clear_bit(irq_nr, lost_interrupts))
- atomic_dec(&n_lost_interrupts);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- out_le32(&pmac_irq_hw[i]->enable, cached_irq_mask[i]);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- do {
- /* make sure ack gets to controller before we enable interrupts */
- mb();
- } while(in_le32(&pmac_irq_hw[i]->flag) & bit);
-
-}
-
-void __openfirmware chrp_mask_and_ack_irq(unsigned int irq_nr)
-{
- if (is_8259_irq(irq_nr))
- i8259_mask_and_ack_irq(irq_nr);
-}
-
-static void pmac_set_irq_mask(int irq_nr)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- /* enable unmasked interrupts */
- out_le32(&pmac_irq_hw[i]->enable, cached_irq_mask[i]);
-
- do {
- /* make sure mask gets to controller before we
- return to user */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (cached_irq_mask[i] & bit));
-
- /*
- * Unfortunately, setting the bit in the enable register
- * when the device interrupt is already on *doesn't* set
- * the bit in the flag register or request another interrupt.
- */
- if ((bit & cached_irq_mask[i])
- && (ld_le32(&pmac_irq_hw[i]->level) & bit)
- && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) {
- if (!test_and_set_bit(irq_nr, lost_interrupts))
- atomic_inc(&n_lost_interrupts);
- }
-}
-
-static void pmac_mask_irq(unsigned int irq_nr)
-{
- clear_bit(irq_nr, cached_irq_mask);
- pmac_set_irq_mask(irq_nr);
- mb();
-}
-
-static void pmac_unmask_irq(unsigned int irq_nr)
-{
- set_bit(irq_nr, cached_irq_mask);
- pmac_set_irq_mask(irq_nr);
-}
-
-static void __openfirmware chrp_mask_irq(unsigned int irq_nr)
-{
- if (is_8259_irq(irq_nr))
- i8259_mask_irq(irq_nr);
- else
- openpic_disable_irq(irq_to_openpic(irq_nr));
-}
-
-static void __openfirmware chrp_unmask_irq(unsigned int irq_nr)
-{
- if (is_8259_irq(irq_nr))
- i8259_unmask_irq(irq_nr);
- else
- openpic_enable_irq(irq_to_openpic(irq_nr));
-}
-
-/* This routine will fix some missing interrupt values in the device tree
- * on the gatwick mac-io controller used by some PowerBooks
- */
-static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
-{
- struct device_node *node;
- int count;
-
- memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
- node = gw->child;
- count = 0;
- while(node)
- {
- /* Fix SCC */
- if (strcasecmp(node->name, "escc") == 0)
- if (node->child) {
- if (node->child->n_intrs < 3) {
- node->child->intrs = &gatwick_int_pool[count];
- count += 3;
- }
- node->child->n_intrs = 3;
- node->child->intrs[0].line = 15+irq_base;
- node->child->intrs[1].line = 4+irq_base;
- node->child->intrs[2].line = 5+irq_base;
- printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
- node->child->intrs[0].line,
- node->child->intrs[1].line,
- node->child->intrs[2].line);
- }
- /* Fix media-bay & left SWIM */
- if (strcasecmp(node->name, "media-bay") == 0) {
- struct device_node* ya_node;
-
- if (node->n_intrs == 0)
- node->intrs = &gatwick_int_pool[count++];
- node->n_intrs = 1;
- node->intrs[0].line = 29+irq_base;
- printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
- node->intrs[0].line);
-
- ya_node = node->child;
- while(ya_node)
- {
- if (strcasecmp(ya_node->name, "floppy") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 19+irq_base;
- ya_node->intrs[1].line = 1+irq_base;
- printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- if (strcasecmp(ya_node->name, "ata4") == 0) {
- if (ya_node->n_intrs < 2) {
- ya_node->intrs = &gatwick_int_pool[count];
- count += 2;
- }
- ya_node->n_intrs = 2;
- ya_node->intrs[0].line = 14+irq_base;
- ya_node->intrs[1].line = 3+irq_base;
- printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
- ya_node->intrs[0].line, ya_node->intrs[1].line);
- }
- ya_node = ya_node->sibling;
- }
- }
- node = node->sibling;
- }
- if (count > 10) {
- printk("WARNING !! Gatwick interrupt pool overflow\n");
- printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
- printk(" requested = %d\n", count);
- }
-}
-
-#ifdef __SMP__
-static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- smp_message_recv();
-}
-#endif /* __SMP__ */
-
-
-#else /* CONFIG_8xx */
-
-static void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
- int bits, irq;
-
- /* A bug in the QSpan chip causes it to give us 0xff always
- * when doing a character read. So read 32 bits and shift.
- * This doesn't seem to return useful values anyway, but
- * read it to make sure things are acked.
- * -- Cort
- */
- irq = (inl(0x508) >> 24)&0xff;
- if ( irq != 0xff ) printk("iack %d\n", irq);
-
- outb(0x0C, 0x20);
- irq = inb(0x20) & 7;
- if (irq == 2)
- {
- outb(0x0C, 0xA0);
- irq = inb(0xA0);
- irq = (irq&7) + 8;
- }
- bits = 1UL << irq;
- irq += i8259_pic.irq_offset;
- dispatch_handler( regs, irq );
-}
-
-static void mbx_mask_and_ack(unsigned int irq_nr)
-{
- /* this shouldn't be masked, we mask the 8259 if we need to -- Cort */
- if ( irq_nr != ISA_BRIDGE_INT )
- mbx_mask_irq(irq_nr);
- if ( irq_nr >= ppc8xx_pic.irq_offset )
- irq_nr -= ppc8xx_pic.irq_offset;
- /* clear the pending bits */
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-irq_nr);
-}
-
-static void mbx_mask_irq(unsigned int irq_nr)
-{
- if ( irq_nr == ISA_BRIDGE_INT ) return;
- if ( irq_nr >= ppc8xx_pic.irq_offset )
- irq_nr -= ppc8xx_pic.irq_offset;
- cached_irq_mask[0] &= ~(1 << (31-irq_nr));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = cached_irq_mask[0];
-}
-
-static void mbx_unmask_irq(unsigned int irq_nr)
-{
- if ( irq_nr >= ppc8xx_pic.irq_offset )
- irq_nr -= ppc8xx_pic.irq_offset;
- cached_irq_mask[0] |= (1 << (31-irq_nr));
- ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = cached_irq_mask[0];
-}
-#endif /* CONFIG_8xx */
-
-static void __init i8259_init(void)
-{
- /* init master interrupt controller */
- outb(0x11, 0x20); /* Start init sequence */
- outb(0x00, 0x21); /* Vector base */
- outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0x21); /* Select 8086 mode */
- outb(0xFF, 0x21); /* Mask all */
- /* init slave interrupt controller */
- outb(0x11, 0xA0); /* Start init sequence */
- outb(0x08, 0xA1); /* Vector base */
- outb(0x02, 0xA1); /* edge triggered, Cascade (slave) on IRQ2 */
- outb(0x01, 0xA1); /* Select 8086 mode */
- outb(0xFF, 0xA1); /* Mask all */
- outb(cached_A1, 0xA1);
- outb(cached_21, 0x21);
- request_irq( i8259_pic.irq_offset + 2, no_action, SA_INTERRUPT,
- "8259 secondary cascade", NULL );
- enable_irq(i8259_pic.irq_offset + 2); /* Enable cascade interrupt */
-}
-
X void __init init_IRQ(void)
X {
- extern void xmon_irq(int, void *, struct pt_regs *);
- int i;
X static int once = 0;
-#ifndef CONFIG_8xx
- struct device_node *irqctrler;
- unsigned long addr;
- struct device_node *np;
- int second_irq = -999;
-#endif
+
X if ( once )
X return;
X else
X once++;
X
-#ifndef CONFIG_8xx
- switch (_machine)
- {
- case _MACH_Pmac:
- /* G3 powermacs have 64 interrupts, G3 Series PowerBook have 128,
- others have 32 */
- max_irqs = max_real_irqs = 32;
- irqctrler = find_devices("mac-io");
- if (irqctrler)
- {
- max_real_irqs = 64;
- if (irqctrler->next)
- max_irqs = 128;
- else
- max_irqs = 64;
- }
- for ( i = 0; i < max_real_irqs ; i++ )
- irq_desc[i].ctl = &pmac_pic;
-
- /* get addresses of first controller */
- if (irqctrler) {
- if (irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 0; i < 2; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (2 - i) * 0x10);
- }
-
- /* get addresses of second controller */
- irqctrler = (irqctrler->next) ? irqctrler->next : NULL;
- if (irqctrler && irqctrler->n_addrs > 0) {
- addr = (unsigned long)
- ioremap(irqctrler->addrs[0].address, 0x40);
- for (i = 2; i < 4; ++i)
- pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
- (addr + (4 - i) * 0x10);
- }
- }
-
- /* disable all interrupts in all controllers */
- for (i = 0; i * 32 < max_irqs; ++i)
- out_le32(&pmac_irq_hw[i]->enable, 0);
-
- /* get interrupt line of secondary interrupt controller */
- if (irqctrler) {
- second_irq = irqctrler->intrs[0].line;
- printk(KERN_INFO "irq: secondary controller on irq %d\n",
- (int)second_irq);
- if (device_is_compatible(irqctrler, "gatwick"))
- pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
- for ( i = max_real_irqs ; i < max_irqs ; i++ )
- irq_desc[i].ctl = &gatwick_pic;
- request_irq( second_irq, gatwick_action, SA_INTERRUPT,
- "gatwick cascade", 0 );
- }
- printk("System has %d possible interrupts\n", max_irqs);
- if (max_irqs != max_real_irqs)
- printk(KERN_DEBUG "%d interrupts on main controller\n",
- max_real_irqs);
-
-#ifdef CONFIG_XMON
- request_irq(20, xmon_irq, 0, "NMI - XMON", 0);
-#endif /* CONFIG_XMON */
- break;
- case _MACH_chrp:
- if ( !(np = find_devices("pci") ) )
- printk("Cannot find pci to get ack address\n");
- else
- {
- chrp_int_ack_special = (volatile unsigned char *)
- (*(unsigned long *)get_property(np,
- "8259-interrupt-acknowledge", NULL));
- }
- for ( i = 16 ; i < 36 ; i++ )
- irq_desc[i].ctl = &open_pic;
- /* openpic knows that it's at irq 16 offset
- * so we don't need to set it in the pic structure
- * -- Cort
- */
- openpic_init(1);
- for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
- i8259_init();
-#ifdef CONFIG_XMON
- request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
- xmon_irq, 0, "NMI", 0);
-#endif /* CONFIG_XMON */
-#ifdef __SMP__
- request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS),
- openpic_ipi_action, 0, "IPI0", 0);
-#endif /* __SMP__ */
- break;
- case _MACH_prep:
- for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
- i8259_init();
- break;
-#ifdef CONFIG_APUS
- case _MACH_apus:
- apus_init_IRQ();
- break;
-#endif
- }
-#else /* CONFIG_8xx */
- ppc8xx_pic.irq_offset = 16;
- for ( i = 16 ; i < 32 ; i++ )
- irq_desc[i].ctl = &ppc8xx_pic;
- unmask_irq(CPM_INTERRUPT);
-
- for ( i = 0 ; i < 16 ; i++ )
- irq_desc[i].ctl = &i8259_pic;
- i8259_init();
- request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
- enable_irq(ISA_BRIDGE_INT);
-#endif /* CONFIG_8xx */
+ ppc_md.init_IRQ();
X }
X
X #ifdef __SMP__
@@ -1078,9 +316,13 @@
X
X printk("\n%s, CPU %d:\n", str, cpu);
X printk("irq: %d [%d %d]\n",
- atomic_read(&global_irq_count), local_irq_count[0], local_irq_count[1]);
+ atomic_read(&global_irq_count),
+ ppc_local_irq_count[0],
+ ppc_local_irq_count[1]);
X printk("bh: %d [%d %d]\n",
- atomic_read(&global_bh_count), local_bh_count[0], local_bh_count[1]);
+ atomic_read(&global_bh_count),
+ ppc_local_bh_count[0],
+ ppc_local_bh_count[1]);
X stack = (unsigned long *) &str;
X for (i = 40; i ; i--) {
X unsigned long x = *++stack;
@@ -1115,7 +357,8 @@
X * already executing in one..
X */
X if (!atomic_read(&global_irq_count)) {
- if (local_bh_count[cpu] || !atomic_read(&global_bh_count))
+ if (ppc_local_bh_count[cpu]
+ || !atomic_read(&global_bh_count))
X break;
X }
X
@@ -1136,7 +379,8 @@
X continue;
X if (global_irq_lock)
X continue;
- if (!local_bh_count[cpu] && atomic_read(&global_bh_count))
+ if (!ppc_local_bh_count[cpu]
+ && atomic_read(&global_bh_count))
X continue;
X if (!test_and_set_bit(0,&global_irq_lock))
X break;
@@ -1226,7 +470,7 @@
X if (flags & (1 << 15)) {
X int cpu = smp_processor_id();
X __cli();
- if (!local_irq_count[cpu])
+ if (!ppc_local_irq_count[cpu])
X get_irqlock(cpu);
X }
X }
@@ -1235,7 +479,7 @@
X {
X int cpu = smp_processor_id();
X
- if (!local_irq_count[cpu])
+ if (!ppc_local_irq_count[cpu])
X release_irqlock(cpu);
X __sti();
X }
@@ -1259,7 +503,7 @@
X retval = 2 + local_enabled;
X
X /* check for global flags if we're not in an interrupt */
- if (!local_irq_count[smp_processor_id()]) {
+ if (!ppc_local_irq_count[smp_processor_id()]) {
X if (local_enabled)
X retval = 1;
X if (global_irq_holder == (unsigned char) smp_processor_id())
@@ -1268,6 +512,31 @@


X return retval;
X }
X

+int
+tb(long vals[],
+ int max_size)
+{
+ register unsigned long *orig_sp __asm__ ("r1");
+ register unsigned long lr __asm__ ("r3");
+ unsigned long *sp;
+ int i;
+
+ asm volatile ("mflr 3");
+ vals[0] = lr;
+ sp = (unsigned long *) *orig_sp;
+ sp = (unsigned long *) *sp;
+ for (i=1; i<max_size; i++) {
+ if (sp == 0) {
+ break;
+ }
+
+ vals[i] = *(sp+1);
+ sp = (unsigned long *) *sp;
+ }
+
+ return i;
+}
+
X void __global_restore_flags(unsigned long flags)
X {
X switch (flags) {
@@ -1284,8 +553,20 @@
X __sti();
X break;
X default:
+ {
+ unsigned long trace[5];
+ int count;
+ int i;
+
X printk("global_restore_flags: %08lx (%08lx)\n",
X flags, (&flags)[-1]);
+ count = tb(trace, 5);
+ printk("tb:");
+ for(i=0; i<count; i++) {
+ printk(" %8.8lx", trace[i]);
+ }
+ printk("\n");
+ }
X }
X }
X #endif /* __SMP__ */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/local_irq.h linux/arch/ppc/kernel/local_irq.h
--- v2.2.7/linux/arch/ppc/kernel/local_irq.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/local_irq.h Thu Apr 29 12:39:01 1999
@@ -0,0 +1,45 @@
+
+#ifndef _PPC_KERNEL_LOCAL_IRQ_H
+#define _PPC_KERNEL_LOCAL_IRQ_H
+


+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+

+void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
+
+/* Structure describing interrupts */
+struct hw_interrupt_type {
+ const char * typename;
+ void (*startup)(unsigned int irq);
+ void (*shutdown)(unsigned int irq);
+ void (*handle)(unsigned int irq, struct pt_regs * regs);
+ void (*enable)(unsigned int irq);
+ void (*disable)(unsigned int irq);
+ void (*mask_and_ack)(unsigned int irq);
+ int irq_offset;
+};
+
+#define mask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->disable) irq_desc[irq].ctl->disable(irq);})
+#define unmask_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->enable) irq_desc[irq].ctl->enable(irq);})
+#define mask_and_ack_irq(irq) ({if (irq_desc[irq].ctl && irq_desc[irq].ctl->mask_and_ack) irq_desc[irq].ctl->mask_and_ack(irq);})
+
+struct irqdesc {
+ struct irqaction *action;
+ struct hw_interrupt_type *ctl;
+};
+
+extern struct irqdesc irq_desc[NR_IRQS];
+
+
+#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
+
+extern int ppc_spurious_interrupts;
+extern int ppc_second_irq;
+extern struct irqaction *ppc_irq_action[NR_IRQS];
+extern unsigned int ppc_local_bh_count[NR_CPUS];
+extern unsigned int ppc_local_irq_count[NR_CPUS];
+extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS];
+extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS];
+extern atomic_t ppc_n_lost_interrupts;
+
+#endif /* _PPC_KERNEL_LOCAL_IRQ_H */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/mbx_pci.c linux/arch/ppc/kernel/mbx_pci.c
--- v2.2.7/linux/arch/ppc/kernel/mbx_pci.c Thu Apr 23 20:21:29 1998
+++ linux/arch/ppc/kernel/mbx_pci.c Thu Apr 29 12:39:01 1999
@@ -252,3 +252,20 @@
X }
X return PCIBIOS_DEVICE_NOT_FOUND;
X }
+
+__initfunc(
+void
+mbx_pcibios_fixup(void))
+{
+ /* Nothing to do here? */
+}
+
+__initfunc(
+void
+mbx_setup_pci_ptrs(void))
+{
+ set_config_access_method(mbx);
+
+ ppc_md.pcibios_fixup = mbx_pcibios_fixup;
+}
+
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/mbx_setup.c linux/arch/ppc/kernel/mbx_setup.c
--- v2.2.7/linux/arch/ppc/kernel/mbx_setup.c Fri Jan 8 22:36:02 1999
+++ linux/arch/ppc/kernel/mbx_setup.c Thu Apr 29 12:39:01 1999
@@ -1,5 +1,5 @@
X /*
- * $Id: mbx_setup.c,v 1.5 1998/12/29 18:55:07 cort Exp $
+ * $Id: mbx_setup.c,v 1.9 1999/04/28 11:54:09 davem Exp $
X *
X * linux/arch/ppc/kernel/setup.c
X *
@@ -39,6 +39,22 @@
X #include <asm/pgtable.h>
X #include <asm/ide.h>
X #include <asm/mbx.h>
+#include <asm/machdep.h>


+
+#include "time.h"
+#include "local_irq.h"
+

+static int mbx_set_rtc_time(unsigned long time);
+unsigned long mbx_get_rtc_time(void);
+void mbx_calibrate_decr(void);
+


+extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int mackbd_getkeycode(unsigned int scancode);
+extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char mackbd_unexpected_up(unsigned char keycode);
+extern void mackbd_leds(unsigned char leds);
+extern void mackbd_init_hw(void);

X
X extern unsigned long loops_per_sec;
X
@@ -55,35 +71,10 @@
X extern unsigned long find_available_memory(void);
X extern void m8xx_cpm_reset(uint);
X
-/* this really does make things cleaner -- Cort */
-void __init powermac_init(void)
-{
-}
-
X void __init adbdev_init(void)
X {
X }
X
-void __init mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)
-{


- ide_ioreg_t port = base;
- int i = 8;

-


- while (i--)
- *p++ = port++;

- *p++ = base + 0x206;


- if (irq != NULL)

- *irq = 0;
-#ifdef ATA_FLASH
- base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200);
- for (i = 0; i < 8; ++i)
- *p++ = base++;
- *p = ++base; /* Does not matter */
- if (irq)
- *irq = 13;
-#endif
-}
-
X __initfunc(void
X mbx_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p))
X {
@@ -144,4 +135,338 @@
X xmon(0);
X #endif
X machine_restart(NULL);
+}
+
+/* The decrementer counts at the system (internal) clock frequency divided by
+ * sixteen, or external oscillator divided by four. Currently, we only
+ * support the MBX, which is system clock divided by sixteen.
+ */
+__initfunc(void mbx_calibrate_decr(void))
+{
+ bd_t *binfo = (bd_t *)&res;
+ int freq, fp, divisor;
+
+ if ((((immap_t *)MBX_IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0)
+ printk("WARNING: Wrong decrementer source clock.\n");
+
+ /* The manual says the frequency is in Hz, but it is really
+ * as MHz. The value 'fp' is the number of decrementer ticks
+ * per second.
+ */
+ fp = (binfo->bi_intfreq * 1000000) / 16;
+ freq = fp*60; /* try to make freq/1e6 an integer */
+ divisor = 60;
+ printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
+ decrementer_count = freq / HZ / divisor;
+ count_period_num = divisor;
+ count_period_den = freq / 1000000;
+}
+
+/* A place holder for time base interrupts, if they are ever enabled.
+*/
+void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
+{
+ printk("timebase_interrupt()\n");
+}
+
+/* The RTC on the MPC8xx is an internal register.
+ * We want to protect this during power down, so we need to unlock,
+ * modify, and re-lock.
+ */
+static int
+mbx_set_rtc_time(unsigned long time)
+{
+ ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
+ ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc = time;
+ ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
+ return(0);
+}
+
+initfunc(unsigned long
+mbx_get_rtc_time(void)
+{
+ /* First, unlock all of the registers we are going to modify.
+ * To protect them from corruption during power down, registers
+ * that are maintained by keep alive power are "locked". To
+ * modify these registers we have to write the key value to
+ * the key location associated with the register.
+ */
+ ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
+ ((immap_t *)MBX_IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
+
+
+ /* Disable the RTC one second and alarm interrupts.
+ */
+ ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtcsc &=
+ ~(RTCSC_SIE | RTCSC_ALE);
+
+ /* Enabling the decrementer also enables the timebase interrupts
+ * (or from the other point of view, to get decrementer interrupts
+ * we have to enable the timebase). The decrementer interrupt
+ * is wired into the vector table, nothing to do here for that.
+ */
+ ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_tbscr =
+ ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
+ (TBSCR_TBF | TBSCR_TBE));
+ if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
+ panic("Could not allocate timer IRQ!");
+
+ /* Get time from the RTC.
+ */
+ return ((immap_t *)MBX_IMAP_ADDR)->im_sit.sit_rtc;
+}
+
+void
+mbx_restart(char *cmd)
+{
+ extern void MBX_gorom(void);
+
+ MBX_gorom();
+}
+
+void
+mbx_power_off(void)
+{
+ mbx_restart(NULL);
+}
+
+void
+mbx_halt(void)
+{
+ mbx_restart(NULL)
+}
+
+
+int mbx_setup_residual(char *buffer)
+{
+ int len = 0;
+ bd_t *bp;
+ extern RESIDUAL *res;
+
+ bp = (bd_t *)res;
+
+ len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
+ "bus clock\t: %dMHz\n",
+ bp->bi_intfreq /*/ 1000000*/,
+ bp->bi_busfreq /*/ 1000000*/);


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 09'
echo 'File patch-2.2.8 is continued in part 10'
echo 10 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part10

#!/bin/sh
# this is part 10 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 10; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&
+

+ return len;
+}
+

+void
+mbx_do_IRQ(struct pt_regs *regs,


+ int cpu,
+ int isfake)

+{
+ int irq;
+ unsigned long bits = 0;
+
+ /* For MPC8xx, read the SIVEC register and shift the bits down
+ * to get the irq number. */
+ bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
+ irq = bits >> 26;
+ irq += ppc8xx_pic.irq_offset;


+ bits = 1UL << irq;
+
+ if (irq < 0) {

+ printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+ irq, regs->nip);

+ spurious_interrupts++;
+ }
+ else {


+ ppc_irq_dispatch_handler( regs, irq );
+ }

+
+}
+
+static void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ int bits, irq;
+
+ /* A bug in the QSpan chip causes it to give us 0xff always
+ * when doing a character read. So read 32 bits and shift.
+ * This doesn't seem to return useful values anyway, but
+ * read it to make sure things are acked.


+ * -- Cort
+ */

+ irq = (inl(0x508) >> 24)&0xff;
+ if ( irq != 0xff ) printk("iack %d\n", irq);
+

+ outb(0x0C, 0x20);
+ irq = inb(0x20) & 7;
+ if (irq == 2)
+ {

+ outb(0x0C, 0xA0);
+ irq = inb(0xA0);
+ irq = (irq&7) + 8;


+ }
+ bits = 1UL << irq;

+ irq += i8259_pic.irq_offset;


+ ppc_irq_dispatch_handler( regs, irq );
+}
+

+
+/* On MBX8xx, the interrupt control (SIEL) was set by EPPC-bug. External
+ * interrupts can be either edge or level triggered, but there is no
+ * reason for us to change the EPPC-bug values (it would not work if we did).
+ */
+__initfunc(void
+mbx_init_IRQ(void))
+{
+ int i;
+
+ ppc8xx_pic.irq_offset = 16;
+ for ( i = 16 ; i < 32 ; i++ )
+ irq_desc[i].ctl = &ppc8xx_pic;
+ unmask_irq(CPM_INTERRUPT);
+


+ for ( i = 0 ; i < 16 ; i++ )
+ irq_desc[i].ctl = &i8259_pic;
+ i8259_init();

+ request_irq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
+ enable_irq(ISA_BRIDGE_INT);


+}
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */

+void
+mbx_ide_insw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_insw(port+_IO_BASE), buf, ns);
+}
+
+void
+mbx_ide_outsw(ide_ioreg_t port, void *buf, int ns)


+{
+ ide_outsw(port+_IO_BASE, buf, ns);
+}
+
+int

+mbx_ide_default_irq(ide_ioreg_t base)
+{
+ return 14;
+}
+
+ide_ioreg_t
+mbx_ide_default_io_base(int index)
+{
+ return index;
+}
+
+int
+mbx_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+ return 0
+}
+
+void
+mbx_ide_request_region(ide_ioreg_t from,


+ unsigned int extent,
+ const char *name)
+{
+}

+
+void
+mbx_ide_release_region(ide_ioreg_t from,


+ unsigned int extent)
+{
+}

+
+void
+mbx_ide_fix_driveid(struct hd_driveid *id)


+{
+ ppc_generic_ide_fix_driveid(id);
+}
+

+void __init mbx_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq)


+{
+ ide_ioreg_t port = base;
+ int i = 8;
+
+ while (i--)
+ *p++ = port++;

+ *p++ = base + 0x206;


+ if (irq != NULL)

+ *irq = 0;
+#ifdef ATA_FLASH
+ base = (unsigned long) ioremap(PCMCIA_MEM_ADDR, 0x200);
+ for (i = 0; i < 8; ++i)
+ *p++ = base++;
+ *p = ++base; /* Does not matter */
+ if (irq)
+ *irq = 13;
+#endif
+}
+#endif
+
+__initfunc(void
+mbx_init(unsigned long r3, unsigned long r4, unsigned long r5,


+ unsigned long r6, unsigned long r7))
+{
+

+ if ( r3 )

+ memcpy( (void *)&res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
+
+#ifdef CONFIG_PCI
+ mbx_setup_pci_ptrs();
+#endif
+


+#ifdef CONFIG_BLK_DEV_INITRD
+ /* take care of initrd if we have one */

+ if ( r4 )
+ {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;


+ }
+#endif /* CONFIG_BLK_DEV_INITRD */

+ /* take care of cmd line */
+ if ( r6 )
+ {
+
+ *(char *)(r7+KERNELBASE) = 0;
+ strcpy(cmd_line, (char *)(r6+KERNELBASE));
+ }
+
+ ppc_md.setup_arch = mbx_setup_arch;
+ ppc_md.setup_residual = mbx_setup_residual;
+ ppc_md.get_cpuinfo = NULL;
+ ppc_md.irq_cannonicalize = NULL;
+ ppc_md.init_IRQ = mbx_init_IRQ;
+ ppc_md.do_IRQ = mbx_do_IRQ;


+ ppc_md.init = NULL;
+

+ ppc_md.restart = mbx_restart;
+ ppc_md.power_off = mbx_power_off;
+ ppc_md.halt = mbx_halt;


+
+ ppc_md.time_init = NULL;

+ ppc_md.set_rtc_time = mbx_set_rtc_time;
+ ppc_md.get_rtc_time = mbx_get_rtc_time;
+ ppc_md.calibrate_decr = mbx_calibrate_decr;


+
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
+#endif
+

+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+ ppc_ide_md.insw = mbx_ide_insw;
+ ppc_ide_md.outsw = mbx_ide_outsw;
+ ppc_ide_md.default_irq = mbx_ide_default_irq;
+ ppc_ide_md.default_io_base = mbx_ide_default_io_base;
+ ppc_ide_md.check_region = mbx_ide_check_region;
+ ppc_ide_md.request_region = mbx_ide_request_region;
+ ppc_ide_md.release_region = mbx_ide_release_region;
+ ppc_ide_md.fix_driveid = mbx_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = mbx_ide_init_hwif_ports;


+
+ ppc_ide_md.io_base = _IO_BASE;
+#endif

X }
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.2.7/linux/arch/ppc/kernel/misc.S Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/misc.S Thu Apr 29 12:39:01 1999
@@ -36,6 +36,7 @@
X * Returns (address we're running at) - (address we were linked at)
X * for use before the text and data are mapped to KERNELBASE.
X */
+
X _GLOBAL(reloc_offset)
X mflr r0
X bl 1f
@@ -72,8 +73,8 @@
X beqlr /* nothing to do if state == 0 */
X _GLOBAL(__sti)
X _GLOBAL(_hard_sti)
- lis r4,n_lost_interrupts@ha
- lwz r4,n_lost_interrupts@l(r4)
+ lis r4,ppc_n_lost_interrupts@ha
+ lwz r4,ppc_n_lost_interrupts@l(r4)
X mfmsr r3 /* Get current state */
X ori r3,r3,MSR_EE /* Turn on 'EE' bit */
X cmpi 0,r4,0 /* lost interrupts to process first? */
@@ -93,8 +94,8 @@
X stw r0,20(r1)
X stw r3,8(r1)
X 1: bl fake_interrupt
- lis r4,n_lost_interrupts@ha
- lwz r4,n_lost_interrupts@l(r4)
+ lis r4,ppc_n_lost_interrupts@ha


+ lwz r4,ppc_n_lost_interrupts@l(r4)
X cmpi 0,r4,0

X bne- 1b
X lwz r3,8(r1)
@@ -105,6 +106,20 @@
X addi r1,r1,16
X blr
X
+
+/*
+ * complement mask on the msr then "or" some values on.
+ * _nmask_and_or_msr(nmask, value_to_or)
+ */
+ _GLOBAL(_nmask_and_or_msr)
+ mfmsr r0 /* Get current msr */
+ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
+ or r0,r0,r4 /* Or on the bits in r4 (second parm) */
+ sync /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+ blr /* Done */
+
+
X /*
X * Flush MMU TLB
X */
@@ -613,16 +628,6 @@
X stfd 0,-4(r5)
X blr
X
- .globl __clear_msr_me
-__clear_msr_me:
- mfmsr r0 /* Get current interrupt state */
- lis r3,0
- ori r3,r3,MSR_ME
- andc r0,r0,r3 /* Clears bit in (r4) */
- sync /* Some chip revs have problems here */
- mtmsr r0 /* Update machine state */
- blr
-
X _GLOBAL(cvt_df)
X cvt_df:
X lfd 0,-4(r5) /* load up fpscr value */
@@ -633,6 +638,16 @@
X stfd 0,-4(r5)
X blr
X
+ .globl __clear_msr_me
+__clear_msr_me:
+ mfmsr r0 /* Get current interrupt state */
+ lis r3,0
+ ori r3,r3,MSR_ME
+ andc r0,r0,r3 /* Clears bit in (r4) */
+ sync /* Some chip revs have problems here */
+ mtmsr r0 /* Update machine state */
+ blr
+
X /*
X * Fetch the current SR register
X * get_SR(int index)
@@ -651,6 +666,8 @@
X sc
X cmpi 0,r3,0 /* parent or child? */
X bnelr /* return if parent */
+ li r0,0 /* clear out p->tss.regs */
+ stw r0,TSS+PT_REGS(r2) /* since we don't have user ctx */
X mtlr r4 /* fn addr in lr */
X mr r3,r5 /* load arg and call fn */
X blrl
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.2.7/linux/arch/ppc/kernel/mk_defs.c Wed Sep 9 14:51:06 1998
+++ linux/arch/ppc/kernel/mk_defs.c Tue May 11 08:24:32 1999
@@ -29,7 +29,7 @@
X int
X main(void)
X {
- DEFINE(KERNELBASE, KERNELBASE);
+ /*DEFINE(KERNELBASE, KERNELBASE);*/
X DEFINE(STATE, offsetof(struct task_struct, state));
X DEFINE(NEXT_TASK, offsetof(struct task_struct, next_task));
X DEFINE(COUNTER, offsetof(struct task_struct, counter));
@@ -48,7 +48,6 @@
X DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
X DEFINE(TSS_FPR0, offsetof(struct thread_struct, fpr[0]));
X DEFINE(TSS_FPSCR, offsetof(struct thread_struct, fpscr));
- DEFINE(TSS_SMP_FORK_RET, offsetof(struct thread_struct, smp_fork_ret));
X /* Interrupt register frame */
X DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
X DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
--- v2.2.7/linux/arch/ppc/kernel/open_pic.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/open_pic.c Tue May 11 08:24:32 1999
@@ -0,0 +1,48 @@


+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>

+#include <linux/openpic.h>
+#include <asm/irq.h>
+#include "open_pic.h"
+#include "i8259.h"
+
+#ifdef __SMP__
+void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ smp_message_recv();
+}


+#endif /* __SMP__ */
+

+void chrp_mask_and_ack_irq(unsigned int irq_nr)
+{
+ if (is_8259_irq(irq_nr))
+ i8259_pic.mask_and_ack(irq_nr);
+}
+
+static void chrp_mask_irq(unsigned int irq_nr)
+{
+ if (is_8259_irq(irq_nr))
+ i8259_pic.disable(irq_nr);
+ else
+ openpic_disable_irq(irq_to_openpic(irq_nr));
+}
+
+static void chrp_unmask_irq(unsigned int irq_nr)
+{
+ if (is_8259_irq(irq_nr))
+ i8259_pic.enable(irq_nr);
+ else
+ openpic_enable_irq(irq_to_openpic(irq_nr));
+}
+
+struct hw_interrupt_type open_pic = {
+ " OpenPIC ",


+ NULL,
+ NULL,
+ NULL,

+ chrp_unmask_irq,
+ chrp_mask_irq,
+ chrp_mask_and_ack_irq,
+ 0
+};
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/open_pic.h linux/arch/ppc/kernel/open_pic.h
--- v2.2.7/linux/arch/ppc/kernel/open_pic.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/open_pic.h Thu Apr 29 12:39:01 1999
@@ -0,0 +1,11 @@
+
+#ifndef _PPC_KERNEL_OPEN_PIC_H
+#define _PPC_KERNEL_OPEN_PIC_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type open_pic;
+
+void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+
+#endif /* _PPC_KERNEL_OPEN_PIC_H */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/openpic.c linux/arch/ppc/kernel/openpic.c
--- v2.2.7/linux/arch/ppc/kernel/openpic.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/openpic.c Thu Apr 29 12:39:01 1999
@@ -190,6 +190,9 @@
X case 2:
X version = "1.2";
X break;
+ case 3:
+ version = "1.3";
+ break;
X default:
X version = "?";
X break;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- v2.2.7/linux/arch/ppc/kernel/pci.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/pci.c Thu Apr 29 12:39:01 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: pci.c,v 1.53 1999/03/12 23:38:02 cort Exp $
+ * $Id: pci.c,v 1.54 1999/03/18 04:16:04 cort Exp $
X * Common pmac/prep/chrp pci routines. -- Cort
X */
X
@@ -21,97 +21,41 @@
X #include <asm/irq.h>
X #include <asm/gg2.h>
X
-unsigned long isa_io_base;
-unsigned long isa_mem_base;
-unsigned long pci_dram_offset;
-unsigned int * pci_config_address;
-unsigned char * pci_config_data;
-
-static void fix_intr(struct device_node *node, struct pci_dev *dev);
-
-/*
- * It would be nice if we could create a include/asm/pci.h and have just
- * function ptrs for all these in there, but that isn't the case.
- * We have a function, pcibios_*() which calls the function ptr ptr_pcibios_*()
- * which has been setup by pcibios_init(). This is all to avoid a check
- * for pmac/prep every time we call one of these. It should also make the move
- * to a include/asm/pcibios.h easier, we can drop the ptr_ on these functions
- * and create pci.h


- * -- Cort
- */

-int (*ptr_pcibios_read_config_byte)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val);
-int (*ptr_pcibios_read_config_word)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val);
-int (*ptr_pcibios_read_config_dword)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val);
-int (*ptr_pcibios_write_config_byte)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val);
-int (*ptr_pcibios_write_config_word)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val);
-int (*ptr_pcibios_write_config_dword)(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val);
-
-#define decl_config_access_method(name) \
-extern int name##_pcibios_read_config_byte(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned char *val); \
-extern int name##_pcibios_read_config_word(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned short *val); \
-extern int name##_pcibios_read_config_dword(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned int *val); \
-extern int name##_pcibios_write_config_byte(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned char val); \
-extern int name##_pcibios_write_config_word(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned short val); \
-extern int name##_pcibios_write_config_dword(unsigned char bus, \
- unsigned char dev_fn, unsigned char offset, unsigned int val)
-
-#define set_config_access_method(name) \
- ptr_pcibios_read_config_byte = name##_pcibios_read_config_byte; \
- ptr_pcibios_read_config_word = name##_pcibios_read_config_word; \
- ptr_pcibios_read_config_dword = name##_pcibios_read_config_dword; \
- ptr_pcibios_write_config_byte = name##_pcibios_write_config_byte; \
- ptr_pcibios_write_config_word = name##_pcibios_write_config_word; \
- ptr_pcibios_write_config_dword = name##_pcibios_write_config_dword
-
-decl_config_access_method(mech1);
-decl_config_access_method(pmac);
-decl_config_access_method(grackle);
-decl_config_access_method(gg2);
-decl_config_access_method(raven);
-decl_config_access_method(prep);
-decl_config_access_method(mbx);
-decl_config_access_method(python);
+#include "pci.h"
+
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+unsigned long pci_dram_offset = 0;
X
X int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char *val)
X {
- return ptr_pcibios_read_config_byte(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_read_config_byte(bus,dev_fn,offset,val);
X }
X int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short *val)
X {
- return ptr_pcibios_read_config_word(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_read_config_word(bus,dev_fn,offset,val);
X }
X int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int *val)
X {
- return ptr_pcibios_read_config_dword(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_read_config_dword(bus,dev_fn,offset,val);
X }
X int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned char val)
X {
- return ptr_pcibios_write_config_byte(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_write_config_byte(bus,dev_fn,offset,val);
X }
X int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned short val)
X {
- return ptr_pcibios_write_config_word(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_write_config_word(bus,dev_fn,offset,val);
X }
X int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
X unsigned char offset, unsigned int val)
X {
- return ptr_pcibios_write_config_dword(bus,dev_fn,offset,val);
+ return ppc_md.pcibios_write_config_dword(bus,dev_fn,offset,val);
X }
X
X int pcibios_present(void)
@@ -123,175 +67,10 @@
X {
X }
X
-void __init setup_pci_ptrs(void)
-{
-#ifndef CONFIG_MBX
- PPC_DEVICE *hostbridge;
- switch (_machine) {
- case _MACH_prep:
- printk("PReP architecture\n");
- if ( _prep_type == _PREP_Radstone )
- {
- printk("Setting PCI access method to mech1\n");
- set_config_access_method(mech1);
- break;
- }
-
- hostbridge=residual_find_device(PROCESSORDEVICE, NULL,
- BridgeController, PCIBridge,
- -1, 0);
- if (hostbridge &&
- hostbridge->DeviceId.Interface == PCIBridgeIndirect) {
- PnP_TAG_PACKET * pkt;
- set_config_access_method(raven);
- pkt=PnP_find_large_vendor_packet(
- res->DevicePnPHeap+hostbridge->AllocatedOffset,
- 3, 0);
- if(pkt) {
-#define p pkt->L4_Pack.L4_Data.L4_PPCPack
- pci_config_address= (unsigned *)
- ld_le32((unsigned *) p.PPCData);
- pci_config_data= (unsigned char *)
- ld_le32((unsigned *) (p.PPCData+8));
- } else {/* default values */
- pci_config_address= (unsigned *) 0x80000cf8;
- pci_config_data= (unsigned char *) 0x80000cfc;
- }
- } else {
- set_config_access_method(prep);
- }
- break;
- case _MACH_Pmac:
- if (find_devices("pci") != 0) {
- /* looks like a G3 powermac */
- set_config_access_method(grackle);
- } else {
- set_config_access_method(pmac);


- }
- break;
- case _MACH_chrp:

- if ( !strncmp("MOT",
- get_property(find_path_device("/"), "model", NULL),3) )
- {
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xfe000000;
- set_config_access_method(grackle);
- }
- else
- {
- if ( !strncmp("F5",
- get_property(find_path_device("/"),
- "ibm,model-class", NULL),2) )
-
- {
- pci_dram_offset = 0x80000000;
- isa_mem_base = 0xa0000000;
- isa_io_base = 0x88000000;
- set_config_access_method(python);
- }
- else
- {
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xf8000000;
- set_config_access_method(gg2);
- }
- }
- break;
- default:
- printk("setup_pci_ptrs(): unknown machine type!\n");
- }
-#else /* CONFIG_MBX */
- set_config_access_method(mbx);
-#endif /* CONFIG_MBX */
-#undef set_config_access_method
-}
X
X void __init pcibios_fixup(void)
X {
- extern unsigned long route_pci_interrupts(void);
- struct pci_dev *dev;
- extern struct bridge_data **bridges;
- extern unsigned char *Motherboard_map;
- extern unsigned char *Motherboard_routes;
- unsigned char i;
-#ifndef CONFIG_MBX
- switch (_machine )
- {
- case _MACH_prep:
- if ( _prep_type == _PREP_Radstone )
- {
- printk("Radstone boards require no PCI fixups\n");
- break;
- }
-
- route_pci_interrupts();
- for(dev=pci_devices; dev; dev=dev->next)
- {
- /*
- * Use our old hard-coded kludge to figure out what
- * irq this device uses. This is necessary on things
- * without residual data. -- Cort
- */
- unsigned char d = PCI_SLOT(dev->devfn);
- dev->irq = Motherboard_routes[Motherboard_map[d]];
- for ( i = 0 ; i <= 5 ; i++ )
- {
- if ( dev->base_address[i] > 0x10000000 )
- {
- printk("Relocating PCI address %lx -> %lx\n",
- dev->base_address[i],
- (dev->base_address[i] & 0x00FFFFFF)
- | 0x01000000);
- dev->base_address[i] =
- (dev->base_address[i] & 0x00FFFFFF) | 0x01000000;
- pci_write_config_dword(dev,
- PCI_BASE_ADDRESS_0+(i*0x4),
- dev->base_address[i] );
- }
- }
-#if 0
- /*
- * If we have residual data and if it knows about this
- * device ask it what the irq is.


- * -- Cort
- */

- ppcd = residual_find_device_id( ~0L, dev->device,
- -1,-1,-1, 0);
-#endif

- }
- break;
- case _MACH_chrp:

- /* PCI interrupts are controlled by the OpenPIC */
- for(dev=pci_devices; dev; dev=dev->next)
- if (dev->irq)
- dev->irq = openpic_to_irq(dev->irq);
- break;
- case _MACH_Pmac:
- for(dev=pci_devices; dev; dev=dev->next)
- {
- /*
- * Open Firmware often doesn't initialize the,
- * PCI_INTERRUPT_LINE config register properly, so we
- * should find the device node and se if it has an
- * AAPL,interrupts property.
- */
- struct bridge_data *bp = bridges[dev->bus->number];
- unsigned char pin;
-
- if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) ||
- !pin)
- continue; /* No interrupt generated -> no fixup */
- fix_intr(bp->node->child, dev);
- }
- break;
- }
-#else /* CONFIG_MBX */
- for(dev=pci_devices; dev; dev=dev->next)
- {
- }
-#endif /* CONFIG_MBX */
+ ppc_md.pcibios_fixup();
X }
X
X void __init pcibios_fixup_bus(struct pci_bus *bus)
@@ -309,7 +88,7 @@
X * fix IRQ's for cards located behind P2P bridges.
X * - Ranjit Deshpande, 01/20/99
X */
-static void __init fix_intr(struct device_node *node, struct pci_dev *dev)
+void __init fix_intr(struct device_node *node, struct pci_dev *dev)
X {
X unsigned int *reg, *class_code;
X
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pci.h linux/arch/ppc/kernel/pci.h
--- v2.2.7/linux/arch/ppc/kernel/pci.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/pci.h Thu Apr 29 12:39:01 1999
@@ -0,0 +1,36 @@
+
+#ifndef __PPC_KERNEL_PCI_H__
+#define __PPC_KERNEL_PCI_H__
+
+extern unsigned long isa_io_base;
+extern unsigned long isa_mem_base;
+extern unsigned long pci_dram_offset;
+
+extern unsigned int *pci_config_address;
+extern unsigned char *pci_config_data;
+
+void fix_intr(struct device_node *node, struct pci_dev *dev);
+
+#define decl_config_access_method(name) \
+extern int name##_pcibios_read_config_byte(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned char *val); \
+extern int name##_pcibios_read_config_word(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned short *val); \
+extern int name##_pcibios_read_config_dword(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned int *val); \
+extern int name##_pcibios_write_config_byte(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned char val); \
+extern int name##_pcibios_write_config_word(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned short val); \
+extern int name##_pcibios_write_config_dword(unsigned char bus, \
+ unsigned char dev_fn, unsigned char offset, unsigned int val)
+
+#define set_config_access_method(name) \
+ ppc_md.pcibios_read_config_byte = name##_pcibios_read_config_byte; \
+ ppc_md.pcibios_read_config_word = name##_pcibios_read_config_word; \
+ ppc_md.pcibios_read_config_dword = name##_pcibios_read_config_dword; \
+ ppc_md.pcibios_write_config_byte = name##_pcibios_write_config_byte; \
+ ppc_md.pcibios_write_config_word = name##_pcibios_write_config_word; \
+ ppc_md.pcibios_write_config_dword = name##_pcibios_write_config_dword
+
+#endif /* __PPC_KERNEL_PCI_H__ */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- v2.2.7/linux/arch/ppc/kernel/pmac_pci.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/pmac_pci.c Thu Apr 29 12:39:01 1999
@@ -21,6 +21,9 @@
X #include <asm/pgtable.h>
X #include <asm/prom.h>
X #include <asm/pci-bridge.h>


+#include <asm/machdep.h>
+
+#include "pci.h"
X

X struct bridge_data **bridges, *bridge_list;
X static int max_bus;
@@ -437,5 +440,49 @@
X if (strcmp(dev->name, "bandit") == 0)
X init_bandit(bp);
X }
+}
+
+__initfunc(
+void
+pmac_pcibios_fixup(void))


+{
+ struct pci_dev *dev;

+
+ /*
+ * FIXME: This is broken: We should not assign IRQ's to IRQless
+ * devices (look at PCI_INTERRUPT_PIN) and we also should
+ * honor the existence of multi-function devices where
+ * different functions have different interrupt pins. [mj]
+ */
+ for(dev=pci_devices; dev; dev=dev->next)
+ {
+ /*
+ * Open Firmware often doesn't initialize the,
+ * PCI_INTERRUPT_LINE config register properly, so we
+ * should find the device node and se if it has an
+ * AAPL,interrupts property.
+ */
+ struct bridge_data *bp = bridges[dev->bus->number];
+ unsigned char pin;
+
+ if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) ||
+ !pin)
+ continue; /* No interrupt generated -> no fixup */
+ fix_intr(bp->node->child, dev);
+ }
+}
+
+__initfunc(
+void
+pmac_setup_pci_ptrs(void))
+{
+ if (find_devices("pci") != 0) {
+ /* looks like a G3 powermac */
+ set_config_access_method(grackle);
+ } else {
+ set_config_access_method(pmac);
+ }
+
+ ppc_md.pcibios_fixup = pmac_pcibios_fixup;
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
--- v2.2.7/linux/arch/ppc/kernel/pmac_pic.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/pmac_pic.c Tue May 11 08:24:32 1999
@@ -0,0 +1,362 @@


+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/io.h>

+#include <asm/smp.h>
+#include <asm/prom.h>
+#include "pmac_pic.h"
+
+/* pmac */struct pmac_irq_hw {
+ unsigned int flag;
+ unsigned int enable;
+ unsigned int ack;
+ unsigned int level;
+};
+
+/* XXX these addresses should be obtained from the device tree */
+static volatile struct pmac_irq_hw *pmac_irq_hw[4] = {
+ (struct pmac_irq_hw *) 0xf3000020,
+ (struct pmac_irq_hw *) 0xf3000010,
+ (struct pmac_irq_hw *) 0xf4000020,
+ (struct pmac_irq_hw *) 0xf4000010,
+};
+
+static int max_irqs;
+static int max_real_irqs;
+
+#define MAXCOUNT 10000000
+
+#define GATWICK_IRQ_POOL_SIZE 10
+static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
+
+static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ if (test_and_clear_bit(irq_nr, ppc_lost_interrupts))
+ atomic_dec(&ppc_n_lost_interrupts);
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+ out_le32(&pmac_irq_hw[i]->ack, bit);
+ do {
+ /* make sure ack gets to controller before we enable
+ interrupts */
+ mb();
+ } while(in_le32(&pmac_irq_hw[i]->flag) & bit);
+}
+
+static void __pmac pmac_set_irq_mask(unsigned int irq_nr)
+{
+ unsigned long bit = 1UL << (irq_nr & 0x1f);
+ int i = irq_nr >> 5;
+
+ if ((unsigned)irq_nr >= max_irqs)
+ return;
+
+ /* enable unmasked interrupts */
+ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
+
+ do {
+ /* make sure mask gets to controller before we
+ return to user */
+ mb();
+ } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
+ != (ppc_cached_irq_mask[i] & bit));
+
+ /*
+ * Unfortunately, setting the bit in the enable register
+ * when the device interrupt is already on *doesn't* set
+ * the bit in the flag register or request another interrupt.
+ */
+ if ((bit & ppc_cached_irq_mask[i])
+ && (ld_le32(&pmac_irq_hw[i]->level) & bit)
+ && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) {
+ if (!test_and_set_bit(irq_nr, ppc_lost_interrupts))
+ atomic_inc(&ppc_n_lost_interrupts);
+ }
+}
+
+static void __pmac pmac_mask_irq(unsigned int irq_nr)
+{
+ clear_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr);
+ mb();
+}
+
+static void __pmac pmac_unmask_irq(unsigned int irq_nr)
+{
+ set_bit(irq_nr, ppc_cached_irq_mask);
+ pmac_set_irq_mask(irq_nr);
+}
+
+struct hw_interrupt_type pmac_pic = {
+ " PMAC-PIC ",


+ NULL,
+ NULL,
+ NULL,

+ pmac_unmask_irq,
+ pmac_mask_irq,
+ pmac_mask_and_ack_irq,
+ 0
+};
+
+struct hw_interrupt_type gatwick_pic = {
+ " GATWICK ",


+ NULL,
+ NULL,
+ NULL,

+ pmac_unmask_irq,
+ pmac_mask_irq,
+ pmac_mask_and_ack_irq,
+ 0
+};
+
+static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+ int irq, bits;
+
+ for (irq = max_irqs - 1; irq > max_real_irqs; irq -= 32) {
+ int i = irq >> 5;
+ bits = ld_le32(&pmac_irq_hw[i]->flag)
+ | ppc_lost_interrupts[i];
+ if (bits == 0)
+ continue;
+ irq -= cntlzw(bits);
+ break;
+ }
+ /* The previous version of this code allowed for this case, we
+ * don't. Put this here to check for it.


+ * -- Cort
+ */

+ if ( irq_desc[irq].ctl != &gatwick_pic )
+ printk("gatwick irq not from gatwick pic\n");
+ else


+ ppc_irq_dispatch_handler( regs, irq );
+}
+

+void
+pmac_do_IRQ(struct pt_regs *regs,


+ int cpu,
+ int isfake)

+{
+ int irq;
+ unsigned long bits = 0;
+
+#ifdef __SMP__
+ /* IPI's are a hack on the powersurge -- Cort */
+ if ( cpu != 0 )
+ {
+ if (!isfake)
+ {
+#ifdef CONFIG_XMON
+ static int xmon_2nd;
+ if (xmon_2nd)
+ xmon(regs);
+#endif
+ smp_message_recv();
+ goto out;
+ }
+ /* could be here due to a do_fake_interrupt call but we don't
+ mess with the controller from the second cpu -- Cort */


+ goto out;
+ }
+

+ {
+ unsigned int loops = MAXCOUNT;


+ while (test_bit(0, &global_irq_lock)) {
+ if (smp_processor_id() == global_irq_holder) {
+ printk("uh oh, interrupt while we hold global irq lock!\n");
+#ifdef CONFIG_XMON
+ xmon(0);
+#endif
+ break;
+ }
+ if (loops-- == 0) {
+ printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
+#ifdef CONFIG_XMON
+ xmon(0);
+#endif
+ }
+ }
+ }

+#endif /* __SMP__ */
+

+ for (irq = max_real_irqs - 1; irq > 0; irq -= 32) {
+ int i = irq >> 5;
+ bits = ld_le32(&pmac_irq_hw[i]->flag)
+ | ppc_lost_interrupts[i];
+ if (bits == 0)
+ continue;
+ irq -= cntlzw(bits);
+ break;
+ }
+


+ if (irq < 0)
+ {
+ printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+ irq, regs->nip);
+ ppc_spurious_interrupts++;
+ }
+ else
+ {
+ ppc_irq_dispatch_handler( regs, irq );
+ }

+#ifdef CONFIG_SMP
+out:
+#endif /* CONFIG_SMP */
+}
+
+/* This routine will fix some missing interrupt values in the device tree
+ * on the gatwick mac-io controller used by some PowerBooks
+ */
+static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base)
+{
+ struct device_node *node;
+ int count;
+
+ memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool));
+ node = gw->child;
+ count = 0;
+ while(node)
+ {
+ /* Fix SCC */
+ if (strcasecmp(node->name, "escc") == 0)
+ if (node->child) {
+ if (node->child->n_intrs < 3) {
+ node->child->intrs = &gatwick_int_pool[count];
+ count += 3;
+ }
+ node->child->n_intrs = 3;
+ node->child->intrs[0].line = 15+irq_base;
+ node->child->intrs[1].line = 4+irq_base;
+ node->child->intrs[2].line = 5+irq_base;
+ printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n",
+ node->child->intrs[0].line,
+ node->child->intrs[1].line,
+ node->child->intrs[2].line);
+ }
+ /* Fix media-bay & left SWIM */
+ if (strcasecmp(node->name, "media-bay") == 0) {
+ struct device_node* ya_node;
+
+ if (node->n_intrs == 0)
+ node->intrs = &gatwick_int_pool[count++];
+ node->n_intrs = 1;
+ node->intrs[0].line = 29+irq_base;
+ printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n",
+ node->intrs[0].line);
+
+ ya_node = node->child;
+ while(ya_node)
+ {
+ if (strcasecmp(ya_node->name, "floppy") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 19+irq_base;
+ ya_node->intrs[1].line = 1+irq_base;
+ printk(KERN_INFO "irq: fixed floppy on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ if (strcasecmp(ya_node->name, "ata4") == 0) {
+ if (ya_node->n_intrs < 2) {
+ ya_node->intrs = &gatwick_int_pool[count];
+ count += 2;
+ }
+ ya_node->n_intrs = 2;
+ ya_node->intrs[0].line = 14+irq_base;
+ ya_node->intrs[1].line = 3+irq_base;
+ printk(KERN_INFO "irq: fixed ide on second controller (%d,%d)\n",
+ ya_node->intrs[0].line, ya_node->intrs[1].line);
+ }
+ ya_node = ya_node->sibling;
+ }
+ }
+ node = node->sibling;
+ }
+ if (count > 10) {
+ printk("WARNING !! Gatwick interrupt pool overflow\n");
+ printk(" GATWICK_IRQ_POOL_SIZE = %d\n", GATWICK_IRQ_POOL_SIZE);
+ printk(" requested = %d\n", count);
+ }
+}
+
+__initfunc(void
+pmac_pic_init(void))
+{
+ int i;
+ struct device_node *irqctrler;
+ unsigned long addr;
+ int second_irq = -999;
+
+
+ /* G3 powermacs have 64 interrupts, G3 Series PowerBook have 128,
+ others have 32 */
+ max_irqs = max_real_irqs = 32;
+ irqctrler = find_devices("mac-io");
+ if (irqctrler)
+ {
+ max_real_irqs = 64;
+ if (irqctrler->next)
+ max_irqs = 128;
+ else
+ max_irqs = 64;
+ }
+ for ( i = 0; i < max_real_irqs ; i++ )
+ irq_desc[i].ctl = &pmac_pic;
+
+ /* get addresses of first controller */
+ if (irqctrler) {
+ if (irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 0; i < 2; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (2 - i) * 0x10);
+ }
+
+ /* get addresses of second controller */
+ irqctrler = (irqctrler->next) ? irqctrler->next : NULL;
+ if (irqctrler && irqctrler->n_addrs > 0) {
+ addr = (unsigned long)
+ ioremap(irqctrler->addrs[0].address, 0x40);
+ for (i = 2; i < 4; ++i)
+ pmac_irq_hw[i] = (volatile struct pmac_irq_hw*)
+ (addr + (4 - i) * 0x10);
+ }
+ }
+
+ /* disable all interrupts in all controllers */
+ for (i = 0; i * 32 < max_irqs; ++i)
+ out_le32(&pmac_irq_hw[i]->enable, 0);
+
+ /* get interrupt line of secondary interrupt controller */
+ if (irqctrler) {
+ second_irq = irqctrler->intrs[0].line;
+ printk(KERN_INFO "irq: secondary controller on irq %d\n",
+ (int)second_irq);
+ if (device_is_compatible(irqctrler, "gatwick"))
+ pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs);
+ for ( i = max_real_irqs ; i < max_irqs ; i++ )
+ irq_desc[i].ctl = &gatwick_pic;
+ request_irq( second_irq, gatwick_action, SA_INTERRUPT,
+ "gatwick cascade", 0 );
+ }
+ printk("System has %d possible interrupts\n", max_irqs);
+ if (max_irqs != max_real_irqs)
+ printk(KERN_DEBUG "%d interrupts on main controller\n",
+ max_real_irqs);
+
+#ifdef CONFIG_XMON
+ request_irq(20, xmon_irq, 0, "NMI - XMON", 0);
+#endif /* CONFIG_XMON */
+}
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pmac_pic.h linux/arch/ppc/kernel/pmac_pic.h
--- v2.2.7/linux/arch/ppc/kernel/pmac_pic.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/pmac_pic.h Thu Apr 29 12:39:01 1999
@@ -0,0 +1,15 @@
+#ifndef _PPC_KERNEL_PMAC_PIC_H
+#define _PPC_KERNEL_PMAC_PIC_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+void pmac_do_IRQ(struct pt_regs *regs,


+ int cpu,
+ int isfake);
+
+

+#endif /* _PPC_KERNEL_PMAC_PIC_H */
+
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.2.7/linux/arch/ppc/kernel/pmac_setup.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/pmac_setup.c Tue May 11 08:24:32 1999
@@ -44,6 +44,7 @@
X #include <asm/prom.h>
X #include <asm/system.h>
X #include <asm/pgtable.h>
+#include <asm/bitops.h>
X #include <asm/io.h>
X #include <asm/pci-bridge.h>
X #include <asm/adb.h>
@@ -52,7 +53,38 @@
X #include <asm/ohare.h>
X #include <asm/mediabay.h>
X #include <asm/feature.h>


+#include <asm/ide.h>
+#include <asm/machdep.h>
+

X #include "time.h"
+#include "local_irq.h"
+#include "pmac_pic.h"
+
+#undef SHOW_GATWICK_IRQS
+
+unsigned long pmac_get_rtc_time(void);
+int pmac_set_rtc_time(unsigned long nowtime);
+void pmac_read_rtc_time(void);
+void pmac_calibrate_decr(void);
+void pmac_setup_pci_ptrs(void);


+
+extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int mackbd_getkeycode(unsigned int scancode);
+extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char mackbd_unexpected_up(unsigned char keycode);
+extern void mackbd_leds(unsigned char leds);
+extern void mackbd_init_hw(void);

+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char mackbd_sysrq_xlate[128];
+#endif /* CONFIG_MAGIC_SYSRQ */


+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);

+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);


+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);

X
X unsigned char drive_info;
X
@@ -291,15 +323,12 @@
X int boot_part;
X kdev_t boot_dev;
X
-void __init powermac_init(void)
+__initfunc(void
+pmac_init2(void))
X {
- if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
- return;
X adb_init();
X pmac_nvram_init();
- if (_machine == _MACH_Pmac) {
- media_bay_init();
- }
+ media_bay_init();
X }
X
X #ifdef CONFIG_SCSI
@@ -402,5 +431,176 @@
X boot_dev = NODEV;
X printk(" (root)");
X }
+}
+
+void
+pmac_restart(char *cmd)
+{
+ struct adb_request req;
+
+ switch (adb_hardware) {
+ case ADB_VIACUDA:
+ cuda_request(&req, NULL, 2, CUDA_PACKET,
+ CUDA_RESET_SYSTEM);
+ for (;;)
+ cuda_poll();
+ break;
+
+ case ADB_VIAPMU:
+ pmu_restart();


+ break;
+ default:
+ }

+}
+
+void
+pmac_power_off(void)
+{
+ struct adb_request req;
+
+ switch (adb_hardware) {
+ case ADB_VIACUDA:
+ cuda_request(&req, NULL, 2, CUDA_PACKET,
+ CUDA_POWERDOWN);
+ for (;;)
+ cuda_poll();
+ break;
+
+ case ADB_VIAPMU:
+ pmu_shutdown();


+ break;
+ default:
+ }

+}
+
+void
+pmac_halt(void)
+{
+ pmac_power_off();
+}


+
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */

+void
+pmac_ide_insw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_insw(port, buf, ns);
+}
+
+void
+pmac_ide_outsw(ide_ioreg_t port, void *buf, int ns)
+{
+ ide_outsw(port, buf, ns);
+}
+
+int
+pmac_ide_default_irq(ide_ioreg_t base)


+{
+ return 0;
+}
+

+ide_ioreg_t
+pmac_ide_default_io_base(int index)
+{
+#if defined(CONFIG_BLK_DEV_IDE_PMAC)
+ return pmac_ide_regbase[index];


+#else
+ return 0;
+#endif
+}
+

+int
+pmac_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{
+ return 0;
+}
+
+void
+pmac_ide_request_region(ide_ioreg_t from,


+ unsigned int extent,
+ const char *name)
+{
+}

+
+void
+pmac_ide_release_region(ide_ioreg_t from,


+ unsigned int extent)
+{
+}

+
+/* Convert the shorts/longs in hd_driveid from little to big endian;
+ * chars are endian independant, of course, but strings need to be flipped.
+ * (Despite what it says in drivers/block/ide.h, they come up as little
+ * endian...)
+ *
+ * Changes to linux/hdreg.h may require changes here. */
+void
+pmac_ide_fix_driveid(struct hd_driveid *id)


+{
+ ppc_generic_ide_fix_driveid(id);
+}
+

+/* This is declared in drivers/block/ide-pmac.c */
+void pmac_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq);
+#endif
+
+__initfunc(void
+pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,


+ unsigned long r6, unsigned long r7))
+{

+ pmac_setup_pci_ptrs();
+
+ /* isa_io_base gets set in pmac_find_bridges */
+ isa_mem_base = PMAC_ISA_MEM_BASE;
+ pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
+ ISA_DMA_THRESHOLD = ~0L;
+ DMA_MODE_READ = 1;
+ DMA_MODE_WRITE = 2;
+
+ ppc_md.setup_arch = pmac_setup_arch;
+ ppc_md.setup_residual = NULL;
+ ppc_md.get_cpuinfo = pmac_get_cpuinfo;
+ ppc_md.irq_cannonicalize = NULL;
+ ppc_md.init_IRQ = pmac_pic_init;
+ ppc_md.do_IRQ = pmac_do_IRQ;
+ ppc_md.init = pmac_init2;
+
+ ppc_md.restart = pmac_restart;
+ ppc_md.power_off = pmac_power_off;
+ ppc_md.halt = pmac_halt;


+
+ ppc_md.time_init = NULL;

+ ppc_md.set_rtc_time = pmac_set_rtc_time;
+ ppc_md.get_rtc_time = pmac_get_rtc_time;
+ ppc_md.calibrate_decr = pmac_calibrate_decr;
+
+#if defined(CONFIG_VT) && defined(CONFIG_MAC_KEYBOARD)


+ ppc_md.kbd_setkeycode = mackbd_setkeycode;
+ ppc_md.kbd_getkeycode = mackbd_getkeycode;
+ ppc_md.kbd_translate = mackbd_translate;
+ ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
+ ppc_md.kbd_leds = mackbd_leds;
+ ppc_md.kbd_init_hw = mackbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = mackbd_sysrq_xlate;
+#endif

+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE_PMAC)
+ ppc_ide_md.insw = pmac_ide_insw;
+ ppc_ide_md.outsw = pmac_ide_outsw;
+ ppc_ide_md.default_irq = pmac_ide_default_irq;
+ ppc_ide_md.default_io_base = pmac_ide_default_io_base;
+ ppc_ide_md.check_region = pmac_ide_check_region;
+ ppc_ide_md.request_region = pmac_ide_request_region;
+ ppc_ide_md.release_region = pmac_ide_release_region;
+ ppc_ide_md.fix_driveid = pmac_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
+
+ ppc_ide_md.io_base = 0;
+#endif
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/ppc8xx_pic.c linux/arch/ppc/kernel/ppc8xx_pic.c
--- v2.2.7/linux/arch/ppc/kernel/ppc8xx_pic.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/ppc8xx_pic.c Thu Apr 29 12:39:01 1999
@@ -0,0 +1,49 @@


+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>

+#include <asm/irq.h>
+#include <asm/8xx_immap.h>
+#include <asm/mbx.h>
+#include "ppc8xx_pic.h"
+
+
+static void mbx_mask_irq(unsigned int irq_nr)
+{
+ if ( irq_nr == ISA_BRIDGE_INT ) return;
+ if ( irq_nr >= ppc8xx_pic.irq_offset )
+ irq_nr -= ppc8xx_pic.irq_offset;
+ ppc_cached_irq_mask[0] &= ~(1 << (31-irq_nr));
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask[0];
+}
+
+static void mbx_unmask_irq(unsigned int irq_nr)
+{
+ if ( irq_nr >= ppc8xx_pic.irq_offset )
+ irq_nr -= ppc8xx_pic.irq_offset;
+ ppc_cached_irq_mask[0] |= (1 << (31-irq_nr));
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask[0];
+}
+
+static void mbx_mask_and_ack(unsigned int irq_nr)
+{
+ /* this shouldn't be masked, we mask the 8259 if we need to -- Cort */
+ if ( irq_nr != ISA_BRIDGE_INT )
+ mbx_mask_irq(irq_nr);
+ if ( irq_nr >= ppc8xx_pic.irq_offset )
+ irq_nr -= ppc8xx_pic.irq_offset;
+ /* clear the pending bits */
+ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-irq_nr);
+}
+
+struct hw_interrupt_type ppc8xx_pic = {
+ " 8xx SIU ",


+ NULL,
+ NULL,
+ NULL,

+ mbx_unmask_irq,
+ mbx_mask_irq,
+ mbx_mask_and_ack,
+ 0
+};
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/ppc8xx_pic.h linux/arch/ppc/kernel/ppc8xx_pic.h
--- v2.2.7/linux/arch/ppc/kernel/ppc8xx_pic.h Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/ppc8xx_pic.h Thu Apr 29 12:39:01 1999
@@ -0,0 +1,9 @@
+
+#ifndef _PPC_KERNEL_PPC8xx_H
+#define _PPC_KERNEL_PPC8xx_H
+
+#include "local_irq.h"
+
+extern struct hw_interrupt_type ppc8xx_pic;
+
+#endif /* _PPC_KERNEL_PPC8xx_H */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.2.7/linux/arch/ppc/kernel/ppc_ksyms.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/ppc_ksyms.c Thu Apr 29 12:39:01 1999
@@ -27,6 +27,8 @@
X #include <asm/irq.h>
X #include <asm/feature.h>
X #include <asm/spinlock.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
X
X #define __KERNEL_SYSCALLS__
X #include <linux/unistd.h>
@@ -40,7 +42,7 @@
X extern void ProgramCheckException(struct pt_regs *regs);
X extern void SingleStepException(struct pt_regs *regs);
X extern int sys_sigreturn(struct pt_regs *regs);
-extern atomic_t n_lost_interrupts;
+extern atomic_t ppc_n_lost_interrupts;
X extern void do_lost_interrupts(unsigned long);
X extern int do_signal(sigset_t *, struct pt_regs *);
X
@@ -59,16 +61,21 @@
X EXPORT_SYMBOL(ProgramCheckException);
X EXPORT_SYMBOL(SingleStepException);
X EXPORT_SYMBOL(sys_sigreturn);
-EXPORT_SYMBOL(n_lost_interrupts);
+EXPORT_SYMBOL(ppc_n_lost_interrupts);
X EXPORT_SYMBOL(do_lost_interrupts);
X EXPORT_SYMBOL(enable_irq);
X EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(local_irq_count);
-EXPORT_SYMBOL(local_bh_count);
+EXPORT_SYMBOL(ppc_local_irq_count);
+EXPORT_SYMBOL(ppc_local_bh_count);
X
X EXPORT_SYMBOL(isa_io_base);
X EXPORT_SYMBOL(isa_mem_base);
X EXPORT_SYMBOL(pci_dram_offset);
+EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
+EXPORT_SYMBOL(DMA_MODE_READ);
+EXPORT_SYMBOL(DMA_MODE_WRITE);
+EXPORT_SYMBOL(_prep_type);
+EXPORT_SYMBOL(ucSystemType);
X
X EXPORT_SYMBOL(atomic_add);
X EXPORT_SYMBOL(atomic_sub);
@@ -157,6 +164,7 @@
X EXPORT_SYMBOL(flush_instruction_cache);
X EXPORT_SYMBOL(_get_PVR);
X EXPORT_SYMBOL(giveup_fpu);
+EXPORT_SYMBOL(enable_kernel_fp);
X EXPORT_SYMBOL(flush_icache_range);
X EXPORT_SYMBOL(xchg_u32);
X #ifdef __SMP__
@@ -173,18 +181,14 @@
X EXPORT_SYMBOL(_write_unlock);
X #endif
X
-#ifndef CONFIG_MACH_SPECIFIC
X EXPORT_SYMBOL(_machine);
-#endif
+EXPORT_SYMBOL(ppc_md);
X
X EXPORT_SYMBOL(adb_request);
-EXPORT_SYMBOL(adb_autopoll);
X EXPORT_SYMBOL(adb_register);
X EXPORT_SYMBOL(cuda_request);
-EXPORT_SYMBOL(cuda_send_request);
X EXPORT_SYMBOL(cuda_poll);
X EXPORT_SYMBOL(pmu_request);
-EXPORT_SYMBOL(pmu_send_request);
X EXPORT_SYMBOL(pmu_poll);
X #ifdef CONFIG_PMAC_PBOOK
X EXPORT_SYMBOL(sleep_notifier_list);
@@ -196,7 +200,6 @@
X EXPORT_SYMBOL(find_path_device);
X EXPORT_SYMBOL(find_phandle);
X EXPORT_SYMBOL(get_property);
-EXPORT_SYMBOL(device_is_compatible);
X EXPORT_SYMBOL(pci_io_base);
X EXPORT_SYMBOL(pci_device_loc);
X EXPORT_SYMBOL(feature_set);
@@ -211,9 +214,8 @@
X EXPORT_SYMBOL(nvram_write_byte);
X #endif /* CONFIG_PMAC */
X
-#ifdef CONFIG_SOUND_MODULE
X EXPORT_SYMBOL(abs);
-#endif
+EXPORT_SYMBOL(device_is_compatible);
X
X /* The following are special because they're not called
X explicitly (the C compiler generates them). Fortunately,
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prep_nvram.c linux/arch/ppc/kernel/prep_nvram.c
--- v2.2.7/linux/arch/ppc/kernel/prep_nvram.c Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/prep_nvram.c Thu Apr 29 12:39:01 1999
@@ -0,0 +1,173 @@
+/*
+ * linux/arch/ppc/kernel/prep_nvram.c
+ *
+ * Copyright (C) 1998 Corey Minyard
+ *
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/machdep.h>
+#include <asm/prep_nvram.h>
+
+/*
+ * Allow for a maximum of 32K of PReP NvRAM data
+ */
+#define MAX_PREP_NVRAM 0x8000
+static char nvramData[MAX_PREP_NVRAM];
+static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0];
+
+#define PREP_NVRAM_AS0 0x74
+#define PREP_NVRAM_AS1 0x75
+#define PREP_NVRAM_DATA 0x77
+
+unsigned char *rs_pcNvRAM;
+
+unsigned char prep_nvram_read_val(int addr)
+{
+ outb(addr, PREP_NVRAM_AS0);
+ outb(addr>>8, PREP_NVRAM_AS1);
+ return inb(PREP_NVRAM_DATA);
+}
+
+void prep_nvram_write_val(int addr,
+ unsigned char val)
+{
+ outb(addr, PREP_NVRAM_AS0);
+ outb(addr>>8, PREP_NVRAM_AS1);
+ outb(val, PREP_NVRAM_DATA);
+}
+
+/*
+ * Most Radstone boards have NvRAM memory mapped at offset 8M in ISA space
+ */
+unsigned char rs_nvram_read_val(int addr)
+{
+ return rs_pcNvRAM[addr];
+}
+
+void rs_nvram_write_val(int addr,
+ unsigned char val)
+{
+ rs_pcNvRAM[addr]=val;
+}
+
+__initfunc(void init_prep_nvram(void))
+{
+ unsigned char *nvp;
+ int i;
+ int nvramSize;
+
+ /*
+ * I'm making the assumption that 32k will always cover the
+ * nvramsize. If this isn't the case please let me know and we can
+ * map the header, then get the size from the header, then map
+ * the whole size. -- Cort
+ */
+ if ( _prep_type == _PREP_Radstone )
+ rs_pcNvRAM = (unsigned char *)ioremap(_ISA_MEM_BASE+0x00800000,
+ 32<<10);
+ request_region(PREP_NVRAM_AS0, 0x8, "PReP NVRAM");
+ /*
+ * The following could fail if the NvRAM were corrupt but
+ * we expect the boot firmware to have checked its checksum
+ * before boot
+ */
+ nvp = (char *) &nvram->Header;
+ for (i=0; i<sizeof(HEADER); i++)
+ {
+ *nvp = ppc_md.nvram_read_val(i);
+ nvp++;
+ }
+
+ /*
+ * The PReP NvRAM may be any size so read in the header to
+ * determine how much we must read in order to get the complete
+ * GE area
+ */
+ nvramSize=(int)nvram->Header.GEAddress+nvram->Header.GELength;
+ if(nvramSize>MAX_PREP_NVRAM)
+ {
+ /*
+ * NvRAM is too large
+ */
+ nvram->Header.GELength=0;
+ return;
+ }
+
+ /*
+ * Read the remainder of the PReP NvRAM
+ */
+ nvp = (char *) &nvram->GEArea[0];
+ for (i=sizeof(HEADER); i<nvramSize; i++)
+ {
+ *nvp = ppc_md.nvram_read_val(i);
+ nvp++;
+ }
+}
+
+__prep
+char *prep_nvram_get_var(const char *name)
+{
+ char *cp;
+ int namelen;
+
+ namelen = strlen(name);
+ cp = prep_nvram_first_var();
+ while (cp != NULL) {
+ if ((strncmp(name, cp, namelen) == 0)
+ && (cp[namelen] == '='))
+ {
+ return cp+namelen+1;
+ }
+ cp = prep_nvram_next_var(cp);
+ }
+
+ return NULL;
+}
+
+__prep
+char *prep_nvram_first_var(void)
+{
+ if (nvram->Header.GELength == 0) {
+ return NULL;
+ } else {
+ return (((char *)nvram)
+ + ((unsigned int) nvram->Header.GEAddress));
+ }
+}
+
+__prep
+char *prep_nvram_next_var(char *name)
+{
+ char *cp;
+
+
+ cp = name;
+ while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
+ && (*cp != '\0'))
+ {
+ cp++;
+ }
+
+ /* Skip over any null characters. */
+ while (((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength)
+ && (*cp == '\0'))
+ {
+ cp++;
+ }
+
+ if ((cp - ((char *) nvram->GEArea)) < nvram->Header.GELength) {
+ return cp;
+ } else {
+ return NULL;
+ }
+}
+
+
+
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.2.7/linux/arch/ppc/kernel/prep_pci.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/prep_pci.c Tue May 11 08:24:32 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: prep_pci.c,v 1.25 1999/03/03 15:09:45 cort Exp $
+ * $Id: prep_pci.c,v 1.33 1999/05/09 20:15:54 cort Exp $
X * PReP pci functions.
X * Originally by Gary Thomas
X * rewritten and updated by Cort Dougan (co...@cs.nmt.edu)
@@ -11,11 +11,19 @@
X #include <linux/pci.h>
X #include <linux/kernel.h>
X #include <linux/init.h>
+#include <linux/openpic.h>
X
X #include <asm/byteorder.h>
X #include <asm/io.h>
X #include <asm/ptrace.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/residual.h>
X #include <asm/processor.h>
+#include <asm/irq.h>


+#include <asm/machdep.h>
+
+#include "pci.h"
X

X #define MAX_DEVNR 22
X
@@ -27,6 +35,9 @@
X /* How is the 82378 PIRQ mapping setup? */
X unsigned char *Motherboard_routes;
X
+/* Used for Motorola to store system config register */
+static unsigned long *ProcInfo;
+
X /* Tables for known hardware */
X
X /* Motorola PowerStackII - Utah */
@@ -34,38 +45,39 @@
X {
X 0, /* Slot 0 - unused */
X 0, /* Slot 1 - unused */
- 4, /* Slot 2 - SCSI - NCR825A */
+ 5, /* Slot 2 - SCSI - NCR825A */
X 0, /* Slot 3 - unused */
X 1, /* Slot 4 - Ethernet - DEC2114x */
X 0, /* Slot 5 - unused */
- 2, /* Slot 6 - PCI Card slot #1 */
- 3, /* Slot 7 - PCI Card slot #2 */
- 4, /* Slot 8 - PCI Card slot #3 */
- 4, /* Slot 9 - PCI Bridge */
+ 3, /* Slot 6 - PCI Card slot #1 */
+ 4, /* Slot 7 - PCI Card slot #2 */
+ 5, /* Slot 8 - PCI Card slot #3 */
+ 5, /* Slot 9 - PCI Bridge */
X /* added here in case we ever support PCI bridges */
X /* Secondary PCI bus cards are at slot-9,6 & slot-9,7 */
X 0, /* Slot 10 - unused */
X 0, /* Slot 11 - unused */
- 4, /* Slot 12 - SCSI - NCR825A */
+ 5, /* Slot 12 - SCSI - NCR825A */
X 0, /* Slot 13 - unused */
- 2, /* Slot 14 - enet */
+ 3, /* Slot 14 - enet */
X 0, /* Slot 15 - unused */
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
+ 2, /* Slot 16 - unused */
+ 3, /* Slot 17 - unused */
+ 5, /* Slot 18 - unused */
+ 0, /* Slot 19 - unused */
+ 0, /* Slot 20 - unused */
+ 0, /* Slot 21 - unused */
+ 0, /* Slot 22 - unused */
X };
X
X static char Utah_pci_IRQ_routes[] __prepdata =
X {
X 0, /* Line 0 - Unused */
X 9, /* Line 1 */
- 11, /* Line 2 */
- 14, /* Line 3 */
- 15, /* Line 4 */
+ 10, /* Line 2 */
+ 11, /* Line 3 */
+ 14, /* Line 4 */
+ 15, /* Line 5 */
X };
X
X /* Motorola PowerStackII - Omaha */
@@ -125,9 +137,9 @@
X 0, /* Slot 13 - unused */
X 1, /* Slot 14 - Ethernet */
X 0, /* Slot 15 - unused */
- 1, /* Slot P7 */
- 2, /* Slot P6 */
- 3, /* Slot P5 */
+ 1, /* Slot P7 */
+ 2, /* Slot P6 */
+ 3, /* Slot P5 */
X };
X
X static char Blackhawk_pci_IRQ_routes[] __prepdata =
@@ -139,6 +151,122 @@
X 15 /* Line 4 */
X };
X
+/* Motorola Mesquite */
+static char Mesquite_pci_IRQ_map[23] __prepdata =
+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */
+ 0, /* Slot 10 - unxued */
+ 0, /* Slot 11 - unused */
+ 0, /* Slot 12 - unused */
+ 0, /* Slot 13 - unused */
+ 2, /* Slot 14 - Ethernet */
+ 0, /* Slot 15 - unused */
+ 3, /* Slot 16 - PMC */
+ 0, /* Slot 17 - unused */
+ 0, /* Slot 18 - unused */
+ 0, /* Slot 19 - unused */
+ 0, /* Slot 20 - unused */
+ 0, /* Slot 21 - unused */
+ 0, /* Slot 22 - unused */
+};
+
+/* Motorola Sitka */
+static char Sitka_pci_IRQ_map[21] __prepdata =
+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */
+ 0, /* Slot 10 - unxued */
+ 0, /* Slot 11 - unused */
+ 0, /* Slot 12 - unused */
+ 0, /* Slot 13 - unused */
+ 2, /* Slot 14 - Ethernet */
+ 0, /* Slot 15 - unused */
+ 9, /* Slot 16 - PMC 1 */
+ 12, /* Slot 17 - PMC 2 */
+ 0, /* Slot 18 - unused */
+ 0, /* Slot 19 - unused */
+ 4, /* Slot 20 - NT P2P bridge */
+};
+
+/* Motorola MTX */
+static char MTX_pci_IRQ_map[23] __prepdata =
+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */
+ 0, /* Slot 10 - unused */
+ 0, /* Slot 11 - unused */
+ 3, /* Slot 12 - SCSI */
+ 0, /* Slot 13 - unused */
+ 2, /* Slot 14 - Ethernet */
+ 0, /* Slot 15 - unused */
+ 9, /* Slot 16 - PCI/PMC slot 1 */
+ 10, /* Slot 17 - PCI/PMC slot 2 */
+ 11, /* Slot 18 - PCI slot 3 */
+ 0, /* Slot 19 - unused */
+ 0, /* Slot 20 - unused */
+ 0, /* Slot 21 - unused */
+ 0, /* Slot 22 - unused */
+};
+
+/* Motorola MTX Plus */
+/* Secondary bus interrupt routing is not supported yet */
+static char MTXplus_pci_IRQ_map[23] __prepdata =
+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */
+ 0, /* Slot 10 - unused */
+ 0, /* Slot 11 - unused */
+ 3, /* Slot 12 - SCSI */
+ 0, /* Slot 13 - unused */
+ 2, /* Slot 14 - Ethernet 1 */
+ 0, /* Slot 15 - unused */
+ 9, /* Slot 16 - PCI slot 1P */
+ 10, /* Slot 17 - PCI slot 2P */
+ 11, /* Slot 18 - PCI slot 3P */
+ 10, /* Slot 19 - Ethernet 2 */


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 10'
echo 'File patch-2.2.8 is continued in part 11'
echo 11 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part11

#!/bin/sh
# this is part 11 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 11; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

+ 0, /* Slot 20 - P2P Bridge */


+ 0, /* Slot 21 - unused */
+ 0, /* Slot 22 - unused */
+};
+

+static char Raven_pci_IRQ_routes[] __prepdata =
+{
+ 0, /* This is a dummy structure */
+};
+
X /* Motorola MVME16xx */
X static char Genesis_pci_IRQ_map[16] __prepdata =
X {
@@ -169,8 +297,35 @@


X 15 /* Line 4 */
X };
X

+static char Genesis2_pci_IRQ_map[23] __prepdata =


+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */
+ 0, /* Slot 2 - unused */
+ 0, /* Slot 3 - unused */
+ 0, /* Slot 4 - unused */
+ 0, /* Slot 5 - unused */
+ 0, /* Slot 6 - unused */
+ 0, /* Slot 7 - unused */
+ 0, /* Slot 8 - unused */
+ 0, /* Slot 9 - unused */

+ 0, /* Slot 10 - Ethernet */
+ 0, /* Slot 11 - Universe PCI - VME Bridge */
+ 3, /* Slot 12 - unused */


+ 0, /* Slot 13 - unused */

+ 2, /* Slot 14 - SCSI */
+ 0, /* Slot 15 - graphics on 3600 */
+ 9, /* Slot 16 - PMC */
+ 12, /* Slot 17 - pci */
+ 11, /* Slot 18 - pci */
+ 10, /* Slot 19 - pci */
+ 0, /* Slot 20 - pci */


+ 0, /* Slot 21 - unused */
+ 0, /* Slot 22 - unused */
+};
+

X /* Motorola Series-E */
-static char Comet_pci_IRQ_map[16] __prepdata =
+static char Comet_pci_IRQ_map[23] __prepdata =
X {


X 0, /* Slot 0 - unused */
X 0, /* Slot 1 - unused */

@@ -188,6 +343,13 @@


X 0, /* Slot 13 - unused */
X 1, /* Slot 14 - Ethernet */
X 0, /* Slot 15 - unused */

+ 1, /* Slot 16 - PCI slot 1 */
+ 2, /* Slot 17 - PCI slot 2 */
+ 3, /* Slot 18 - PCI slot 3 */
+ 4, /* Slot 19 - PCI bridge */
+ 0,
+ 0,
+ 0,
X };
X
X static char Comet_pci_IRQ_routes[] __prepdata =
@@ -199,6 +361,43 @@


X 15 /* Line 4 */
X };
X

+/* Motorola Series-EX */
+static char Comet2_pci_IRQ_map[23] __prepdata =


+{
+ 0, /* Slot 0 - unused */
+ 0, /* Slot 1 - unused */

+ 3, /* Slot 2 - SCSI - NCR825A */


+ 0, /* Slot 3 - unused */

+ 1, /* Slot 4 - Ethernet - DEC2104X */


+ 0, /* Slot 5 - unused */

+ 1, /* Slot 6 - PCI slot 1 */
+ 2, /* Slot 7 - PCI slot 2 */
+ 3, /* Slot 8 - PCI slot 3 */
+ 4, /* Slot 9 - PCI bridge */


+ 0, /* Slot 10 - unused */
+ 0, /* Slot 11 - unused */

+ 3, /* Slot 12 - SCSI - NCR825A */


+ 0, /* Slot 13 - unused */

+ 1, /* Slot 14 - Ethernet - DEC2104X */


+ 0, /* Slot 15 - unused */

+ 1, /* Slot 16 - PCI slot 1 */
+ 2, /* Slot 17 - PCI slot 2 */
+ 3, /* Slot 18 - PCI slot 3 */
+ 4, /* Slot 19 - PCI bridge */
+ 0,
+ 0,
+ 0,
+};
+
+static char Comet2_pci_IRQ_routes[] __prepdata =
+{
+ 0, /* Line 0 - Unused */
+ 10, /* Line 1 */
+ 11, /* Line 2 */
+ 14, /* Line 3 */
+ 15, /* Line 4 */
+};
+
X /*
X * ibm 830 (and 850?).
X * This is actually based on the Carolina motherboard
@@ -328,106 +527,24 @@
X #define ELCRM_INT7_LVL 0x80
X #define ELCRM_INT5_LVL 0x20
X
-/*
- * Mechanism 1 configuration space access as defined in the PCI spec.
- */
-#define CFG_ADDR (volatile u_int *)0x80000cf8
-#define CFG_DATA 0x80000cfc
-
-#define CFG_DEV_ADDR(b, d, o) (0x80000000 | \
- ((b) << 16) | \
- ((d) << 8) | \
- ((o) & ~3))
-
-unsigned char max_bus=255;
-
-int mech1_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned char *val)

-{
- *val = 0xff;
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- *val = in_8((unsigned char *)CFG_DATA + (offset & 3));


- return PCIBIOS_SUCCESSFUL;
-}
-

-int mech1_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned short *val)

-{
- *val = 0xffff;
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- *val = in_le16((volatile unsigned short *)(CFG_DATA + (offset&3)));


- return PCIBIOS_SUCCESSFUL;
-}
-

-int mech1_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned int *val)

-{
- *val = 0xffffffff;
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 3) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- *val = in_le32((volatile unsigned int *)CFG_DATA);


- return PCIBIOS_SUCCESSFUL;
-}
-

-int mech1_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned char val)

-{
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- out_8((unsigned char *)CFG_DATA + (offset & 3), val);


- return PCIBIOS_SUCCESSFUL;
-}
-

-int mech1_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned short val)

-{
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- out_le16((volatile unsigned short *)(CFG_DATA + (offset&3)), val);


- return PCIBIOS_SUCCESSFUL;
-}
-

-int mech1_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,


- unsigned char offset, unsigned int val)

-{
- if (bus > max_bus)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if ((offset & 1) != 0)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
- out_le32((volatile unsigned int *)CFG_DATA, val);
- return PCIBIOS_SUCCESSFUL;
-}
+#define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset)
+#define DEVNO(dev) (dev>>3)
X
X __prep
X int
X prep_pcibios_read_config_dword (unsigned char bus,
X unsigned char dev, unsigned char offset, unsigned int *val)
X {
- unsigned long _val;
+ unsigned long _val;
X unsigned long *ptr;
- dev >>= 3;
-
- if ((bus != 0) || (dev > MAX_DEVNR))
- {
+
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+ {
X *val = 0xFFFFFFFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else
X {
- ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+ ptr = (unsigned long *)CFGPTR(dev);
X _val = le32_to_cpu(*ptr);
X }
X *val = _val;
@@ -439,16 +556,16 @@
X prep_pcibios_read_config_word (unsigned char bus,
X unsigned char dev, unsigned char offset, unsigned short *val)
X {
- unsigned short _val;
+ unsigned short _val;
X unsigned short *ptr;
- dev >>= 3;
- if ((bus != 0) || (dev > MAX_DEVNR))
- {
- *val = (unsigned short)0xFFFFFFFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
+
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+ {
+ *val = 0xFFFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else
X {
- ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+ ptr = (unsigned short *)CFGPTR(dev);
X _val = le16_to_cpu(*ptr);
X }
X *val = _val;
@@ -460,16 +577,16 @@
X prep_pcibios_read_config_byte (unsigned char bus,
X unsigned char dev, unsigned char offset, unsigned char *val)
X {
- unsigned char _val;
- volatile unsigned char *ptr;
- dev >>= 3;
- if ((bus != 0) || (dev > MAX_DEVNR))
- {
- *(unsigned long *)val = (unsigned long) 0xFFFFFFFF;
- return PCIBIOS_DEVICE_NOT_FOUND;
- } else
+ unsigned char _val;
+ unsigned char *ptr;
+
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+ {
+ *val = 0xFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else
X {
- ptr = (unsigned char *)(0x80800000 | (1<<dev) | (offset ^ 1));
+ ptr = (unsigned char *)CFGPTR(dev);
X _val = *ptr;
X }
X *val = _val;
@@ -483,14 +600,14 @@
X {
X unsigned long _val;
X unsigned long *ptr;
- dev >>= 3;
+
X _val = le32_to_cpu(val);
- if ((bus != 0) || (dev > MAX_DEVNR))
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
X {
X return PCIBIOS_DEVICE_NOT_FOUND;
X } else
X {
- ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+ ptr = (unsigned long *)CFGPTR(dev);
X *ptr = _val;
X }
X return PCIBIOS_SUCCESSFUL;
@@ -503,14 +620,14 @@
X {
X unsigned short _val;
X unsigned short *ptr;
- dev >>= 3;
+
X _val = le16_to_cpu(val);
- if ((bus != 0) || (dev > MAX_DEVNR))
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
X {
X return PCIBIOS_DEVICE_NOT_FOUND;
X } else
X {
- ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+ ptr = (unsigned short *)CFGPTR(dev);
X *ptr = _val;
X }
X return PCIBIOS_SUCCESSFUL;
@@ -523,20 +640,151 @@
X {
X unsigned char _val;
X unsigned char *ptr;
- dev >>= 3;
+
X _val = val;
- if ((bus != 0) || (dev > MAX_DEVNR))
+ if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
X {
X return PCIBIOS_DEVICE_NOT_FOUND;
X } else
X {
- ptr = (unsigned char *)(0x80800000 | (1<<dev) | (offset^1));
+ ptr = (unsigned char *)CFGPTR(dev);
X *ptr = _val;
X }
X return PCIBIOS_SUCCESSFUL;
X }
X
-__initfunc(unsigned long route_pci_interrupts(void))
+#define MOTOROLA_CPUTYPE_REG 0x800
+#define MOTOROLA_BASETYPE_REG 0x803
+#define MPIC_RAVEN_ID 0x48010000
+#define MPIC_HAWK_ID 0x48030000
+#define MOT_PROC2_BIT 0x800
+
+static u_char mvme2600_openpic_initsenses[] __initdata = {
+ 1, /* MVME2600_INT_SIO */
+ 0, /* MVME2600_INT_FALCN_ECC_ERR */
+ 1, /* MVME2600_INT_PCI_ETHERNET */
+ 1, /* MVME2600_INT_PCI_SCSI */
+ 1, /* MVME2600_INT_PCI_GRAPHICS */
+ 1, /* MVME2600_INT_PCI_VME0 */
+ 1, /* MVME2600_INT_PCI_VME1 */
+ 1, /* MVME2600_INT_PCI_VME2 */
+ 1, /* MVME2600_INT_PCI_VME3 */
+ 1, /* MVME2600_INT_PCI_INTA */
+ 1, /* MVME2600_INT_PCI_INTB */
+ 1, /* MVME2600_INT_PCI_INTC */
+ 1, /* MVME2600_INT_PCI_INTD */
+ 1, /* MVME2600_INT_LM_SIG0 */
+ 1, /* MVME2600_INT_LM_SIG1 */
+};
+
+#define MOT_RAVEN_PRESENT 0x1
+#define MOT_HAWK_PRESENT 0x2
+
+int prep_keybd_present = 1;
+int MotMPIC = 0;
+
+__initfunc(int raven_init(void))
+{
+ unsigned int devid;
+ unsigned int pci_membase;
+ unsigned char base_mod;
+
+ /* Check to see if the Raven chip exists. */
+ if ( _prep_type != _PREP_Motorola) {
+ OpenPIC = NULL;


+ return 0;
+ }
+

+ /* Check to see if this board is a type that might have a Raven. */
+ if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) {
+ OpenPIC = NULL;


+ return 0;
+ }
+

+ /* Check the first PCI device to see if it is a Raven. */
+ pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid);
+
+ switch (devid & 0xffff0000) {
+ case MPIC_RAVEN_ID:
+ MotMPIC = MOT_RAVEN_PRESENT;
+ break;
+ case MPIC_HAWK_ID:
+ MotMPIC = MOT_HAWK_PRESENT;
+ break;
+ default:
+ OpenPIC = NULL;


+ return 0;
+ }
+
+

+ /* Read the memory base register. */
+ pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
+
+ if (pci_membase == 0) {
+ OpenPIC = NULL;


+ return 0;
+ }
+

+ /* Map the Raven MPIC registers to virtual memory. */
+ OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000);
+
+ OpenPIC_InitSenses = mvme2600_openpic_initsenses;
+ OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
+
+ /* If raven is present on Motorola store the system config register
+ * for later use.
+ */
+ ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);
+
+ /* This is a hack. If this is a 2300 or 2400 mot board then there is
+ * no keyboard controller and we have to indicate that.
+ */
+ base_mod = inb(MOTOROLA_BASETYPE_REG);
+ if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) ||
+ (base_mod == 0xFA) || (base_mod == 0xE1))
+ prep_keybd_present = 0;
+
+ return 1;
+}
+
+struct mot_info {
+ int cpu_type; /* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */
+ /* 0x200 if this board has a Hawk chip. */
+ int base_type;
+ int max_cpu; /* ored with 0x80 if this board should be checked for multi CPU */
+ const char *name;
+ unsigned char *map;
+ unsigned char *routes;
+} mot_info[] = {
+ {0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes},
+ {0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes},
+ {0x040, 0x00, 0x00, "Blackhawk (Powerstack)", Blackhawk_pci_IRQ_map, Blackhawk_pci_IRQ_routes},
+ {0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)", Omaha_pci_IRQ_map, Omaha_pci_IRQ_routes},
+ {0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)", Utah_pci_IRQ_map, Utah_pci_IRQ_routes},
+ {0x0A0, 0x00, 0x00, "Powerstack (Series EX)", Comet2_pci_IRQ_map, Comet2_pci_IRQ_routes},
+ {0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", Sitka_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC", Mesquite_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF6, 0x80, "MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF6, 0x81, "Dual MTX Plus", MTXplus_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port", MTX_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xF9, 0x00, "MVME 2300", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFA, 0x00, "MVME 2300SC/2600", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes},
+ {0x000, 0x00, 0x00, "", NULL, NULL}
+};
+
+__initfunc(unsigned long prep_route_pci_interrupts(void))
X {
X unsigned char *ibc_pirq = (unsigned char *)0x80800860;
X unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
@@ -545,49 +793,66 @@
X if ( _prep_type == _PREP_Motorola)
X {
X unsigned short irq_mode;
+ unsigned char cpu_type;
+ unsigned char base_mod;
+ int entry;
+ int mot_entry = -1;
+
+ cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
+ base_mod = inb(MOTOROLA_BASETYPE_REG);
+
+ for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
+ if (mot_info[entry].cpu_type & 0x200) { /* Check for Hawk chip */
+ if (!(MotMPIC & MOT_HAWK_PRESENT))
+ continue;
+ } else { /* Check non hawk boards */
+ if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
+ continue;
+
+ if (mot_info[entry].base_type == 0) {
+ mot_entry = entry;
+ break;
+ }
X
- switch (inb(0x800) & 0xF0)
- {
- case 0x10: /* MVME16xx */
- Motherboard_map_name = "Genesis";
- Motherboard_map = Genesis_pci_IRQ_map;
- Motherboard_routes = Genesis_pci_IRQ_routes;
- break;
- case 0x20: /* Series E */
- Motherboard_map_name = "Powerstack (Series E)";
- Motherboard_map = Comet_pci_IRQ_map;
- Motherboard_routes = Comet_pci_IRQ_routes;
- break;
- case 0x50: /* PowerStackII Pro3000 */
- Motherboard_map_name = "Omaha (PowerStack II Pro3000)";
- Motherboard_map = Omaha_pci_IRQ_map;
- Motherboard_routes = Omaha_pci_IRQ_routes;
- break;
- case 0x60: /* PowerStackII Pro4000 */
- Motherboard_map_name = "Utah (Powerstack II Pro4000)";
- Motherboard_map = Utah_pci_IRQ_map;
- Motherboard_routes = Utah_pci_IRQ_routes;
- break;
- case 0xE0: /* MTX -- close enough?? to Genesis, so reuse it */
- Motherboard_map_name = "Motorola MTX";
- Motherboard_map = Genesis_pci_IRQ_map;
- Motherboard_routes = Genesis_pci_IRQ_routes;
- break;
- case 0x40: /* PowerStack */
- default: /* Can't hurt, can it? */
- Motherboard_map_name = "Blackhawk (Powerstack)";
- Motherboard_map = Blackhawk_pci_IRQ_map;
- Motherboard_routes = Blackhawk_pci_IRQ_routes;
- break;
+ if (mot_info[entry].base_type != base_mod)
+ continue;
+ }
+
+ if (!(mot_info[entry].max_cpu & 0x80)) {
+ mot_entry = entry;
+ break;
+ }
+
+ /* processor 1 not present and max processor zero indicated */
+ if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) {
+ mot_entry = entry;
+ break;
+ }
+
+ /* processor 1 present and max processor zero indicated */
+ if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) {
+ mot_entry = entry;
+ break;
+ }
X }
- /* AJF adjust level/edge control according to routes */
- irq_mode = 0;
- for (i = 1; i <= 4; i++)
- {
- irq_mode |= ( 1 << Motherboard_routes[i] );
+
+ if (mot_entry == -1) /* No particular cpu type found - assume Blackhawk */
+ mot_entry = 3;
+
+ Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
+ Motherboard_map = mot_info[mot_entry].map;
+ Motherboard_routes = mot_info[mot_entry].routes;
+
+ if (!(mot_info[entry].cpu_type & 0x100)) {
+ /* AJF adjust level/edge control according to routes */
+ irq_mode = 0;
+ for (i = 1; i <= 4; i++)
+ {
+ irq_mode |= ( 1 << Motherboard_routes[i] );
+ }
+ outb( irq_mode & 0xff, 0x4d0 );
+ outb( (irq_mode >> 8) & 0xff, 0x4d1 );
X }
- outb( irq_mode & 0xff, 0x4d0 );
- outb( (irq_mode >> 8) & 0xff, 0x4d1 );
X } else if ( _prep_type == _PREP_IBM )
X {
X unsigned char pl_id;
@@ -705,5 +970,119 @@
X /* Enable PCI interrupts */
X *ibc_pcicon |= 0x20;
X return 0;
+}
+
+__initfunc(
+void
+prep_pcibios_fixup(void))


+{
+ struct pci_dev *dev;

+ extern unsigned char *Motherboard_map;
+ extern unsigned char *Motherboard_routes;
+ unsigned char i;
+


+ if ( _prep_type == _PREP_Radstone )

+ {
+ printk("Radstone boards require no PCI fixups\n");
+ return;
+ }
+
+ prep_route_pci_interrupts();
+
+ printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
+ if (OpenPIC) {
+ /* PCI interrupts are controlled by the OpenPIC */


+ for(dev=pci_devices; dev; dev=dev->next) {

+ if (dev->bus->number == 0) {
+ dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
+ pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq);
+ }
+ }
+ return;
+ }
+


+ for(dev=pci_devices; dev; dev=dev->next)
+ {
+ /*

+ * Use our old hard-coded kludge to figure out what
+ * irq this device uses. This is necessary on things
+ * without residual data. -- Cort
+ */
+ unsigned char d = PCI_SLOT(dev->devfn);
+ dev->irq = Motherboard_routes[Motherboard_map[d]];
+
+ for ( i = 0 ; i <= 5 ; i++ )
+ {
+ if ( dev->base_address[i] > 0x10000000 )
+ {
+ printk("Relocating PCI address %lx -> %lx\n",
+ dev->base_address[i],
+ (dev->base_address[i] & 0x00FFFFFF)
+ | 0x01000000);
+ dev->base_address[i] =
+ (dev->base_address[i] & 0x00FFFFFF) | 0x01000000;
+ pci_write_config_dword(dev,
+ PCI_BASE_ADDRESS_0+(i*0x4),
+ dev->base_address[i] );
+ }


+ }
+#if 0
+ /*

+ * If we have residual data and if it knows about this
+ * device ask it what the irq is.


+ * -- Cort
+ */

+ ppcd = residual_find_device_id( ~0L, dev->device,
+ -1,-1,-1, 0);
+#endif
+ }
+}
+
+decl_config_access_method(indirect);
+
+__initfunc(
+void
+prep_setup_pci_ptrs(void))
+{
+ PPC_DEVICE *hostbridge;
+
+ printk("PReP architecture\n");


+ if ( _prep_type == _PREP_Radstone )

+ {
+ pci_config_address = (unsigned *)0x80000cf8;
+ pci_config_data = (char *)0x80000cfc;
+ set_config_access_method(indirect);
+ }
+ else
+ {
+ hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
+ BridgeController, PCIBridge, -1, 0);
+ if (hostbridge &&
+ hostbridge->DeviceId.Interface == PCIBridgeIndirect) {
+ PnP_TAG_PACKET * pkt;
+ set_config_access_method(indirect);
+ pkt = PnP_find_large_vendor_packet(
+ res->DevicePnPHeap+hostbridge->AllocatedOffset,
+ 3, 0);
+ if(pkt)
+ {
+#define p pkt->L4_Pack.L4_Data.L4_PPCPack
+ pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData);
+ pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8));
+ }
+ else
+ {
+ pci_config_address= (unsigned *) 0x80000cf8;
+ pci_config_data= (unsigned char *) 0x80000cfc;
+ }
+ }
+ else
+ {
+ set_config_access_method(prep);
+ }
+
+ }
+
+ ppc_md.pcibios_fixup = prep_pcibios_fixup;
X }
X
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.2.7/linux/arch/ppc/kernel/prep_setup.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/prep_setup.c Tue May 11 08:24:32 1999
@@ -30,6 +30,9 @@
X #include <linux/blk.h>
X #include <linux/ioport.h>
X #include <linux/console.h>
+#include <linux/timex.h>
+#include <linux/pci.h>
+#include <linux/openpic.h>
X
X #include <asm/mmu.h>
X #include <asm/processor.h>
@@ -38,12 +41,57 @@
X #include <asm/pgtable.h>
X #include <asm/ide.h>
X #include <asm/cache.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/mk48t59.h>
+#include <asm/prep_nvram.h>
+#include <asm/raven.h>
+


+
+#include "time.h"
+#include "local_irq.h"

+#include "i8259.h"
+#include "open_pic.h"
X
X #if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
X #include <../drivers/sound/sound_config.h>
X #include <../drivers/sound/dev_table.h>
X #endif
X
+unsigned char ucSystemType;
+unsigned char ucBoardRev;
+unsigned char ucBoardRevMaj, ucBoardRevMin;
+
+extern unsigned long mc146818_get_rtc_time(void);
+extern int mc146818_set_rtc_time(unsigned long nowtime);
+extern unsigned long mk48t59_get_rtc_time(void);
+extern int mk48t59_set_rtc_time(unsigned long nowtime);
+
+extern unsigned char prep_nvram_read_val(int addr);
+extern void prep_nvram_write_val(int addr,
+ unsigned char val);
+extern unsigned char rs_nvram_read_val(int addr);
+extern void rs_nvram_write_val(int addr,


+ unsigned char val);
+

+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char pckbd_unexpected_up(unsigned char keycode);
+extern void pckbd_leds(unsigned char leds);
+extern void pckbd_init_hw(void);

+extern unsigned char pckbd_sysrq_xlate[128];
+

+extern void prep_setup_pci_ptrs(void);
+extern void chrp_do_IRQ(struct pt_regs *regs, int cpu, int isfake);
+extern char saved_command_line[256];
+
+int _prep_type;
+
+#define cached_21 (((char *)(ppc_cached_irq_mask))[3])
+#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])
+


X /* for the mac fs */
X kdev_t boot_dev;

X /* used in nasty hack for sound - see prep_setup_arch() -- Cort */
@@ -60,6 +108,9 @@
X extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
X extern int rd_image_start; /* starting block # of image */
X #endif
+#ifdef CONFIG_VGA_CONSOLE
+unsigned long vgacon_remap_base;
+#endif
X
X __prep
X int
@@ -177,6 +228,13 @@
X outb(reg, SIO_CONFIG_RD);
X outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */
X
+ /*
+ * We need to set up the NvRAM access routines early as prep_init
+ * has yet to be called
+ */
+ ppc_md.nvram_read_val = prep_nvram_read_val;
+ ppc_md.nvram_write_val = prep_nvram_write_val;
+
X /* we should determine this according to what we find! -- Cort */
X switch ( _prep_type )
X {
@@ -210,9 +268,38 @@
X ucBoardRev=inb(0x854);
X ucBoardRevMaj=ucBoardRev>>5;
X ucBoardRevMin=ucBoardRev&0x1f;
+
+ /*
+ * Most Radstone boards have memory mapped NvRAM
+ */
+ if((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj<5))
+ {
+ ppc_md.nvram_read_val = prep_nvram_read_val;
+ ppc_md.nvram_write_val = prep_nvram_write_val;
+ }
+ else
+ {
+ ppc_md.nvram_read_val = rs_nvram_read_val;
+ ppc_md.nvram_write_val = rs_nvram_write_val;
+ }
X break;
X }
X
+ /* Read in NVRAM data */
+ init_prep_nvram();
+
+ /* if no bootargs, look in NVRAM */
+ if ( cmd_line[0] == '\0' ) {
+ char *bootargs;
+ bootargs = prep_nvram_get_var("bootargs");
+ if (bootargs != NULL) {
+ strcpy(cmd_line, bootargs);
+
+ /* again.. */
+ strcpy(saved_command_line, cmd_line);
+ }
+ }
+
X printk("Boot arguments: %s\n", cmd_line);
X
X #ifdef CONFIG_SOUND_CS4232
@@ -262,12 +349,349 @@
X request_region(0x80,0x10,"dma page reg");
X request_region(0xc0,0x20,"dma2");
X
+ raven_init();
+
X #ifdef CONFIG_VGA_CONSOLE
+ /* remap the VGA memory */
+ vgacon_remap_base = 0xf0000000;
+ /*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/
X conswitchp = &vga_con;
X #endif
X }
X
-__initfunc(void prep_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq))
+/*
+ * Determine the decrementer frequency from the residual data
+ * This allows for a faster boot as we do not need to calibrate the
+ * decrementer against another clock. This is important for embedded systems.
+ */
+__initfunc(void prep_res_calibrate_decr(void))
+{
+ int freq, divisor;
+
+ freq = res->VitalProductData.ProcessorBusHz;
+ divisor = 4;


+ printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
+ decrementer_count = freq / HZ / divisor;
+ count_period_num = divisor;
+ count_period_den = freq / 1000000;

+}
+
+/*
+ * Uses the on-board timer to calibrate the on-chip decrementer register
+ * for prep systems. On the pmac the OF tells us what the frequency is
+ * but on prep we have to figure it out.


+ * -- Cort
+ */

+int calibrate_done = 0;
+volatile int *done_ptr = &calibrate_done;
+
+__initfunc(void
+prep_calibrate_decr_handler(int irq,
+ void *dev,
+ struct pt_regs *regs))
+{
+ unsigned long freq, divisor;
+ static unsigned long t1 = 0, t2 = 0;
+
+ if ( !t1 )
+ t1 = get_dec();
+ else if (!t2)
+ {
+ t2 = get_dec();
+ t2 = t1-t2; /* decr's in 1/HZ */
+ t2 = t2*HZ; /* # decrs in 1s - thus in Hz */
+ freq = t2 * 60; /* try to make freq/1e6 an integer */
+ divisor = 60;
+ printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
+ freq, divisor,t2>>20);


+ decrementer_count = freq / HZ / divisor;
+ count_period_num = divisor;
+ count_period_den = freq / 1000000;

+ *done_ptr = 1;
+ }
+}
+
+__initfunc(void prep_calibrate_decr(void))


+{
+ unsigned long flags;
+
+

+ save_flags(flags);
+
+#define TIMER0_COUNT 0x40
+#define TIMER_CONTROL 0x43
+ /* set timer to periodic mode */
+ outb_p(0x34,TIMER_CONTROL);/* binary, mode 2, LSB/MSB, ch 0 */
+ /* set the clock to ~100 Hz */
+ outb_p(LATCH & 0xff , TIMER0_COUNT); /* LSB */
+ outb(LATCH >> 8 , TIMER0_COUNT); /* MSB */
+
+ if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)


+ panic("Could not allocate timer IRQ!");

+ __sti();
+ while ( ! *done_ptr ) /* nothing */; /* wait for calibrate */
+ restore_flags(flags);
+ free_irq( 0, NULL);
+}
+
+
+/* We use the NVRAM RTC to time a second to calibrate the decrementer. */
+__initfunc(void mk48t59_calibrate_decr(void))
+{
+ unsigned long freq, divisor;
+ unsigned long t1, t2;
+ unsigned char save_control;
+ long i;
+ unsigned char sec;
+
+
+ /* Make sure the time is not stopped. */
+ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
+
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
+ (save_control & (~MK48T59_RTC_CB_STOP)));
+
+ /* Now make sure the read bit is off so the value will change. */
+ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
+ save_control &= ~MK48T59_RTC_CA_READ;
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
+
+
+ /* Read the seconds value to see when it changes. */
+ sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
+ for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
+ if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
+ break;
+ }
+ }
+ t1 = get_dec();
+
+ sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
+ for (i = 0 ; i < 1000000 ; i++) { /* Should take up 1 second... */
+ if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {


+ break;
+ }
+ }
+

+ t2 = t1 - get_dec();
+
+ freq = t2 * 60; /* try to make freq/1e6 an integer */
+ divisor = 60;
+ printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
+ freq, divisor,t2>>20);


+ decrementer_count = freq / HZ / divisor;
+ count_period_num = divisor;
+ count_period_den = freq / 1000000;
+}
+

+void
+prep_restart(char *cmd)
+{
+ unsigned long i = 10000;
+
+
+ _disable_interrupts();
+
+ /* set exception prefix high - to the prom */
+ _nmask_and_or_msr(0, MSR_IP);
+
+ /* make sure bit 0 (reset) is a 0 */
+ outb( inb(0x92) & ~1L , 0x92 );
+ /* signal a reset to system control port A - soft reset */
+ outb( inb(0x92) | 1 , 0x92 );
+
+ while ( i != 0 ) i++;
+ panic("restart failed\n");
+}
+
+/*
+ * This function will restart a board regardless of port 92 functionality
+ */
+void
+prep_direct_restart(char *cmd)
+{
+ u32 jumpaddr=0xfff00100;
+ u32 defaultmsr=MSR_IP;
+
+ /*
+ * This will ALWAYS work regardless of port 92
+ * functionality
+ */
+ _disable_interrupts();
+
+ __asm__ __volatile__("\n\
+ mtspr 26, %1 /* SRR0 */
+ mtspr 27, %0 /* SRR1 */
+ rfi"
+ :
+ : "r" (defaultmsr), "r" (jumpaddr));
+ /*
+ * Not reached
+ */
+}
+
+void
+prep_halt(void)


+{
+ unsigned long flags;

+ _disable_interrupts();
+ /* set exception prefix high - to the prom */
+ save_flags( flags );
+ restore_flags( flags|MSR_IP );
+
+ /* make sure bit 0 (reset) is a 0 */
+ outb( inb(0x92) & ~1L , 0x92 );
+ /* signal a reset to system control port A - soft reset */
+ outb( inb(0x92) | 1 , 0x92 );
+
+ while ( 1 ) ;
+ /*
+ * Not reached
+ */
+}
+
+void
+prep_power_off(void)
+{
+ prep_halt();
+}
+
+int prep_setup_residual(char *buffer)


+{
+ int len = 0;
+

+
+ /* PREP's without residual data will give incorrect values here */
+ len += sprintf(len+buffer, "clock\t\t: ");
+ if ( res->ResidualLength )
+ len += sprintf(len+buffer, "%ldMHz\n",
+ (res->VitalProductData.ProcessorHz > 1024) ?
+ res->VitalProductData.ProcessorHz>>20 :
+ res->VitalProductData.ProcessorHz);
+ else
+ len += sprintf(len+buffer, "???\n");


+
+ return len;
+}
+

+u_int
+prep_irq_cannonicalize(u_int irq)
+{


+ if (irq == 2)
+ {

+ return 9;
+ }
+ else
+ {


+ return irq;
+ }
+}
+
+void

+prep_do_IRQ(struct pt_regs *regs, int cpu, int isfake)


+{
+ int irq;
+

+ if ( (irq = i8259_irq(0)) < 0 )
+ {
+ printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n",
+ regs->nip);
+ ppc_spurious_interrupts++;
+ return;


+ }
+ ppc_irq_dispatch_handler( regs, irq );
+}
+

+__initfunc(void
+prep_init_IRQ(void))


+{
+ int i;
+

+ if (OpenPIC != NULL) {
+ for ( i = 16 ; i < 36 ; i++ )
+ irq_desc[i].ctl = &open_pic;
+ openpic_init(1);
+ }


+
+ for ( i = 0 ; i < 16 ; i++ )
+ irq_desc[i].ctl = &i8259_pic;
+ i8259_init();

+#ifdef __SMP__
+ request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action,
+ 0, "IPI0", 0);


+#endif /* __SMP__ */
+}
+

+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+/*
+ * IDE stuff.
+ */
+void

+prep_ide_insw(ide_ioreg_t port, void *buf, int ns)
+{
+ _insw((unsigned short *)((port)+_IO_BASE), buf, ns);
+}
+
+void
+prep_ide_outsw(ide_ioreg_t port, void *buf, int ns)
+{
+ _outsw((unsigned short *)((port)+_IO_BASE), buf, ns);
+}
+
+int
+prep_ide_default_irq(ide_ioreg_t base)
+{
+ switch (base) {
+ case 0x1f0: return 13;
+ case 0x170: return 13;
+ case 0x1e8: return 11;
+ case 0x168: return 10;
+ default:


+ return 0;
+ }
+}
+

+ide_ioreg_t
+prep_ide_default_io_base(int index)
+{
+ switch (index) {
+ case 0: return 0x1f0;
+ case 1: return 0x170;
+ case 2: return 0x1e8;
+ case 3: return 0x168;
+ default:


+ return 0;
+ }
+}
+

+int
+prep_ide_check_region(ide_ioreg_t from, unsigned int extent)
+{


+ return check_region(from, extent);
+}
+
+void

+prep_ide_request_region(ide_ioreg_t from,


+ unsigned int extent,
+ const char *name)
+{

+ request_region(from, extent, name);
+}
+
+void

+prep_ide_release_region(ide_ioreg_t from,


+ unsigned int extent)
+{

+ release_region(from, extent);
+}
+
+void

+prep_ide_fix_driveid(struct hd_driveid *id)
+{
+}
+
+__initfunc(void
+prep_ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq))
X {
X ide_ioreg_t port = base;
X int i = 8;
@@ -277,6 +701,143 @@
X *p++ = base + 0x206;
X if (irq != NULL)
X *irq = 0;
+}
+#endif
+
+__initfunc(void
+prep_init(unsigned long r3, unsigned long r4, unsigned long r5,


+ unsigned long r6, unsigned long r7))
+{

+ /* make a copy of residual data */


+ if ( r3 )

+ {
+ memcpy((void *)res,(void *)(r3+KERNELBASE),
+ sizeof(RESIDUAL));
+ }
+
+ isa_io_base = PREP_ISA_IO_BASE;
+ isa_mem_base = PREP_ISA_MEM_BASE;
+ pci_dram_offset = PREP_PCI_DRAM_OFFSET;
+ ISA_DMA_THRESHOLD = 0x00ffffff;


+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+

+ /* figure out what kind of prep workstation we are */
+ if ( res->ResidualLength != 0 )
+ {
+ if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
+ _prep_type = _PREP_IBM;
+ else if (!strncmp(res->VitalProductData.PrintableModel,
+ "Radstone",8))
+ {
+ extern char *Motherboard_map_name;
+
+ _prep_type = _PREP_Radstone;
+ Motherboard_map_name=
+ res->VitalProductData.PrintableModel;
+ }
+ else
+ _prep_type = _PREP_Motorola;
+ }
+ else /* assume motorola if no residual (netboot?) */
+ {
+ _prep_type = _PREP_Motorola;
+ }
+
+ prep_setup_pci_ptrs();


+
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* take care of initrd if we have one */
+ if ( r4 )
+ {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* take care of cmd line */

+ if ( r6 && (((char *) r6) != '\0'))
+ {


+ *(char *)(r7+KERNELBASE) = 0;
+ strcpy(cmd_line, (char *)(r6+KERNELBASE));
+ }
+

+ ppc_md.setup_arch = prep_setup_arch;
+ ppc_md.setup_residual = prep_setup_residual;
+ ppc_md.get_cpuinfo = prep_get_cpuinfo;
+ ppc_md.irq_cannonicalize = prep_irq_cannonicalize;
+ ppc_md.init_IRQ = prep_init_IRQ;
+ if ( !OpenPIC )
+ ppc_md.do_IRQ = prep_do_IRQ;
+ else
+ ppc_md.do_IRQ = chrp_do_IRQ;


+ ppc_md.init = NULL;
+

+ ppc_md.restart = prep_restart;
+ ppc_md.power_off = prep_power_off;
+ ppc_md.halt = prep_halt;


+
+ ppc_md.time_init = NULL;

+ if (_prep_type == _PREP_Radstone) {
+ /*
+ * We require a direct restart as port 92 does not work on
+ * all Radstone boards
+ */
+ ppc_md.restart = prep_direct_restart;
+ /*
+ * The RTC device used varies according to board type
+ */
+ if(((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj>=5)) ||
+ (ucSystemType==RS_SYS_TYPE_PPC1a))
+ {
+ ppc_md.set_rtc_time = mk48t59_set_rtc_time;
+ ppc_md.get_rtc_time = mk48t59_get_rtc_time;
+ }
+ else
+ {
+ ppc_md.set_rtc_time = mc146818_set_rtc_time;
+ ppc_md.get_rtc_time = mc146818_get_rtc_time;
+ }
+ /*
+ * Determine the decrementer rate from the residual data
+ */
+ ppc_md.calibrate_decr = prep_res_calibrate_decr;
+ }
+ else if (_prep_type == _PREP_IBM) {
+ ppc_md.set_rtc_time = mc146818_set_rtc_time;
+ ppc_md.get_rtc_time = mc146818_get_rtc_time;
+ ppc_md.calibrate_decr = prep_calibrate_decr;
+ }
+ else {
+ ppc_md.set_rtc_time = mk48t59_set_rtc_time;
+ ppc_md.get_rtc_time = mk48t59_get_rtc_time;
+ ppc_md.calibrate_decr = mk48t59_calibrate_decr;


+ }
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)

+ ppc_ide_md.insw = prep_ide_insw;
+ ppc_ide_md.outsw = prep_ide_outsw;
+ ppc_ide_md.default_irq = prep_ide_default_irq;
+ ppc_ide_md.default_io_base = prep_ide_default_io_base;
+ ppc_ide_md.check_region = prep_ide_check_region;
+ ppc_ide_md.request_region = prep_ide_request_region;
+ ppc_ide_md.release_region = prep_ide_release_region;
+ ppc_ide_md.fix_driveid = prep_ide_fix_driveid;
+ ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports;
+#endif
+ ppc_ide_md.io_base = _IO_BASE;
+
+#ifdef CONFIG_VT


+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.kbd_sysrq_xlate = pckbd_sysrq_xlate;
+#endif

+#endif
X }
X
X #ifdef CONFIG_SOUND_MODULE
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c
--- v2.2.7/linux/arch/ppc/kernel/prep_time.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/prep_time.c Thu Apr 29 12:39:01 1999
@@ -22,7 +22,9 @@
X #include <asm/segment.h>
X #include <asm/io.h>
X #include <asm/processor.h>
-#include <asm/nvram.h>
+#include <asm/machdep.h>
+#include <asm/prep_nvram.h>
+#include <asm/mk48t59.h>
X
X #include "time.h"
X
@@ -41,133 +43,44 @@
X * is setup at boot time to use the correct addresses.
X * -- Cort
X */
-/*
- * translate from mc146818 to m48t18 addresses
- */
-unsigned int clock_transl[] __prepdata = { MOTO_RTC_SECONDS,0 /* alarm */,
- MOTO_RTC_MINUTES,0 /* alarm */,
- MOTO_RTC_HOURS,0 /* alarm */, /* 4,5 */
- MOTO_RTC_DAY_OF_WEEK,
- MOTO_RTC_DAY_OF_MONTH,
- MOTO_RTC_MONTH,
- MOTO_RTC_YEAR, /* 9 */
- MOTO_RTC_CONTROLA, MOTO_RTC_CONTROLB /* 10,11 */
-};
-
-/*
- * The following struture is used to access the MK48T18
- */
-typedef volatile struct _MK48T18 {
- unsigned char ucNvRAM[0x3ff8]; /* NvRAM locations */
- unsigned char ucControl;
- unsigned char ucSecond; /* 0-59 */
- unsigned char ucMinute; /* 0-59 */
- unsigned char ucHour; /* 0-23 */
- unsigned char ucDay; /* 1-7 */
- unsigned char ucDate; /* 1-31 */
- unsigned char ucMonth; /* 1-12 */
- unsigned char ucYear; /* 0-99 */
-} MK48T18, *PMK48T18;
-
-/*
- * The control register contains a 5 bit calibration value plus sign
- * and read/write enable bits
- */
-#define MK48T18_CTRL_CAL_MASK 0x1f
-#define MK48T18_CTRL_CAL_SIGN 0x20
-#define MK48T18_CTRL_READ 0x40
-#define MK48T18_CTRL_WRITE 0x80
-/*
- * The STOP bit is the most significant bit of the seconds location
- */
-#define MK48T18_SEC_MASK 0x7f
-#define MK48T18_SEC_STOP 0x80
-/*
- * The day location also contains the frequency test bit which should
- * be zero for normal operation
- */
-#define MK48T18_DAY_MASK 0x07
-#define MK48T18_DAY_FT 0x40
-
-__prep
-int prep_cmos_clock_read(int addr)
-{
- if ( _prep_type == _PREP_IBM )
- return CMOS_READ(addr);
- else if ( _prep_type == _PREP_Motorola )
- {
- outb(clock_transl[addr]>>8, NVRAM_AS1);
- outb(clock_transl[addr], NVRAM_AS0);
- return (inb(NVRAM_DATA));
- }
- else if ( _prep_type == _PREP_Radstone )
- return CMOS_READ(addr);
-
- printk("Unknown machine in prep_cmos_clock_read()!\n");
- return -1;
-}
-
-__prep
-void prep_cmos_clock_write(unsigned long val, int addr)
-{
- if ( _prep_type == _PREP_IBM )
- {
- CMOS_WRITE(val,addr);
- return;
- }
- else if ( _prep_type == _PREP_Motorola )
- {
- outb(clock_transl[addr]>>8, NVRAM_AS1);
- outb(clock_transl[addr], NVRAM_AS0);
- outb(val,NVRAM_DATA);
- return;
- }
- else if ( _prep_type == _PREP_Radstone )
- {
- CMOS_WRITE(val,addr);
- return;
- }
-
- printk("Unknown machine in prep_cmos_clock_write()!\n");
-}
X
X /*
X * Set the hardware clock. -- Cort
X */
X __prep
-int prep_set_rtc_time(unsigned long nowtime)
+int mc146818_set_rtc_time(unsigned long nowtime)
X {
X unsigned char save_control, save_freq_select;
X struct rtc_time tm;
X
X to_tm(nowtime, &tm);
X
- save_control = prep_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
-
- prep_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
-
- save_freq_select = prep_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ /* tell the clock it's being set */
+ save_control = CMOS_READ(RTC_CONTROL);
X
- prep_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
- tm.tm_year -= 1900;
+ CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+ /* stop and reset prescaler */
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ tm.tm_year = (tm.tm_year - 1900) % 100;
X if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
X BIN_TO_BCD(tm.tm_sec);
X BIN_TO_BCD(tm.tm_min);
X BIN_TO_BCD(tm.tm_hour);
X BIN_TO_BCD(tm.tm_mon);
- BIN_TO_BCD(tm.tm_wday);
X BIN_TO_BCD(tm.tm_mday);
X BIN_TO_BCD(tm.tm_year);
X }
- prep_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
- prep_cmos_clock_write(tm.tm_min,RTC_MINUTES);
- prep_cmos_clock_write(tm.tm_hour,RTC_HOURS);
- prep_cmos_clock_write(tm.tm_mon,RTC_MONTH);
- prep_cmos_clock_write(tm.tm_wday+1,RTC_DAY_OF_WEEK);
- prep_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
- prep_cmos_clock_write(tm.tm_year,RTC_YEAR);
-
+ CMOS_WRITE(tm.tm_sec, RTC_SECONDS);
+ CMOS_WRITE(tm.tm_min, RTC_MINUTES);
+ CMOS_WRITE(tm.tm_hour, RTC_HOURS);
+ CMOS_WRITE(tm.tm_mon, RTC_MONTH);
+ CMOS_WRITE(tm.tm_mday, RTC_DAY_OF_MONTH);
+ CMOS_WRITE(tm.tm_year, RTC_YEAR);
+
X /* The following flags have to be released exactly in this order,
X * otherwise the DS12887 (popular MC146818A clone with integrated
X * battery and quartz) will not reset the oscillator and will not
@@ -175,52 +88,14 @@
X * the Dallas Semiconductor data sheets, but who believes data
X * sheets anyway ... -- Markus Kuhn
X */
- prep_cmos_clock_write(save_control, RTC_CONTROL);
- prep_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
X
- /*
- * Radstone Technology PPC1a boards use an MK48T18 device
- * as the "master" RTC but also have a DS1287 equivalent incorporated
- * into the PCI-ISA bridge device. The DS1287 is initialised by the boot
- * firmware to reflect the value held in the MK48T18 and thus the
- * time may be read from this device both here and in the rtc driver.
- * Whenever we set the time, however, if it is to be preserved across
- * boots we must also update the "master" RTC.
- */
- if((_prep_type==_PREP_Radstone) && (ucSystemType==RS_SYS_TYPE_PPC1a))
- {
- PMK48T18 pMk48t18=(PMK48T18)(_ISA_MEM_BASE+0x00800000);
-
- /*
- * Set the write enable bit
- */
- pMk48t18->ucControl|=MK48T18_CTRL_WRITE;
- eieio();
- /*
- * Update the clock
- */
- pMk48t18->ucSecond=tm.tm_sec;
- pMk48t18->ucMinute=tm.tm_min;
- pMk48t18->ucHour=tm.tm_hour;
- pMk48t18->ucMonth=tm.tm_mon;
- pMk48t18->ucDay=tm.tm_wday+1;
- pMk48t18->ucDate=tm.tm_mday;
- pMk48t18->ucYear=tm.tm_year;
-
- eieio();
- /*
- * Clear the write enable bit
- */
- pMk48t18->ucControl&=~MK48T18_CTRL_WRITE;
- }
-
- if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) )
- time_state = TIME_OK;


X return 0;
X }
X

X __prep
-unsigned long prep_get_rtc_time(void)
+unsigned long mc146818_get_rtc_time(void)
X {
X unsigned int year, mon, day, hour, min, sec;
X int i;
@@ -232,29 +107,123 @@
X */
X /* read RTC exactly on falling edge of update flag */
X for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (prep_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP)
+ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
X break;
X for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(prep_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP))
+ if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
X break;
X do { /* Isn't this overkill ? UIP above should guarantee consistency */
- sec = prep_cmos_clock_read(RTC_SECONDS);
- min = prep_cmos_clock_read(RTC_MINUTES);
- hour = prep_cmos_clock_read(RTC_HOURS);
- day = prep_cmos_clock_read(RTC_DAY_OF_MONTH);
- mon = prep_cmos_clock_read(RTC_MONTH);
- year = prep_cmos_clock_read(RTC_YEAR);
- } while (sec != prep_cmos_clock_read(RTC_SECONDS));
- if (!(prep_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
- }
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+ } while (sec != CMOS_READ(RTC_SECONDS));
+ if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
+ || RTC_ALWAYS_BCD)
+ {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
X if ((year += 1900) < 1970)
X year += 100;
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+__prep
+int mk48t59_set_rtc_time(unsigned long nowtime)
+{
+ unsigned char save_control;
+ struct rtc_time tm;
+
+
+ to_tm(nowtime, &tm);
+
+ /* tell the clock it's being written */
+ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
+
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
+ (save_control | MK48T59_RTC_CA_WRITE));
+
+ tm.tm_year = (tm.tm_year - 1900) % 100;
+ BIN_TO_BCD(tm.tm_sec);
+ BIN_TO_BCD(tm.tm_min);
+ BIN_TO_BCD(tm.tm_hour);
+ BIN_TO_BCD(tm.tm_mon);
+ BIN_TO_BCD(tm.tm_mday);
+ BIN_TO_BCD(tm.tm_year);
+
+ ppc_md.nvram_write_val(MK48T59_RTC_SECONDS, tm.tm_sec);
+ ppc_md.nvram_write_val(MK48T59_RTC_MINUTES, tm.tm_min);
+ ppc_md.nvram_write_val(MK48T59_RTC_HOURS, tm.tm_hour);
+ ppc_md.nvram_write_val(MK48T59_RTC_MONTH, tm.tm_mon);
+ ppc_md.nvram_write_val(MK48T59_RTC_DAY_OF_MONTH, tm.tm_mday);
+ ppc_md.nvram_write_val(MK48T59_RTC_YEAR, tm.tm_year);
+
+ /* Turn off the write bit. */
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);


+
+ return 0;
+}
+

+__prep
+unsigned long mk48t59_get_rtc_time(void)
+{
+ unsigned char save_control;
+ unsigned int year, mon, day, hour, min, sec;
+ int i;
+
+ /* Make sure the time is not stopped. */
+ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
+
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
+ (save_control & (~MK48T59_RTC_CB_STOP)));
+
+ /* Now make sure the read bit is off so the value will change. */
+ save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
+ save_control &= ~MK48T59_RTC_CA_READ;
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
+
+ /* Read the seconds value to see when it changes. */
+ sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
+
+ /* Wait until the seconds value changes, then read the value. */
+ for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
+ if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {


+ break;
+ }
+ }
+

+ /* Set the register to read the value. */
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
+ (save_control | MK48T59_RTC_CA_READ));
+
+ sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
+ min = ppc_md.nvram_read_val(MK48T59_RTC_MINUTES);
+ hour = ppc_md.nvram_read_val(MK48T59_RTC_HOURS);
+ day = ppc_md.nvram_read_val(MK48T59_RTC_DAY_OF_MONTH);
+ mon = ppc_md.nvram_read_val(MK48T59_RTC_MONTH);
+ year = ppc_md.nvram_read_val(MK48T59_RTC_YEAR);
+
+ /* Let the time values change again. */
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
+
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+
+ year = year + 1900;
+ if (year < 1970) {
+ year += 100;
+ }
+
X return mktime(year, mon, day, hour, min, sec);
X }
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.2.7/linux/arch/ppc/kernel/process.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/process.c Tue May 11 08:24:32 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: process.c,v 1.75 1999/02/12 07:06:29 cort Exp $
+ * $Id: process.c,v 1.83 1999/05/10 04:43:43 cort Exp $
X *
X * linux/arch/ppc/kernel/process.c
X *
@@ -43,10 +43,7 @@
X #include <asm/prom.h>
X
X int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
-void switch_to(struct task_struct *, struct task_struct *);
-
X extern unsigned long _get_SP(void);
-extern spinlock_t scheduler_lock;
X
X struct task_struct *last_task_used_math = NULL;
X static struct vm_area_struct init_mmap = INIT_MMAP;
@@ -77,17 +74,25 @@
X int
X dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
X {
-#ifdef __SMP__
- if ( regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- if (last_task_used_math == current)
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
X memcpy(fpregs, &current->tss.fpr[0], sizeof(*fpregs));


X return 1;
X }
X

+void
+enable_kernel_fp(void)
+{
+#ifdef __SMP__
+ if (current->tss.regs && (current->tss.regs->msr & MSR_FP))
+ giveup_fpu(current);
+ else
+ giveup_fpu(NULL); /* just enables FP for kernel */
+#else
+ giveup_fpu(last_task_used_math);


+#endif /* __SMP__ */
+}
+

X /* check to make sure the kernel stack is healthy */
X int check_stack(struct task_struct *tsk)
X {
@@ -152,7 +157,8 @@
X }
X
X void
-switch_to(struct task_struct *prev, struct task_struct *new)
+_switch_to(struct task_struct *prev, struct task_struct *new,
+ struct task_struct **last)
X {
X struct thread_struct *new_tss, *old_tss;
X int s = _disable_interrupts();
@@ -162,10 +168,10 @@
X #endif
X
X #ifdef SHOW_TASK_SWITCHES
- printk("%s/%d -> %s/%d NIP %08lx cpu %d lock %x root %x/%x\n",
+ printk("%s/%d -> %s/%d NIP %08lx cpu %d root %x/%x\n",
X prev->comm,prev->pid,
X new->comm,new->pid,new->tss.regs->nip,new->processor,
- scheduler_lock.lock,new->fs->root,prev->fs->root);
+ new->fs->root,prev->fs->root);
X #endif
X #ifdef __SMP__
X /* avoid complexity of lazy save/restore of fpu
@@ -173,18 +179,19 @@
X * this task used the fpu during the last quantum.
X *
X * If it tries to use the fpu again, it'll trap and
- * reload its fp regs.
+ * reload its fp regs. So we don't have to do a restore
+ * every switch, just a save.
X * -- Cort
X */
- if ( prev->tss.regs->msr & MSR_FP )
- smp_giveup_fpu(prev);
+ if (prev->tss.regs && (prev->tss.regs->msr & MSR_FP))
+ giveup_fpu(prev);
X
X prev->last_processor = prev->processor;
X current_set[smp_processor_id()] = new;


X #endif /* __SMP__ */

X new_tss = &new->tss;
X old_tss = &current->tss;
- _switch(old_tss, new_tss, new->mm->context);
+ *last = _switch(old_tss, new_tss, new->mm->context);
X _enable_interrupts(s);
X }
X
@@ -237,7 +244,12 @@
X
X printk("Instruction DUMP:");
X for(i = -3; i < 6; i++)
- printk("%c%08lx%c",i?' ':'<',pc[i],i?' ':'>');
+ {
+ unsigned long p;
+ if (__get_user( p, &pc[i] ))
+ break;
+ printk("%c%08lx%c",i?' ':'<',p,i?' ':'>');
+ }
X printk("\n");
X }
X
@@ -265,8 +277,12 @@
X copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
X struct task_struct * p, struct pt_regs * regs)
X {
- struct pt_regs * childregs;
-
+ struct pt_regs * childregs, *kregs;
+#ifdef __SMP__
+ extern void ret_from_smpfork(void);
+#else
+ extern void ret_from_syscall(void);
+#endif
X /* Copy registers */
X childregs = ((struct pt_regs *)
X ((unsigned long)p + sizeof(union task_union)
@@ -275,8 +291,19 @@
X if ((childregs->msr & MSR_PR) == 0)
X childregs->gpr[2] = (unsigned long) p; /* `current' in new task */
X childregs->gpr[3] = 0; /* Result from fork() */
+ p->tss.regs = childregs;
X p->tss.ksp = (unsigned long) childregs - STACK_FRAME_OVERHEAD;
- p->tss.regs = childregs;
+ p->tss.ksp -= sizeof(struct pt_regs ) + STACK_FRAME_OVERHEAD;
+ kregs = (struct pt_regs *)(p->tss.ksp + STACK_FRAME_OVERHEAD);
+#ifdef __SMP__
+ kregs->nip = (unsigned long)ret_from_smpfork;
+#else
+ kregs->nip = (unsigned long)ret_from_syscall;
+#endif
+ kregs->msr = MSR_KERNEL;
+ kregs->gpr[1] = (unsigned long)childregs - STACK_FRAME_OVERHEAD;
+ kregs->gpr[2] = (unsigned long)p;
+
X if (usp >= (unsigned long) regs) {
X /* Stack is in kernel space - must adjust */
X childregs->gpr[1] = (unsigned long)(childregs + 1);
@@ -290,21 +317,14 @@
X * copy fpu info - assume lazy fpu switch now always
X * -- Cort
X */
-#ifdef __SMP__
- if ( regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- if ( last_task_used_math == current )
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
X
X memcpy(&p->tss.fpr, &current->tss.fpr, sizeof(p->tss.fpr));
X p->tss.fpscr = current->tss.fpscr;
X childregs->msr &= ~MSR_FP;
X
X #ifdef __SMP__
- if ( (p->pid != 0) || !(clone_flags & CLONE_PID) )
- p->tss.smp_fork_ret = 1;
X p->last_processor = NO_PROC_ID;


X #endif /* __SMP__ */

X return 0;
@@ -371,11 +391,6 @@
X int res;
X lock_kernel();
X res = do_fork(clone_flags, regs->gpr[1], regs);
- /*
- * only parent returns here, child returns to either
- * syscall_ret_1() or kernel_thread()


- * -- Cort
- */

X #ifdef __SMP__
X /* When we clone the idle task we keep the same pid but
X * the return value of 0 for both causes problems.
@@ -395,7 +410,6 @@
X int res;
X
X res = do_fork(SIGCHLD, regs->gpr[1], regs);
- /* only parent returns here */
X #ifdef __SMP__
X /* When we clone the idle task we keep the same pid but
X * the return value of 0 for both causes problems.
@@ -424,13 +438,8 @@
X error = PTR_ERR(filename);
X if (IS_ERR(filename))
X goto out;
-#ifdef __SMP__
- if ( regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- if ( last_task_used_math == current )
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
X error = do_execve(filename, (char **) a1, (char **) a2, regs);
X putname(filename);
X out:
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.2.7/linux/arch/ppc/kernel/prom.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/prom.c Tue May 11 08:24:32 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: prom.c,v 1.50 1999/03/16 10:40:34 cort Exp $
+ * $Id: prom.c,v 1.54 1999/05/10 04:43:46 cort Exp $
X *
X * Procedures for interfacing to the Open Firmware PROM on
X * Power Macintosh computers.
@@ -16,6 +16,7 @@
X #include <linux/string.h>
X #include <linux/init.h>
X #include <linux/version.h>
+#include <asm/spinlock.h>
X #include <asm/prom.h>
X #include <asm/page.h>
X #include <asm/processor.h>
@@ -263,9 +264,11 @@
X void
X prom_init(int r3, int r4, prom_entry pp)
X {
+#ifdef CONFIG_SMP
X int cpu = 0, i;
X phandle node;
X char type[16], *path;
+#endif
X unsigned long mem;
X ihandle prom_rtas;
X unsigned long offset = reloc_offset();
@@ -454,7 +457,7 @@
X * a holding pattern controlled by the kernel (not OF) before
X * we destroy the OF.
X *
- * This used a chunk of high memory, puts some holding pattern
+ * This uses a chunk of high memory, puts some holding pattern
X * code there and sends the other processors off to there until
X * smp_boot_cpus tells them to do something. We do that by using
X * physical address 0x0. The holding pattern checks that address
@@ -1141,7 +1144,7 @@
X if (cp == NULL)
X return 0;
X while (cplen > 0) {
- if (strcasecmp(cp, compat) == 0)
+ if (strncasecmp(cp, compat, strlen(compat)) == 0)
X return 1;
X l = strlen(cp) + 1;
X cp += l;
@@ -1277,6 +1280,8 @@
X }
X #endif
X
+spinlock_t rtas_lock = SPIN_LOCK_UNLOCKED;
+
X /* this can be called after setup -- Cort */
X __openfirmware
X int
@@ -1307,7 +1312,9 @@
X for (i = 0; i < nargs; ++i)
X u.words[i+3] = va_arg(list, unsigned long);
X va_end(list);
+ spin_lock(&rtas_lock);
X enter_rtas((void *)__pa(&u));
+ spin_unlock(&rtas_lock);
X if (nret > 1 && outputs != NULL)
X for (i = 0; i < nret-1; ++i)
X outputs[i] = u.words[i+nargs+4];
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- v2.2.7/linux/arch/ppc/kernel/ptrace.c Thu Dec 31 10:28:59 1998
+++ linux/arch/ppc/kernel/ptrace.c Thu Apr 29 12:39:01 1999
@@ -392,14 +392,8 @@
X tmp = get_reg(child, addr);
X }
X else if (addr >= PT_FPR0 && addr <= PT_FPSCR) {
-#ifdef __SMP__
- if (child->tss.regs->msr & MSR_FP )
- smp_giveup_fpu(child);
-#else
- /* only current can be last task to use math on SMP */
- if (last_task_used_math == child)
- giveup_fpu();
-#endif
+ if (child->tss.regs->msr & MSR_FP)
+ giveup_fpu(child);
X tmp = ((long *)child->tss.fpr)[addr - PT_FPR0];
X }
X else
@@ -433,13 +427,8 @@
X goto out;
X }
X if (addr >= PT_FPR0 && addr < PT_FPR0 + 64) {
-#ifndef __SMP__
- if (last_task_used_math == child)


SHAR_EOF
true || echo 'restore of patch-2.2.8 failed'
fi

echo 'End of part 11'
echo 'File patch-2.2.8 is continued in part 12'
echo 12 > _shar_seq_.tmp

Thomas...@ciw.uni-karlsruhe.de

unread,
May 12, 1999, 3:00:00 AM5/12/99
to
Archive-name: v2.2/patch-2.2.8/part12

#!/bin/sh
# this is part 12 of a 33 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.8 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 12; then


echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.8'
else
echo 'x - continuing with patch-2.2.8'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.8' &&

- giveup_fpu();
-#else

- if (child->tss.regs->msr & MSR_FP )
- smp_giveup_fpu(child);

-#endif
+ if (child->tss.regs->msr & MSR_FP)
+ giveup_fpu(child);

X ((long *)child->tss.fpr)[addr - PT_FPR0] = data;
X ret = 0;
X goto out;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.2.7/linux/arch/ppc/kernel/setup.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/setup.c Thu Apr 29 12:39:01 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: setup.c,v 1.130 1999/03/11 01:45:15 cort Exp $
+ * $Id: setup.c,v 1.132 1999/03/24 00:32:19 cort Exp $
X * Common prep/pmac/chrp boot and setup code.
X */
X
@@ -30,31 +30,62 @@
X #include <asm/8xx_immap.h>
X #endif
X #include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/ide.h>
X
-/* APUS defs */
-extern unsigned long m68k_machtype;
-extern int parse_bootinfo(const struct bi_record *);
-extern char _end[];
-#ifdef CONFIG_APUS
-extern struct mem_info ramdisk;


-unsigned long isa_io_base;
-unsigned long isa_mem_base;
-unsigned long pci_dram_offset;

-#endif
-/* END APUS defs */
+extern void pmac_init(unsigned long r3,
+ unsigned long r4,
+ unsigned long r5,
+ unsigned long r6,
+ unsigned long r7);
+
+extern void chrp_init(unsigned long r3,
+ unsigned long r4,
+ unsigned long r5,
+ unsigned long r6,
+ unsigned long r7);
+
+extern void prep_init(unsigned long r3,
+ unsigned long r4,
+ unsigned long r5,
+ unsigned long r6,
+ unsigned long r7);
+
+extern void mbx_init(unsigned long r3,
+ unsigned long r4,
+ unsigned long r5,
+ unsigned long r6,
+ unsigned long r7);
+
+extern void apus_init(unsigned long r3,
+ unsigned long r4,
+ unsigned long r5,
+ unsigned long r6,
+ unsigned long r7);
X
X extern boot_infos_t *boot_infos;
X extern char cmd_line[512];
X char saved_command_line[256];
X unsigned char aux_device_present;
X
-#if !defined(CONFIG_MACH_SPECIFIC)
+struct ide_machdep_calls ppc_ide_md;
+
X unsigned long ISA_DMA_THRESHOLD;
X unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
-int _machine;
-/* if we have openfirmware */
-unsigned long have_of;
-#endif /* ! CONFIG_MACH_SPECIFIC */
+
+/* Temporary hacks until machdep.h is fully done. */
+int _machine = 0;
+/* do we have OF? */
+int have_of = 0;
+int is_prep = 0;
+int is_chrp = 0;
+/* For MTX/MVME boards.. with Raven/Falcon Chipset
+ Real close to CHRP, but boot like PReP (via PPCbug)
+ There's probably a nicer way to do this.. --Troy */
+int is_powerplus = 0;
+
+struct machdep_calls ppc_md;
+
X
X /* copy of the residual data */
X #ifndef CONFIG_MBX
@@ -65,15 +96,6 @@
X
X RESIDUAL *res = (RESIDUAL *)&__res;
X
-int _prep_type;
-/*
- * This is used to identify the board type from a given PReP board
- * vendor. Board revision is also made available.
- */
-unsigned char ucSystemType;
-unsigned char ucBoardRev;
-unsigned char ucBoardRevMaj, ucBoardRevMin;
-
X /*
X * Perhaps we can put the pmac screen_info[] here
X * on pmac as well so we don't need the ifdef's.
@@ -122,164 +144,28 @@
X };
X #endif /* CONFIG_MBX */
X
-/* cmd is ignored for now... */
X void machine_restart(char *cmd)
X {
-#ifndef CONFIG_MBX
- unsigned long flags;
- struct adb_request req;
-
- switch(_machine)
- {
- case _MACH_Pmac:
- switch (adb_hardware) {
- case ADB_VIACUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_RESET_SYSTEM);
- for (;;)
- cuda_poll();
- break;
- case ADB_VIAPMU:
- pmu_restart();


- break;
- default:
- }

- break;
-
- case _MACH_chrp:
-#if 0 /* RTAS doesn't seem to work on Longtrail.
- For now, do it the same way as the PReP. */
- /*err = call_rtas("system-reboot", 0, 1, NULL);
- printk("RTAS system-reboot returned %d\n", err);
- for (;;);*/
-
- {
- extern unsigned int rtas_entry, rtas_data, rtas_size;
- unsigned long status, value;
- printk("rtas_ent`ry: %08x rtas_data: %08x rtas_size: %08x\n",
- rtas_entry,rtas_data,rtas_size);
- }
-#endif
- case _MACH_prep:
- _disable_interrupts();
- /* set exception prefix high - to the prom */
- save_flags( flags );
- restore_flags( flags|MSR_IP );
-
- /* make sure bit 0 (reset) is a 0 */
- outb( inb(0x92) & ~1L , 0x92 );
- /* signal a reset to system control port A - soft reset */
- outb( inb(0x92) | 1 , 0x92 );
-
- while ( 1 ) ;
- break;
- /*
- * Not reached
- */
- case _MACH_apus:
- cli();
-
- APUS_WRITE(APUS_REG_LOCK,
- REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK2);
- APUS_WRITE(APUS_REG_LOCK,
- REGLOCK_BLACKMAGICK1|REGLOCK_BLACKMAGICK3);
- APUS_WRITE(APUS_REG_LOCK,
- REGLOCK_BLACKMAGICK2|REGLOCK_BLACKMAGICK3);
- APUS_WRITE(APUS_REG_SHADOW, REGSHADOW_SELFRESET);
- APUS_WRITE(APUS_REG_RESET, REGRESET_AMIGARESET);
- for(;;);


- break;
- }
-#else /* CONFIG_MBX */

- extern void __clear_msr_me(void);
- __volatile__ unsigned char dummy;
-
- cli();
- ((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr |= 0x00000080;
- __clear_msr_me();
- dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
-
- printk("Restart failed\n");
- while(1);
-#endif /* CONFIG_MBX */
+ ppc_md.restart(cmd);
X }
-
+
X void machine_power_off(void)
X {
-#ifndef CONFIG_MBX
- struct adb_request req;
-#if 0
- int err;
-#endif
-
- switch (_machine) {
- case _MACH_Pmac:
- switch (adb_hardware) {
- case ADB_VIACUDA:
- cuda_request(&req, NULL, 2, CUDA_PACKET,
- CUDA_POWERDOWN);
- for (;;)
- cuda_poll();
- break;
- case ADB_VIAPMU:
- pmu_shutdown();


- break;
- default:
- }

- break;
-
- case _MACH_chrp:
-#if 0 /* RTAS doesn't seem to work on Longtrail.
- For now, do it the same way as the PReP. */
- err = call_rtas("power-off", 2, 1, NULL, 0, 0);
- printk("RTAS system-reboot returned %d\n", err);
- for (;;);
-#endif
-
- case _MACH_prep:
- machine_restart(NULL);
- case _MACH_apus:
- for (;;);
- }
- for (;;);
-#else /* CONFIG_MBX */
- machine_halt();
-#endif /* CONFIG_MBX */
+ ppc_md.power_off();
X }
-
+
X void machine_halt(void)
X {
- if ( _machine == _MACH_Pmac )
- {
- machine_power_off();
- }
- else /* prep, chrp or apus */
- machine_restart(NULL);
+ ppc_md.halt();
X }
-
+
X #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
X void ide_init_hwif_ports (ide_ioreg_t *p, ide_ioreg_t base, int *irq)
X {
-#if !defined(CONFIG_MBX) && !defined(CONFIG_APUS)
- switch (_machine) {
-#if defined(CONFIG_BLK_DEV_IDE_PMAC)
- case _MACH_Pmac:
- pmac_ide_init_hwif_ports(p,base,irq);
- break;
-#endif
- case _MACH_chrp:
- chrp_ide_init_hwif_ports(p,base,irq);


- break;
- case _MACH_prep:

- prep_ide_init_hwif_ports(p,base,irq);
- break;
+ if (ppc_ide_md.ide_init_hwif != NULL) {
+ ppc_ide_md.ide_init_hwif(p, base, irq);
X }
-#endif
-#if defined(CONFIG_MBX)
- mbx_ide_init_hwif_ports(p,base,irq);
-#endif
X }
-EXPORT_SYMBOL(ide_init_hwif_ports);
X #endif
X
X unsigned long cpu_temp(void)
@@ -313,10 +199,6 @@
X
X int get_cpuinfo(char *buffer)
X {
- extern int pmac_get_cpuinfo(char *);
- extern int chrp_get_cpuinfo(char *);
- extern int prep_get_cpuinfo(char *);
- extern int apus_get_cpuinfo(char *);
X unsigned long len = 0;
X unsigned long bogosum = 0;
X unsigned long i;
@@ -380,7 +262,6 @@
X break;
X }
X
-#ifndef CONFIG_MBX
X /*
X * Assume here that all clock rates are the same in a
X * smp system. -- Cort
@@ -397,33 +278,11 @@
X len += sprintf(len+buffer, "clock\t\t: %dMHz\n",
X *fp / 1000000);
X }
-
- /* PREP's without residual data for some reason will give
- incorrect values here */
- if ( is_prep )
- {
- len += sprintf(len+buffer, "clock\t\t: ");
- if ( res->ResidualLength )
- len += sprintf(len+buffer, "%ldMHz\n",
- (res->VitalProductData.ProcessorHz > 1024) ?
- res->VitalProductData.ProcessorHz>>20 :
- res->VitalProductData.ProcessorHz);
- else
- len += sprintf(len+buffer, "???\n");


- }
-#else /* CONFIG_MBX */

+
+ if (ppc_md.setup_residual != NULL)
X {
- bd_t *bp;
- extern RESIDUAL *res;
-
- bp = (bd_t *)res;
-
- len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
- "bus clock\t: %dMHz\n",
- bp->bi_intfreq /*/ 1000000*/,
- bp->bi_busfreq /*/ 1000000*/);
+ len += ppc_md.setup_residual(buffer + len);
X }
-#endif /* CONFIG_MBX */
X
X len += sprintf(len+buffer, "revision\t: %ld.%ld\n",
X (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff);
@@ -438,8 +297,8 @@
X if ( i )
X len += sprintf(buffer+len, "\n");
X len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
- (bogosum+2500)/500000,
- (bogosum+2500)/5000 % 100);
+ (bogosum+2500)/500000,
+ (bogosum+2500)/5000 % 100);


X #endif /* __SMP__ */
X

X /*
@@ -455,27 +314,14 @@
X zero_cache_hits,zero_cache_calls,
X /* : 1 below is so we don't div by zero */
X (zero_cache_hits*100) /
- ((zero_cache_calls)?zero_cache_calls:1));
+ ((zero_cache_calls)?zero_cache_calls:1));
X }
X
-#ifndef CONFIG_MBX
- switch (_machine)
+ if (ppc_md.get_cpuinfo != NULL)
X {
- case _MACH_Pmac:
- len += pmac_get_cpuinfo(buffer+len);


- break;
- case _MACH_prep:

- len += prep_get_cpuinfo(buffer+len);


- break;
- case _MACH_chrp:

- len += chrp_get_cpuinfo(buffer+len);
- break;
- case _MACH_apus:
- /* Not much point in printing m68k info when it is not
- used. */
- break;
+ len += ppc_md.get_cpuinfo(buffer+len);
X }
-#endif /* ndef CONFIG_MBX */
+


X return len;
X }
X

@@ -487,25 +333,22 @@
X identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
X unsigned long r6, unsigned long r7)
X {
- extern void setup_pci_ptrs(void);
X
X #ifdef __SMP__
X if ( first_cpu_booted ) return 0;


X #endif /* __SMP__ */
X

-#ifndef CONFIG_MBX
X #ifndef CONFIG_MACH_SPECIFIC
X /* boot loader will tell us if we're APUS */
X if ( r3 == 0x61707573 )
X {
X _machine = _MACH_apus;
- have_of = 0;
X r3 = 0;
X }
X /* prep boot loader tells us if we're prep or not */
X else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) {
X _machine = _MACH_prep;
- have_of = 0;
+ is_prep = 1;
X } else {
X char *model;
X
@@ -516,19 +359,49 @@
X /* ask the OF info if we're a chrp or pmac */
X model = get_property(find_path_device("/"), "device_type", NULL);
X if ( model && !strncmp("chrp",model,4) )
+ {
X _machine = _MACH_chrp;
+ is_chrp = 1;
+ }
X else
X {
X model = get_property(find_path_device("/"),
X "model", NULL);
X if ( model && !strncmp(model, "IBM", 3))
+ {
X _machine = _MACH_chrp;
+ is_chrp = 1;
+ }
X else
+ {
X _machine = _MACH_Pmac;
+ is_prep = 1;
+ }
X }
X
X }
-#endif /* CONFIG_MACH_SPECIFIC */
+#else /* CONFIG_MACH_SPECIFIC */
+
+#ifdef CONFIG_PREP
+ _machine = _MACH_prep;
+ is_prep = 1;
+#elif defined(CONFIG_CHRP)
+ _machine = _MACH_chrp;
+ is_chrp = 1;
+ have_of = 1;
+#elif defined(CONFIG_PMAC)
+ _machine = _MACH_Pmac;
+ have_of = 1;
+#elif defined(CONFIG_MBX)
+ _machine = _MACH_mbx;
+#elif defined(CONFIG_FADS)
+ _machine = _MACH_fads;
+#elif defined(CONFIG_APUS)
+ _machine = _MACH_apus;
+#else
+#error "Machine not defined correctly"
+#endif /* CONFIG_APUS */
+#endif /* CONFIG_MACH_SPECIFIC */
X
X if ( have_of )
X {
@@ -587,138 +460,31 @@
X cmd_line[sizeof(cmd_line) - 1] = 0;
X }
X
-
X switch (_machine)
X {
X case _MACH_Pmac:
- setup_pci_ptrs();
- /* isa_io_base gets set in pmac_find_bridges */
- isa_mem_base = PMAC_ISA_MEM_BASE;
- pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
-#if !defined(CONFIG_MACH_SPECIFIC)
- ISA_DMA_THRESHOLD = ~0L;
- DMA_MODE_READ = 1;
- DMA_MODE_WRITE = 2;
-#endif /* ! CONFIG_MACH_SPECIFIC */
+ pmac_init(r3, r4, r5, r6, r7);
X break;
X case _MACH_prep:
- /* make a copy of residual data */
- if ( r3 )
- memcpy((void *)res,(void *)(r3+KERNELBASE),
- sizeof(RESIDUAL));
- isa_io_base = PREP_ISA_IO_BASE;
- isa_mem_base = PREP_ISA_MEM_BASE;
- pci_dram_offset = PREP_PCI_DRAM_OFFSET;
-#if !defined(CONFIG_MACH_SPECIFIC)
- ISA_DMA_THRESHOLD = 0x00ffffff;
- DMA_MODE_READ = 0x44;
- DMA_MODE_WRITE = 0x48;
-#endif /* ! CONFIG_MACH_SPECIFIC */
- /* figure out what kind of prep workstation we are */
- if ( res->ResidualLength != 0 )
- {
- if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
- _prep_type = _PREP_IBM;
- else if (!strncmp(res->VitalProductData.PrintableModel,
- "Radstone",8))
- {
- extern char *Motherboard_map_name;
-
- _prep_type = _PREP_Radstone;
- Motherboard_map_name=
- res->VitalProductData.PrintableModel;
- }
- else
- _prep_type = _PREP_Motorola;
- }
- else /* assume motorola if no residual (netboot?) */
- _prep_type = _PREP_Motorola;
- setup_pci_ptrs();
-#ifdef CONFIG_BLK_DEV_INITRD
- /* take care of initrd if we have one */
- if ( r4 )
- {
- initrd_start = r4 + KERNELBASE;
- initrd_end = r5 + KERNELBASE;
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
- /* take care of cmd line */
- if ( r6 )
- {
- *(char *)(r7+KERNELBASE) = 0;
- strcpy(cmd_line, (char *)(r6+KERNELBASE));
- }
+ prep_init(r3, r4, r5, r6, r7);
X break;
X case _MACH_chrp:
- setup_pci_ptrs();
-#ifdef CONFIG_BLK_DEV_INITRD
- /* take care of initrd if we have one */
- if ( r3 )
- {
- initrd_start = r3 + KERNELBASE;
- initrd_end = r3 + r4 + KERNELBASE;
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
- /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
-#if !defined(CONFIG_MACH_SPECIFIC)
- ISA_DMA_THRESHOLD = ~0L;
- DMA_MODE_READ = 0x44;
- DMA_MODE_WRITE = 0x48;
-#endif /* ! CONFIG_MACH_SPECIFIC */
+ chrp_init(r3, r4, r5, r6, r7);
X break;
-#ifdef CONFIG_APUS
+#ifdef CONFIG_APUS
X case _MACH_apus:
- /* Parse bootinfo. The bootinfo is located right after
- the kernel bss */
- parse_bootinfo((const struct bi_record *)&_end);
-#ifdef CONFIG_BLK_DEV_INITRD
- /* Take care of initrd if we have one. Use data from
- bootinfo to avoid the need to initialize PPC
- registers when kernel is booted via a PPC reset. */
- if ( ramdisk.addr ) {
- initrd_start = (unsigned long) __va(ramdisk.addr);
- initrd_end = (unsigned long)
- __va(ramdisk.size + ramdisk.addr);
- }
- /* Make sure code below is not executed. */
- r4 = 0;
- r6 = 0;
-#endif /* CONFIG_BLK_DEV_INITRD */
-#if !defined(CONFIG_MACH_SPECIFIC)
- ISA_DMA_THRESHOLD = 0x00ffffff;
-#endif /* ! CONFIG_MACH_SPECIFIC */
+ apus_init(r3, r4, r5, r6, r7);
X break;
X #endif
+#ifdef CONFIG_MBX
+ case _MACH_mbx:
+ mbx_init(r3, r4, r5, r6, r7);


+ break;
+#endif
X default:

X printk("Unknown machine type in identify_machine!\n");
X }
X

-#else /* CONFIG_MBX */
-

- if ( r3 )
- memcpy( (void *)res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
-
-#ifdef CONFIG_PCI
- setup_pci_ptrs();
-#endif
-
-#ifdef CONFIG_BLK_DEV_INITRD
- /* take care of initrd if we have one */
- if ( r4 )
- {
- initrd_start = r4 + KERNELBASE;
- initrd_end = r5 + KERNELBASE;
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
- /* take care of cmd line */
- if ( r6 )
- {
-
- *(char *)(r7+KERNELBASE) = 0;
- strcpy(cmd_line, (char *)(r6+KERNELBASE));


- }
-#endif /* CONFIG_MBX */

-
X /* Check for nobats option (used in mapin_ram). */
X if (strstr(cmd_line, "nobats")) {
X extern int __map_without_bats;
@@ -740,14 +506,17 @@
X }
X }
X
+__initfunc(void
+ ppc_init(void))
+{
+ if (ppc_md.init != NULL) {
+ ppc_md.init();
+ }
+}
+
X __initfunc(void setup_arch(char **cmdline_p,
- unsigned long * memory_start_p, unsigned long * memory_end_p))
+ unsigned long * memory_start_p, unsigned long * memory_end_p))
X {
- extern void pmac_setup_arch(unsigned long *, unsigned long *);
- extern void chrp_setup_arch(unsigned long *, unsigned long *);
- extern void prep_setup_arch(unsigned long *, unsigned long *);
- extern void mbx_setup_arch(unsigned long *, unsigned long *);
- extern void apus_setup_arch(unsigned long *, unsigned long *);
X extern int panic_timeout;
X extern char _etext[], _edata[];
X extern char *klimit;
@@ -776,27 +545,113 @@
X *memory_start_p = find_available_memory();
X *memory_end_p = (unsigned long) end_of_DRAM;
X
-#ifdef CONFIG_MBX
- mbx_setup_arch(memory_start_p,memory_end_p);
-#else /* CONFIG_MBX */
- switch (_machine) {
- case _MACH_Pmac:
- pmac_setup_arch(memory_start_p, memory_end_p);


- break;
- case _MACH_prep:

- prep_setup_arch(memory_start_p, memory_end_p);


- break;
- case _MACH_chrp:

- chrp_setup_arch(memory_start_p, memory_end_p);


- break;
-#ifdef CONFIG_APUS
- case _MACH_apus:

- m68k_machtype = MACH_AMIGA;
- apus_setup_arch(memory_start_p,memory_end_p);
- break;
-#endif
- default:
- printk("Unknown machine %d in setup_arch()\n", _machine);


- }
-#endif /* CONFIG_MBX */

+ ppc_md.setup_arch(memory_start_p, memory_end_p);
+}
+
+void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
+{
+ int i;
+ unsigned short *stringcast;
+
+
+ id->config = __le16_to_cpu(id->config);
+ id->cyls = __le16_to_cpu(id->cyls);
+ id->reserved2 = __le16_to_cpu(id->reserved2);
+ id->heads = __le16_to_cpu(id->heads);
+ id->track_bytes = __le16_to_cpu(id->track_bytes);
+ id->sector_bytes = __le16_to_cpu(id->sector_bytes);
+ id->sectors = __le16_to_cpu(id->sectors);
+ id->vendor0 = __le16_to_cpu(id->vendor0);
+ id->vendor1 = __le16_to_cpu(id->vendor1);
+ id->vendor2 = __le16_to_cpu(id->vendor2);
+ stringcast = (unsigned short *)&id->serial_no[0];
+ for (i=0; i<(20/2); i++)
+ stringcast[i] = __le16_to_cpu(stringcast[i]);
+ id->buf_type = __le16_to_cpu(id->buf_type);
+ id->buf_size = __le16_to_cpu(id->buf_size);
+ id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
+ stringcast = (unsigned short *)&id->fw_rev[0];
+ for (i=0; i<(8/2); i++)
+ stringcast[i] = __le16_to_cpu(stringcast[i]);
+ stringcast = (unsigned short *)&id->model[0];
+ for (i=0; i<(40/2); i++)
+ stringcast[i] = __le16_to_cpu(stringcast[i]);
+ id->dword_io = __le16_to_cpu(id->dword_io);
+ id->reserved50 = __le16_to_cpu(id->reserved50);
+ id->field_valid = __le16_to_cpu(id->field_valid);
+ id->cur_cyls = __le16_to_cpu(id->cur_cyls);
+ id->cur_heads = __le16_to_cpu(id->cur_heads);
+ id->cur_sectors = __le16_to_cpu(id->cur_sectors);
+ id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
+ id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
+ id->lba_capacity = __le32_to_cpu(id->lba_capacity);
+ id->dma_1word = __le16_to_cpu(id->dma_1word);
+ id->dma_mword = __le16_to_cpu(id->dma_mword);
+ id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
+ id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
+ id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
+ id->eide_pio = __le16_to_cpu(id->eide_pio);
+ id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
+ id->word69 = __le16_to_cpu(id->word69);
+ id->word70 = __le16_to_cpu(id->word70);
+ id->word71 = __le16_to_cpu(id->word71);
+ id->word72 = __le16_to_cpu(id->word72);
+ id->word73 = __le16_to_cpu(id->word73);
+ id->word74 = __le16_to_cpu(id->word74);
+ id->word75 = __le16_to_cpu(id->word75);
+ id->word76 = __le16_to_cpu(id->word76);
+ id->word77 = __le16_to_cpu(id->word77);
+ id->word78 = __le16_to_cpu(id->word78);
+ id->word79 = __le16_to_cpu(id->word79);
+ id->word80 = __le16_to_cpu(id->word80);
+ id->word81 = __le16_to_cpu(id->word81);
+ id->command_sets = __le16_to_cpu(id->command_sets);
+ id->word83 = __le16_to_cpu(id->word83);
+ id->word84 = __le16_to_cpu(id->word84);
+ id->word85 = __le16_to_cpu(id->word85);
+ id->word86 = __le16_to_cpu(id->word86);
+ id->word87 = __le16_to_cpu(id->word87);
+ id->dma_ultra = __le16_to_cpu(id->dma_ultra);
+ id->word89 = __le16_to_cpu(id->word89);
+ id->word90 = __le16_to_cpu(id->word90);
+ id->word91 = __le16_to_cpu(id->word91);
+ id->word92 = __le16_to_cpu(id->word92);
+ id->word93 = __le16_to_cpu(id->word93);
+ id->word94 = __le16_to_cpu(id->word94);
+ id->word95 = __le16_to_cpu(id->word95);
+ id->word96 = __le16_to_cpu(id->word96);
+ id->word97 = __le16_to_cpu(id->word97);
+ id->word98 = __le16_to_cpu(id->word98);
+ id->word99 = __le16_to_cpu(id->word99);
+ id->word100 = __le16_to_cpu(id->word100);
+ id->word101 = __le16_to_cpu(id->word101);
+ id->word102 = __le16_to_cpu(id->word102);
+ id->word103 = __le16_to_cpu(id->word103);
+ id->word104 = __le16_to_cpu(id->word104);
+ id->word105 = __le16_to_cpu(id->word105);
+ id->word106 = __le16_to_cpu(id->word106);
+ id->word107 = __le16_to_cpu(id->word107);
+ id->word108 = __le16_to_cpu(id->word108);
+ id->word109 = __le16_to_cpu(id->word109);
+ id->word110 = __le16_to_cpu(id->word110);
+ id->word111 = __le16_to_cpu(id->word111);
+ id->word112 = __le16_to_cpu(id->word112);
+ id->word113 = __le16_to_cpu(id->word113);
+ id->word114 = __le16_to_cpu(id->word114);
+ id->word115 = __le16_to_cpu(id->word115);
+ id->word116 = __le16_to_cpu(id->word116);
+ id->word117 = __le16_to_cpu(id->word117);
+ id->word118 = __le16_to_cpu(id->word118);
+ id->word119 = __le16_to_cpu(id->word119);
+ id->word120 = __le16_to_cpu(id->word120);
+ id->word121 = __le16_to_cpu(id->word121);
+ id->word122 = __le16_to_cpu(id->word122);
+ id->word123 = __le16_to_cpu(id->word123);
+ id->word124 = __le16_to_cpu(id->word124);
+ id->word125 = __le16_to_cpu(id->word125);
+ id->word126 = __le16_to_cpu(id->word126);
+ id->word127 = __le16_to_cpu(id->word127);
+ id->security = __le16_to_cpu(id->security);
+ for (i=0; i<127; i++)
+ id->reserved[i] = __le16_to_cpu(id->reserved[i]);
X }
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- v2.2.7/linux/arch/ppc/kernel/signal.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/signal.c Thu Apr 29 12:39:01 1999


@@ -1,7 +1,7 @@
X /*

X * linux/arch/ppc/kernel/signal.c
X *
- * $Id: signal.c,v 1.23 1999/03/01 16:51:53 cort Exp $
+ * $Id: signal.c,v 1.24 1999/04/03 11:25:16 paulus Exp $
X *


X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)

@@ -218,13 +218,8 @@
X if (sc == (struct sigcontext_struct *)(sigctx.regs)) {
X /* Last stacked signal - restore registers */
X sr = (struct sigregs *) sigctx.regs;


-#ifdef __SMP__
- if ( regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- if (last_task_used_math == current)
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP )
+ giveup_fpu(current);

X if (copy_from_user(saved_regs, &sr->gp_regs,
X sizeof(sr->gp_regs)))
X goto badframe;
@@ -271,13 +266,8 @@
X
X if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
X goto badframe;


-#ifdef __SMP__
- if ( regs->msr & MSR_FP )
- smp_giveup_fpu(current);
-#else
- if (last_task_used_math == current)
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);

X if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
X || __copy_to_user(&frame->fp_regs, current->tss.fpr,
X ELF_NFPREG * sizeof(double))
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.2.7/linux/arch/ppc/kernel/smp.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/smp.c Thu Apr 29 12:39:01 1999
@@ -1,10 +1,13 @@
X /*
- * $Id: smp.c,v 1.48 1999/03/16 10:40:32 cort Exp $
+ * $Id: smp.c,v 1.49 1999/03/18 04:16:31 cort Exp $
X *
X * Smp support for ppc.
X *
X * Written by Cort Dougan (co...@cs.nmt.edu) borrowing a great
X * deal of code from the sparc and intel versions.
+ *
+ * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes
+ * (tr...@microux.com, ho...@drgw.net)
X */
X
X #include <linux/kernel.h>
@@ -253,6 +256,7 @@
X * cpu 0, the master -- Cort
X */
X cpu_callin_map[0] = 1;
+ cpu_callin_map[1] = 0;
X smp_store_cpu_info(0);
X active_kernel_processor = 0;
X current->processor = 0;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- v2.2.7/linux/arch/ppc/kernel/syscalls.c Mon Oct 5 13:13:36 1998
+++ linux/arch/ppc/kernel/syscalls.c Sat May 8 11:14:01 1999
@@ -205,12 +205,15 @@


X
X lock_kernel();
X if (!(flags & MAP_ANONYMOUS)) {

- if (fd >= NR_OPEN || !(file = current->files->fd[fd]))

+ file = fget(fd);
+ if (!file)

X goto out;
X }
X

X flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);

X ret = do_mmap(file, addr, len, prot, flags, offset);
+ if (file)


+ fput(file);
X out:
X unlock_kernel();

X return ret;
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.2.7/linux/arch/ppc/kernel/time.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/kernel/time.c Thu Apr 29 12:39:01 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: time.c,v 1.45 1999/03/03 15:09:59 cort Exp $
+ * $Id: time.c,v 1.47 1999/03/18 05:11:11 cort Exp $
X * Common time routines among all ppc machines.
X *
X * Written by Cort Dougan (co...@cs.nmt.edu) to merge
@@ -41,18 +41,14 @@
X #include <asm/processor.h>
X #include <asm/nvram.h>
X #include <asm/cache.h>
-#ifdef CONFIG_MBX
-#include <asm/mbx.h>
-#endif
+/* Fixme - Why is this here? - Corey */
X #ifdef CONFIG_8xx
X #include <asm/8xx_immap.h>
X #endif
+#include <asm/machdep.h>


X
X #include "time.h"
X

-/* this is set to the appropriate pmac/prep/chrp func in init_IRQ() */
-int (*set_rtc_time)(unsigned long);
-
X void smp_local_timer_interrupt(struct pt_regs *);
X
X /* keep track of when we need to update the rtc */
@@ -116,16 +112,21 @@
X */
X if ( xtime.tv_sec > last_rtc_update + 660 )
X {
- if (set_rtc_time(xtime.tv_sec) == 0)
+ if (ppc_md.set_rtc_time(xtime.tv_sec) == 0) {
X last_rtc_update = xtime.tv_sec;
- else
- last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+ }
+ else {
+ /* do it again in 60 s */
+ last_rtc_update = xtime.tv_sec - 60;
+ }
X }


X }
X }
X #ifdef __SMP__

X smp_local_timer_interrupt(regs);
X #endif
+
+ /* Fixme - make this more generic - Corey */
X #ifdef CONFIG_APUS
X {
X extern void apus_heartbeat (void);
@@ -135,28 +136,6 @@
X hardirq_exit(cpu);
X }
X
-#ifdef CONFIG_MBX
-/* A place holder for time base interrupts, if they are ever enabled.
-*/
-void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
-{
- printk("timebase_interrupt()\n");
-}
-
-/* The RTC on the MPC8xx is an internal register.
- * We want to protect this during power down, so we need to unlock,
- * modify, and re-lock.
- */
-static int
-mbx_set_rtc_time(unsigned long time)
-{
- ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
- ((immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
- ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
- return(0);


-}
-#endif /* CONFIG_MBX */

-
X /*
X * This version of gettimeofday has microsecond resolution.
X */
@@ -203,199 +182,29 @@
X
X __initfunc(void time_init(void))
X {
-#ifndef CONFIG_MBX
+ if (ppc_md.time_init != NULL)
+ {
+ ppc_md.time_init();
+ }
+
X if ((_get_PVR() >> 16) == 1) {
X /* 601 processor: dec counts down by 128 every 128ns */
X decrementer_count = DECREMENTER_COUNT_601;
X count_period_num = COUNT_PERIOD_NUM_601;
X count_period_den = COUNT_PERIOD_DEN_601;
+ } else if (!smp_processor_id()) {
+ ppc_md.calibrate_decr();
X }
X
- switch (_machine) {
- case _MACH_Pmac:
- xtime.tv_sec = pmac_get_rtc_time();
- if ( (_get_PVR() >> 16) != 1 && (!smp_processor_id()) )
- pmac_calibrate_decr();
- if ( !smp_processor_id() )
- set_rtc_time = pmac_set_rtc_time;


- break;
- case _MACH_chrp:

- chrp_time_init();
- xtime.tv_sec = chrp_get_rtc_time();
- if ((_get_PVR() >> 16) != 1)
- chrp_calibrate_decr();
- set_rtc_time = chrp_set_rtc_time;


- break;
- case _MACH_prep:

- xtime.tv_sec = prep_get_rtc_time();
- prep_calibrate_decr();
- set_rtc_time = prep_set_rtc_time;


- break;
-#ifdef CONFIG_APUS
- case _MACH_apus:
- {

- xtime.tv_sec = apus_get_rtc_time();
- apus_calibrate_decr();
- set_rtc_time = apus_set_rtc_time;
- break;
- }
-#endif
- }
- xtime.tv_usec = 0;
-#else /* CONFIG_MBX */
- mbx_calibrate_decr();
- set_rtc_time = mbx_set_rtc_time;
-
- /* First, unlock all of the registers we are going to modify.
- * To protect them from corruption during power down, registers
- * that are maintained by keep alive power are "locked". To
- * modify these registers we have to write the key value to
- * the key location associated with the register.
- */
- ((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
- ((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
-
-
- /* Disable the RTC one second and alarm interrupts.
- */
- ((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
- ~(RTCSC_SIE | RTCSC_ALE);
-
- /* Enabling the decrementer also enables the timebase interrupts
- * (or from the other point of view, to get decrementer interrupts
- * we have to enable the timebase). The decrementer interrupt
- * is wired into the vector table, nothing to do here for that.
- */
- ((immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
- ((mk_int_int_mask(DEC_INTERRUPT) << 8) |
- (TBSCR_TBF | TBSCR_TBE));
- if (request_irq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
- panic("Could not allocate timer IRQ!");
-
- /* Get time from the RTC.
- */
- xtime.tv_sec = ((immap_t *)IMAP_ADDR)->im_sit.sit_rtc;
- xtime.tv_usec = 0;
+ xtime.tv_sec = ppc_md.get_rtc_time();
+ xtime.tv_usec = 0;
X
-#endif /* CONFIG_MBX */
X set_dec(decrementer_count);
X /* mark the rtc/on-chip timer as in sync
X * so we don't update right away
X */
X last_rtc_update = xtime.tv_sec;
X }
-
-#ifndef CONFIG_MBX
-/*
- * Uses the on-board timer to calibrate the on-chip decrementer register
- * for prep systems. On the pmac the OF tells us what the frequency is
- * but on prep we have to figure it out.


- * -- Cort
- */

-int calibrate_done = 0;
-volatile int *done_ptr = &calibrate_done;
-__initfunc(void prep_calibrate_decr(void))
-{
- unsigned long flags;
- unsigned long freq, divisor;
-
- /* the Powerstack II's have trouble with the timer so
- * we use a default value -- Cort
- */
- if ( (_prep_type == _PREP_Motorola) &&
- ((inb(0x800) & 0xF0) & 0x40) )
- {
- static unsigned long t2 = 0;
-
- t2 = 998700000/60;
- freq = t2 * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
- freq, divisor,t2>>20);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
- return;
- }
- if ( _prep_type == _PREP_Radstone )
- {
- freq = res->VitalProductData.ProcessorBusHz;
- divisor = 4;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
- return;
- }
-
- save_flags(flags);
-
-#define TIMER0_COUNT 0x40
-#define TIMER_CONTROL 0x43
- /* set timer to periodic mode */
- outb_p(0x34,TIMER_CONTROL);/* binary, mode 2, LSB/MSB, ch 0 */
- /* set the clock to ~100 Hz */
- outb_p(LATCH & 0xff , TIMER0_COUNT); /* LSB */
- outb(LATCH >> 8 , TIMER0_COUNT); /* MSB */
-
- if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)
- panic("Could not allocate timer IRQ!");
- __sti();
- while ( ! *done_ptr ) /* nothing */; /* wait for calibrate */
- restore_flags(flags);
- free_irq( 0, NULL);
-}
-
-__initfunc(void prep_calibrate_decr_handler(int irq, void *dev, struct pt_regs * regs))
-{
- unsigned long freq, divisor;
- static unsigned long t1 = 0, t2 = 0;
-
- if ( !t1 )
- t1 = get_dec();
- else if (!t2)
- {
- t2 = get_dec();
- t2 = t1-t2; /* decr's in 1/HZ */
- t2 = t2*HZ; /* # decrs in 1s - thus in Hz */
- freq = t2 * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
- freq, divisor,t2>>20);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
- *done_ptr = 1;
- }
-}


-
-#else /* CONFIG_MBX */
-

-/* The decrementer counts at the system (internal) clock frequency divided by
- * sixteen, or external oscillator divided by four. Currently, we only
- * support the MBX, which is system clock divided by sixteen.
- */
-__initfunc(void mbx_calibrate_decr(void))
-{
- bd_t *binfo = (bd_t *)res;
- int freq, fp, divisor;
-
- if ((((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr & 0x02000000) == 0)
- printk("WARNING: Wrong decrementer source clock.\n");
-
- /* The manual says the frequency is in Hz, but it is really
- * as MHz. The value 'fp' is the number of decrementer ticks
- * per second.
- */
- fp = (binfo->bi_intfreq * 1000000) / 16;
- freq = fp*60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;


-}
-#endif /* CONFIG_MBX */

X
X /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
X * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/time.h linux/arch/ppc/kernel/time.h
--- v2.2.7/linux/arch/ppc/kernel/time.h Thu Apr 23 20:21:29 1998
+++ linux/arch/ppc/kernel/time.h Thu Apr 29 12:39:01 1999


@@ -1,5 +1,5 @@
X /*

- * $Id: time.h,v 1.10 1998/04/01 07:46:03 geert Exp $
+ * $Id: time.h,v 1.11 1999/03/18 04:16:34 cort Exp $
X * Common time prototypes and such for all ppc machines.
X *
X * Written by Cort Dougan (co...@cs.nmt.edu) to merge
@@ -9,32 +9,15 @@
X #include <linux/mc146818rtc.h>
X
X /* time.c */
-void prep_calibrate_decr_handler(int, void *,struct pt_regs *);
-void prep_calibrate_decr(void);
-void pmac_calibrate_decr(void);
-extern void apus_calibrate_decr(void);
X extern unsigned decrementer_count;
X extern unsigned count_period_num;
X extern unsigned count_period_den;
-extern unsigned long mktime(unsigned int, unsigned int,unsigned int,
+extern unsigned long mktime(unsigned int, unsigned int, unsigned int,
X unsigned int, unsigned int, unsigned int);
X extern void to_tm(int tim, struct rtc_time * tm);
X extern unsigned long last_rtc_update;
X
-/* pmac/prep/chrp_time.c */
-unsigned long prep_get_rtc_time(void);
-unsigned long pmac_get_rtc_time(void);
-unsigned long chrp_get_rtc_time(void);
-unsigned long apus_get_rtc_time(void);
-int prep_set_rtc_time(unsigned long nowtime);
-int pmac_set_rtc_time(unsigned long nowtime);
-int chrp_set_rtc_time(unsigned long nowtime);
-int apus_set_rtc_time(unsigned long nowtime);
-void pmac_read_rtc_time(void);
-void chrp_calibrate_decr(void);
-void chrp_time_init(void);
X int via_calibrate_decr(void);
-void mbx_calibrate_decr(void);
X
X /* Accessor functions for the decrementer register. */
X static __inline__ unsigned int get_dec(void)
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.2.7/linux/arch/ppc/kernel/traps.c Thu Jan 7 15:11:36 1999
+++ linux/arch/ppc/kernel/traps.c Thu Apr 29 12:39:01 1999
@@ -191,13 +191,8 @@
X {
X int fixed;
X
-#ifdef __SMP__
- if (regs->msr & MSR_FP )


- smp_giveup_fpu(current);
-#else
- if (last_task_used_math == current)
- giveup_fpu();
-#endif
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);

X fixed = fix_alignment(regs);
X if (fixed == 1) {
X regs->nip += 4; /* skip over emulated instruction */
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/lib/strcase.c linux/arch/ppc/lib/strcase.c
--- v2.2.7/linux/arch/ppc/lib/strcase.c Sat Aug 16 09:51:08 1997
+++ linux/arch/ppc/lib/strcase.c Thu Apr 29 12:39:01 1999
@@ -10,3 +10,14 @@
X } while (c1 == c2 && c1 != 0);
X return c1 - c2;
X }
+
+int strncasecmp(const char *s1, const char *s2, int n)
+{
+ int c1, c2;
+
+ do {
+ c1 = tolower(*s1++);
+ c2 = tolower(*s2++);
+ } while ((--n > 0) && c1 == c2 && c1 != 0);
+ return c1 - c2;
+}
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/mbxboot/head.S linux/arch/ppc/mbxboot/head.S
--- v2.2.7/linux/arch/ppc/mbxboot/head.S Fri Apr 16 14:47:30 1999
+++ linux/arch/ppc/mbxboot/head.S Thu Apr 29 12:39:01 1999


@@ -6,7 +6,7 @@
X .text
X

X /*
- * $Id: head.S,v 1.2 1999/02/17 06:29:41 cort Exp $
+ * $Id: head.S,v 1.4 1999/04/22 06:32:09 davem Exp $
X *
X * This code is loaded by the ROM loader at some arbitrary location.
X * Move it to high memory so that it can load the kernel at 0x0000.
@@ -67,7 +67,7 @@
X mr r11, r21
X lis r8,start@h
X ori r8,r8,start@l
- li r9,end@h
+ lis r9,end@h
X ori r9,r9,end@l
X sub r7,r8,r9
X srwi r7,r7,2
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.2.7/linux/arch/ppc/mm/fault.c Thu Jan 7 15:11:36 1999
+++ linux/arch/ppc/mm/fault.c Tue May 11 08:24:32 1999
@@ -140,7 +140,8 @@
X if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
X goto bad_area;
X }
- handle_mm_fault(current, vma, address, error_code & 0x02000000);
+ if (!handle_mm_fault(current, vma, address, error_code & 0x02000000))
+ goto bad_area;
X up(&mm->mmap_sem);
X /*
X * keep track of tlb+htab misses that are good addrs but
diff -u --recursive --new-file v2.2.7/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.2.7/linux/arch/ppc/mm/init.c Tue Mar 23 14:35:46 1999
+++ linux/arch/ppc/mm/init.c Tue May 11 08:24:32 1999
@@ -1,5 +1,5 @@
- /*
- * $Id: init.c,v 1.150 1999/03/10 08:16:33 cort Exp $
+/*
+ * $Id: init.c,v 1.164 1999/05/05 17:33:55 cort Exp $
X *


X * PowerPC version
X * Copyright (C) 1995-1996 Gary Thomas (g...@linuxppc.org)

@@ -119,12 +119,19 @@
X PTE *Hash, *Hash_end;
X unsigned long Hash_size, Hash_mask;
X #ifndef CONFIG_8xx
+#ifdef CONFIG_PPC64
+unsigned long long _SDR1;
+#else
X unsigned long _SDR1;
+#endif
X static void hash_init(void);
X union ubat { /* BAT register values to be loaded */
X BAT bat;
- P601_BAT bat_601;
+#ifdef CONFIG_PPC64
+ u64 word[2];
+#else
X u32 word[2];
+#endif
X } BATS[4][2]; /* 4 pairs of IBAT, DBAT */
X
X struct batrange { /* stores address ranges mapped by BATs */
@@ -132,6 +139,8 @@
X unsigned long limit;
X unsigned long phys;
X } bat_addrs[4];
+unsigned long inline v_mapped_by_bats(unsigned long);
+unsigned long inline p_mapped_by_bats(unsigned long);
X #endif /* CONFIG_8xx */
X
X /*
@@ -332,15 +341,40 @@
X * virt == phys; for addresses below this we use
X * space going down from ioremap_base (ioremap_bot
X * records where we're up to).
- *
- * We should also look out for a frame buffer and
- * map it with a free BAT register, if there is one.
X */
X p = addr & PAGE_MASK;
X size = PAGE_ALIGN(addr + size) - p;
+
+ /*
+ * Don't allow anybody to remap normal RAM that we're using.
+ * mem_init() sets high_memory so only do the check after that.
+ */
+ if ( mem_init_done && (p < virt_to_phys(high_memory)) )
+ {
+ printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p,
+ __builtin_return_address(0));


+ return NULL;
+ }
+

X if (size == 0)
X return NULL;
X
+#ifndef CONFIG_8xx
+ /*
+ * Is it already mapped? Perhaps overlapped by a previous
+ * BAT mapping. If the whole area is mapped then we're done,
+ * otherwise remap it since we want to keep the virt addrs for
+ * each request contiguous.
+ *
+ * We make the assumption here that if the bottom and top
+ * of the range we want are mapped then it's mapped to the
+ * same virt address (and this is contiguous).


+ * -- Cort
+ */

+ if ( (v = p_mapped_by_bats(addr)) /*&& p_mapped_by_bats(addr+(size-1))*/ )
+ goto out;
+#endif /* CONFIG_8xx */
+
X if (mem_init_done) {
X struct vm_struct *area;
X area = get_vm_area(size);
@@ -358,10 +392,17 @@
X flags |= pgprot_val(PAGE_KERNEL);
X if (flags & (_PAGE_NO_CACHE | _PAGE_WRITETHRU))
X flags |= _PAGE_GUARDED;
+
+#ifndef CONFIG_8xx
+ /*
+ * Is it a candidate for a BAT mapping?
+ */
+#endif /* CONFIG_8xx */
+
X for (i = 0; i < size; i += PAGE_SIZE)
X map_page(&init_task, v+i, p+i, flags);
-
- return (void *) (v + (addr & ~PAGE_MASK));
+out:
+ return (void *) (v + (p & ~PAGE_MASK));
X }
X
X void iounmap(void *addr)
@@ -412,9 +453,7 @@
X {
X pmd_t *pd;
X pte_t *pg;
-#ifndef CONFIG_8xx
- int b;
-#endif
+
X if (tsk->mm->pgd == NULL) {
X /* Allocate upper level page map */
X tsk->mm->pgd = (pgd_t *) MMU_get_page();
@@ -422,20 +461,8 @@
X /* Use upper 10 bits of VA to index the first level map */
X pd = (pmd_t *) (tsk->mm->pgd + (va >> PGDIR_SHIFT));
X if (pmd_none(*pd)) {
-#ifndef CONFIG_8xx
- /*
- * Need to allocate second-level table, but first
- * check whether this address is already mapped by
- * the BATs; if so, don't bother allocating the page.
- */
- for (b = 0; b < 4; ++b) {
- if (va >= bat_addrs[b].start
- && va <= bat_addrs[b].limit) {
- /* XXX should check the phys address matches */
- return;
- }


- }
-#endif /* CONFIG_8xx */

+ if ( v_mapped_by_bats(va) )
+ return;
X pg = (pte_t *) MMU_get_page();
X pmd_val(*pd) = (unsigned long) pg;
X }
@@ -680,6 +707,33 @@
X static void sort_mem_pieces(struct mem_pieces *);
X static void coalesce_mem_pieces(struct mem_pieces *);
X
+/*
+ * Return 1 if this VA is mapped by BATs
+ */
+unsigned long inline v_mapped_by_bats(unsigned long va)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (va >= bat_addrs[b].start
+ && va < bat_addrs[b].limit)
+ return 1;


+ return 0;
+}
+
+/*

+ * Return VA for a given PA or 0 if not mapped
+ */
+unsigned long inline p_mapped_by_bats(unsigned long pa)
+{
+ int b;
+ for (b = 0; b < 4; ++b)
+ if (pa >= bat_addrs[b].phys
+ && pa < (bat_addrs[b].limit-bat_addrs[b].start)
+ +bat_addrs[b].phys)
+ return bat_addrs[b].start+(pa-bat_addrs[b].phys);


+ return 0;
+}
+

X __initfunc(static void sort_mem_pieces(struct mem_pieces *mp))
X {
X unsigned long a, s;
@@ -836,7 +890,7 @@
X
X setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE);
X done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1;
- if (done < tot) {
+ if ((done < tot) && !bat_addrs[3].limit) {
X /* use BAT3 to cover a bit more */
X tot -= done;
X for (bl = 128<<10; bl < max_size; bl <<= 1)
@@ -990,11 +1044,13 @@
X switch (_machine) {
X case _MACH_prep:
X setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
- setbat(1, 0xd0000000, 0xc0000000, 0x10000000, IO_PAGE);
+ setbat(1, 0xf0000000, 0xc0000000, 0x08000000, IO_PAGE);
+ ioremap_base = 0xf0000000;
X break;
X case _MACH_chrp:
X setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE);
X setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
+ setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
X break;
X case _MACH_Pmac:
X {
@@ -1245,7 +1301,7 @@
X int i;
X
X /* max amount of RAM we allow -- Cort */
-#define RAM_LIMIT (768<<20)
+#define RAM_LIMIT (768<<20)
X
X memory_node = find_devices("memory");
X if (memory_node == NULL) {
@@ -1449,10 +1505,18 @@
X * up to a maximum of 2MB.
X */
X ramsize = (ulong)end_of_DRAM - KERNELBASE;
+#ifdef CONFIG_PPC64
+ Hash_mask = 0;
+ for (h = 256<<10; h < ramsize / 256 && h < 4<<20; h *= 2, Hash_mask++)
+ ;
+ Hash_size = h;
+ Hash_mask << 10; /* so setting _SDR1 works the same -- Cort */
+#else
X for (h = 64<<10; h < ramsize / 256 && h < 2<<20; h *= 2)
X ;
X Hash_size = h;
X Hash_mask = (h >> 6) - 1;
+#endif
X
X #ifdef NO_RELOAD_HTAB
X /* shrink the htab since we don't use it on 603's -- Cort */
@@ -1530,4 +1594,3 @@
X }
X }
X #endif /* ndef CONFIG_8xx */
-
diff -u --recursive --new-file v2.2.7/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v2.2.7/linux/arch/sparc/kernel/entry.S Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc/kernel/entry.S Tue May 11 08:24:31 1999
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.158 1999/04/27 14:35:07 davem Exp $
+/* $Id: entry.S,v 1.159 1999/05/08 03:00:03 davem Exp $
X * arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -1476,7 +1476,7 @@
X wr %l0, PSR_ET, %psr
X WRITE_PAUSE
X call schedule_tail
- nop
+ mov %g3, %o0
X b C_LABEL(ret_sys_call)
X ld [%sp + REGWIN_SZ + PT_I0], %o0
X #endif
diff -u --recursive --new-file v2.2.7/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.2.7/linux/arch/sparc/kernel/process.c Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc/kernel/process.c Tue May 11 08:24:31 1999
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.136 1999/04/16 01:20:33 anton Exp $
+/* $Id: process.c,v 1.137 1999/05/08 03:00:10 davem Exp $
X * linux/arch/sparc/kernel/process.c
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -63,6 +63,8 @@


X /* endless idle loop with no priority at all */
X current->priority = 0;
X current->counter = -100;
+ init_idle();
+
X for (;;) {

X if (ARCH_SUN4C_SUN4) {
X static int count = HZ;
@@ -111,6 +113,8 @@


X /* endless idle loop with no priority at all */
X current->priority = 0;
X current->counter = -100;
+ init_idle();
+
X while(1) {

X if(current->need_resched) {
X schedule();
diff -u --recursive --new-file v2.2.7/linux/arch/sparc/kernel/sun4d_smp.c linux/arch/sparc/kernel/sun4d_smp.c
--- v2.2.7/linux/arch/sparc/kernel/sun4d_smp.c Thu Nov 19 09:56:27 1998
+++ linux/arch/sparc/kernel/sun4d_smp.c Tue May 11 08:24:31 1999
@@ -190,6 +190,7 @@
X current->processor = boot_cpu_id;
X smp_store_cpu_info(boot_cpu_id);
X smp_setup_percpu_timer();
+ init_idle();
X local_flush_cache_all();
X if(linux_num_cpus == 1)
X return; /* Not an MP box. */
@@ -211,6 +212,7 @@
X p = task[++cpucount];
X
X p->processor = i;
+ p->has_cpu = 1; /* we schedule the first task manually */
X current_set[i] = p;
X
X for (no = 0; no < linux_num_cpus; no++)
diff -u --recursive --new-file v2.2.7/linux/arch/sparc/kernel/sun4m_smp.c linux/arch/sparc/kernel/sun4m_smp.c
--- v2.2.7/linux/arch/sparc/kernel/sun4m_smp.c Wed Apr 28 11:37:30 1999
+++ linux/arch/sparc/kernel/sun4m_smp.c Tue May 11 08:24:31 1999
@@ -161,6 +161,7 @@
X smp_store_cpu_info(boot_cpu_id);
X set_irq_udt(mid_xlate[boot_cpu_id]);
X smp_setup_percpu_timer();
+ init_idle();
X local_flush_cache_all();
X if(linux_num_cpus == 1)
X return; /* Not an MP box. */
@@ -180,6 +181,7 @@
X p = task[++cpucount];
X
X p->processor = i;
+ p->has_cpu = 1; /* we schedule the first task manually */
X current_set[i] = p;
X
X /* See trampoline.S for details... */
diff -u --recursive --new-file v2.2.7/linux/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c
--- v2.2.7/linux/arch/sparc/kernel/sys_sparc.c Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc/kernel/sys_sparc.c Tue May 11 08:24:31 1999
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.51 1999/03/20 22:02:00 davem Exp $
+/* $Id: sys_sparc.c,v 1.52 1999/05/08 08:09:48 anton Exp $
X * linux/arch/sparc/kernel/sys_sparc.c
X *
X * This file contains various random system calls that
@@ -231,7 +231,7 @@
X
X if (count++ > 5) return -ENOSYS;
X lock_kernel();
- printk ("Unimplemented SPARC system call %d\n",(int)regs->u_regs[1]);
+ printk ("%s[%d]: Unimplemented SPARC system call %d\n", current->comm, current->pid, (int)regs->u_regs[1]);
X #ifdef DEBUG_UNIMP_SYSCALL
X show_regs (regs);
X #endif
diff -u --recurs