diff options
Diffstat (limited to 'include/asm-ppc')
-rw-r--r-- | include/asm-ppc/elf.h | 5 | ||||
-rw-r--r-- | include/asm-ppc/hardirq.h | 34 | ||||
-rw-r--r-- | include/asm-ppc/page.h | 17 | ||||
-rw-r--r-- | include/asm-ppc/pci.h | 34 | ||||
-rw-r--r-- | include/asm-ppc/pgtable.h | 5 | ||||
-rw-r--r-- | include/asm-ppc/posix_types.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/processor.h | 7 | ||||
-rw-r--r-- | include/asm-ppc/smp.h | 2 | ||||
-rw-r--r-- | include/asm-ppc/softirq.h | 113 | ||||
-rw-r--r-- | include/asm-ppc/spinlock.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/types.h | 6 |
11 files changed, 99 insertions, 129 deletions
diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h index 002736abf..3ae89d9cc 100644 --- a/include/asm-ppc/elf.h +++ b/include/asm-ppc/elf.h @@ -8,6 +8,7 @@ #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ #define ELF_NFPREG 33 /* includes fpscr */ +#define ELF_NVRREG 33 /* includes vscr */ /* * This is used to ensure we don't load something for the wrong architecture. @@ -37,6 +38,10 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; +/* Altivec registers */ +typedef vector128 elf_vrreg_t; +typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; + #define ELF_CORE_COPY_REGS(gregs, regs) \ memcpy(gregs, regs, \ sizeof(struct pt_regs) < sizeof(elf_gregset_t)? \ diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index ac5ac69fc..c2c58315e 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -1,24 +1,27 @@ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H +#include <linux/config.h> #include <asm/smp.h> -extern unsigned int ppc_local_irq_count[NR_CPUS]; +extern unsigned int local_irq_count[NR_CPUS]; /* * Are we in an interrupt context? Either doing bottom half * or hardware interrupt processing? */ #define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (ppc_local_irq_count[__cpu] + ppc_local_bh_count[__cpu] != 0); }) + (local_irq_count[__cpu] + local_bh_count[__cpu] != 0); }) + +#define in_irq() (local_irq_count[smp_processor_id()] != 0) #ifndef __SMP__ -#define hardirq_trylock(cpu) (ppc_local_irq_count[cpu] == 0) +#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) #define hardirq_endlock(cpu) do { } while (0) -#define hardirq_enter(cpu) (ppc_local_irq_count[cpu]++) -#define hardirq_exit(cpu) (ppc_local_irq_count[cpu]--) +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) #define synchronize_irq() do { } while (0) @@ -41,14 +44,31 @@ static inline void release_irqlock(int cpu) static inline void hardirq_enter(int cpu) { - ++ppc_local_irq_count[cpu]; + unsigned int loops = 10000000; + + ++local_irq_count[cpu]; atomic_inc(&global_irq_count); + 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 + } + } } static inline void hardirq_exit(int cpu) { atomic_dec(&global_irq_count); - --ppc_local_irq_count[cpu]; + --local_irq_count[cpu]; } static inline int hardirq_trylock(int cpu) diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index 55168a8b2..1be8ddfa5 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -77,7 +77,7 @@ typedef unsigned long pgprot_t; #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) extern void clear_page(void *page); -#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +extern void copy_page(void *to, void *from); /* map phys->virtual and virtual->phys for RAM pages */ static inline unsigned long ___pa(unsigned long v) @@ -113,6 +113,21 @@ static inline void* ___va(unsigned long p) #define MAP_PAGE_RESERVED (1<<15) extern unsigned long get_zero_page_fast(void); + +/* Pure 2^n version of get_order */ +extern __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ #endif /* _PPC_PAGE_H */ diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 92347e406..5d022e02c 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -27,38 +27,60 @@ extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, - size_t size) + size_t size, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); return virt_to_bus(ptr); } extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size) + size_t size, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); /* nothing to do */ } extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents) + int nents, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); return nents; } extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nents) + int nents, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); /* nothing to do */ } extern inline void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, - size_t size) + size_t size, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); /* nothing to do */ } extern inline void pci_dma_syng_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nelems) + int nelems, int direction) { + if (direction == PCI_DMA_NONE) + BUG(); /* nothing to do */ } +/* Return whether the given PCI device DMA address mask can + * be supported properly. For example, if your device can + * only drive the low 24-bits during PCI bus mastering, then + * you would pass 0x00ffffff as the mask to this function. + */ +extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) +{ + return 1; +} + #define sg_dma_address(sg) (virt_to_bus((sg)->address)) #define sg_dma_len(sg) ((sg)->length) diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index f1f0f578a..303b2aa05 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -69,6 +69,8 @@ extern inline void flush_tlb_pgtables(struct mm_struct *mm, extern void flush_icache_range(unsigned long, unsigned long); extern void __flush_page_to_ram(unsigned long page_va); #define flush_page_to_ram(page) __flush_page_to_ram(page_address(page)) +extern void __flush_icache_page(unsigned long page_va); +#define flush_icache_page(vma, page) __flush_icache_page(page_address(page)) extern unsigned long va_to_phys(unsigned long address); extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address); @@ -413,7 +415,8 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_offset_k(address) pgd_offset(&init_mm, address) /* to find an entry in a page-table-directory */ -#define pgd_offset(mm, address) ((mm)->pgd + ((address) >> PGDIR_SHIFT)) +#define pgd_index(address) ((address) >> PGDIR_SHIFT) +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) /* Find an entry in the second-level page table.. */ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h index f6d0d70ea..04c59a5b3 100644 --- a/include/asm-ppc/posix_types.h +++ b/include/asm-ppc/posix_types.h @@ -24,8 +24,8 @@ typedef long __kernel_clock_t; typedef int __kernel_daddr_t; typedef char * __kernel_caddr_t; typedef short __kernel_ipc_pid_t; -typedef unsigned int __kernel_uid16_t; -typedef unsigned int __kernel_gid16_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 20e337f34..704bd68ab 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -11,6 +11,7 @@ #include <asm/ptrace.h> #include <asm/residual.h> +#include <asm/types.h> /* Machine State Register (MSR) Fields */ @@ -625,9 +626,11 @@ struct thread_struct { double fpr[32]; /* Complete floating point set */ unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ unsigned long fpscr; /* Floating point status */ - unsigned long vrf[128]; - unsigned long vscr; +#ifdef CONFIG_ALTIVEC + vector128 vr[32]; /* Complete AltiVec set */ + vector128 vscr; /* AltiVec status */ unsigned long vrsave; +#endif /* CONFIG_ALTIVEC */ }; #define INIT_SP (sizeof(init_stack) + (unsigned long) &init_stack) diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index ac1442861..156d8db72 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -33,7 +33,7 @@ void smp_send_tlb_invalidate(int); /* 1 to 1 mapping on PPC -- Cort */ #define cpu_logical_map(cpu) (cpu) -extern int cpu_number_map[NR_CPUS]; +#define cpu_number_map(x) (x) extern volatile unsigned long cpu_callin_map[NR_CPUS]; #define hard_smp_processor_id() (0) diff --git a/include/asm-ppc/softirq.h b/include/asm-ppc/softirq.h index 1188809e9..550b46192 100644 --- a/include/asm-ppc/softirq.h +++ b/include/asm-ppc/softirq.h @@ -4,116 +4,11 @@ #include <asm/atomic.h> #include <asm/hardirq.h> -#define get_active_bhs() (bh_mask & bh_active) -#define clear_active_bhs(x) atomic_clear_mask((x),&bh_active) +extern unsigned int local_bh_count[NR_CPUS]; -extern unsigned int ppc_local_bh_count[NR_CPUS]; +#define local_bh_disable() do { local_bh_count[smp_processor_id()]++; barrier(); } while (0) +#define local_bh_enable() do { barrier(); local_bh_count[smp_processor_id()]--; } while (0) -extern inline void init_bh(int nr, void (*routine)(void)) -{ - bh_base[nr] = routine; - atomic_set(&bh_mask_count[nr], 0); - bh_mask |= 1 << nr; -} - -extern inline void remove_bh(int nr) -{ - bh_mask &= ~(1 << nr); - wmb(); - bh_base[nr] = 0; -} - -extern inline void mark_bh(int nr) -{ - set_bit(nr, &bh_active); -} - -#ifdef __SMP__ - -/* - * The locking mechanism for base handlers, to prevent re-entrancy, - * is entirely private to an implementation, it should not be - * referenced at all outside of this file. - */ -extern atomic_t global_bh_lock; -extern atomic_t global_bh_count; - -extern void synchronize_bh(void); - -static inline void start_bh_atomic(void) -{ - atomic_inc(&global_bh_lock); - synchronize_bh(); -} - -static inline void end_bh_atomic(void) -{ - atomic_dec(&global_bh_lock); -} - -/* These are for the IRQs testing the lock */ -static inline int softirq_trylock(int cpu) -{ - if (ppc_local_bh_count[cpu] == 0) { - ppc_local_bh_count[cpu] = 1; - if (!test_and_set_bit(0,&global_bh_count)) { - mb(); - if (atomic_read(&global_bh_lock) == 0) - return 1; - clear_bit(0,&global_bh_count); - } - ppc_local_bh_count[cpu] = 0; - mb(); - } - return 0; -} - -static inline void softirq_endlock(int cpu) -{ - mb(); - ppc_local_bh_count[cpu]--; - clear_bit(0,&global_bh_count); -} - -#else - -extern inline void start_bh_atomic(void) -{ - ppc_local_bh_count[smp_processor_id()]++; - barrier(); -} - -extern inline void end_bh_atomic(void) -{ - barrier(); - ppc_local_bh_count[smp_processor_id()]--; -} - -/* These are for the irq's testing the lock */ -#define softirq_trylock(cpu) (ppc_local_bh_count[cpu] ? 0 : (ppc_local_bh_count[cpu]=1)) -#define softirq_endlock(cpu) (ppc_local_bh_count[cpu] = 0) -#define synchronize_bh() barrier() - -#endif /* SMP */ - -#define local_bh_disable() (ppc_local_bh_count[smp_processor_id()]++) -#define local_bh_enable() (ppc_local_bh_count[smp_processor_id()]--) - -/* - * These use a mask count to correctly handle - * nested disable/enable calls - */ -extern inline void disable_bh(int nr) -{ - bh_mask &= ~(1 << nr); - atomic_inc(&bh_mask_count[nr]); - synchronize_bh(); -} - -extern inline void enable_bh(int nr) -{ - if (atomic_dec_and_test(&bh_mask_count[nr])) - bh_mask |= 1 << nr; -} +#define in_softirq() (local_bh_count[smp_processor_id()] != 0) #endif /* __ASM_SOFTIRQ_H */ diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index ad1fdda17..5e7e2a19e 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -14,6 +14,7 @@ typedef struct { #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0, 0 } #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0) #define spin_unlock_wait(lp) do { barrier(); } while((lp)->lock) +#define spin_is_locked(x) ((x)->lock != 0) extern void _spin_lock(spinlock_t *lock); extern void _spin_unlock(spinlock_t *lock); diff --git a/include/asm-ppc/types.h b/include/asm-ppc/types.h index 4c5e9766e..d39f91cf9 100644 --- a/include/asm-ppc/types.h +++ b/include/asm-ppc/types.h @@ -1,6 +1,7 @@ #ifndef _PPC_TYPES_H #define _PPC_TYPES_H +#ifndef __ASSEMBLY__ /* * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the * header files exported to user space @@ -41,10 +42,15 @@ typedef unsigned long long u64; #define BITS_PER_LONG 32 +typedef struct { + u32 u[4]; +} __attribute((aligned(16))) vector128; + /* DMA addresses are 32-bits wide */ typedef u32 dma_addr_t; #endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ #endif |