Skip to content
  • Chris Packham's avatar
    mips: Use unsigned int when reading c0 registers · 73a4152b
    Chris Packham authored
    In commit a18a4771 (MIPS: use common code from lib/time.c) MIPS platforms
    started using common the common timer functions which are based around
    the fact that many platforms have a 32-bit free running counter register
    that can be used see commit 8dfafdde
    
     (Introduce common timer functions).
    
    Even MIPS64 has such a 32-bit register (some have an additional 64-bit free
    running counter, but that's something for another time).
    
    The problem is that in __read_32bit_c0_register() we read the value from
    this register into an _signed_ int and as it's returned up the call
    chain to timer_read_counter() it gets assigned to an unsigned long. On a
    32-bit system there is no problem. On a 64-bit system odd things happen,
    sign extension seems to kick in and all of a sudden if the counter
    register happens to have the MSb (i.e. the sign bit) set the negative
    int gets sign extended into a very large unsigned long value. This in
    turn throws out things from get_ticks() up.
    
    Update __read_32bit_c0_register() and __read_32bit_c0_ctrl_register() to
    use "unsigned int res;" instead of "int res;". There seems to be little
    reason to treat these register values as signed. They are either
    counters (which by definition are unsigned) or are made up of various
    bit fields to be interpreted as per the CPU datasheet.
    
    Reported-by: default avatarSachin Surendran <sachin.surendran@alliedtelesis.co.nz>
    Signed-off-by: default avatarChris Packham <judge.packham@gmail.com>
    73a4152b