Re: [Fwd: [bug report] 0xffffffffc0000000 can't be used on bcm1250]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Maciej,

I have tried your suggested patch, and it works well.

And I am sorry to forget adding linux-mips to the cc list.

Thanks
Weiwei

Maciej W. Rozycki wrote:
> On Mon, 13 Oct 2008, weiwei wang wrote:
>
>   
>> your patch can't work. For the original code, I dump the memory mirror
>>     
>
>  Yes, that's correct -- it wasn't the best idea indeed.
>
>   
>> And I think the key issue is the field Fill / VPN2 in EntryHi, normally
>> this field will equal to corresponding field in BADVADDR. But for
>> address 0xffffffffc0000000, it doesn't; In the book "see mips run",
>> there is a description for register EntryHi:
>>     
>
>  Good point! -- you are correct.  This compatibility area is a special 
> case.  Thanks a lot for the analysis.
>
>   
>> Below is my patch, and it works well in my side.
>>
>> Signed-off-by: Weiwei Wang <weiwei.wang@xxxxxxxxxxxxx>
>> diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
>> index 5a0835b..1b2ef20 100644
>> --- a/arch/mips/mm/tlbex.c
>> +++ b/arch/mips/mm/tlbex.c
>> @@ -674,6 +674,8 @@ static void __cpuinit
>> build_r4000_tlb_refill_handler(void)
>>                 UASM_i_MFC0(&p, K0, C0_BADVADDR);
>>                 UASM_i_MFC0(&p, K1, C0_ENTRYHI);
>>                 uasm_i_xor(&p, K0, K0, K1);
>> +               UASM_i_SLL(&p, K0, K0, 24);
>> +               UASM_i_SRL(&p, K0, K0, 24);
>>                 UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
>>                 uasm_il_bnez(&p, &r, K0, label_leave);
>>                 /* No need for uasm_i_nop */
>>     
>
>  This is a hack for a single core type, so hardcoding the width of the 
> virtual address space is fine.  I am assuming you've got these right for 
> the SB-1.
>
>  However preserving the check of the two most significant bits is 
> desirable.  So I would suggest a patch as follows instead.
>
>   
>> Note: The bit-shift amount for dsrl in the range 0 to 31, so I split
>> into 2 dsrl operations.
>>     
>
>  That is actually not needed -- you can use DSRL32.
>
>  Please try the following patch and see if it works for you.  It boots 
> into the user mode for me with a 64-bit big-endian 16kB page 
> configuration, but I haven't checked it any further.
>
>   Maciej
>
> Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxxxxx>
> ---
> patch-mips-2.6.27-rc8-20081004-sb1250-m3-3
> diff -up --recursive --new-file linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/tlbex.c linux-mips-2.6.27-rc8-20081004/arch/mips/mm/tlbex.c
> --- linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/tlbex.c	2008-10-13 14:45:55.000000000 +0000
> +++ linux-mips-2.6.27-rc8-20081004/arch/mips/mm/tlbex.c	2008-10-13 14:47:50.000000000 +0000
> @@ -6,7 +6,7 @@
>   * Synthesize TLB refill handlers at runtime.
>   *
>   * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
> - * Copyright (C) 2005, 2007  Maciej W. Rozycki
> + * Copyright (C) 2005, 2007, 2008  Maciej W. Rozycki
>   * Copyright (C) 2006  Ralf Baechle (ralf@xxxxxxxxxxxxxx)
>   *
>   * ... and the days got worse and worse and now you see
> @@ -200,6 +200,23 @@ static void __cpuinit build_r3000_tlb_re
>  static u32 final_handler[64] __cpuinitdata;
>  
>  /*
> + * To avoid the BCM1250 M3 erratum check whether EntryHi is consistent
> + * with BadVAddr and return for the exception to retrigger if not.
> + */
> +static void __cpuinit build_bcm1250_m3_war(u32 **p, struct uasm_reloc **r)
> +{
> +	uasm_i_dmfc0(p, K0, C0_BADVADDR);
> +	uasm_i_dmfc0(p, K1, C0_ENTRYHI);
> +	uasm_i_xor(p, K0, K0, K1);
> +	uasm_i_dsll(p, K1, K0, 24);
> +	uasm_i_dsrl32(p, K1, K1, (24 + PAGE_SHIFT + 1) - 32);
> +	uasm_i_dsrl32(p, K0, K0, 30);
> +	uasm_i_or(p, K0, K0, K1);
> +	uasm_il_bnez(p, r, K0, label_leave);
> +	/* No need for uasm_i_nop */
> +}
> +
> +/*
>   * Hazards
>   *
>   * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
> @@ -669,14 +686,8 @@ static void __cpuinit build_r4000_tlb_re
>  	/*
>  	 * create the plain linear handler
>  	 */
> -	if (bcm1250_m3_war()) {
> -		UASM_i_MFC0(&p, K0, C0_BADVADDR);
> -		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
> -		uasm_i_xor(&p, K0, K0, K1);
> -		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
> -		uasm_il_bnez(&p, &r, K0, label_leave);
> -		/* No need for uasm_i_nop */
> -	}
> +	if (bcm1250_m3_war())
> +		build_bcm1250_m3_war(&p, &r);
>  
>  #ifdef CONFIG_64BIT
>  	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
> @@ -1132,14 +1143,8 @@ static void __cpuinit build_r4000_tlb_lo
>  	memset(labels, 0, sizeof(labels));
>  	memset(relocs, 0, sizeof(relocs));
>  
> -	if (bcm1250_m3_war()) {
> -		UASM_i_MFC0(&p, K0, C0_BADVADDR);
> -		UASM_i_MFC0(&p, K1, C0_ENTRYHI);
> -		uasm_i_xor(&p, K0, K0, K1);
> -		UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
> -		uasm_il_bnez(&p, &r, K0, label_leave);
> -		/* No need for uasm_i_nop */
> -	}
> +	if (bcm1250_m3_war())
> +		build_bcm1250_m3_war(&p, &r);
>  
>  	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
>  	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
> diff -up --recursive --new-file linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/uasm.c linux-mips-2.6.27-rc8-20081004/arch/mips/mm/uasm.c
> --- linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/uasm.c	2008-10-13 14:45:55.000000000 +0000
> +++ linux-mips-2.6.27-rc8-20081004/arch/mips/mm/uasm.c	2008-10-13 14:50:42.000000000 +0000
> @@ -8,7 +8,7 @@
>   * effects like branch delay slots.
>   *
>   * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
> - * Copyright (C) 2005, 2007  Maciej W. Rozycki
> + * Copyright (C) 2005, 2007, 2008  Maciej W. Rozycki
>   * Copyright (C) 2006  Ralf Baechle (ralf@xxxxxxxxxxxxxx)
>   */
>  
> @@ -62,9 +62,10 @@ enum opcode {
>  	insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
>  	insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr,
>  	insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
> -	insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
> -	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
> -	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
> +	insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc,
> +	insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_subu,
> +	insn_sw, insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor,
> +	insn_xori
>  };
>  
>  struct insn {
> @@ -116,6 +117,7 @@ static struct insn insn_table[] __cpuini
>  	{ insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
>  	{ insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
>  	{ insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
> +	{ insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
>  	{ insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
>  	{ insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
>  	{ insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
> @@ -361,6 +363,7 @@ I_u1s2(_lui)
>  I_u2s3u1(_lw)
>  I_u1u2u3(_mfc0)
>  I_u1u2u3(_mtc0)
> +I_u3u1u2(_or)
>  I_u2u1u3(_ori)
>  I_u2s3u1(_pref)
>  I_0(_rfe)
> diff -up --recursive --new-file linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/uasm.h linux-mips-2.6.27-rc8-20081004/arch/mips/mm/uasm.h
> --- linux-mips-2.6.27-rc8-20081004.macro/arch/mips/mm/uasm.h	2008-10-13 14:45:55.000000000 +0000
> +++ linux-mips-2.6.27-rc8-20081004/arch/mips/mm/uasm.h	2008-10-13 14:26:23.000000000 +0000
> @@ -4,7 +4,7 @@
>   * for more details.
>   *
>   * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
> - * Copyright (C) 2005  Maciej W. Rozycki
> + * Copyright (C) 2005, 2008  Maciej W. Rozycki
>   * Copyright (C) 2006  Ralf Baechle (ralf@xxxxxxxxxxxxxx)
>   */
>  
> @@ -77,6 +77,7 @@ Ip_u1s2(_lui);
>  Ip_u2s3u1(_lw);
>  Ip_u1u2u3(_mfc0);
>  Ip_u1u2u3(_mtc0);
> +Ip_u3u1u2(_or);
>  Ip_u2u1u3(_ori);
>  Ip_u2s3u1(_pref);
>  Ip_0(_rfe);


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux