Merge branch 'parisc-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller: "Lots of small fixes and enhancements, most noteably: - Many TLB and cache flush optimizations (Dave) - Fixed HPMC/crash handler on 64-bit kernel (Dave and myself) - Added alternative infrastructre. The kernel now live-patches itself for various situations, e.g. replace SMP code when running on one CPU only or drop cache flushes when system has no cache installed. - vmlinuz now contains a full copy of the compressed vmlinux file. This simplifies debugging the currently booted kernel. - Unused driver removal (Christoph) - Reduced warnings of Dino PCI bridge when running in qemu - Removed gcc version check (Masahiro)" * 'parisc-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (23 commits) parisc: Retrieve and display the PDC PAT capabilities parisc: Optimze cache flush algorithms parisc: Remove pte_inserted define parisc: Add PDC PAT cell_info() and pd_get_pdc_revisions() functions parisc: Drop two instructions from pte lookup code parisc: Use zdep for shlw macro on PA1.1 and PA2.0 parisc: Add alternative coding infrastructure parisc: Include compressed vmlinux file in vmlinuz boot kernel extract-vmlinux: Check for uncompressed image as fallback parisc: Fix address in HPMC IVA parisc: Fix exported address of os_hpmc handler parisc: Fix map_pages() to not overwrite existing pte entries parisc: Purge TLB entries after updating page table entry and set page accessed flag in TLB handler parisc: Release spinlocks using ordered store parisc: Ratelimit dino stuck interrupt warnings parisc: dino: Utilize DINO_MASK_IRQ() macro parisc: Clean up crash header output parisc: Add SYSTEM_INFO and REGISTER TOC PAT functions parisc: Remove PTE load and fault check from L2_ptep macro parisc: Reorder TLB flush timing calculation ...
This commit is contained in:
@@ -36,6 +36,7 @@ EXPORT_SYMBOL(dcache_stride);
|
||||
|
||||
void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
|
||||
EXPORT_SYMBOL(flush_dcache_page_asm);
|
||||
void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
|
||||
void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
|
||||
|
||||
|
||||
@@ -303,6 +304,17 @@ __flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline void
|
||||
__purge_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
|
||||
unsigned long physaddr)
|
||||
{
|
||||
preempt_disable();
|
||||
purge_dcache_page_asm(physaddr, vmaddr);
|
||||
if (vma->vm_flags & VM_EXEC)
|
||||
flush_icache_page_asm(physaddr, vmaddr);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
void flush_dcache_page(struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page_mapping_file(page);
|
||||
@@ -364,7 +376,7 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm);
|
||||
#define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
|
||||
static unsigned long parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
|
||||
|
||||
#define FLUSH_TLB_THRESHOLD (2*1024*1024) /* 2MB initial TLB threshold */
|
||||
#define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */
|
||||
static unsigned long parisc_tlb_flush_threshold __read_mostly = FLUSH_TLB_THRESHOLD;
|
||||
|
||||
void __init parisc_setup_cache_timing(void)
|
||||
@@ -404,10 +416,6 @@ void __init parisc_setup_cache_timing(void)
|
||||
goto set_tlb_threshold;
|
||||
}
|
||||
|
||||
alltime = mfctl(16);
|
||||
flush_tlb_all();
|
||||
alltime = mfctl(16) - alltime;
|
||||
|
||||
size = 0;
|
||||
start = (unsigned long) _text;
|
||||
rangetime = mfctl(16);
|
||||
@@ -418,13 +426,19 @@ void __init parisc_setup_cache_timing(void)
|
||||
}
|
||||
rangetime = mfctl(16) - rangetime;
|
||||
|
||||
printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n",
|
||||
alltime = mfctl(16);
|
||||
flush_tlb_all();
|
||||
alltime = mfctl(16) - alltime;
|
||||
|
||||
printk(KERN_INFO "Whole TLB flush %lu cycles, Range flush %lu bytes %lu cycles\n",
|
||||
alltime, size, rangetime);
|
||||
|
||||
threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
|
||||
threshold = PAGE_ALIGN((num_online_cpus() * size * alltime) / rangetime);
|
||||
printk(KERN_INFO "Calculated TLB flush threshold %lu KiB\n",
|
||||
threshold/1024);
|
||||
|
||||
set_tlb_threshold:
|
||||
if (threshold)
|
||||
if (threshold > parisc_tlb_flush_threshold)
|
||||
parisc_tlb_flush_threshold = threshold;
|
||||
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
|
||||
parisc_tlb_flush_threshold/1024);
|
||||
@@ -477,18 +491,6 @@ int __flush_tlb_range(unsigned long sid, unsigned long start,
|
||||
/* Purge TLB entries for small ranges using the pdtlb and
|
||||
pitlb instructions. These instructions execute locally
|
||||
but cause a purge request to be broadcast to other TLBs. */
|
||||
if (likely(!split_tlb)) {
|
||||
while (start < end) {
|
||||
purge_tlb_start(flags);
|
||||
mtsp(sid, 1);
|
||||
pdtlb(start);
|
||||
purge_tlb_end(flags);
|
||||
start += PAGE_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* split TLB case */
|
||||
while (start < end) {
|
||||
purge_tlb_start(flags);
|
||||
mtsp(sid, 1);
|
||||
@@ -573,9 +575,12 @@ void flush_cache_mm(struct mm_struct *mm)
|
||||
pfn = pte_pfn(*ptep);
|
||||
if (!pfn_valid(pfn))
|
||||
continue;
|
||||
if (unlikely(mm->context))
|
||||
if (unlikely(mm->context)) {
|
||||
flush_tlb_page(vma, addr);
|
||||
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
} else {
|
||||
__purge_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -610,9 +615,12 @@ void flush_cache_range(struct vm_area_struct *vma,
|
||||
continue;
|
||||
pfn = pte_pfn(*ptep);
|
||||
if (pfn_valid(pfn)) {
|
||||
if (unlikely(vma->vm_mm->context))
|
||||
if (unlikely(vma->vm_mm->context)) {
|
||||
flush_tlb_page(vma, addr);
|
||||
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
} else {
|
||||
__purge_cache_page(vma, addr, PFN_PHYS(pfn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,9 +629,12 @@ void
|
||||
flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
|
||||
{
|
||||
if (pfn_valid(pfn)) {
|
||||
if (likely(vma->vm_mm->context))
|
||||
if (likely(vma->vm_mm->context)) {
|
||||
flush_tlb_page(vma, vmaddr);
|
||||
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
||||
__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
||||
} else {
|
||||
__purge_cache_page(vma, vmaddr, PFN_PHYS(pfn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <asm/ldcw.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/alternative.h>
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
@@ -186,7 +187,7 @@
|
||||
bv,n 0(%r3)
|
||||
nop
|
||||
.word 0 /* checksum (will be patched) */
|
||||
.word PA(os_hpmc) /* address of handler */
|
||||
.word 0 /* address of handler */
|
||||
.word 0 /* length of handler */
|
||||
.endm
|
||||
|
||||
@@ -426,13 +427,10 @@
|
||||
ldw,s \index(\pmd),\pmd
|
||||
bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
|
||||
dep %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
|
||||
copy \pmd,%r9
|
||||
SHLREG %r9,PxD_VALUE_SHIFT,\pmd
|
||||
SHLREG \pmd,PxD_VALUE_SHIFT,\pmd
|
||||
extru \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
|
||||
dep %r0,31,PAGE_SHIFT,\pmd /* clear offset */
|
||||
shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd /* pmd is now pte */
|
||||
LDREG %r0(\pmd),\pte
|
||||
bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
|
||||
.endm
|
||||
|
||||
/* Look up PTE in a 3-Level scheme.
|
||||
@@ -448,7 +446,6 @@
|
||||
.macro L3_ptep pgd,pte,index,va,fault
|
||||
#if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */
|
||||
extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
|
||||
copy %r0,\pte
|
||||
extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
|
||||
ldw,s \index(\pgd),\pgd
|
||||
extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0
|
||||
@@ -463,36 +460,39 @@
|
||||
L2_ptep \pgd,\pte,\index,\va,\fault
|
||||
.endm
|
||||
|
||||
/* Acquire pa_tlb_lock lock and recheck page is still present. */
|
||||
/* Acquire pa_tlb_lock lock and check page is present. */
|
||||
.macro tlb_lock spc,ptp,pte,tmp,tmp1,fault
|
||||
#ifdef CONFIG_SMP
|
||||
cmpib,COND(=),n 0,\spc,2f
|
||||
98: cmpib,COND(=),n 0,\spc,2f
|
||||
load_pa_tlb_lock \tmp
|
||||
1: LDCW 0(\tmp),\tmp1
|
||||
cmpib,COND(=) 0,\tmp1,1b
|
||||
nop
|
||||
LDREG 0(\ptp),\pte
|
||||
bb,<,n \pte,_PAGE_PRESENT_BIT,2f
|
||||
bb,<,n \pte,_PAGE_PRESENT_BIT,3f
|
||||
b \fault
|
||||
stw \spc,0(\tmp)
|
||||
2:
|
||||
stw,ma \spc,0(\tmp)
|
||||
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
|
||||
#endif
|
||||
2: LDREG 0(\ptp),\pte
|
||||
bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
|
||||
3:
|
||||
.endm
|
||||
|
||||
/* Release pa_tlb_lock lock without reloading lock address. */
|
||||
.macro tlb_unlock0 spc,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
or,COND(=) %r0,\spc,%r0
|
||||
sync
|
||||
or,COND(=) %r0,\spc,%r0
|
||||
stw \spc,0(\tmp)
|
||||
98: or,COND(=) %r0,\spc,%r0
|
||||
stw,ma \spc,0(\tmp)
|
||||
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* Release pa_tlb_lock lock. */
|
||||
.macro tlb_unlock1 spc,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
load_pa_tlb_lock \tmp
|
||||
98: load_pa_tlb_lock \tmp
|
||||
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
|
||||
tlb_unlock0 \spc,\tmp
|
||||
#endif
|
||||
.endm
|
||||
@@ -1658,7 +1658,7 @@ dbit_fault:
|
||||
|
||||
itlb_fault:
|
||||
b intr_save
|
||||
ldi 6,%r8
|
||||
ldi PARISC_ITLB_TRAP,%r8
|
||||
|
||||
nadtlb_fault:
|
||||
b intr_save
|
||||
|
@@ -1325,6 +1325,36 @@ int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_pat_cell_info - Retrieve the cell's information.
|
||||
* @info: The pointer to a struct pdc_pat_cell_info_rtn_block.
|
||||
* @actcnt: The number of bytes which should be written to info.
|
||||
* @offset: offset of the structure.
|
||||
* @cell_number: The cell number which should be asked, or -1 for current cell.
|
||||
*
|
||||
* This PDC call returns information about the given cell (or all cells).
|
||||
*/
|
||||
int pdc_pat_cell_info(struct pdc_pat_cell_info_rtn_block *info,
|
||||
unsigned long *actcnt, unsigned long offset,
|
||||
unsigned long cell_number)
|
||||
{
|
||||
int retval;
|
||||
unsigned long flags;
|
||||
struct pdc_pat_cell_info_rtn_block result;
|
||||
|
||||
spin_lock_irqsave(&pdc_lock, flags);
|
||||
retval = mem_pdc_call(PDC_PAT_CELL, PDC_PAT_CELL_GET_INFO,
|
||||
__pa(pdc_result), __pa(&result), *actcnt,
|
||||
offset, cell_number);
|
||||
if (!retval) {
|
||||
*actcnt = pdc_result[0];
|
||||
memcpy(info, &result, *actcnt);
|
||||
}
|
||||
spin_unlock_irqrestore(&pdc_lock, flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_pat_cpu_get_number - Retrieve the cpu number.
|
||||
* @cpu_info: The return buffer.
|
||||
@@ -1412,6 +1442,33 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pdc_pat_pd_get_PDC_interface_revisions - Retrieve PDC interface revisions.
|
||||
* @legacy_rev: The legacy revision.
|
||||
* @pat_rev: The PAT revision.
|
||||
* @pdc_cap: The PDC capabilities.
|
||||
*
|
||||
*/
|
||||
int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev,
|
||||
unsigned long *pat_rev, unsigned long *pdc_cap)
|
||||
{
|
||||
int retval;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pdc_lock, flags);
|
||||
retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_PDC_INTERF_REV,
|
||||
__pa(pdc_result));
|
||||
if (retval == PDC_OK) {
|
||||
*legacy_rev = pdc_result[0];
|
||||
*pat_rev = pdc_result[1];
|
||||
*pdc_cap = pdc_result[2];
|
||||
}
|
||||
spin_unlock_irqrestore(&pdc_lock, flags);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pdc_pat_io_pci_cfg_read - Read PCI configuration space.
|
||||
* @pci_addr: PCI configuration space address for which the read request is being made.
|
||||
|
@@ -85,7 +85,7 @@ END(hpmc_pim_data)
|
||||
|
||||
.import intr_save, code
|
||||
.align 16
|
||||
ENTRY_CFI(os_hpmc)
|
||||
ENTRY(os_hpmc)
|
||||
.os_hpmc:
|
||||
|
||||
/*
|
||||
@@ -302,7 +302,6 @@ os_hpmc_6:
|
||||
b .
|
||||
nop
|
||||
.align 16 /* make function length multiple of 16 bytes */
|
||||
ENDPROC_CFI(os_hpmc)
|
||||
.os_hpmc_end:
|
||||
|
||||
|
||||
|
@@ -43,6 +43,7 @@ int pdc_type __read_mostly = PDC_TYPE_ILLEGAL;
|
||||
/* cell number and location (PAT firmware only) */
|
||||
unsigned long parisc_cell_num __read_mostly;
|
||||
unsigned long parisc_cell_loc __read_mostly;
|
||||
unsigned long parisc_pat_pdc_cap __read_mostly;
|
||||
|
||||
|
||||
void __init setup_pdc(void)
|
||||
@@ -81,12 +82,21 @@ void __init setup_pdc(void)
|
||||
#ifdef CONFIG_64BIT
|
||||
status = pdc_pat_cell_get_number(&cell_info);
|
||||
if (status == PDC_OK) {
|
||||
unsigned long legacy_rev, pat_rev;
|
||||
pdc_type = PDC_TYPE_PAT;
|
||||
pr_cont("64 bit PAT.\n");
|
||||
parisc_cell_num = cell_info.cell_num;
|
||||
parisc_cell_loc = cell_info.cell_loc;
|
||||
pr_info("PAT: Running on cell %lu and location %lu.\n",
|
||||
parisc_cell_num, parisc_cell_loc);
|
||||
status = pdc_pat_pd_get_pdc_revisions(&legacy_rev,
|
||||
&pat_rev, &parisc_pat_pdc_cap);
|
||||
pr_info("PAT: legacy revision 0x%lx, pat_rev 0x%lx, pdc_cap 0x%lx, S-PTLB %d, HPMC_RENDEZ %d.\n",
|
||||
legacy_rev, pat_rev, parisc_pat_pdc_cap,
|
||||
parisc_pat_pdc_cap
|
||||
& PDC_PAT_CAPABILITY_BIT_SIMULTANEOUS_PTLB ? 1:0,
|
||||
parisc_pat_pdc_cap
|
||||
& PDC_PAT_CAPABILITY_BIT_PDC_HPMC_RENDEZ ? 1:0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/ldcw.h>
|
||||
#include <asm/alternative.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
@@ -190,7 +191,7 @@ ENDPROC_CFI(flush_tlb_all_local)
|
||||
.import cache_info,data
|
||||
|
||||
ENTRY_CFI(flush_instruction_cache_local)
|
||||
load32 cache_info, %r1
|
||||
88: load32 cache_info, %r1
|
||||
|
||||
/* Flush Instruction Cache */
|
||||
|
||||
@@ -243,6 +244,7 @@ fioneloop2:
|
||||
fisync:
|
||||
sync
|
||||
mtsm %r22 /* restore I-bit */
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_instruction_cache_local)
|
||||
@@ -250,7 +252,7 @@ ENDPROC_CFI(flush_instruction_cache_local)
|
||||
|
||||
.import cache_info, data
|
||||
ENTRY_CFI(flush_data_cache_local)
|
||||
load32 cache_info, %r1
|
||||
88: load32 cache_info, %r1
|
||||
|
||||
/* Flush Data Cache */
|
||||
|
||||
@@ -304,6 +306,7 @@ fdsync:
|
||||
syncdma
|
||||
sync
|
||||
mtsm %r22 /* restore I-bit */
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_data_cache_local)
|
||||
@@ -312,6 +315,7 @@ ENDPROC_CFI(flush_data_cache_local)
|
||||
|
||||
.macro tlb_lock la,flags,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
98:
|
||||
#if __PA_LDCW_ALIGNMENT > 4
|
||||
load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
|
||||
depi 0,31,__PA_LDCW_ALIGN_ORDER, \la
|
||||
@@ -326,15 +330,17 @@ ENDPROC_CFI(flush_data_cache_local)
|
||||
nop
|
||||
b,n 2b
|
||||
3:
|
||||
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro tlb_unlock la,flags,tmp
|
||||
#ifdef CONFIG_SMP
|
||||
ldi 1,\tmp
|
||||
98: ldi 1,\tmp
|
||||
sync
|
||||
stw \tmp,0(\la)
|
||||
mtsm \flags
|
||||
99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
|
||||
#endif
|
||||
.endm
|
||||
|
||||
@@ -596,9 +602,11 @@ ENTRY_CFI(copy_user_page_asm)
|
||||
pdtlb,l %r0(%r29)
|
||||
#else
|
||||
tlb_lock %r20,%r21,%r22
|
||||
pdtlb %r0(%r28)
|
||||
pdtlb %r0(%r29)
|
||||
0: pdtlb %r0(%r28)
|
||||
1: pdtlb %r0(%r29)
|
||||
tlb_unlock %r20,%r21,%r22
|
||||
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -736,8 +744,9 @@ ENTRY_CFI(clear_user_page_asm)
|
||||
pdtlb,l %r0(%r28)
|
||||
#else
|
||||
tlb_lock %r20,%r21,%r22
|
||||
pdtlb %r0(%r28)
|
||||
0: pdtlb %r0(%r28)
|
||||
tlb_unlock %r20,%r21,%r22
|
||||
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -813,11 +822,12 @@ ENTRY_CFI(flush_dcache_page_asm)
|
||||
pdtlb,l %r0(%r28)
|
||||
#else
|
||||
tlb_lock %r20,%r21,%r22
|
||||
pdtlb %r0(%r28)
|
||||
0: pdtlb %r0(%r28)
|
||||
tlb_unlock %r20,%r21,%r22
|
||||
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
#endif
|
||||
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), r31
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -828,8 +838,7 @@ ENTRY_CFI(flush_dcache_page_asm)
|
||||
add %r28, %r25, %r25
|
||||
sub %r25, r31, %r25
|
||||
|
||||
|
||||
1: fdc,m r31(%r28)
|
||||
1: fdc,m r31(%r28)
|
||||
fdc,m r31(%r28)
|
||||
fdc,m r31(%r28)
|
||||
fdc,m r31(%r28)
|
||||
@@ -844,14 +853,76 @@ ENTRY_CFI(flush_dcache_page_asm)
|
||||
fdc,m r31(%r28)
|
||||
fdc,m r31(%r28)
|
||||
fdc,m r31(%r28)
|
||||
cmpb,COND(<<) %r28, %r25,1b
|
||||
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
|
||||
fdc,m r31(%r28)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_dcache_page_asm)
|
||||
|
||||
ENTRY_CFI(purge_dcache_page_asm)
|
||||
ldil L%(TMPALIAS_MAP_START), %r28
|
||||
#ifdef CONFIG_64BIT
|
||||
#if (TMPALIAS_MAP_START >= 0x80000000)
|
||||
depdi 0, 31,32, %r28 /* clear any sign extension */
|
||||
#endif
|
||||
convert_phys_for_tlb_insert20 %r26 /* convert phys addr to tlb insert format */
|
||||
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
|
||||
depdi 0, 63,PAGE_SHIFT, %r28 /* Clear any offset bits */
|
||||
#else
|
||||
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
|
||||
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
|
||||
depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
|
||||
#endif
|
||||
|
||||
/* Purge any old translation */
|
||||
|
||||
#ifdef CONFIG_PA20
|
||||
pdtlb,l %r0(%r28)
|
||||
#else
|
||||
tlb_lock %r20,%r21,%r22
|
||||
0: pdtlb %r0(%r28)
|
||||
tlb_unlock %r20,%r21,%r22
|
||||
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
#endif
|
||||
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), r31
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
depdi,z 1, 63-PAGE_SHIFT,1, %r25
|
||||
#else
|
||||
depwi,z 1, 31-PAGE_SHIFT,1, %r25
|
||||
#endif
|
||||
add %r28, %r25, %r25
|
||||
sub %r25, r31, %r25
|
||||
|
||||
1: pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
pdc,m r31(%r28)
|
||||
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
|
||||
pdc,m r31(%r28)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(purge_dcache_page_asm)
|
||||
|
||||
ENTRY_CFI(flush_icache_page_asm)
|
||||
ldil L%(TMPALIAS_MAP_START), %r28
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -874,15 +945,19 @@ ENTRY_CFI(flush_icache_page_asm)
|
||||
|
||||
#ifdef CONFIG_PA20
|
||||
pdtlb,l %r0(%r28)
|
||||
pitlb,l %r0(%sr4,%r28)
|
||||
1: pitlb,l %r0(%sr4,%r28)
|
||||
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
|
||||
#else
|
||||
tlb_lock %r20,%r21,%r22
|
||||
pdtlb %r0(%r28)
|
||||
pitlb %r0(%sr4,%r28)
|
||||
0: pdtlb %r0(%r28)
|
||||
1: pitlb %r0(%sr4,%r28)
|
||||
tlb_unlock %r20,%r21,%r22
|
||||
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
|
||||
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
|
||||
#endif
|
||||
|
||||
ldil L%icache_stride, %r1
|
||||
88: ldil L%icache_stride, %r1
|
||||
ldw R%icache_stride(%r1), %r31
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -893,7 +968,6 @@ ENTRY_CFI(flush_icache_page_asm)
|
||||
add %r28, %r25, %r25
|
||||
sub %r25, %r31, %r25
|
||||
|
||||
|
||||
/* fic only has the type 26 form on PA1.1, requiring an
|
||||
* explicit space specification, so use %sr4 */
|
||||
1: fic,m %r31(%sr4,%r28)
|
||||
@@ -911,16 +985,17 @@ ENTRY_CFI(flush_icache_page_asm)
|
||||
fic,m %r31(%sr4,%r28)
|
||||
fic,m %r31(%sr4,%r28)
|
||||
fic,m %r31(%sr4,%r28)
|
||||
cmpb,COND(<<) %r28, %r25,1b
|
||||
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
|
||||
fic,m %r31(%sr4,%r28)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_icache_page_asm)
|
||||
|
||||
ENTRY_CFI(flush_kernel_dcache_page_asm)
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r23
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -931,7 +1006,6 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
|
||||
add %r26, %r25, %r25
|
||||
sub %r25, %r23, %r25
|
||||
|
||||
|
||||
1: fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
@@ -947,16 +1021,17 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
cmpb,COND(<<) %r26, %r25,1b
|
||||
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
|
||||
fdc,m %r23(%r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_kernel_dcache_page_asm)
|
||||
|
||||
ENTRY_CFI(purge_kernel_dcache_page_asm)
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r23
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -982,74 +1057,183 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
cmpb,COND(<<) %r26, %r25, 1b
|
||||
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
|
||||
pdc,m %r23(%r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(purge_kernel_dcache_page_asm)
|
||||
|
||||
ENTRY_CFI(flush_user_dcache_range_asm)
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r23
|
||||
ldo -1(%r23), %r21
|
||||
ANDCM %r26, %r21, %r26
|
||||
|
||||
1: cmpb,COND(<<),n %r26, %r25, 1b
|
||||
#ifdef CONFIG_64BIT
|
||||
depd,z %r23, 59, 60, %r21
|
||||
#else
|
||||
depw,z %r23, 27, 28, %r21
|
||||
#endif
|
||||
add %r26, %r21, %r22
|
||||
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
|
||||
1: add %r22, %r21, %r22
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
|
||||
2: cmpb,COND(>>),n %r25, %r26, 2b
|
||||
fdc,m %r23(%sr3, %r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_user_dcache_range_asm)
|
||||
|
||||
ENTRY_CFI(flush_kernel_dcache_range_asm)
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r23
|
||||
ldo -1(%r23), %r21
|
||||
ANDCM %r26, %r21, %r26
|
||||
|
||||
1: cmpb,COND(<<),n %r26, %r25,1b
|
||||
#ifdef CONFIG_64BIT
|
||||
depd,z %r23, 59, 60, %r21
|
||||
#else
|
||||
depw,z %r23, 27, 28, %r21
|
||||
#endif
|
||||
add %r26, %r21, %r22
|
||||
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
|
||||
1: add %r22, %r21, %r22
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
fdc,m %r23(%r26)
|
||||
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
|
||||
fdc,m %r23(%r26)
|
||||
|
||||
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
|
||||
fdc,m %r23(%r26)
|
||||
|
||||
sync
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
syncdma
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_kernel_dcache_range_asm)
|
||||
|
||||
ENTRY_CFI(purge_kernel_dcache_range_asm)
|
||||
ldil L%dcache_stride, %r1
|
||||
88: ldil L%dcache_stride, %r1
|
||||
ldw R%dcache_stride(%r1), %r23
|
||||
ldo -1(%r23), %r21
|
||||
ANDCM %r26, %r21, %r26
|
||||
|
||||
1: cmpb,COND(<<),n %r26, %r25,1b
|
||||
#ifdef CONFIG_64BIT
|
||||
depd,z %r23, 59, 60, %r21
|
||||
#else
|
||||
depw,z %r23, 27, 28, %r21
|
||||
#endif
|
||||
add %r26, %r21, %r22
|
||||
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
|
||||
1: add %r22, %r21, %r22
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
pdc,m %r23(%r26)
|
||||
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
|
||||
pdc,m %r23(%r26)
|
||||
|
||||
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
|
||||
pdc,m %r23(%r26)
|
||||
|
||||
sync
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
|
||||
syncdma
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(purge_kernel_dcache_range_asm)
|
||||
|
||||
ENTRY_CFI(flush_user_icache_range_asm)
|
||||
ldil L%icache_stride, %r1
|
||||
88: ldil L%icache_stride, %r1
|
||||
ldw R%icache_stride(%r1), %r23
|
||||
ldo -1(%r23), %r21
|
||||
ANDCM %r26, %r21, %r26
|
||||
|
||||
1: cmpb,COND(<<),n %r26, %r25,1b
|
||||
#ifdef CONFIG_64BIT
|
||||
depd,z %r23, 59, 60, %r21
|
||||
#else
|
||||
depw,z %r23, 27, 28, %r21
|
||||
#endif
|
||||
add %r26, %r21, %r22
|
||||
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
|
||||
1: add %r22, %r21, %r22
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
fic,m %r23(%sr3, %r26)
|
||||
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
|
||||
fic,m %r23(%sr3, %r26)
|
||||
|
||||
2: cmpb,COND(>>),n %r25, %r26, 2b
|
||||
fic,m %r23(%sr3, %r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_user_icache_range_asm)
|
||||
|
||||
ENTRY_CFI(flush_kernel_icache_page)
|
||||
ldil L%icache_stride, %r1
|
||||
88: ldil L%icache_stride, %r1
|
||||
ldw R%icache_stride(%r1), %r23
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
@@ -1076,23 +1260,51 @@ ENTRY_CFI(flush_kernel_icache_page)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
cmpb,COND(<<) %r26, %r25, 1b
|
||||
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
|
||||
fic,m %r23(%sr4, %r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
ENDPROC_CFI(flush_kernel_icache_page)
|
||||
|
||||
ENTRY_CFI(flush_kernel_icache_range_asm)
|
||||
ldil L%icache_stride, %r1
|
||||
88: ldil L%icache_stride, %r1
|
||||
ldw R%icache_stride(%r1), %r23
|
||||
ldo -1(%r23), %r21
|
||||
ANDCM %r26, %r21, %r26
|
||||
|
||||
1: cmpb,COND(<<),n %r26, %r25, 1b
|
||||
#ifdef CONFIG_64BIT
|
||||
depd,z %r23, 59, 60, %r21
|
||||
#else
|
||||
depw,z %r23, 27, 28, %r21
|
||||
#endif
|
||||
add %r26, %r21, %r22
|
||||
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
|
||||
1: add %r22, %r21, %r22
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
fic,m %r23(%sr4, %r26)
|
||||
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
|
||||
fic,m %r23(%sr4, %r26)
|
||||
|
||||
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
|
||||
fic,m %r23(%sr4, %r26)
|
||||
|
||||
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
|
||||
sync
|
||||
bv %r0(%r2)
|
||||
nop
|
||||
|
@@ -305,6 +305,86 @@ static int __init parisc_init_resources(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int no_alternatives __initdata;
|
||||
static int __init setup_no_alternatives(char *str)
|
||||
{
|
||||
no_alternatives = 1;
|
||||
return 1;
|
||||
}
|
||||
__setup("no-alternatives", setup_no_alternatives);
|
||||
|
||||
static void __init apply_alternatives_all(void)
|
||||
{
|
||||
struct alt_instr *entry;
|
||||
int index = 0, applied = 0;
|
||||
|
||||
|
||||
pr_info("alternatives: %spatching kernel code\n",
|
||||
no_alternatives ? "NOT " : "");
|
||||
if (no_alternatives)
|
||||
return;
|
||||
|
||||
set_kernel_text_rw(1);
|
||||
|
||||
for (entry = (struct alt_instr *) &__alt_instructions;
|
||||
entry < (struct alt_instr *) &__alt_instructions_end;
|
||||
entry++, index++) {
|
||||
|
||||
u32 *from, len, cond, replacement;
|
||||
|
||||
from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
|
||||
len = entry->len;
|
||||
cond = entry->cond;
|
||||
replacement = entry->replacement;
|
||||
|
||||
WARN_ON(!cond);
|
||||
pr_debug("Check %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
|
||||
index, cond, len, from, replacement);
|
||||
|
||||
if ((cond & ALT_COND_NO_SMP) && (num_online_cpus() != 1))
|
||||
continue;
|
||||
if ((cond & ALT_COND_NO_DCACHE) && (cache_info.dc_size != 0))
|
||||
continue;
|
||||
if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit
|
||||
* set (bit #61, big endian), we have to flush and sync every
|
||||
* time IO-PDIR is changed in Ike/Astro.
|
||||
*/
|
||||
if ((cond & ALT_COND_NO_IOC_FDC) &&
|
||||
(boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC))
|
||||
continue;
|
||||
|
||||
/* Want to replace pdtlb by a pdtlb,l instruction? */
|
||||
if (replacement == INSN_PxTLB) {
|
||||
replacement = *from;
|
||||
if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */
|
||||
replacement |= (1 << 10); /* set el bit */
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace instruction with NOPs?
|
||||
* For long distance insert a branch instruction instead.
|
||||
*/
|
||||
if (replacement == INSN_NOP && len > 1)
|
||||
replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
|
||||
|
||||
pr_debug("Do %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
|
||||
index, cond, len, from, replacement);
|
||||
|
||||
/* Replace instruction */
|
||||
*from = replacement;
|
||||
applied++;
|
||||
}
|
||||
|
||||
pr_info("alternatives: applied %d out of %d patches\n", applied, index);
|
||||
|
||||
set_kernel_text_rw(0);
|
||||
}
|
||||
|
||||
|
||||
extern void gsc_init(void);
|
||||
extern void processor_init(void);
|
||||
extern void ccio_init(void);
|
||||
@@ -346,6 +426,7 @@ static int __init parisc_init(void)
|
||||
boot_cpu_data.cpu_hz / 1000000,
|
||||
boot_cpu_data.cpu_hz % 1000000 );
|
||||
|
||||
apply_alternatives_all();
|
||||
parisc_setup_cache_timing();
|
||||
|
||||
/* These are in a non-obvious order, will fix when we have an iotree */
|
||||
|
@@ -65,7 +65,6 @@
|
||||
#define INSN_LDI_R25_1 0x34190002 /* ldi 1,%r25 (in_syscall=1) */
|
||||
#define INSN_LDI_R20 0x3414015a /* ldi __NR_rt_sigreturn,%r20 */
|
||||
#define INSN_BLE_SR2_R0 0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
|
||||
#define INSN_NOP 0x08000240 /* nop */
|
||||
/* For debugging */
|
||||
#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
|
||||
|
||||
|
@@ -640,8 +640,7 @@ cas_action:
|
||||
sub,<> %r28, %r25, %r0
|
||||
2: stw %r24, 0(%r26)
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
#if ENABLE_LWS_DEBUG
|
||||
/* Clear thread register indicator */
|
||||
stw %r0, 4(%sr2,%r20)
|
||||
@@ -655,8 +654,7 @@ cas_action:
|
||||
3:
|
||||
/* Error occurred on load or store */
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
#if ENABLE_LWS_DEBUG
|
||||
stw %r0, 4(%sr2,%r20)
|
||||
#endif
|
||||
@@ -857,8 +855,7 @@ cas2_action:
|
||||
|
||||
cas2_end:
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
/* Enable interrupts */
|
||||
ssm PSW_SM_I, %r0
|
||||
/* Return to userspace, set no error */
|
||||
@@ -868,8 +865,7 @@ cas2_end:
|
||||
22:
|
||||
/* Error occurred on load or store */
|
||||
/* Free lock */
|
||||
sync
|
||||
stw %r20, 0(%sr2,%r20)
|
||||
stw,ma %r20, 0(%sr2,%r20)
|
||||
ssm PSW_SM_I, %r0
|
||||
ldo 1(%r0),%r28
|
||||
b lws_exit
|
||||
|
@@ -430,8 +430,8 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
pr_crit("%s: Code=%d (%s) regs=%p (Addr=" RFMT ")\n",
|
||||
msg, code, trap_name(code), regs, offset);
|
||||
pr_crit("%s: Code=%d (%s) at addr " RFMT "\n",
|
||||
msg, code, trap_name(code), offset);
|
||||
show_regs(regs);
|
||||
|
||||
spin_unlock(&terminate_lock);
|
||||
@@ -802,7 +802,8 @@ void __init initialize_ivt(const void *iva)
|
||||
* the Length/4 words starting at Address is zero.
|
||||
*/
|
||||
|
||||
/* Compute Checksum for HPMC handler */
|
||||
/* Setup IVA and compute checksum for HPMC handler */
|
||||
ivap[6] = (u32)__pa(os_hpmc);
|
||||
length = os_hpmc_size;
|
||||
ivap[7] = length;
|
||||
|
||||
|
@@ -61,6 +61,12 @@ SECTIONS
|
||||
EXIT_DATA
|
||||
}
|
||||
PERCPU_SECTION(8)
|
||||
. = ALIGN(4);
|
||||
.altinstructions : {
|
||||
__alt_instructions = .;
|
||||
*(.altinstructions)
|
||||
__alt_instructions_end = .;
|
||||
}
|
||||
. = ALIGN(HUGEPAGE_SIZE);
|
||||
__init_end = .;
|
||||
/* freed after init ends here */
|
||||
|
Reference in New Issue
Block a user