1. 06 Sep, 2017 14 commits
    • Matt Redfearn's avatar
      MIPS: microMIPS: Fix decoding of addiusp instruction · a0ae2b08
      Matt Redfearn authored
      Commit 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      added handling of microMIPS instructions to manipulate the stack
      pointer. Unfortunately the decoding of the addiusp instruction was
      incorrect, and performed a left shift by 2 bits to the raw immediate,
      rather than decoding the immediate and then performing the shift, as
      documented in the ISA.
      
      This led to incomplete stack traces, due to incorrect frame sizes being
      calculated. For example the instruction:
      801faee0 <do_sys_poll>:
      801faee0:       4e25            addiu   sp,sp,-952
      
      As decoded by objdump, would be interpreted by the existing code as
      having manipulated the stack pointer by +1096.
      
      Fix this by changing the order of decoding the immediate and applying
      the left shift. Also change to accessing the instuction through the
      union to avoid the endianness problem of accesing halfword[0], which
      will fail on big endian systems.
      
      Cope with the special behaviour of immediates 0x0, 0x1, 0x1fe and 0x1ff
      by XORing with 0x100 again if mod(immediate) < 4. This logic was tested
      with the following test code:
      
      int main(int argc, char **argv)
      {
      	unsigned int enc;
      	int imm;
      
      	for (enc = 0; enc < 512; ++enc) {
      		int tmp = enc << 2;
      		imm = -(signed short)(tmp | ((tmp & 0x100) ? 0xfe00 : 0));
      		unsigned short tmp = enc;
      		tmp = (tmp ^ 0x100) - 0x100;
      		if ((unsigned short)(tmp + 2) < 4)
      			tmp ^= 0x100;
      		imm = -(signed short)(tmp << 2);
      		printf("%#x\t%d\t->\t(%#x\t%d)\t%#x\t%d\n",
      		       enc, enc,
      		       (short)tmp, (short)tmp,
      		       imm, imm);
      	}
      	return EXIT_SUCCESS;
      }
      
      Which generates the table:
      
      input encoding	->	tmp (matching manual)	frame size
      -----------------------------------------------------------------------
      0	0	->	(0x100		256)	0xfffffc00	-1024
      0x1	1	->	(0x101		257)	0xfffffbfc	-1028
      0x2	2	->	(0x2		2)	0xfffffff8	-8
      0x3	3	->	(0x3		3)	0xfffffff4	-12
      ...
      0xfe	254	->	(0xfe		254)	0xfffffc08	-1016
      0xff	255	->	(0xff		255)	0xfffffc04	-1020
      0x100	256	->	(0xffffff00	-256)	0x400		1024
      0x101	257	->	(0xffffff01	-255)	0x3fc		1020
      ...
      0x1fc	508	->	(0xfffffffc	-4)	0x10		16
      0x1fd	509	->	(0xfffffffd	-3)	0xc		12
      0x1fe	510	->	(0xfffffefe	-258)	0x408		1032
      0x1ff	511	->	(0xfffffeff	-257)	0x404		1028
      
      Thanks to James Hogan for the test code & verifying the logic.
      
      Fixes: 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      Suggested-by: default avatarJames Hogan <james.hogan@imgtec.com>
      Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
      Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
      Cc: Ingo Molnar <mingo@kernel.org>
      Cc: Paul Burton <paul.burton@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16955/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      a0ae2b08
    • Matt Redfearn's avatar
      MIPS: microMIPS: Fix detection of addiusp instruction · b332fec0
      Matt Redfearn authored
      The addiusp instruction uses the pool16d opcode, with bit 0 of the
      immediate set. The test for the addiusp opcode erroneously did a logical
      and of the immediate with mm_addiusp_func, which has value 1, so this
      test always passes when the immediate is non-zero.
      
      Fix the test by replacing the logical and with a bitwise and.
      
      Fixes: 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
      Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
      Cc: Ingo Molnar <mingo@kernel.org>
      Cc: Paul Burton <paul.burton@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16954/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      b332fec0
    • Matt Redfearn's avatar
      MIPS: Handle non word sized instructions when examining frame · 11887ed1
      Matt Redfearn authored
      Commit 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      added fairly broken support for handling 16bit microMIPS instructions in
      get_frame_info(). It adjusts the instruction pointer by 16bits in the
      case of a 16bit sp move instruction, but not any other 16bit
      instruction.
      
      Commit b6c7a324 ("MIPS: Fix get_frame_info() handling of microMIPS
      function size") goes some way to fixing get_frame_info() to iterate over
      microMIPS instuctions, but the instruction pointer is still manipulated
      using a postincrement, and is of union mips_instruction type. Since the
      union is sized to the largest member (a word), but microMIPS
      instructions are a mix of halfword and word sizes, the function does not
      always iterate correctly, ending up misaligned with the instruction
      stream and interpreting it incorrectly.
      
      Since the instruction modifying the stack pointer is usually the first
      in the function, that one is usually handled correctly. But the
      instruction which saves the return address to the sp is some variable
      number of instructions into the frame and is frequently missed due to
      not being on a word boundary, leading to incomplete walking of the
      stack.
      
      Fix this by incrementing the instruction pointer based on the size of
      the previously decoded instruction (& remove the hack introduced by
      commit 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      which adjusts the instruction pointer in the case of a 16bit sp move
      instruction, but not any other).
      
      Fixes: 34c2f668 ("MIPS: microMIPS: Add unaligned access support.")
      Signed-off-by: default avatarMatt Redfearn <matt.redfearn@imgtec.com>
      Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
      Cc: James Hogan <james.hogan@imgtec.com>
      Cc: Ingo Molnar <mingo@kernel.org>
      Cc: Paul Burton <paul.burton@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16953/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      11887ed1
    • Jonas Gorski's avatar
      MIPS: ralink: allow NULL clock for clk_get_rate · a18097b7
      Jonas Gorski authored
      Make the behaviour of clk_get_rate consistent with common clk's
      clk_get_rate by accepting NULL clocks as parameter. Some device
      drivers rely on this, and will cause an OOPS otherwise.
      
      Fixes: 3f0a06b0 ("MIPS: ralink: adds clkdev code")
      Reported-by: default avatarMathias Kresin <dev@kresin.me>
      Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
      Cc: John Crispin <john@phrozen.org>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16778/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      a18097b7
    • Jonas Gorski's avatar
      MIPS: Loongson 2F: allow NULL clock for clk_get_rate · 386787b1
      Jonas Gorski authored
      Make the behaviour of clk_get_rate consistent with common clk's
      clk_get_rate by accepting NULL clocks as parameter, as some device
      drivers rely on this.
      
      Make the behaviour of clk_get_rate consistent with common clk's
      clk_get_rate by accepting NULL clocks as parameter. Some device
      drivers rely on this, and will cause an OOPS otherwise.
      
      Fixes: f8ede0f7 ("MIPS: Loongson 2F: Add CPU frequency scaling support")
      Reported-by: default avatarMathias Kresin <dev@kresin.me>
      Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16777/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      386787b1
    • Jonas Gorski's avatar
      MIPS: BCM63XX: allow NULL clock for clk_get_rate · 1b495fae
      Jonas Gorski authored
      Make the behaviour of clk_get_rate consistent with common clk's
      clk_get_rate by accepting NULL clocks as parameter. Some device
      drivers rely on this, and will cause an OOPS otherwise.
      
      Fixes: e7300d04 ("MIPS: BCM63xx: Add support for the Broadcom BCM63xx family of SOCs.")
      Reported-by: default avatarMathias Kresin <dev@kresin.me>
      Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
      Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
      Cc: bcm-kernel-feedback-list@broadcom.com
      Cc: James Hogan <james.hogan@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16776/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      1b495fae
    • Jonas Gorski's avatar
      MIPS: AR7: allow NULL clock for clk_get_rate · 585e0e9d
      Jonas Gorski authored
      Make the behaviour of clk_get_rate consistent with common clk's
      clk_get_rate by accepting NULL clocks as parameter. Some device
      drivers rely on this, and will cause an OOPS otherwise.
      
      Fixes: 780019dd ("MIPS: AR7: Implement clock API")
      Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
      Reported-by: default avatarMathias Kresin <dev@kresin.me>
      Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
      Cc: James Hogan <james.hogan@imgtec.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16775/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      585e0e9d
    • Jonas Gorski's avatar
      MIPS: BCM63XX: fix ENETDMA_6345_MAXBURST_REG offset · eebc6056
      Jonas Gorski authored
      The channels are only 0x40 bytes large, so 0x40 would be the next one's
      CHANCFG_REG. Also the position makes it clear that this was intended to
      be 0x04. So clearly a typo.
      Signed-off-by: default avatarJonas Gorski <jonas.gorski@gmail.com>
      Cc: Florian Fainelli <f.fainelli@gmail.com>
      Cc: linux-mips@linux-mips.org
      Cc: bcm-kernel-feedback-list@broadcom.com
      Patchwork: https://patchwork.linux-mips.org/patch/15316/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      eebc6056
    • Corey Minyard's avatar
      mips: Save all registers when saving the frame · 5b6b0847
      Corey Minyard authored
      The MIPS frame save code was just saving a few registers, enough to
      do a backtrace if every function set up a frame.  However, this is
      not working if you are using DWARF unwinding, because most of the
      registers are wrong.  This was causing kdump backtraces to be short
      or bogus.
      
      So save all the registers.
      Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16989/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      5b6b0847
    • Corey Minyard's avatar
      MIPS: Add DWARF unwinding to assembly · 866b6a89
      Corey Minyard authored
      This will allow kdump dumps to work correclty with MIPS and
      future DWARF unwinding of the stack to give accurate tracebacks.
      Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16990/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      866b6a89
    • Corey Minyard's avatar
      MIPS: Make SAVE_SOME more standard · 9fef6868
      Corey Minyard authored
      Modify the SAVE_SOME macro to look more like a standard
      function, doing the arithmetic for the frame on the SP
      register instead of copying it from K1, and by saving
      the stored EPC from the RA.  This lets the get_frame_info()
      function process this function like any other.  It also
      remove an instruction or two from the kernel entry,
      making it more efficient.
      
      unwind_stack_by_address() has special handling for
      the top of the interrupt stack, but without this change
      unwinding will still fail if you get an interrupt while
      handling an interrupt and try to do a traceback from
      the second interrupt.
      
      This change modifies the get_saved_sp macro to
      optionally store the fetched value right into sp and store the
      old SP value into K0.  Then it's just a matter of subtracting
      the frame from SP and storing the old SP from K0.
      
      This required changing the DADDI workaround a bit, since K0
      holds the SP, we had to use K1 for AT.  But it eliminated
      some of the special handling for the DADDI workaround.
      
      Saving the RA register was moved up to before fetching the
      CP0_EPC register, so the CP0_EPC register could be stored
      into RA and the saved.  This lets the traceback code know
      where RA is actually stored.
      Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16991/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      9fef6868
    • Corey Minyard's avatar
      MIPS: Fix issues in backtraces · aee16625
      Corey Minyard authored
      I saw two problems when doing backtraces:
      
      The compiler was putting a "fast return" at the top of some
      functions, before it set up the frame.  The backtrace code
      would stop when it saw a jump instruction, so it would never
      get to the stack frame setup and would thus misinterpret it.
      To fix this, don't look for jump instructions until the
      frame setup has been seen.
      
      The assembly code here is:
      
      ffffffff80b885a0 <serial8250_handle_irq>:
      ffffffff80b885a0:       c8a00003        bbit0   a1,0x0,ffffffff80b885b0 <serial8250_handle_irq+0x10>
      ffffffff80b885a4:       0000102d        move    v0,zero
      ffffffff80b885a8:       03e00008        jr      ra
      ffffffff80b885ac:       00000000        nop
      ffffffff80b885b0:       67bdffd0        daddiu  sp,sp,-48
      ffffffff80b885b4:       ffb00008        sd      s0,8(sp)
      
      The second problem was the compiler was putting the last
      instruction of the frame save in the delay slot of the
      jump instruction.  If it saved the RA in there, the
      backtrace could would miss it and misinterpret the frame.
      To fix this, make sure to process the instruction after
      the first jump seen.
      
      The assembly code for this is:
      
      ffffffff80806fd0 <plat_irq_dispatch>:
      ffffffff80806fd0:       67bdffd0        daddiu  sp,sp,-48
      ffffffff80806fd4:       ffb30020        sd      s3,32(sp)
      ffffffff80806fd8:       24130018        li      s3,24
      ffffffff80806fdc:       ffb20018        sd      s2,24(sp)
      ffffffff80806fe0:       3c12811c        lui     s2,0x811c
      ffffffff80806fe4:       ffb10010        sd      s1,16(sp)
      ffffffff80806fe8:       3c11811c        lui     s1,0x811c
      ffffffff80806fec:       ffb00008        sd      s0,8(sp)
      ffffffff80806ff0:       3c10811c        lui     s0,0x811c
      ffffffff80806ff4:       08201c03        j       ffffffff8080700c <plat_irq_dispa
      tch+0x3c>
      ffffffff80806ff8:       ffbf0028        sd      ra,40(sp)
      Signed-off-by: default avatarCorey Minyard <cminyard@mvista.com>
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/16992/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      aee16625
    • Mathieu Malaterre's avatar
      MIPS: jz4780: DTS: Probe the jz4740-rtc driver from devicetree · ed326616
      Mathieu Malaterre authored
      The jz4740-rtc driver supports both jz4740 & jz4780, setup the compatible
      string to jz4780.
      Signed-off-by: default avatarMathieu Malaterre <malat@debian.org>
      Cc: Rob Herring <robh+dt@kernel.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Linus Walleij <linus.walleij@linaro.org>
      Cc: Paul Cercueil <paul@crapouillou.net>
      Cc: Krzysztof Kozlowski <krzk@kernel.org>
      Cc: devicetree@vger.kernel.org
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/17237/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      ed326616
    • Mathieu Malaterre's avatar
      MIPS: Ci20: Enable RTC driver · c76a5ba2
      Mathieu Malaterre authored
      Update the Ci20's defconfig to enable the JZ4780's RTC driver.
      Signed-off-by: default avatarMathieu Malaterre <malat@debian.org>
      Cc: Rob Herring <robh+dt@kernel.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Linus Walleij <linus.walleij@linaro.org>
      Cc: Paul Cercueil <paul@crapouillou.net>
      Cc: Krzysztof Kozlowski <krzk@kernel.org>
      Cc: devicetree@vger.kernel.org
      Cc: linux-mips@linux-mips.org
      Cc: linux-kernel@vger.kernel.org
      Patchwork: https://patchwork.linux-mips.org/patch/17236/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
      c76a5ba2
  2. 04 Sep, 2017 26 commits