* Add patches from linux-mips.org's 2.6.18-stable branch:
- bugfix/copy-user-highpage.patch, needed for cache alias handling on mips/mipsel/hppa. - bugfix/mips/syscall-wiring.patch, fixes TLS register access, and n32 rt_sigqueueinfo. - bugfix/mips/sb1-flush-cache-data-page.patch, missing cache flush on SB-1. - bugfix/mips/trylock.patch, fix trylock implementation for R1x000 and R3xxx. - bugfix/mips/smp-cpu-bringup.patch, correct initialization of non-contiguous CPU topology. - bugfix/mips/header-exports.patch, clean up userland exports of kernel headers. - bugfix/mips/sb1-interrupt-handler.patch, fix broken interrupt routing on SB-1. - bugfix/mips/cache-alias.patch, fixes #387498 for mips/mipsel. - bugfix/mips/ip22-zilog-console.patch, fix long delays seen with SGI ip22 serial console. - bugfix/mips/signal-handling.patch, fixes a signal handling race condition shown with gdb. - bugfix/mips/sb1-duart-tts.patch, replaces mips-sb1-duart-tts.patch, use standard Linux names for SB-1 consoles. - bugfix/mips/wait-race.patch, correct behaviour of the idle loop. - bugfix/mips/sgi-ioc3.patch, checksumming fix for IOC3 network driver. - features/mips/qemu-kernel.patch, support for the mips/mipsel machine emulated by Qemu. - features/mips/backtrace.patch, reimplementation of stack analysis and backtrace printing, useful for in-kernel debugging. - bugfix/mips/dec-scsi.patch, replaces mips-dec-scsi.patch, fixes DSP SCSI driver for DECstations. - bugfix/mips/dec-serial.patch, replaces mips-dec-serial.patch, fix serial console handling on DECstations. svn path=/dists/trunk/linux-2.6/; revision=7681
This commit is contained in:
parent
d946f6a129
commit
2411151738
|
@ -54,6 +54,41 @@ linux-2.6 (2.6.18-4) UNRELEASED; urgency=low
|
|||
* Bump ABI to 2.
|
||||
* Update vserver patch to 2.0.2.2-rc4.
|
||||
|
||||
[ Thiemo Seufer ]
|
||||
* Add patches from linux-mips.org's 2.6.18-stable branch:
|
||||
- bugfix/copy-user-highpage.patch, needed for cache alias handling
|
||||
on mips/mipsel/hppa.
|
||||
- bugfix/mips/syscall-wiring.patch, fixes TLS register access, and
|
||||
n32 rt_sigqueueinfo.
|
||||
- bugfix/mips/sb1-flush-cache-data-page.patch, missing cache flush
|
||||
on SB-1.
|
||||
- bugfix/mips/trylock.patch, fix trylock implementation for R1x000
|
||||
and R3xxx.
|
||||
- bugfix/mips/smp-cpu-bringup.patch, correct initialization of
|
||||
non-contiguous CPU topology.
|
||||
- bugfix/mips/header-exports.patch, clean up userland exports of
|
||||
kernel headers.
|
||||
- bugfix/mips/sb1-interrupt-handler.patch, fix broken interrupt
|
||||
routing on SB-1.
|
||||
- bugfix/mips/cache-alias.patch, fixes #387498 for mips/mipsel.
|
||||
- bugfix/mips/ip22-zilog-console.patch, fix long delays seen with
|
||||
SGI ip22 serial console.
|
||||
- bugfix/mips/signal-handling.patch, fixes a signal handling race
|
||||
condition shown with gdb.
|
||||
- bugfix/mips/sb1-duart-tts.patch, replaces mips-sb1-duart-tts.patch,
|
||||
use standard Linux names for SB-1 consoles.
|
||||
- bugfix/mips/wait-race.patch, correct behaviour of the idle loop.
|
||||
- bugfix/mips/sgi-ioc3.patch, checksumming fix for IOC3 network
|
||||
driver.
|
||||
- features/mips/qemu-kernel.patch, support for the mips/mipsel
|
||||
machine emulated by Qemu.
|
||||
- features/mips/backtrace.patch, reimplementation of stack analysis
|
||||
and backtrace printing, useful for in-kernel debugging.
|
||||
- bugfix/mips/dec-scsi.patch, replaces mips-dec-scsi.patch, fixes DSP
|
||||
SCSI driver for DECstations.
|
||||
- bugfix/mips/dec-serial.patch, replaces mips-dec-serial.patch, fix
|
||||
serial console handling on DECstations.
|
||||
|
||||
-- Frederik Schüler <fs@debian.org> Wed, 1 Nov 2006 23:44:06 +0100
|
||||
|
||||
linux-2.6 (2.6.18-3) unstable; urgency=low
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# Arch-specific copy_user_highpage, from linux-mips.org 2.6.18-stable,
|
||||
# also in kernel.org mainline, needed for cache alias fix.
|
||||
|
||||
|
||||
--- a/include/linux/highmem.h
|
||||
+++ b/include/linux/highmem.h
|
||||
@@ -89,7 +89,10 @@ static inline void memclear_highpage_flu
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
}
|
||||
|
||||
-static inline void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr)
|
||||
+#ifndef __HAVE_ARCH_COPY_USER_HIGHPAGE
|
||||
+
|
||||
+static inline void copy_user_highpage(struct page *to, struct page *from,
|
||||
+ unsigned long vaddr, struct vm_area_struct *vma)
|
||||
{
|
||||
char *vfrom, *vto;
|
||||
|
||||
@@ -102,6 +105,8 @@ static inline void copy_user_highpage(st
|
||||
smp_wmb();
|
||||
}
|
||||
|
||||
+#endif
|
||||
+
|
||||
static inline void copy_highpage(struct page *to, struct page *from)
|
||||
{
|
||||
char *vfrom, *vto;
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index 109e986..2e4ee87 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -1407,7 +1407,7 @@ static inline pte_t maybe_mkwrite(pte_t
|
||||
return pte;
|
||||
}
|
||||
|
||||
-static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va)
|
||||
+static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va, struct vm_area_struct *vma)
|
||||
{
|
||||
/*
|
||||
* If the source page was a PFN mapping, we don't have
|
||||
@@ -1429,9 +1429,9 @@ static inline void cow_user_page(struct
|
||||
memset(kaddr, 0, PAGE_SIZE);
|
||||
kunmap_atomic(kaddr, KM_USER0);
|
||||
return;
|
||||
-
|
||||
+
|
||||
}
|
||||
- copy_user_highpage(dst, src, va);
|
||||
+ copy_user_highpage(dst, src, va, vma);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1531,7 +1531,7 @@ gotten:
|
||||
new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
|
||||
if (!new_page)
|
||||
goto oom;
|
||||
- cow_user_page(new_page, old_page, address);
|
||||
+ cow_user_page(new_page, old_page, address, vma);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2135,7 +2135,7 @@ retry:
|
||||
page = alloc_page_vma(GFP_HIGHUSER, vma, address);
|
||||
if (!page)
|
||||
goto oom;
|
||||
- copy_user_highpage(page, new_page, address);
|
||||
+ copy_user_highpage(page, new_page, address, vma);
|
||||
page_cache_release(new_page);
|
||||
new_page = page;
|
||||
anon = 1;
|
|
@ -0,0 +1,675 @@
|
|||
# Fix cache alias handling for mips (see #387498), from linux-mips.org
|
||||
# 2.6.18-stable, also in kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
|
||||
index bb041a2..e1f35ef 100644
|
||||
--- a/arch/mips/mm/c-r3k.c
|
||||
+++ b/arch/mips/mm/c-r3k.c
|
||||
@@ -335,7 +335,7 @@ void __init r3k_cache_init(void)
|
||||
flush_cache_mm = r3k_flush_cache_mm;
|
||||
flush_cache_range = r3k_flush_cache_range;
|
||||
flush_cache_page = r3k_flush_cache_page;
|
||||
- flush_icache_page = r3k_flush_icache_page;
|
||||
+ __flush_icache_page = r3k_flush_icache_page;
|
||||
flush_icache_range = r3k_flush_icache_range;
|
||||
|
||||
flush_cache_sigtramp = r3k_flush_cache_sigtramp;
|
||||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
|
||||
index 069803f..2d729f6 100644
|
||||
--- a/arch/mips/mm/c-r4k.c
|
||||
+++ b/arch/mips/mm/c-r4k.c
|
||||
@@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache
|
||||
}
|
||||
}
|
||||
if (exec) {
|
||||
- if (cpu_has_vtag_icache) {
|
||||
+ if (cpu_has_vtag_icache && mm == current->active_mm) {
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (cpu_context(cpu, mm) != 0)
|
||||
@@ -599,7 +599,7 @@ static inline void local_r4k_flush_icach
|
||||
* We're not sure of the virtual address(es) involved here, so
|
||||
* we have to flush the entire I-cache.
|
||||
*/
|
||||
- if (cpu_has_vtag_icache) {
|
||||
+ if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (cpu_context(cpu, vma->vm_mm) != 0)
|
||||
@@ -1291,7 +1291,7 @@ void __init r4k_cache_init(void)
|
||||
__flush_cache_all = r4k___flush_cache_all;
|
||||
flush_cache_mm = r4k_flush_cache_mm;
|
||||
flush_cache_page = r4k_flush_cache_page;
|
||||
- flush_icache_page = r4k_flush_icache_page;
|
||||
+ __flush_icache_page = r4k_flush_icache_page;
|
||||
flush_cache_range = r4k_flush_cache_range;
|
||||
|
||||
flush_cache_sigtramp = r4k_flush_cache_sigtramp;
|
||||
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
|
||||
index 2d71efb..16bad7c 100644
|
||||
--- a/arch/mips/mm/c-sb1.c
|
||||
+++ b/arch/mips/mm/c-sb1.c
|
||||
@@ -155,6 +155,26 @@ static inline void __sb1_flush_icache_al
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Invalidate a range of the icache. The addresses are virtual, and
|
||||
+ * the cache is virtually indexed and tagged. However, we don't
|
||||
+ * necessarily have the right ASID context, so use index ops instead
|
||||
+ * of hit ops.
|
||||
+ */
|
||||
+static inline void __sb1_flush_icache_range(unsigned long start,
|
||||
+ unsigned long end)
|
||||
+{
|
||||
+ start &= ~(icache_line_size - 1);
|
||||
+ end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
|
||||
+
|
||||
+ while (start != end) {
|
||||
+ cache_set_op(Index_Invalidate_I, start & icache_index_mask);
|
||||
+ start += icache_line_size;
|
||||
+ }
|
||||
+ mispredict();
|
||||
+ sync();
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Flush the icache for a given physical page. Need to writeback the
|
||||
* dcache first, then invalidate the icache. If the page isn't
|
||||
* executable, nothing is required.
|
||||
@@ -173,8 +193,11 @@ #endif
|
||||
/*
|
||||
* Bumping the ASID is probably cheaper than the flush ...
|
||||
*/
|
||||
- if (cpu_context(cpu, vma->vm_mm) != 0)
|
||||
- drop_mmu_context(vma->vm_mm, cpu);
|
||||
+ if (vma->vm_mm == current->active_mm) {
|
||||
+ if (cpu_context(cpu, vma->vm_mm) != 0)
|
||||
+ drop_mmu_context(vma->vm_mm, cpu);
|
||||
+ } else
|
||||
+ __sb1_flush_icache_range(addr, addr + PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -210,26 +233,6 @@ void sb1_flush_cache_page(struct vm_area
|
||||
__attribute__((alias("local_sb1_flush_cache_page")));
|
||||
#endif
|
||||
|
||||
-/*
|
||||
- * Invalidate a range of the icache. The addresses are virtual, and
|
||||
- * the cache is virtually indexed and tagged. However, we don't
|
||||
- * necessarily have the right ASID context, so use index ops instead
|
||||
- * of hit ops.
|
||||
- */
|
||||
-static inline void __sb1_flush_icache_range(unsigned long start,
|
||||
- unsigned long end)
|
||||
-{
|
||||
- start &= ~(icache_line_size - 1);
|
||||
- end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
|
||||
-
|
||||
- while (start != end) {
|
||||
- cache_set_op(Index_Invalidate_I, start & icache_index_mask);
|
||||
- start += icache_line_size;
|
||||
- }
|
||||
- mispredict();
|
||||
- sync();
|
||||
-}
|
||||
-
|
||||
|
||||
/*
|
||||
* Invalidate all caches on this CPU
|
||||
@@ -326,9 +329,12 @@ #endif
|
||||
* If there's a context, bump the ASID (cheaper than a flush,
|
||||
* since we don't know VAs!)
|
||||
*/
|
||||
- if (cpu_context(cpu, vma->vm_mm) != 0) {
|
||||
- drop_mmu_context(vma->vm_mm, cpu);
|
||||
- }
|
||||
+ if (vma->vm_mm == current->active_mm) {
|
||||
+ if (cpu_context(cpu, vma->vm_mm) != 0)
|
||||
+ drop_mmu_context(vma->vm_mm, cpu);
|
||||
+ } else
|
||||
+ __sb1_flush_icache_range(start, start + PAGE_SIZE);
|
||||
+
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -520,7 +526,7 @@ #endif
|
||||
|
||||
/* These routines are for Icache coherence with the Dcache */
|
||||
flush_icache_range = sb1_flush_icache_range;
|
||||
- flush_icache_page = sb1_flush_icache_page;
|
||||
+ __flush_icache_page = sb1_flush_icache_page;
|
||||
flush_icache_all = __sb1_flush_icache_all; /* local only */
|
||||
|
||||
/* This implies an Icache flush too, so can't be nop'ed */
|
||||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
|
||||
index ddd3a2d..40c8b02 100644
|
||||
--- a/arch/mips/mm/cache.c
|
||||
+++ b/arch/mips/mm/cache.c
|
||||
@@ -25,7 +25,7 @@ void (*flush_cache_range)(struct vm_area
|
||||
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
|
||||
unsigned long pfn);
|
||||
void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
-void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
|
||||
+void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
|
||||
|
||||
/* MIPS specific cache operations */
|
||||
void (*flush_cache_sigtramp)(unsigned long addr);
|
||||
@@ -70,6 +70,8 @@ void __flush_dcache_page(struct page *pa
|
||||
struct address_space *mapping = page_mapping(page);
|
||||
unsigned long addr;
|
||||
|
||||
+ if (PageHighMem(page))
|
||||
+ return;
|
||||
if (mapping && !mapping_mapped(mapping)) {
|
||||
SetPageDcacheDirty(page);
|
||||
return;
|
||||
@@ -91,16 +93,16 @@ void __update_cache(struct vm_area_struc
|
||||
{
|
||||
struct page *page;
|
||||
unsigned long pfn, addr;
|
||||
+ int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
|
||||
|
||||
pfn = pte_pfn(pte);
|
||||
- if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) &&
|
||||
- Page_dcache_dirty(page)) {
|
||||
- if (pages_do_alias((unsigned long)page_address(page),
|
||||
- address & PAGE_MASK)) {
|
||||
- addr = (unsigned long) page_address(page);
|
||||
+ if (unlikely(!pfn_valid(pfn)))
|
||||
+ return;
|
||||
+ page = pfn_to_page(pfn);
|
||||
+ if (page_mapping(page) && Page_dcache_dirty(page)) {
|
||||
+ addr = (unsigned long) page_address(page);
|
||||
+ if (exec || pages_do_alias(addr, address & PAGE_MASK))
|
||||
flush_data_cache_page(addr);
|
||||
- }
|
||||
-
|
||||
ClearPageDcacheDirty(page);
|
||||
}
|
||||
}
|
||||
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
|
||||
index e3a6172..a4f8c45 100644
|
||||
--- a/arch/mips/mm/fault.c
|
||||
+++ b/arch/mips/mm/fault.c
|
||||
@@ -89,7 +89,7 @@ good_area:
|
||||
if (!(vma->vm_flags & VM_WRITE))
|
||||
goto bad_area;
|
||||
} else {
|
||||
- if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
|
||||
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
|
||||
index c52497b..a681f57 100644
|
||||
--- a/arch/mips/mm/init.c
|
||||
+++ b/arch/mips/mm/init.c
|
||||
@@ -30,11 +30,39 @@ #include <asm/bootinfo.h>
|
||||
#include <asm/cachectl.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/dma.h>
|
||||
+#include <asm/kmap_types.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/tlb.h>
|
||||
+#include <asm/fixmap.h>
|
||||
+
|
||||
+/* CP0 hazard avoidance. */
|
||||
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
|
||||
+ "nop; nop; nop; nop; nop; nop;\n\t" \
|
||||
+ ".set reorder\n\t")
|
||||
+
|
||||
+/* Atomicity and interruptability */
|
||||
+#ifdef CONFIG_MIPS_MT_SMTC
|
||||
+
|
||||
+#include <asm/mipsmtregs.h>
|
||||
+
|
||||
+#define ENTER_CRITICAL(flags) \
|
||||
+ { \
|
||||
+ unsigned int mvpflags; \
|
||||
+ local_irq_save(flags);\
|
||||
+ mvpflags = dvpe()
|
||||
+#define EXIT_CRITICAL(flags) \
|
||||
+ evpe(mvpflags); \
|
||||
+ local_irq_restore(flags); \
|
||||
+ }
|
||||
+#else
|
||||
+
|
||||
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
|
||||
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
|
||||
+
|
||||
+#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
|
||||
|
||||
@@ -80,13 +108,184 @@ unsigned long setup_zero_pages(void)
|
||||
return 1UL << order;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_HIGHMEM
|
||||
-pte_t *kmap_pte;
|
||||
-pgprot_t kmap_prot;
|
||||
+/*
|
||||
+ * These are almost like kmap_atomic / kunmap_atmic except they take an
|
||||
+ * additional address argument as the hint.
|
||||
+ */
|
||||
|
||||
#define kmap_get_fixmap_pte(vaddr) \
|
||||
pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
|
||||
|
||||
+#ifdef CONFIG_MIPS_MT_SMTC
|
||||
+static pte_t *kmap_coherent_pte;
|
||||
+static void __init kmap_coherent_init(void)
|
||||
+{
|
||||
+ unsigned long vaddr;
|
||||
+
|
||||
+ /* cache the first coherent kmap pte */
|
||||
+ vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
|
||||
+ kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
|
||||
+}
|
||||
+#else
|
||||
+static inline void kmap_coherent_init(void) {}
|
||||
+#endif
|
||||
+
|
||||
+static inline void *kmap_coherent(struct page *page, unsigned long addr)
|
||||
+{
|
||||
+ enum fixed_addresses idx;
|
||||
+ unsigned long vaddr, flags, entrylo;
|
||||
+ unsigned long old_ctx;
|
||||
+ pte_t pte;
|
||||
+ int tlbidx;
|
||||
+
|
||||
+ inc_preempt_count();
|
||||
+ idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
|
||||
+#ifdef CONFIG_MIPS_MT_SMTC
|
||||
+ idx += FIX_N_COLOURS * smp_processor_id();
|
||||
+#endif
|
||||
+ vaddr = __fix_to_virt(FIX_CMAP_END - idx);
|
||||
+ pte = mk_pte(page, PAGE_KERNEL);
|
||||
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
|
||||
+ entrylo = pte.pte_high;
|
||||
+#else
|
||||
+ entrylo = pte_val(pte) >> 6;
|
||||
+#endif
|
||||
+
|
||||
+ ENTER_CRITICAL(flags);
|
||||
+ old_ctx = read_c0_entryhi();
|
||||
+ write_c0_entryhi(vaddr & (PAGE_MASK << 1));
|
||||
+ write_c0_entrylo0(entrylo);
|
||||
+ write_c0_entrylo1(entrylo);
|
||||
+#ifdef CONFIG_MIPS_MT_SMTC
|
||||
+ set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
|
||||
+ /* preload TLB instead of local_flush_tlb_one() */
|
||||
+ mtc0_tlbw_hazard();
|
||||
+ tlb_probe();
|
||||
+ BARRIER;
|
||||
+ tlbidx = read_c0_index();
|
||||
+ mtc0_tlbw_hazard();
|
||||
+ if (tlbidx < 0)
|
||||
+ tlb_write_random();
|
||||
+ else
|
||||
+ tlb_write_indexed();
|
||||
+#else
|
||||
+ tlbidx = read_c0_wired();
|
||||
+ write_c0_wired(tlbidx + 1);
|
||||
+ write_c0_index(tlbidx);
|
||||
+ mtc0_tlbw_hazard();
|
||||
+ tlb_write_indexed();
|
||||
+#endif
|
||||
+ tlbw_use_hazard();
|
||||
+ write_c0_entryhi(old_ctx);
|
||||
+ EXIT_CRITICAL(flags);
|
||||
+
|
||||
+ return (void*) vaddr;
|
||||
+}
|
||||
+
|
||||
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
|
||||
+
|
||||
+static inline void kunmap_coherent(struct page *page)
|
||||
+{
|
||||
+#ifndef CONFIG_MIPS_MT_SMTC
|
||||
+ unsigned int wired;
|
||||
+ unsigned long flags, old_ctx;
|
||||
+
|
||||
+ ENTER_CRITICAL(flags);
|
||||
+ old_ctx = read_c0_entryhi();
|
||||
+ wired = read_c0_wired() - 1;
|
||||
+ write_c0_wired(wired);
|
||||
+ write_c0_index(wired);
|
||||
+ write_c0_entryhi(UNIQUE_ENTRYHI(wired));
|
||||
+ write_c0_entrylo0(0);
|
||||
+ write_c0_entrylo1(0);
|
||||
+ mtc0_tlbw_hazard();
|
||||
+ tlb_write_indexed();
|
||||
+ tlbw_use_hazard();
|
||||
+ write_c0_entryhi(old_ctx);
|
||||
+ EXIT_CRITICAL(flags);
|
||||
+#endif
|
||||
+ dec_preempt_count();
|
||||
+ preempt_check_resched();
|
||||
+}
|
||||
+
|
||||
+void copy_user_highpage(struct page *to, struct page *from,
|
||||
+ unsigned long vaddr, struct vm_area_struct *vma)
|
||||
+{
|
||||
+ void *vfrom, *vto;
|
||||
+
|
||||
+ vto = kmap_atomic(to, KM_USER1);
|
||||
+ if (cpu_has_dc_aliases) {
|
||||
+ vfrom = kmap_coherent(from, vaddr);
|
||||
+ copy_page(vto, vfrom);
|
||||
+ kunmap_coherent(from);
|
||||
+ } else {
|
||||
+ vfrom = kmap_atomic(from, KM_USER0);
|
||||
+ copy_page(vto, vfrom);
|
||||
+ kunmap_atomic(vfrom, KM_USER0);
|
||||
+ }
|
||||
+ if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) ||
|
||||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
|
||||
+ flush_data_cache_page((unsigned long)vto);
|
||||
+ kunmap_atomic(vto, KM_USER1);
|
||||
+ /* Make sure this page is cleared on other CPU's too before using it */
|
||||
+ smp_wmb();
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(copy_user_highpage);
|
||||
+
|
||||
+void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
|
||||
+ struct page *to)
|
||||
+{
|
||||
+ if (cpu_has_dc_aliases) {
|
||||
+ struct page *from = virt_to_page(vfrom);
|
||||
+ vfrom = kmap_coherent(from, vaddr);
|
||||
+ copy_page(vto, vfrom);
|
||||
+ kunmap_coherent(from);
|
||||
+ } else
|
||||
+ copy_page(vto, vfrom);
|
||||
+ if (!cpu_has_ic_fills_f_dc ||
|
||||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
|
||||
+ flush_data_cache_page((unsigned long)vto);
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(copy_user_page);
|
||||
+
|
||||
+void copy_to_user_page(struct vm_area_struct *vma,
|
||||
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
+ unsigned long len)
|
||||
+{
|
||||
+ if (cpu_has_dc_aliases) {
|
||||
+ void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
|
||||
+ memcpy(vto, src, len);
|
||||
+ kunmap_coherent(page);
|
||||
+ } else
|
||||
+ memcpy(dst, src, len);
|
||||
+ if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
|
||||
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(copy_to_user_page);
|
||||
+
|
||||
+void copy_from_user_page(struct vm_area_struct *vma,
|
||||
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
+ unsigned long len)
|
||||
+{
|
||||
+ if (cpu_has_dc_aliases) {
|
||||
+ void *vfrom =
|
||||
+ kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
|
||||
+ memcpy(dst, vfrom, len);
|
||||
+ kunmap_coherent(page);
|
||||
+ } else
|
||||
+ memcpy(dst, src, len);
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(copy_from_user_page);
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_HIGHMEM
|
||||
+pte_t *kmap_pte;
|
||||
+pgprot_t kmap_prot;
|
||||
+
|
||||
static void __init kmap_init(void)
|
||||
{
|
||||
unsigned long kmap_vstart;
|
||||
@@ -97,11 +296,12 @@ static void __init kmap_init(void)
|
||||
|
||||
kmap_prot = PAGE_KERNEL;
|
||||
}
|
||||
+#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
-#ifdef CONFIG_32BIT
|
||||
void __init fixrange_init(unsigned long start, unsigned long end,
|
||||
pgd_t *pgd_base)
|
||||
{
|
||||
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
@@ -122,7 +322,7 @@ void __init fixrange_init(unsigned long
|
||||
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
- set_pmd(pmd, __pmd(pte));
|
||||
+ set_pmd(pmd, __pmd((unsigned long)pte));
|
||||
if (pte != pte_offset_kernel(pmd, 0))
|
||||
BUG();
|
||||
}
|
||||
@@ -132,9 +332,8 @@ void __init fixrange_init(unsigned long
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
-#endif /* CONFIG_32BIT */
|
||||
-#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
#ifndef CONFIG_NEED_MULTIPLE_NODES
|
||||
extern void pagetable_init(void);
|
||||
@@ -175,6 +374,7 @@ #endif
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
kmap_init();
|
||||
#endif
|
||||
+ kmap_coherent_init();
|
||||
|
||||
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
|
||||
low = max_low_pfn;
|
||||
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
|
||||
index 4bdaa05..4a61e62 100644
|
||||
--- a/arch/mips/mm/pgtable-32.c
|
||||
+++ b/arch/mips/mm/pgtable-32.c
|
||||
@@ -31,9 +31,10 @@ void pgd_init(unsigned long page)
|
||||
|
||||
void __init pagetable_init(void)
|
||||
{
|
||||
-#ifdef CONFIG_HIGHMEM
|
||||
unsigned long vaddr;
|
||||
- pgd_t *pgd, *pgd_base;
|
||||
+ pgd_t *pgd_base;
|
||||
+#ifdef CONFIG_HIGHMEM
|
||||
+ pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
@@ -44,7 +45,6 @@ #endif
|
||||
pgd_init((unsigned long)swapper_pg_dir
|
||||
+ sizeof(pgd_t) * USER_PTRS_PER_PGD);
|
||||
|
||||
-#ifdef CONFIG_HIGHMEM
|
||||
pgd_base = swapper_pg_dir;
|
||||
|
||||
/*
|
||||
@@ -53,6 +53,7 @@ #ifdef CONFIG_HIGHMEM
|
||||
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
|
||||
fixrange_init(vaddr, 0, pgd_base);
|
||||
|
||||
+#ifdef CONFIG_HIGHMEM
|
||||
/*
|
||||
* Permanent kmaps:
|
||||
*/
|
||||
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
|
||||
index 44b5e97..8d600d3 100644
|
||||
--- a/arch/mips/mm/pgtable-64.c
|
||||
+++ b/arch/mips/mm/pgtable-64.c
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/mm.h>
|
||||
+#include <asm/fixmap.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
void pgd_init(unsigned long page)
|
||||
@@ -52,7 +53,17 @@ void pmd_init(unsigned long addr, unsign
|
||||
|
||||
void __init pagetable_init(void)
|
||||
{
|
||||
+ unsigned long vaddr;
|
||||
+ pgd_t *pgd_base;
|
||||
+
|
||||
/* Initialize the entire pgd. */
|
||||
pgd_init((unsigned long)swapper_pg_dir);
|
||||
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
|
||||
+
|
||||
+ pgd_base = swapper_pg_dir;
|
||||
+ /*
|
||||
+ * Fixed mappings:
|
||||
+ */
|
||||
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
|
||||
+ fixrange_init(vaddr, 0, pgd_base);
|
||||
}
|
||||
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h
|
||||
index 47bc8f6..d10517c 100644
|
||||
--- a/include/asm-mips/cacheflush.h
|
||||
+++ b/include/asm-mips/cacheflush.h
|
||||
@@ -21,7 +21,6 @@ #include <asm/cpu-features.h>
|
||||
* - flush_cache_range(vma, start, end) flushes a range of pages
|
||||
* - flush_icache_range(start, end) flush a range of instructions
|
||||
* - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
|
||||
- * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
|
||||
*
|
||||
* MIPS specific flush operations:
|
||||
*
|
||||
@@ -39,7 +38,7 @@ extern void __flush_dcache_page(struct p
|
||||
|
||||
static inline void flush_dcache_page(struct page *page)
|
||||
{
|
||||
- if (cpu_has_dc_aliases)
|
||||
+ if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
|
||||
__flush_dcache_page(page);
|
||||
|
||||
}
|
||||
@@ -47,30 +46,24 @@ static inline void flush_dcache_page(str
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
|
||||
-extern void (*flush_icache_page)(struct vm_area_struct *vma,
|
||||
+extern void (*__flush_icache_page)(struct vm_area_struct *vma,
|
||||
struct page *page);
|
||||
+static inline void flush_icache_page(struct vm_area_struct *vma,
|
||||
+ struct page *page)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
extern void (*flush_icache_range)(unsigned long start, unsigned long end);
|
||||
#define flush_cache_vmap(start, end) flush_cache_all()
|
||||
#define flush_cache_vunmap(start, end) flush_cache_all()
|
||||
|
||||
-static inline void copy_to_user_page(struct vm_area_struct *vma,
|
||||
+extern void copy_to_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
- unsigned long len)
|
||||
-{
|
||||
- if (cpu_has_dc_aliases)
|
||||
- flush_cache_page(vma, vaddr, page_to_pfn(page));
|
||||
- memcpy(dst, src, len);
|
||||
- flush_icache_page(vma, page);
|
||||
-}
|
||||
+ unsigned long len);
|
||||
|
||||
-static inline void copy_from_user_page(struct vm_area_struct *vma,
|
||||
+extern void copy_from_user_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vaddr, void *dst, const void *src,
|
||||
- unsigned long len)
|
||||
-{
|
||||
- if (cpu_has_dc_aliases)
|
||||
- flush_cache_page(vma, vaddr, page_to_pfn(page));
|
||||
- memcpy(dst, src, len);
|
||||
-}
|
||||
+ unsigned long len);
|
||||
|
||||
extern void (*flush_cache_sigtramp)(unsigned long addr);
|
||||
extern void (*flush_icache_all)(void);
|
||||
diff --git a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h
|
||||
index 6959bdb..02c8a13 100644
|
||||
--- a/include/asm-mips/fixmap.h
|
||||
+++ b/include/asm-mips/fixmap.h
|
||||
@@ -45,8 +45,16 @@ #endif
|
||||
* fix-mapped?
|
||||
*/
|
||||
enum fixed_addresses {
|
||||
+#define FIX_N_COLOURS 8
|
||||
+ FIX_CMAP_BEGIN,
|
||||
+#ifdef CONFIG_MIPS_MT_SMTC
|
||||
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS),
|
||||
+#else
|
||||
+ FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
|
||||
+#endif
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
- FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
|
||||
+ /* reserved pte's for temporary kernel mappings */
|
||||
+ FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
|
||||
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
|
||||
#endif
|
||||
__end_of_fixed_addresses
|
||||
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
|
||||
index 219d359..67bea9e 100644
|
||||
--- a/include/asm-mips/page.h
|
||||
+++ b/include/asm-mips/page.h
|
||||
@@ -53,19 +53,17 @@ static inline void clear_user_page(void
|
||||
extern void (*flush_data_cache_page)(unsigned long addr);
|
||||
|
||||
clear_page(addr);
|
||||
- if (pages_do_alias((unsigned long) addr, vaddr))
|
||||
+ if (pages_do_alias((unsigned long) addr, vaddr & PAGE_MASK))
|
||||
flush_data_cache_page((unsigned long)addr);
|
||||
}
|
||||
|
||||
-static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
|
||||
- struct page *to)
|
||||
-{
|
||||
- extern void (*flush_data_cache_page)(unsigned long addr);
|
||||
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
|
||||
+ struct page *to);
|
||||
+struct vm_area_struct;
|
||||
+extern void copy_user_highpage(struct page *to, struct page *from,
|
||||
+ unsigned long vaddr, struct vm_area_struct *vma);
|
||||
|
||||
- copy_page(vto, vfrom);
|
||||
- if (pages_do_alias((unsigned long)vto, vaddr))
|
||||
- flush_data_cache_page((unsigned long)vto);
|
||||
-}
|
||||
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
|
||||
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
@@ -74,15 +72,17 @@ #ifdef CONFIG_64BIT_PHYS_ADDR
|
||||
#ifdef CONFIG_CPU_MIPS32
|
||||
typedef struct { unsigned long pte_low, pte_high; } pte_t;
|
||||
#define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
|
||||
+ #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
|
||||
#else
|
||||
typedef struct { unsigned long long pte; } pte_t;
|
||||
#define pte_val(x) ((x).pte)
|
||||
+ #define __pte(x) ((pte_t) { (x) } )
|
||||
#endif
|
||||
#else
|
||||
typedef struct { unsigned long pte; } pte_t;
|
||||
#define pte_val(x) ((x).pte)
|
||||
-#endif
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* For 3-level pagetables we defines these ourselves, for 2-level the
|
|
@ -0,0 +1,32 @@
|
|||
# Upstream status: in linux-mips tree; someone needs to figure out how to
|
||||
# integrate this into the Linux tree...
|
||||
|
||||
From: Maciej W. Rozycki <macro@linux-mips.org>
|
||||
|
||||
--- a/drivers/scsi/NCR53C9x.h 2006-03-05 20:35:04.000000000 +0100
|
||||
+++ b/drivers/scsi/NCR53C9x.h 2006-03-05 19:51:16.000000000 +0100
|
||||
@@ -145,12 +145,7 @@
|
||||
|
||||
#ifndef MULTIPLE_PAD_SIZES
|
||||
|
||||
-#ifdef CONFIG_CPU_HAS_WB
|
||||
-#include <asm/wbflush.h>
|
||||
-#define esp_write(__reg, __val) do{(__reg) = (__val); wbflush();} while(0)
|
||||
-#else
|
||||
-#define esp_write(__reg, __val) ((__reg) = (__val))
|
||||
-#endif
|
||||
+#define esp_write(__reg, __val) do{(__reg) = (__val); iob();} while(0)
|
||||
#define esp_read(__reg) (__reg)
|
||||
|
||||
struct ESP_regs {
|
||||
--- a/drivers/scsi/dec_esp.c
|
||||
+++ b/drivers/scsi/dec_esp.c
|
||||
@@ -230,7 +230,7 @@ static int dec_esp_detect(struct scsi_ho
|
||||
mem_start = get_tc_base_addr(slot);
|
||||
|
||||
/* Store base addr into esp struct */
|
||||
- esp->slot = CPHYSADDR(mem_start);
|
||||
+ esp->slot = mem_start;
|
||||
|
||||
esp->dregs = 0;
|
||||
esp->eregs = (void *)CKSEG1ADDR(mem_start +
|
|
@ -0,0 +1,197 @@
|
|||
# Upstream status: won't go into Linus' tree like this but is in the
|
||||
# linux-mips tree. The drivers/char serial drivers need to be converted to
|
||||
# real serial drivers in drivers/serial
|
||||
|
||||
# Author: Martin Michlmayr <tbm@cyrius.com>, mostly taken from the
|
||||
# linux-mips tree, with some updates by Maciej W. Rozycki.
|
||||
|
||||
|
||||
--- b/drivers/char/Kconfig~ 2006-05-25 12:51:58.000000000 +0200
|
||||
+++ b/drivers/char/Kconfig 2006-05-25 12:53:03.000000000 +0200
|
||||
@@ -362,6 +362,41 @@
|
||||
bool "Console on BCM1xxx DUART"
|
||||
depends on SIBYTE_SB1250_DUART
|
||||
|
||||
+config SERIAL_DEC
|
||||
+ bool "DECstation serial support"
|
||||
+ depends on MACH_DECSTATION
|
||||
+ default y
|
||||
+ help
|
||||
+ This selects whether you want to be asked about drivers for
|
||||
+ DECstation serial ports.
|
||||
+
|
||||
+ Note that the answer to this question won't directly affect the
|
||||
+ kernel: saying N will just cause the configurator to skip all
|
||||
+ the questions about DECstation serial ports.
|
||||
+
|
||||
+ If unsure, say Y.
|
||||
+
|
||||
+config SERIAL_DEC_CONSOLE
|
||||
+ bool "Support for console on a DECstation serial port"
|
||||
+ depends on SERIAL_DEC
|
||||
+ default y
|
||||
+ help
|
||||
+ If you say Y here, it will be possible to use a serial port as the
|
||||
+ system console (the system console is the device which receives all
|
||||
+ kernel messages and warnings and which allows logins in single user
|
||||
+ mode). Note that the firmware uses ttyS0 as the serial console on
|
||||
+ the Maxine and ttyS2 on the others.
|
||||
+
|
||||
+ If unsure, say Y.
|
||||
+
|
||||
+config ZS
|
||||
+ bool "Z85C30 Serial Support"
|
||||
+ depends on SERIAL_DEC
|
||||
+ default y
|
||||
+ help
|
||||
+ Documentation on the Zilog 85C350 serial communications controller
|
||||
+ is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>.
|
||||
+
|
||||
config QTRONIX_KEYBOARD
|
||||
bool "Enable Qtronix 990P Keyboard Support"
|
||||
depends on IT8712
|
||||
--- b/drivers/char/Makefile~ 2006-05-25 12:51:52.000000000 +0200
|
||||
+++ b/drivers/char/Makefile 2006-05-25 12:52:27.000000000 +0200
|
||||
@@ -50,6 +50,7 @@
|
||||
obj-$(CONFIG_VIOTAPE) += viotape.o
|
||||
obj-$(CONFIG_HVCS) += hvcs.o
|
||||
obj-$(CONFIG_SGI_MBCS) += mbcs.o
|
||||
+obj-$(CONFIG_SERIAL_DEC) += decserial.o
|
||||
|
||||
obj-$(CONFIG_PRINTER) += lp.o
|
||||
obj-$(CONFIG_TIPAR) += tipar.o
|
||||
--- a/drivers/char/decserial.c
|
||||
+++ b/drivers/char/decserial.c
|
||||
@@ -14,86 +14,84 @@
|
||||
* device. Added support for PROM console in drivers/char/tty_io.c
|
||||
* instead. Although it may work to enable more than one
|
||||
* console device I strongly recommend to use only one.
|
||||
+ *
|
||||
+ * Copyright (C) 2004 Maciej W. Rozycki
|
||||
*/
|
||||
|
||||
+#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
-#include <asm/dec/machtype.h>
|
||||
-
|
||||
-#ifdef CONFIG_ZS
|
||||
-extern int zs_init(void);
|
||||
-#endif
|
||||
|
||||
-#ifdef CONFIG_DZ
|
||||
-extern int dz_init(void);
|
||||
-#endif
|
||||
+#include <asm/dec/machtype.h>
|
||||
+#include <asm/dec/serial.h>
|
||||
|
||||
-#ifdef CONFIG_SERIAL_CONSOLE
|
||||
+extern int register_zs_hook(unsigned int channel,
|
||||
+ struct dec_serial_hook *hook);
|
||||
+extern int unregister_zs_hook(unsigned int channel);
|
||||
|
||||
+int register_dec_serial_hook(unsigned int channel,
|
||||
+ struct dec_serial_hook *hook)
|
||||
+{
|
||||
#ifdef CONFIG_ZS
|
||||
-extern void zs_serial_console_init(void);
|
||||
-#endif
|
||||
-
|
||||
-#ifdef CONFIG_DZ
|
||||
-extern void dz_serial_console_init(void);
|
||||
+ if (IOASIC)
|
||||
+ return register_zs_hook(channel, hook);
|
||||
#endif
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
+int unregister_dec_serial_hook(unsigned int channel)
|
||||
+{
|
||||
+#ifdef CONFIG_ZS
|
||||
+ if (IOASIC)
|
||||
+ return unregister_zs_hook(channel);
|
||||
#endif
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
-/* rs_init - starts up the serial interface -
|
||||
- handle normal case of starting up the serial interface */
|
||||
|
||||
-#ifdef CONFIG_SERIAL
|
||||
+extern int zs_init(void);
|
||||
+extern int dz_init(void);
|
||||
|
||||
+/*
|
||||
+ * rs_init - starts up the serial interface -
|
||||
+ * handle normal case of starting up the serial interface
|
||||
+ */
|
||||
int __init rs_init(void)
|
||||
{
|
||||
-
|
||||
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
|
||||
- if (IOASIC)
|
||||
- return zs_init();
|
||||
- else
|
||||
- return dz_init();
|
||||
-#else
|
||||
-
|
||||
#ifdef CONFIG_ZS
|
||||
- return zs_init();
|
||||
+ if (IOASIC)
|
||||
+ return zs_init();
|
||||
#endif
|
||||
-
|
||||
#ifdef CONFIG_DZ
|
||||
- return dz_init();
|
||||
-#endif
|
||||
-
|
||||
+ if (!IOASIC)
|
||||
+ return dz_init();
|
||||
#endif
|
||||
+ return -ENXIO;
|
||||
}
|
||||
|
||||
__initcall(rs_init);
|
||||
|
||||
-#endif
|
||||
|
||||
-#ifdef CONFIG_SERIAL_CONSOLE
|
||||
+#ifdef CONFIG_SERIAL_DEC_CONSOLE
|
||||
|
||||
-/* serial_console_init handles the special case of starting
|
||||
- * up the console on the serial port
|
||||
+extern void zs_serial_console_init(void);
|
||||
+extern void dz_serial_console_init(void);
|
||||
+
|
||||
+/*
|
||||
+ * dec_serial_console_init handles the special case of starting
|
||||
+ * up the console on the serial port
|
||||
*/
|
||||
-static int __init decserial_console_init(void)
|
||||
+static int __init dec_serial_console_init(void)
|
||||
{
|
||||
-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
|
||||
- if (IOASIC)
|
||||
- zs_serial_console_init();
|
||||
- else
|
||||
- dz_serial_console_init();
|
||||
-#else
|
||||
-
|
||||
#ifdef CONFIG_ZS
|
||||
- zs_serial_console_init();
|
||||
+ if (IOASIC)
|
||||
+ zs_serial_console_init();
|
||||
#endif
|
||||
-
|
||||
#ifdef CONFIG_DZ
|
||||
- dz_serial_console_init();
|
||||
-#endif
|
||||
-
|
||||
+ if (!IOASIC)
|
||||
+ dz_serial_console_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
-console_initcall(decserial_console_init);
|
||||
+console_initcall(dec_serial_console_init);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
# Cleanups for kernel header exports, from linux-mips.org 2.6.18-stable,
|
||||
# scheduled for mainline.
|
||||
|
||||
|
||||
diff --git a/include/asm-mips/Kbuild b/include/asm-mips/Kbuild
|
||||
index c68e168..7897f05 100644
|
||||
--- a/include/asm-mips/Kbuild
|
||||
+++ b/include/asm-mips/Kbuild
|
||||
@@ -1 +1,3 @@
|
||||
include include/asm-generic/Kbuild.asm
|
||||
+
|
||||
+header-y += cachectl.h sgidefs.h sysmips.h
|
||||
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h
|
||||
index 4113316..4fb0fc4 100644
|
||||
--- a/include/asm-mips/ptrace.h
|
||||
+++ b/include/asm-mips/ptrace.h
|
||||
@@ -10,8 +10,6 @@ #ifndef _ASM_PTRACE_H
|
||||
#define _ASM_PTRACE_H
|
||||
|
||||
|
||||
-#include <asm/isadep.h>
|
||||
-
|
||||
/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
|
||||
#define FPR_BASE 32
|
||||
#define PC 64
|
||||
@@ -73,6 +71,7 @@ #define PTRACE_GET_THREAD_AREA_3264 0xc4
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/linkage.h>
|
||||
+#include <asm/isadep.h>
|
||||
|
||||
/*
|
||||
* Does the process account for user or for system time?
|
||||
diff --git a/include/asm-mips/timex.h b/include/asm-mips/timex.h
|
||||
index 98aa737..b80de8e 100644
|
||||
--- a/include/asm-mips/timex.h
|
||||
+++ b/include/asm-mips/timex.h
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef _ASM_TIMEX_H
|
||||
#define _ASM_TIMEX_H
|
||||
|
||||
+#ifdef __KERNEL__
|
||||
+
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
/*
|
||||
@@ -51,4 +53,6 @@ static inline cycles_t get_cycles (void)
|
||||
return read_c0_count();
|
||||
}
|
||||
|
||||
+#endif /* __KERNEL__ */
|
||||
+
|
||||
#endif /* _ASM_TIMEX_H */
|
||||
diff --git a/include/asm-mips/user.h b/include/asm-mips/user.h
|
||||
index 89bf8b4..61f2a09 100644
|
||||
--- a/include/asm-mips/user.h
|
||||
+++ b/include/asm-mips/user.h
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef _ASM_USER_H
|
||||
#define _ASM_USER_H
|
||||
|
||||
+#ifdef __KERNEL__
|
||||
+
|
||||
#include <asm/page.h>
|
||||
#include <asm/reg.h>
|
||||
|
||||
@@ -55,4 +57,6 @@ #define HOST_TEXT_START_ADDR (u.start_co
|
||||
#define HOST_DATA_START_ADDR (u.start_data)
|
||||
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
|
||||
|
||||
+#endif /* __KERNEL__ */
|
||||
+
|
||||
#endif /* _ASM_USER_H */
|
|
@ -0,0 +1,22 @@
|
|||
# Upstream status: in linux-mips tree; someone needs to figure out how to
|
||||
# integrate this into the Linux tree...
|
||||
|
||||
--- a/drivers/serial/ip22zilog.c
|
||||
+++ b/drivers/serial/ip22zilog.c
|
||||
@@ -865,6 +865,7 @@ ip22zilog_set_termios(struct uart_port *
|
||||
up->cflag = termios->c_cflag;
|
||||
|
||||
ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
|
||||
+ uart_update_timeout(port, termios->c_cflag, baud);
|
||||
|
||||
spin_unlock_irqrestore(&up->port.lock, flags);
|
||||
}
|
||||
@@ -1026,6 +1027,8 @@ ip22serial_console_termios(struct consol
|
||||
}
|
||||
|
||||
con->cflag = cflag | CS8; /* 8N1 */
|
||||
+
|
||||
+ uart_update_timeout(&ip22zilog_port_table[con->index].port, cflag, baud);
|
||||
}
|
||||
|
||||
static int __init ip22zilog_console_setup(struct console *con, char *options)
|
|
@ -0,0 +1,24 @@
|
|||
Patch: change the name of the sb1250 DUART from duart to ttyS
|
||||
Needed for debian-installer
|
||||
Status: the sb1250_duart.c driver needs a completely re-write...
|
||||
|
||||
--- a/drivers/char/sb1250_duart.c~ 2006-09-05 15:04:15.015419723 +0200
|
||||
+++ b/drivers/char/sb1250_duart.c 2006-09-05 15:04:24.442152073 +0200
|
||||
@@ -762,7 +762,7 @@
|
||||
return -ENOMEM;
|
||||
|
||||
sb1250_duart_driver->owner = THIS_MODULE;
|
||||
- sb1250_duart_driver->name = "duart";
|
||||
+ sb1250_duart_driver->name = "ttyS";
|
||||
sb1250_duart_driver->major = TTY_MAJOR;
|
||||
sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE;
|
||||
sb1250_duart_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
@@ -891,7 +891,7 @@ #endif
|
||||
}
|
||||
|
||||
static struct console sb1250_ser_cons = {
|
||||
- .name = "duart",
|
||||
+ .name = "ttyS",
|
||||
.write = ser_console_write,
|
||||
.device = ser_console_device,
|
||||
.setup = ser_console_setup,
|
|
@ -0,0 +1,67 @@
|
|||
# Add missing cache flush, fixes hang on boot from PIO-driven devices,
|
||||
# proposed patch at linux-mips.org.
|
||||
#
|
||||
# Signed-off-by: Thiemo Seufer <ths@networkno.de>
|
||||
|
||||
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
|
||||
index 16bad7c..acae51c 100644
|
||||
--- a/arch/mips/mm/c-sb1.c
|
||||
+++ b/arch/mips/mm/c-sb1.c
|
||||
@@ -19,6 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
+#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/bootinfo.h>
|
||||
@@ -233,6 +234,25 @@ void sb1_flush_cache_page(struct vm_area
|
||||
__attribute__((alias("local_sb1_flush_cache_page")));
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_SMP
|
||||
+static void sb1_flush_cache_data_page_ipi(void *info)
|
||||
+{
|
||||
+ unsigned long start = (unsigned long)info;
|
||||
+
|
||||
+ __sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE);
|
||||
+}
|
||||
+
|
||||
+static void sb1_flush_cache_data_page(unsigned long addr)
|
||||
+{
|
||||
+ if (in_atomic())
|
||||
+ __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
|
||||
+ else
|
||||
+ on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1);
|
||||
+}
|
||||
+#else
|
||||
+void sb1_flush_cache_data_page(unsigned long)
|
||||
+ __attribute__((alias("local_sb1_flush_cache_data_page")));
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Invalidate all caches on this CPU
|
||||
@@ -504,7 +524,6 @@ static __init void probe_cache_sizes(voi
|
||||
void sb1_cache_init(void)
|
||||
{
|
||||
extern char except_vec2_sb1;
|
||||
- extern char handle_vec2_sb1;
|
||||
|
||||
/* Special cache error handler for SB1 */
|
||||
set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
|
||||
@@ -534,7 +553,7 @@ #endif
|
||||
|
||||
flush_cache_sigtramp = sb1_flush_cache_sigtramp;
|
||||
local_flush_data_cache_page = (void *) sb1_nop;
|
||||
- flush_data_cache_page = (void *) sb1_nop;
|
||||
+ flush_data_cache_page = sb1_flush_cache_data_page;
|
||||
|
||||
/* Full flush */
|
||||
__flush_cache_all = sb1___flush_cache_all;
|
||||
@@ -558,5 +577,5 @@ #endif
|
||||
:
|
||||
: "memory");
|
||||
|
||||
- flush_cache_all();
|
||||
+ local_sb1___flush_cache_all();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
# Fix broken interrupt routing for sb1, from linux-mips.org
|
||||
# 2.6.18-stable, also in kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
|
||||
index ed325f0..a0222fa 100644
|
||||
--- a/arch/mips/sibyte/bcm1480/irq.c
|
||||
+++ b/arch/mips/sibyte/bcm1480/irq.c
|
||||
@@ -469,21 +469,6 @@ void bcm1480_kgdb_interrupt(struct pt_re
|
||||
|
||||
#endif /* CONFIG_KGDB */
|
||||
|
||||
-static inline int dclz(unsigned long long x)
|
||||
-{
|
||||
- int lz;
|
||||
-
|
||||
- __asm__ (
|
||||
- " .set push \n"
|
||||
- " .set mips64 \n"
|
||||
- " dclz %0, %1 \n"
|
||||
- " .set pop \n"
|
||||
- : "=r" (lz)
|
||||
- : "r" (x));
|
||||
-
|
||||
- return lz;
|
||||
-}
|
||||
-
|
||||
extern void bcm1480_timer_interrupt(struct pt_regs *regs);
|
||||
extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
|
||||
extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
|
||||
@@ -536,9 +521,9 @@ #endif
|
||||
|
||||
if (mask_h) {
|
||||
if (mask_h ^ 1)
|
||||
- do_IRQ(63 - dclz(mask_h), regs);
|
||||
+ do_IRQ(fls64(mask_h) - 1, regs);
|
||||
else
|
||||
- do_IRQ(127 - dclz(mask_l), regs);
|
||||
+ do_IRQ(63 + fls64(mask_l), regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
|
||||
index 1de71ad..a451b4c 100644
|
||||
--- a/arch/mips/sibyte/sb1250/irq.c
|
||||
+++ b/arch/mips/sibyte/sb1250/irq.c
|
||||
@@ -419,21 +419,6 @@ static void sb1250_kgdb_interrupt(struct
|
||||
|
||||
#endif /* CONFIG_KGDB */
|
||||
|
||||
-static inline int dclz(unsigned long long x)
|
||||
-{
|
||||
- int lz;
|
||||
-
|
||||
- __asm__ (
|
||||
- " .set push \n"
|
||||
- " .set mips64 \n"
|
||||
- " dclz %0, %1 \n"
|
||||
- " .set pop \n"
|
||||
- : "=r" (lz)
|
||||
- : "r" (x));
|
||||
-
|
||||
- return lz;
|
||||
-}
|
||||
-
|
||||
extern void sb1250_timer_interrupt(struct pt_regs *regs);
|
||||
extern void sb1250_mailbox_interrupt(struct pt_regs *regs);
|
||||
extern void sb1250_kgdb_interrupt(struct pt_regs *regs);
|
||||
@@ -490,6 +475,6 @@ #endif
|
||||
mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
|
||||
R_IMR_INTERRUPT_STATUS_BASE)));
|
||||
if (mask)
|
||||
- do_IRQ(63 - dclz(mask), regs);
|
||||
+ do_IRQ(fls64(mask) - 1, regs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
# ioc3 driver checksumming fix, from linux-mips.org 2.6.18-stable,
|
||||
# scheduled for kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
|
||||
index a2bd811..778fbae 100644
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -467,25 +471,6 @@ config SGI_IOC3_ETH
|
||||
the Ethernet-HOWTO, available from
|
||||
<http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
-config SGI_IOC3_ETH_HW_RX_CSUM
|
||||
- bool "Receive hardware checksums"
|
||||
- depends on SGI_IOC3_ETH && INET
|
||||
- default y
|
||||
- help
|
||||
- The SGI IOC3 network adapter supports TCP and UDP checksums in
|
||||
- hardware to offload processing of these checksums from the CPU. At
|
||||
- the moment only acceleration of IPv4 is supported. This option
|
||||
- enables offloading for checksums on receive. If unsure, say Y.
|
||||
-
|
||||
-config SGI_IOC3_ETH_HW_TX_CSUM
|
||||
- bool "Transmit hardware checksums"
|
||||
- depends on SGI_IOC3_ETH && INET
|
||||
- default y
|
||||
- help
|
||||
- The SGI IOC3 network adapter supports TCP and UDP checksums in
|
||||
- hardware to offload processing of these checksums from the CPU. At
|
||||
- the moment only acceleration of IPv4 is supported. This option
|
||||
- enables offloading for checksums on transmit. If unsure, say Y.
|
||||
|
||||
config MIPS_SIM_NET
|
||||
tristate "MIPS simulator Network device (EXPERIMENTAL)"
|
||||
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
|
||||
index 68d8af7..9837213 100644
|
||||
--- a/drivers/net/ioc3-eth.c
|
||||
+++ b/drivers/net/ioc3-eth.c
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Driver for SGI's IOC3 based Ethernet cards as found in the PCI card.
|
||||
*
|
||||
- * Copyright (C) 1999, 2000, 2001, 2003 Ralf Baechle
|
||||
+ * Copyright (C) 1999, 2000, 01, 03, 06 Ralf Baechle
|
||||
* Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc.
|
||||
*
|
||||
* References:
|
||||
@@ -62,12 +62,7 @@ #include <asm/io.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/sn/types.h>
|
||||
-#include <asm/sn/sn0/addrs.h>
|
||||
-#include <asm/sn/sn0/hubni.h>
|
||||
-#include <asm/sn/sn0/hubio.h>
|
||||
-#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
-#include <asm/sn/sn0/ip27.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
|
||||
/*
|
||||
@@ -95,6 +90,9 @@ struct ioc3_private {
|
||||
u32 emcr, ehar_h, ehar_l;
|
||||
spinlock_t ioc3_lock;
|
||||
struct mii_if_info mii;
|
||||
+ unsigned long flags;
|
||||
+#define IOC3_FLAG_RX_CHECKSUMS 1
|
||||
+
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* Members used by autonegotiation */
|
||||
@@ -522,8 +520,6 @@ static struct net_device_stats *ioc3_get
|
||||
return &ip->stats;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM
|
||||
-
|
||||
static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len)
|
||||
{
|
||||
struct ethhdr *eh = eth_hdr(skb);
|
||||
@@ -591,7 +587,6 @@ static void ioc3_tcpudp_checksum(struct
|
||||
if (csum == 0xffff)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
-#endif /* CONFIG_SGI_IOC3_ETH_HW_RX_CSUM */
|
||||
|
||||
static inline void ioc3_rx(struct ioc3_private *ip)
|
||||
{
|
||||
@@ -626,9 +621,9 @@ static inline void ioc3_rx(struct ioc3_p
|
||||
goto next;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_SGI_IOC3_ETH_HW_RX_CSUM
|
||||
- ioc3_tcpudp_checksum(skb, w0 & ERXBUF_IPCKSUM_MASK,len);
|
||||
-#endif
|
||||
+ if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS))
|
||||
+ ioc3_tcpudp_checksum(skb,
|
||||
+ w0 & ERXBUF_IPCKSUM_MASK, len);
|
||||
|
||||
netif_rx(skb);
|
||||
|
||||
@@ -1289,9 +1284,7 @@ #endif
|
||||
dev->set_multicast_list = ioc3_set_multicast_list;
|
||||
dev->set_mac_address = ioc3_set_mac_address;
|
||||
dev->ethtool_ops = &ioc3_ethtool_ops;
|
||||
-#ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM
|
||||
dev->features = NETIF_F_IP_CSUM;
|
||||
-#endif
|
||||
|
||||
sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1);
|
||||
sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2);
|
||||
@@ -1378,7 +1371,6 @@ static int ioc3_start_xmit(struct sk_buf
|
||||
uint32_t w0 = 0;
|
||||
int produce;
|
||||
|
||||
-#ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM
|
||||
/*
|
||||
* IOC3 has a fairly simple minded checksumming hardware which simply
|
||||
* adds up the 1's complement checksum for the entire packet and
|
||||
@@ -1426,7 +1418,6 @@ #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM
|
||||
|
||||
w0 = ETXD_DOCHECKSUM | (csoff << ETXD_CHKOFF_SHIFT);
|
||||
}
|
||||
-#endif /* CONFIG_SGI_IOC3_ETH_HW_TX_CSUM */
|
||||
|
||||
spin_lock_irq(&ip->ioc3_lock);
|
||||
|
||||
@@ -1580,12 +1571,37 @@ static u32 ioc3_get_link(struct net_devi
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static u32 ioc3_get_rx_csum(struct net_device *dev)
|
||||
+{
|
||||
+ struct ioc3_private *ip = netdev_priv(dev);
|
||||
+
|
||||
+ return ip->flags & IOC3_FLAG_RX_CHECKSUMS;
|
||||
+}
|
||||
+
|
||||
+static int ioc3_set_rx_csum(struct net_device *dev, u32 data)
|
||||
+{
|
||||
+ struct ioc3_private *ip = netdev_priv(dev);
|
||||
+
|
||||
+ spin_lock_bh(&ip->ioc3_lock);
|
||||
+ if (data)
|
||||
+ ip->flags |= IOC3_FLAG_RX_CHECKSUMS;
|
||||
+ else
|
||||
+ ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS;
|
||||
+ spin_unlock_bh(&ip->ioc3_lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct ethtool_ops ioc3_ethtool_ops = {
|
||||
.get_drvinfo = ioc3_get_drvinfo,
|
||||
.get_settings = ioc3_get_settings,
|
||||
.set_settings = ioc3_set_settings,
|
||||
.nway_reset = ioc3_nway_reset,
|
||||
.get_link = ioc3_get_link,
|
||||
+ .get_rx_csum = ioc3_get_rx_csum,
|
||||
+ .set_rx_csum = ioc3_set_rx_csum,
|
||||
+ .get_tx_csum = ethtool_op_get_tx_csum,
|
||||
+ .set_tx_csum = ethtool_op_set_tx_csum
|
||||
};
|
||||
|
||||
static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|
@ -0,0 +1,78 @@
|
|||
# Fix signal handling, from linux-mips.org 2.6.18-stable, scheduled for
|
||||
# kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
|
||||
index 6b4d9be..b9d358e 100644
|
||||
--- a/arch/mips/kernel/signal.c
|
||||
+++ b/arch/mips/kernel/signal.c
|
||||
@@ -424,15 +424,11 @@ void do_signal(struct pt_regs *regs)
|
||||
if (!user_mode(regs))
|
||||
return;
|
||||
|
||||
- if (try_to_freeze())
|
||||
- goto no_signal;
|
||||
-
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else
|
||||
oldset = ¤t->blocked;
|
||||
|
||||
-
|
||||
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
|
||||
if (signr > 0) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
@@ -446,9 +442,10 @@ void do_signal(struct pt_regs *regs)
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
}
|
||||
+
|
||||
+ return;
|
||||
}
|
||||
|
||||
-no_signal:
|
||||
/*
|
||||
* Who's code doesn't conform to the restartable syscall convention
|
||||
* dies here!!! The li instruction, a single machine instruction,
|
||||
@@ -466,6 +463,7 @@ no_signal:
|
||||
regs->regs[7] = regs->regs[26];
|
||||
regs->cp0_epc -= 4;
|
||||
}
|
||||
+ regs->regs[0] = 0; /* Don't deal with this again. */
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
|
||||
index f32a229..c86a5dd 100644
|
||||
--- a/arch/mips/kernel/signal32.c
|
||||
+++ b/arch/mips/kernel/signal32.c
|
||||
@@ -815,9 +815,6 @@ void do_signal32(struct pt_regs *regs)
|
||||
if (!user_mode(regs))
|
||||
return;
|
||||
|
||||
- if (try_to_freeze())
|
||||
- goto no_signal;
|
||||
-
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
oldset = ¤t->saved_sigmask;
|
||||
else
|
||||
@@ -836,9 +833,10 @@ void do_signal32(struct pt_regs *regs)
|
||||
if (test_thread_flag(TIF_RESTORE_SIGMASK))
|
||||
clear_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
}
|
||||
+
|
||||
+ return;
|
||||
}
|
||||
|
||||
-no_signal:
|
||||
/*
|
||||
* Who's code doesn't conform to the restartable syscall convention
|
||||
* dies here!!! The li instruction, a single machine instruction,
|
||||
@@ -856,6 +854,7 @@ no_signal:
|
||||
regs->regs[7] = regs->regs[26];
|
||||
regs->cp0_epc -= 4;
|
||||
}
|
||||
+ regs->regs[0] = 0; /* Don't deal with this again. */
|
||||
}
|
||||
|
||||
/*
|
|
@ -0,0 +1,85 @@
|
|||
# Fix bringup of non-contiguous CPU topology, from linux-mips.org
|
||||
# 2.6.18-stable, scheduled for kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h
|
||||
index 896550b..d35c617 100644
|
||||
--- a/include/asm-mips/irq.h
|
||||
+++ b/include/asm-mips/irq.h
|
||||
@@ -76,8 +76,4 @@ extern int setup_irq_smtc(unsigned int i
|
||||
unsigned long hwmask);
|
||||
#endif /* CONFIG_MIPS_MT_SMTC */
|
||||
|
||||
-#ifdef CONFIG_SMP
|
||||
-#define ARCH_HAS_IRQ_PER_CPU
|
||||
-#endif
|
||||
-
|
||||
#endif /* _ASM_IRQ_H */
|
||||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
|
||||
index 330f6ab..96165d7 100644
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -614,6 +610,7 @@ config SGI_IP27
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
select SYS_SUPPORTS_NUMA
|
||||
+ select SYS_SUPPORTS_SMP
|
||||
help
|
||||
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
|
||||
workstations. To compile a Linux kernel that runs on these, say Y
|
||||
@@ -1649,9 +1648,7 @@ config GENERIC_IRQ_PROBE
|
||||
default y
|
||||
|
||||
config IRQ_PER_CPU
|
||||
- depends on SMP
|
||||
bool
|
||||
- default y
|
||||
|
||||
#
|
||||
# - Highmem only makes sense for the 32-bit kernel.
|
||||
@@ -1691,9 +1688,6 @@ config ARCH_DISCONTIGMEM_ENABLE
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
bool
|
||||
-
|
||||
-config ARCH_SPARSEMEM_ENABLE
|
||||
- bool
|
||||
select SPARSEMEM_STATIC
|
||||
|
||||
config NUMA
|
||||
@@ -1719,6 +1713,7 @@ source "mm/Kconfig"
|
||||
config SMP
|
||||
bool "Multi-Processing support"
|
||||
depends on SYS_SUPPORTS_SMP
|
||||
+ select IRQ_PER_CPU
|
||||
help
|
||||
This enables support for systems with more than one CPU. If you have
|
||||
a system with only one CPU, like most personal computers, say N. If
|
||||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
|
||||
index 2218958..1af3612 100644
|
||||
--- a/arch/mips/kernel/smp.c
|
||||
+++ b/arch/mips/kernel/smp.c
|
||||
@@ -467,14 +467,18 @@ static DEFINE_PER_CPU(struct cpu, cpu_de
|
||||
|
||||
static int __init topology_init(void)
|
||||
{
|
||||
- int cpu;
|
||||
- int ret;
|
||||
+ int i, ret;
|
||||
|
||||
- for_each_present_cpu(cpu) {
|
||||
- ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
|
||||
+#ifdef CONFIG_NUMA
|
||||
+ for_each_online_node(i)
|
||||
+ register_one_node(i);
|
||||
+#endif /* CONFIG_NUMA */
|
||||
+
|
||||
+ for_each_present_cpu(i) {
|
||||
+ ret = register_cpu(&per_cpu(cpu_devices, i), i);
|
||||
if (ret)
|
||||
printk(KERN_WARNING "topology_init: register_cpu %d "
|
||||
- "failed (%d)\n", cpu, ret);
|
||||
+ "failed (%d)\n", i, ret);
|
||||
}
|
||||
|
||||
return 0;
|
|
@ -0,0 +1,54 @@
|
|||
# Fix syscall wiring for n32 rt_sigqueueinfo, fix implementation of
|
||||
# sys_set_thread_area. Patch from linux-mips.org 2.6.18-stable,
|
||||
# scheduled for kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
|
||||
index 450ac59..dc500e2 100644
|
||||
--- a/arch/mips/kernel/linux32.c
|
||||
+++ b/arch/mips/kernel/linux32.c
|
||||
@@ -1296,9 +1296,3 @@ _sys32_clone(nabi_no_regargs struct pt_r
|
||||
return do_fork(clone_flags, newsp, ®s, 0,
|
||||
parent_tidptr, child_tidptr);
|
||||
}
|
||||
-
|
||||
-extern asmlinkage void sys_set_thread_area(u32 addr);
|
||||
-asmlinkage void sys32_set_thread_area(u32 addr)
|
||||
-{
|
||||
- sys_set_thread_area(AA(addr));
|
||||
-}
|
||||
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
|
||||
index 0721314..9951240 100644
|
||||
--- a/arch/mips/kernel/syscall.c
|
||||
+++ b/arch/mips/kernel/syscall.c
|
||||
@@ -263,7 +263,7 @@ asmlinkage int sys_olduname(struct oldol
|
||||
return error;
|
||||
}
|
||||
|
||||
-void sys_set_thread_area(unsigned long addr)
|
||||
+asmlinkage int sys_set_thread_area(unsigned long addr)
|
||||
{
|
||||
struct thread_info *ti = task_thread_info(current);
|
||||
|
||||
@@ -271,6 +271,8 @@ void sys_set_thread_area(unsigned long a
|
||||
|
||||
/* If some future MIPS implementation has this register in hardware,
|
||||
* we will need to update it here (and in context switches). */
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
|
||||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
|
||||
index 98abbc5..f25c2a2 100644
|
||||
--- a/arch/mips/kernel/scall64-n32.S
|
||||
+++ b/arch/mips/kernel/scall64-n32.S
|
||||
@@ -247,7 +247,7 @@ EXPORT(sysn32_call_table)
|
||||
PTR sys_capset
|
||||
PTR sys32_rt_sigpending /* 6125 */
|
||||
PTR compat_sys_rt_sigtimedwait
|
||||
- PTR sys_rt_sigqueueinfo
|
||||
+ PTR sys32_rt_sigqueueinfo
|
||||
PTR sysn32_rt_sigsuspend
|
||||
PTR sys32_sigaltstack
|
||||
PTR compat_sys_utime /* 6130 */
|
|
@ -0,0 +1,61 @@
|
|||
# Fix __raw_read_trylock implementaation for mips/mipsel, from
|
||||
# linux-mips.org 2.6.18-stable, scheduled for kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
|
||||
index 669b8e3..4c1a1b5 100644
|
||||
--- a/include/asm-mips/spinlock.h
|
||||
+++ b/include/asm-mips/spinlock.h
|
||||
@@ -239,7 +239,51 @@ static inline void __raw_write_unlock(ra
|
||||
: "memory");
|
||||
}
|
||||
|
||||
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
|
||||
+static inline int __raw_read_trylock(raw_rwlock_t *rw)
|
||||
+{
|
||||
+ unsigned int tmp;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (R10000_LLSC_WAR) {
|
||||
+ __asm__ __volatile__(
|
||||
+ " .set noreorder # __raw_read_trylock \n"
|
||||
+ " li %2, 0 \n"
|
||||
+ "1: ll %1, %3 \n"
|
||||
+ " bnez %1, 2f \n"
|
||||
+ " addu %1, 1 \n"
|
||||
+ " sc %1, %0 \n"
|
||||
+ " beqzl %1, 1b \n"
|
||||
+ " .set reorder \n"
|
||||
+#ifdef CONFIG_SMP
|
||||
+ " sync \n"
|
||||
+#endif
|
||||
+ " li %2, 1 \n"
|
||||
+ "2: \n"
|
||||
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
||||
+ : "m" (rw->lock)
|
||||
+ : "memory");
|
||||
+ } else {
|
||||
+ __asm__ __volatile__(
|
||||
+ " .set noreorder # __raw_read_trylock \n"
|
||||
+ " li %2, 0 \n"
|
||||
+ "1: ll %1, %3 \n"
|
||||
+ " bnez %1, 2f \n"
|
||||
+ " addu %1, 1 \n"
|
||||
+ " sc %1, %0 \n"
|
||||
+ " beqz %1, 1b \n"
|
||||
+ " .set reorder \n"
|
||||
+#ifdef CONFIG_SMP
|
||||
+ " sync \n"
|
||||
+#endif
|
||||
+ " li %2, 1 \n"
|
||||
+ "2: \n"
|
||||
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
|
||||
+ : "m" (rw->lock)
|
||||
+ : "memory");
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
static inline int __raw_write_trylock(raw_rwlock_t *rw)
|
||||
{
|
|
@ -0,0 +1,118 @@
|
|||
# Fix race condition of wait with enabled interrupts, from linux-mips.org
|
||||
# 2.6.18-stable, also in kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
|
||||
index aa2caa6..8485af3 100644
|
||||
--- a/arch/mips/kernel/cpu-probe.c
|
||||
+++ b/arch/mips/kernel/cpu-probe.c
|
||||
@@ -38,15 +38,40 @@ static void r3081_wait(void)
|
||||
|
||||
static void r39xx_wait(void)
|
||||
{
|
||||
- unsigned long cfg = read_c0_conf();
|
||||
- write_c0_conf(cfg | TX39_CONF_HALT);
|
||||
+ local_irq_disable();
|
||||
+ if (!need_resched())
|
||||
+ write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
|
||||
+ local_irq_enable();
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * There is a race when WAIT instruction executed with interrupt
|
||||
+ * enabled.
|
||||
+ * But it is implementation-dependent wheter the pipelie restarts when
|
||||
+ * a non-enabled interrupt is requested.
|
||||
+ */
|
||||
static void r4k_wait(void)
|
||||
{
|
||||
- __asm__(".set\tmips3\n\t"
|
||||
- "wait\n\t"
|
||||
- ".set\tmips0");
|
||||
+ __asm__(" .set mips3 \n"
|
||||
+ " wait \n"
|
||||
+ " .set mips0 \n");
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This variant is preferable as it allows testing need_resched and going to
|
||||
+ * sleep depending on the outcome atomically. Unfortunately the "It is
|
||||
+ * implementation-dependent whether the pipeline restarts when a non-enabled
|
||||
+ * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
|
||||
+ * using this version a gamble.
|
||||
+ */
|
||||
+static void r4k_wait_irqoff(void)
|
||||
+{
|
||||
+ local_irq_disable();
|
||||
+ if (!need_resched())
|
||||
+ __asm__(" .set mips3 \n"
|
||||
+ " wait \n"
|
||||
+ " .set mips0 \n");
|
||||
+ local_irq_enable();
|
||||
}
|
||||
|
||||
/* The Au1xxx wait is available only if using 32khz counter or
|
||||
@@ -56,17 +81,17 @@ int allow_au1k_wait;
|
||||
static void au1k_wait(void)
|
||||
{
|
||||
/* using the wait instruction makes CP0 counter unusable */
|
||||
- __asm__(".set mips3\n\t"
|
||||
- "cache 0x14, 0(%0)\n\t"
|
||||
- "cache 0x14, 32(%0)\n\t"
|
||||
- "sync\n\t"
|
||||
- "nop\n\t"
|
||||
- "wait\n\t"
|
||||
- "nop\n\t"
|
||||
- "nop\n\t"
|
||||
- "nop\n\t"
|
||||
- "nop\n\t"
|
||||
- ".set mips0\n\t"
|
||||
+ __asm__(" .set mips3 \n"
|
||||
+ " cache 0x14, 0(%0) \n"
|
||||
+ " cache 0x14, 32(%0) \n"
|
||||
+ " sync \n"
|
||||
+ " nop \n"
|
||||
+ " wait \n"
|
||||
+ " nop \n"
|
||||
+ " nop \n"
|
||||
+ " nop \n"
|
||||
+ " nop \n"
|
||||
+ " .set mips0 \n"
|
||||
: : "r" (au1k_wait));
|
||||
}
|
||||
|
||||
@@ -110,8 +135,6 @@ static inline void check_wait(void)
|
||||
case CPU_R5000:
|
||||
case CPU_NEVADA:
|
||||
case CPU_RM7000:
|
||||
- case CPU_RM9000:
|
||||
- case CPU_TX49XX:
|
||||
case CPU_4KC:
|
||||
case CPU_4KEC:
|
||||
case CPU_4KSC:
|
||||
@@ -125,6 +148,10 @@ static inline void check_wait(void)
|
||||
cpu_wait = r4k_wait;
|
||||
printk(" available.\n");
|
||||
break;
|
||||
+ case CPU_TX49XX:
|
||||
+ cpu_wait = r4k_wait_irqoff;
|
||||
+ printk(" available.\n");
|
||||
+ break;
|
||||
case CPU_AU1000:
|
||||
case CPU_AU1100:
|
||||
case CPU_AU1500:
|
||||
@@ -136,6 +163,14 @@ static inline void check_wait(void)
|
||||
} else
|
||||
printk(" unavailable.\n");
|
||||
break;
|
||||
+ case CPU_RM9000:
|
||||
+ if ((c->processor_id & 0x00ff) >= 0x40) {
|
||||
+ cpu_wait = r4k_wait;
|
||||
+ printk(" available.\n");
|
||||
+ } else {
|
||||
+ printk(" unavailable.\n");
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
printk(" unavailable.\n");
|
||||
break;
|
|
@ -0,0 +1,401 @@
|
|||
# Kernel backtraces for mips/mipsel, from linux-mips.org 2.6.18-stable,
|
||||
# in kernel.org mainline.
|
||||
|
||||
|
||||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
|
||||
index 7ab67f7..951bf9c 100644
|
||||
--- a/arch/mips/kernel/process.c
|
||||
+++ b/arch/mips/kernel/process.c
|
||||
@@ -281,62 +281,63 @@ static struct mips_frame_info {
|
||||
} *schedule_frame, mfinfo[64];
|
||||
static int mfinfo_num;
|
||||
|
||||
-static int __init get_frame_info(struct mips_frame_info *info)
|
||||
+static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
{
|
||||
- int i;
|
||||
- void *func = info->func;
|
||||
- union mips_instruction *ip = (union mips_instruction *)func;
|
||||
+ /* sw / sd $ra, offset($sp) */
|
||||
+ return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
+ ip->i_format.rs == 29 &&
|
||||
+ ip->i_format.rt == 31;
|
||||
+}
|
||||
+
|
||||
+static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
|
||||
+{
|
||||
+ if (ip->j_format.opcode == jal_op)
|
||||
+ return 1;
|
||||
+ if (ip->r_format.opcode != spec_op)
|
||||
+ return 0;
|
||||
+ return ip->r_format.func == jalr_op || ip->r_format.func == jr_op;
|
||||
+}
|
||||
+
|
||||
+static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
+{
|
||||
+ /* addiu/daddiu sp,sp,-imm */
|
||||
+ if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
|
||||
+ return 0;
|
||||
+ if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int get_frame_info(struct mips_frame_info *info)
|
||||
+{
|
||||
+ union mips_instruction *ip = info->func;
|
||||
+ int i, max_insns =
|
||||
+ min(128UL, info->func_size / sizeof(union mips_instruction));
|
||||
+
|
||||
info->pc_offset = -1;
|
||||
info->frame_size = 0;
|
||||
- for (i = 0; i < 128; i++, ip++) {
|
||||
- /* if jal, jalr, jr, stop. */
|
||||
- if (ip->j_format.opcode == jal_op ||
|
||||
- (ip->r_format.opcode == spec_op &&
|
||||
- (ip->r_format.func == jalr_op ||
|
||||
- ip->r_format.func == jr_op)))
|
||||
- break;
|
||||
|
||||
- if (info->func_size && i >= info->func_size / 4)
|
||||
+ for (i = 0; i < max_insns; i++, ip++) {
|
||||
+
|
||||
+ if (is_jal_jalr_jr_ins(ip))
|
||||
break;
|
||||
- if (
|
||||
-#ifdef CONFIG_32BIT
|
||||
- ip->i_format.opcode == addiu_op &&
|
||||
-#endif
|
||||
-#ifdef CONFIG_64BIT
|
||||
- ip->i_format.opcode == daddiu_op &&
|
||||
-#endif
|
||||
- ip->i_format.rs == 29 &&
|
||||
- ip->i_format.rt == 29) {
|
||||
- /* addiu/daddiu sp,sp,-imm */
|
||||
- if (info->frame_size)
|
||||
- continue;
|
||||
- info->frame_size = - ip->i_format.simmediate;
|
||||
+ if (!info->frame_size) {
|
||||
+ if (is_sp_move_ins(ip))
|
||||
+ info->frame_size = - ip->i_format.simmediate;
|
||||
+ continue;
|
||||
}
|
||||
-
|
||||
- if (
|
||||
-#ifdef CONFIG_32BIT
|
||||
- ip->i_format.opcode == sw_op &&
|
||||
-#endif
|
||||
-#ifdef CONFIG_64BIT
|
||||
- ip->i_format.opcode == sd_op &&
|
||||
-#endif
|
||||
- ip->i_format.rs == 29 &&
|
||||
- ip->i_format.rt == 31) {
|
||||
- /* sw / sd $ra, offset($sp) */
|
||||
- if (info->pc_offset != -1)
|
||||
- continue;
|
||||
+ if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
|
||||
info->pc_offset =
|
||||
ip->i_format.simmediate / sizeof(long);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
- if (info->pc_offset == -1 || info->frame_size == 0) {
|
||||
- if (func == schedule)
|
||||
- printk("Can't analyze prologue code at %p\n", func);
|
||||
- info->pc_offset = -1;
|
||||
- info->frame_size = 0;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
+ if (info->frame_size && info->pc_offset >= 0) /* nested */
|
||||
+ return 0;
|
||||
+ if (info->pc_offset < 0) /* leaf */
|
||||
+ return 1;
|
||||
+ /* prologue seems boggus... */
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
static int __init frame_info_init(void)
|
||||
@@ -368,7 +369,14 @@ #else
|
||||
schedule_frame = &mfinfo[0];
|
||||
#endif
|
||||
for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++)
|
||||
- get_frame_info(&mfinfo[i]);
|
||||
+ get_frame_info(mfinfo + i);
|
||||
+
|
||||
+ /*
|
||||
+ * Without schedule() frame info, result given by
|
||||
+ * thread_saved_pc() and get_wchan() are not reliable.
|
||||
+ */
|
||||
+ if (schedule_frame->pc_offset < 0)
|
||||
+ printk("Can't analyze schedule() prologue at %p\n", schedule);
|
||||
|
||||
mfinfo_num = i;
|
||||
return 0;
|
||||
@@ -427,6 +435,8 @@ #ifdef CONFIG_KALLSYMS
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
+ if (mfinfo[i].pc_offset < 0)
|
||||
+ break;
|
||||
pc = ((unsigned long *)frame)[mfinfo[i].pc_offset];
|
||||
if (!mfinfo[i].frame_size)
|
||||
break;
|
||||
@@ -437,3 +447,49 @@ #endif
|
||||
return pc;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+/* used by show_backtrace() */
|
||||
+unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
|
||||
+ unsigned long pc, unsigned long ra)
|
||||
+{
|
||||
+ unsigned long stack_page;
|
||||
+ struct mips_frame_info info;
|
||||
+ char *modname;
|
||||
+ char namebuf[KSYM_NAME_LEN + 1];
|
||||
+ unsigned long size, ofs;
|
||||
+ int leaf;
|
||||
+
|
||||
+ stack_page = (unsigned long)task_stack_page(task);
|
||||
+ if (!stack_page)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
|
||||
+ return 0;
|
||||
+ if (ofs == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ info.func = (void *)(pc - ofs);
|
||||
+ info.func_size = ofs; /* analyze from start to ofs */
|
||||
+ leaf = get_frame_info(&info);
|
||||
+ if (leaf < 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (*sp < stack_page ||
|
||||
+ *sp + info.frame_size > stack_page + THREAD_SIZE - 32)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (leaf)
|
||||
+ /*
|
||||
+ * For some extreme cases, get_frame_info() can
|
||||
+ * consider wrongly a nested function as a leaf
|
||||
+ * one. In that cases avoid to return always the
|
||||
+ * same value.
|
||||
+ */
|
||||
+ pc = pc != ra ? ra : 0;
|
||||
+ else
|
||||
+ pc = ((unsigned long *)(*sp))[info.pc_offset];
|
||||
+
|
||||
+ *sp += info.frame_size;
|
||||
+ return __kernel_text_address(pc) ? pc : 0;
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
|
||||
index 954a198..e51d8fd 100644
|
||||
--- a/arch/mips/kernel/traps.c
|
||||
+++ b/arch/mips/kernel/traps.c
|
||||
@@ -20,6 +20,7 @@ #include <linux/smp_lock.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/bootmem.h>
|
||||
+#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/branch.h>
|
||||
@@ -72,28 +73,68 @@ void (*board_nmi_handler_setup)(void);
|
||||
void (*board_ejtag_handler_setup)(void);
|
||||
void (*board_bind_eic_interrupt)(int irq, int regset);
|
||||
|
||||
-/*
|
||||
- * These constant is for searching for possible module text segments.
|
||||
- * MODULE_RANGE is a guess of how much space is likely to be vmalloced.
|
||||
- */
|
||||
-#define MODULE_RANGE (8*1024*1024)
|
||||
+
|
||||
+static void show_raw_backtrace(unsigned long reg29)
|
||||
+{
|
||||
+ unsigned long *sp = (unsigned long *)reg29;
|
||||
+ unsigned long addr;
|
||||
+
|
||||
+ printk("Call Trace:");
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+ printk("\n");
|
||||
+#endif
|
||||
+ while (!kstack_end(sp)) {
|
||||
+ addr = *sp++;
|
||||
+ if (__kernel_text_address(addr))
|
||||
+ print_ip_sym(addr);
|
||||
+ }
|
||||
+ printk("\n");
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_KALLSYMS
|
||||
+static int raw_show_trace;
|
||||
+static int __init set_raw_show_trace(char *str)
|
||||
+{
|
||||
+ raw_show_trace = 1;
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("raw_show_trace", set_raw_show_trace);
|
||||
+
|
||||
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
|
||||
+ unsigned long pc, unsigned long ra);
|
||||
+
|
||||
+static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
|
||||
+{
|
||||
+ unsigned long sp = regs->regs[29];
|
||||
+ unsigned long ra = regs->regs[31];
|
||||
+ unsigned long pc = regs->cp0_epc;
|
||||
+
|
||||
+ if (raw_show_trace || !__kernel_text_address(pc)) {
|
||||
+ show_raw_backtrace(sp);
|
||||
+ return;
|
||||
+ }
|
||||
+ printk("Call Trace:\n");
|
||||
+ do {
|
||||
+ print_ip_sym(pc);
|
||||
+ pc = unwind_stack(task, &sp, pc, ra);
|
||||
+ ra = 0;
|
||||
+ } while (pc);
|
||||
+ printk("\n");
|
||||
+}
|
||||
+#else
|
||||
+#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* This routine abuses get_user()/put_user() to reference pointers
|
||||
* with at least a bit of error checking ...
|
||||
*/
|
||||
-void show_stack(struct task_struct *task, unsigned long *sp)
|
||||
+static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
|
||||
{
|
||||
const int field = 2 * sizeof(unsigned long);
|
||||
long stackdata;
|
||||
int i;
|
||||
-
|
||||
- if (!sp) {
|
||||
- if (task && task != current)
|
||||
- sp = (unsigned long *) task->thread.reg29;
|
||||
- else
|
||||
- sp = (unsigned long *) &sp;
|
||||
- }
|
||||
+ unsigned long *sp = (unsigned long *)regs->regs[29];
|
||||
|
||||
printk("Stack :");
|
||||
i = 0;
|
||||
@@ -114,32 +155,48 @@ void show_stack(struct task_struct *task
|
||||
i++;
|
||||
}
|
||||
printk("\n");
|
||||
+ show_backtrace(task, regs);
|
||||
}
|
||||
|
||||
-void show_trace(struct task_struct *task, unsigned long *stack)
|
||||
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
|
||||
{
|
||||
- const int field = 2 * sizeof(unsigned long);
|
||||
- unsigned long addr;
|
||||
-
|
||||
- if (!stack) {
|
||||
- if (task && task != current)
|
||||
- stack = (unsigned long *) task->thread.reg29;
|
||||
- else
|
||||
- stack = (unsigned long *) &stack;
|
||||
- }
|
||||
-
|
||||
- printk("Call Trace:");
|
||||
-#ifdef CONFIG_KALLSYMS
|
||||
- printk("\n");
|
||||
+ __asm__ __volatile__(
|
||||
+ ".set push\n\t"
|
||||
+ ".set noat\n\t"
|
||||
+#ifdef CONFIG_64BIT
|
||||
+ "1: dla $1, 1b\n\t"
|
||||
+ "sd $1, %0\n\t"
|
||||
+ "sd $29, %1\n\t"
|
||||
+ "sd $31, %2\n\t"
|
||||
+#else
|
||||
+ "1: la $1, 1b\n\t"
|
||||
+ "sw $1, %0\n\t"
|
||||
+ "sw $29, %1\n\t"
|
||||
+ "sw $31, %2\n\t"
|
||||
#endif
|
||||
- while (!kstack_end(stack)) {
|
||||
- addr = *stack++;
|
||||
- if (__kernel_text_address(addr)) {
|
||||
- printk(" [<%0*lx>] ", field, addr);
|
||||
- print_symbol("%s\n", addr);
|
||||
+ ".set pop\n\t"
|
||||
+ : "=m" (regs->cp0_epc),
|
||||
+ "=m" (regs->regs[29]), "=m" (regs->regs[31])
|
||||
+ : : "memory");
|
||||
+}
|
||||
+
|
||||
+void show_stack(struct task_struct *task, unsigned long *sp)
|
||||
+{
|
||||
+ struct pt_regs regs;
|
||||
+ if (sp) {
|
||||
+ regs.regs[29] = (unsigned long)sp;
|
||||
+ regs.regs[31] = 0;
|
||||
+ regs.cp0_epc = 0;
|
||||
+ } else {
|
||||
+ if (task && task != current) {
|
||||
+ regs.regs[29] = task->thread.reg29;
|
||||
+ regs.regs[31] = 0;
|
||||
+ regs.cp0_epc = task->thread.reg31;
|
||||
+ } else {
|
||||
+ prepare_frametrace(®s);
|
||||
}
|
||||
}
|
||||
- printk("\n");
|
||||
+ show_stacktrace(task, ®s);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -147,9 +204,15 @@ #endif
|
||||
*/
|
||||
void dump_stack(void)
|
||||
{
|
||||
- unsigned long stack;
|
||||
+ struct pt_regs regs;
|
||||
|
||||
- show_trace(current, &stack);
|
||||
+ /*
|
||||
+ * Remove any garbage that may be in regs (specially func
|
||||
+ * addresses) to avoid show_raw_backtrace() to report them
|
||||
+ */
|
||||
+ memset(®s, 0, sizeof(regs));
|
||||
+ prepare_frametrace(®s);
|
||||
+ show_backtrace(current, ®s);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
@@ -268,8 +331,7 @@ void show_registers(struct pt_regs *regs
|
||||
print_modules();
|
||||
printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
|
||||
current->comm, current->pid, current_thread_info(), current);
|
||||
- show_stack(current, (long *) regs->regs[29]);
|
||||
- show_trace(current, (long *) regs->regs[29]);
|
||||
+ show_stacktrace(current, regs);
|
||||
show_code((unsigned int *) regs->cp0_epc);
|
||||
printk("\n");
|
||||
}
|
||||
@@ -292,6 +354,16 @@ #endif /* CONFIG_MIPS_MT_SMTC */
|
||||
printk("%s[#%d]:\n", str, ++die_counter);
|
||||
show_registers(regs);
|
||||
spin_unlock_irq(&die_lock);
|
||||
+
|
||||
+ if (in_interrupt())
|
||||
+ panic("Fatal exception in interrupt");
|
||||
+
|
||||
+ if (panic_on_oops) {
|
||||
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
|
||||
+ ssleep(5);
|
||||
+ panic("Fatal exception");
|
||||
+ }
|
||||
+
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
# Qemu kernel config for mips/mipsel, from linux-mips.org 2.6.18-stable,
|
||||
# some initialization bits should eventually happen in qemu BIOS.
|
||||
|
||||
|
||||
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
|
||||
index 078cd30..493259c 100644
|
||||
--- a/arch/mips/qemu/Makefile
|
||||
+++ b/arch/mips/qemu/Makefile
|
||||
@@ -4,4 +4,5 @@ #
|
||||
|
||||
obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o q-reset.o
|
||||
|
||||
+obj-$(CONFIG_VT) += q-vga.o
|
||||
obj-$(CONFIG_SMP) += q-smp.o
|
||||
diff --git a/arch/mips/qemu/q-setup.c b/arch/mips/qemu/q-setup.c
|
||||
index 8413943..37c2f73 100644
|
||||
--- a/arch/mips/qemu/q-setup.c
|
||||
+++ b/arch/mips/qemu/q-setup.c
|
||||
@@ -2,6 +2,7 @@ #include <linux/init.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
+extern void qvga_init(void);
|
||||
extern void qemu_reboot_setup(void);
|
||||
|
||||
#define QEMU_PORT_BASE 0xb4000000
|
||||
@@ -23,5 +24,9 @@ void __init plat_timer_setup(struct irqa
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
set_io_port_base(QEMU_PORT_BASE);
|
||||
+#ifdef CONFIG_VT
|
||||
+ qvga_init();
|
||||
+#endif
|
||||
+
|
||||
qemu_reboot_setup();
|
||||
}
|
||||
diff --git a/arch/mips/qemu/q-vga.c b/arch/mips/qemu/q-vga.c
|
||||
new file mode 100644
|
||||
index 0000000..e26109a
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/qemu/q-vga.c
|
||||
@@ -0,0 +1,189 @@
|
||||
+/*
|
||||
+ * 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.
|
||||
+ *
|
||||
+ * Copyright (C) 2005 by Ralf Baechle (ralf@linux-mips.org)
|
||||
+ *
|
||||
+ * This will eventually go into the qemu firmware.
|
||||
+ */
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/screen_info.h>
|
||||
+#include <linux/tty.h>
|
||||
+#include <asm/io.h>
|
||||
+#include <video/vga.h>
|
||||
+
|
||||
+/*
|
||||
+ * This will eventually be done by the firmware; right now Linux assumes to
|
||||
+ * run on the uninitialized hardware.
|
||||
+ */
|
||||
+#undef LOAD_VGA_FONT
|
||||
+
|
||||
+static unsigned char sr[8] __initdata = { /* Sequencer */
|
||||
+ 0x03, 0x00, 0x03, 0x04, 0x02, 0x00, 0x00, 0x00
|
||||
+};
|
||||
+
|
||||
+static unsigned char gr[16] __initdata= { /* Graphics Controller */
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
|
||||
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
+};
|
||||
+
|
||||
+static unsigned char ar[21] __initdata= { /* Attribute Controller */
|
||||
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
+ 0x0c, 0x01, 0x07, 0x13, 0x00
|
||||
+};
|
||||
+
|
||||
+static unsigned char cr[32] __initdata= { /* CRT Controller */
|
||||
+ 0x91, 0x4f, 0x4f, 0x95, 0x57, 0x4f, 0xc0, 0x1f,
|
||||
+ 0x00, 0x4f, 0x0d, 0x0e, 0x02, 0x30, 0x09, 0xb0,
|
||||
+ 0x90, 0x83, 0x8f, 0x28, 0x1f, 0x8f, 0xc1, 0xa3,
|
||||
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
+};
|
||||
+
|
||||
+static struct rgb {
|
||||
+ unsigned char r;
|
||||
+ unsigned char g;
|
||||
+ unsigned char b;
|
||||
+} palette[16] __initdata= {
|
||||
+ [ 0] = {0x00, 0x00, 0x00},
|
||||
+ [ 1] = {0x00, 0x00, 0x2a},
|
||||
+ [ 2] = {0x00, 0x2a, 0x00},
|
||||
+ [ 3] = {0x00, 0x2a, 0x2a},
|
||||
+ [ 4] = {0x2a, 0x00, 0x00},
|
||||
+ [ 5] = {0x2a, 0x00, 0x2a},
|
||||
+ [ 6] = {0x2a, 0x15, 0x00},
|
||||
+ [ 7] = {0x2a, 0x2a, 0x2a},
|
||||
+ [ 8] = {0x15, 0x15, 0x15},
|
||||
+ [ 9] = {0x15, 0x15, 0x3f},
|
||||
+ [10] = {0x15, 0x3f, 0x15},
|
||||
+ [11] = {0x15, 0x3f, 0x3f},
|
||||
+ [12] = {0x3f, 0x15, 0x15},
|
||||
+ [13] = {0x3f, 0x15, 0x3f},
|
||||
+ [14] = {0x3f, 0x3f, 0x15},
|
||||
+ [15] = {0x3f, 0x3f, 0x3f}
|
||||
+
|
||||
+};
|
||||
+
|
||||
+void __init qvga_init_ibm(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < 8; i++) { /* Sequencer registers */
|
||||
+ outb(i, 0x3c4);
|
||||
+ outb(sr[i], 0x3c5);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 16; i++) { /* Graphics Controller registers */
|
||||
+ outb(i, 0x3ce);
|
||||
+ outb(gr[i], 0x3cf);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 21; i++) { /* Attribute Controller registers */
|
||||
+ outb(i, 0x3c0);
|
||||
+ outb(ar[i], 0x3c1);
|
||||
+ }
|
||||
+ outb(0x20, 0x3c0); /* enable bit in *index* register */
|
||||
+
|
||||
+ for (i = 0; i < 32; i++) { /* CRT Controller registers */
|
||||
+ outb(i, 0x3d4);
|
||||
+ outb(cr[i], 0x3d5);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 16; i++) { /* palette */
|
||||
+ outb(i, 0x3c8);
|
||||
+ outb(palette[i].r, 0x3c9);
|
||||
+ outb(palette[i].g, 0x3c9);
|
||||
+ outb(palette[i].b, 0x3c9);
|
||||
+ }
|
||||
+
|
||||
+#if 1
|
||||
+ for (i = 0; i < 0x20000; i += 2)
|
||||
+ *(volatile unsigned short *) (0xb00a0000 + i) = 0xaaaa;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+#ifdef LOAD_VGA_FONT
|
||||
+#include "/home/ralf/src/qemu/qemu-mips/vgafont.h"
|
||||
+
|
||||
+static void __init
|
||||
+qvga_load_font(unsigned char *def, unsigned int c)
|
||||
+{
|
||||
+ volatile void *w = (volatile void *) 0xb00a0000;
|
||||
+
|
||||
+ vga_wseq(NULL, 0, 1);
|
||||
+ vga_wseq(NULL, 2, 4);
|
||||
+ vga_wseq(NULL, 4, 7);
|
||||
+ vga_wseq(NULL, 0, 3);
|
||||
+ vga_wgfx(NULL, 4, 2);
|
||||
+ vga_wgfx(NULL, 5, 0);
|
||||
+ vga_wgfx(NULL, 6, 0);
|
||||
+
|
||||
+ memcpy(w, def, c);
|
||||
+
|
||||
+ vga_wseq(NULL, 0, 1);
|
||||
+ vga_wseq(NULL, 2, 3);
|
||||
+ vga_wseq(NULL, 4, 3);
|
||||
+ vga_wseq(NULL, 0, 3);
|
||||
+ vga_wgfx(NULL, 4, 0);
|
||||
+ vga_wgfx(NULL, 5, 0x10);
|
||||
+ vga_wgfx(NULL, 6, 0xe);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+void __init qvga_init(void)
|
||||
+{
|
||||
+ struct screen_info *si = &screen_info;
|
||||
+ unsigned int h;
|
||||
+ int i;
|
||||
+
|
||||
+#if LOAD_VGA_FONT
|
||||
+ qvga_load_font(vgafont16, 4096);
|
||||
+#endif
|
||||
+
|
||||
+ vga_wgfx(NULL, 5, 0x10); /* Set odd/even mode */
|
||||
+ vga_wgfx(NULL, 6, 0x0c); /* map to offset 0xb8000, text mode */
|
||||
+ vga_wseq(NULL, 2, 3); /* Planes 0 & 1 */
|
||||
+ vga_wseq(NULL, 3, 4); /* Font offset */
|
||||
+ outb(1, VGA_MIS_W); /* set msr to MSR_COLOR_EMULATION */
|
||||
+ vga_wcrt(NULL, 1, 79); /* 80 columns */
|
||||
+ vga_wcrt(NULL, 9, 15); /* 16 pixels per character */
|
||||
+ vga_wcrt(NULL, 0x0c, 0); /* start address high 8 bit */
|
||||
+ vga_wcrt(NULL, 0x0d, 0); /* start address low 8 bit */
|
||||
+ vga_wcrt(NULL, 0x13, 0x28); /* line offset */
|
||||
+ vga_wcrt(NULL, 0x07, 0x1f); /* line compare bit 8 */
|
||||
+ vga_wcrt(NULL, 0x09, 0x4f); /* line compare bit 9 */
|
||||
+ vga_wcrt(NULL, 0x18, 0xff); /* line compare low 8 bit */
|
||||
+
|
||||
+ h = (25 * 16);
|
||||
+ vga_wcrt(NULL, 0x12, h);
|
||||
+
|
||||
+ outb(7, 0x3d4);
|
||||
+ outb((inb(0x3d5) & ~0x42) | ((h >> 7) & 2) | ((h >> 3) & 0x40), 0x3d5);
|
||||
+
|
||||
+ for (i = 0; i < 21; i++) /* Attribute Controller */
|
||||
+ vga_wattr(NULL, i, ar[i]);
|
||||
+ outb(0x20, 0x3c0); /* Set bit 5 in Attribute Controller */
|
||||
+ /* index ... VGA is so stupid I want */
|
||||
+ /* to cry all day ... */
|
||||
+ outb(0, VGA_PEL_IW);
|
||||
+ for (i = 0; i < 16; i++) { /* palette */
|
||||
+ outb(palette[i].r, VGA_PEL_D);
|
||||
+ outb(palette[i].g, VGA_PEL_D);
|
||||
+ outb(palette[i].b, VGA_PEL_D);
|
||||
+ }
|
||||
+
|
||||
+ si->orig_x = 0; /* Cursor x position */
|
||||
+ si->orig_y = 0; /* Cursor y position */
|
||||
+ si->orig_video_cols = 80; /* Columns */
|
||||
+ si->orig_video_lines = 25; /* Lines */
|
||||
+ si->orig_video_isVGA = VIDEO_TYPE_VGAC; /* Card type */
|
||||
+ si->orig_video_points = 16;
|
||||
+
|
||||
+#if 0
|
||||
+ for (i = 0; i < 80; i += 2)
|
||||
+ //*(volatile unsigned short *) (0xb00b8000 + i) = 0x0100 | 'A';
|
||||
+ scr_writew(0x0100 | 'A', (volatile unsigned short *) (0xb00b8000 + i));
|
||||
+ while (1);
|
||||
+#endif
|
||||
+}
|
|
@ -24,3 +24,19 @@
|
|||
+ bugfix/sparc/sunblade1k-boot-fix.patch
|
||||
+ bugfix/__div64_32-for-31-bit.patch
|
||||
+ bugfix/net-bcm43xx_netdev_watchdog.patch
|
||||
+ bugfix/copy-user-highpage.patch
|
||||
- mips-sb1-duart-tts.patch
|
||||
+ bugfix/mips/syscall-wiring.patch
|
||||
+ bugfix/mips/sb1-flush-cache-data-page.patch
|
||||
+ bugfix/mips/trylock.patch
|
||||
+ bugfix/mips/smp-cpu-bringup.patch
|
||||
+ bugfix/mips/header-exports.patch
|
||||
+ bugfix/mips/sb1-interrupt-handler.patch
|
||||
+ bugfix/mips/cache-alias.patch
|
||||
+ bugfix/mips/ip22-zilog-console.patch
|
||||
+ bugfix/mips/signal-handling.patch
|
||||
+ bugfix/mips/sb1-duart-tts.patch
|
||||
+ bugfix/mips/wait-race.patch
|
||||
+ bugfix/mips/sgi-ioc3.patch
|
||||
+ features/mips/qemu-kernel.patch
|
||||
+ features/mips/backtrace.patch
|
||||
|
|
|
@ -2,3 +2,7 @@
|
|||
+ features/all/vserver/bindmount-dev.patch *_vserver *_xen-vserver
|
||||
+ features/all/xen/vserver-clash.patch *_xen-vserver
|
||||
+ features/all/xen/fedora-36252.patch *_xen *_xen-vserver
|
||||
- mips-dec-scsi.patch mipsel
|
||||
- mips-dec-serial.patch mipsel
|
||||
+ bugfix/mips/dec-scsi.patch mipsel
|
||||
+ bugfix/mips/dec-serial.patch mipsel
|
||||
|
|
Loading…
Reference in New Issue