All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-27 17:09 Marc St-Jean
  2007-02-27 17:38 ` Thiemo Seufer
  2007-02-27 18:46 ` Andrew Sharp
  0 siblings, 2 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-27 17:09 UTC (permalink / raw)
  To: Andrew Sharp; +Cc: linux-mips


Andrew Sharp wrote:
> On Mon, 26 Feb 2007 18:12:55 -0600 Marc St-Jean 
> <stjeanma@pmc-sierra.com> wrote:
>  > [PATCH 2/5] mips: PMC MSP71xx mips common
>  >
>  > Patch to add mips common support for the PMC-Sierra
>  > MSP71xx devices.
>  >
>  > These 5 patches along with the previously posted serial patch
>  > will boot the PMC-Sierra MSP7120 Residential Gateway board.
>  >
>  > Thanks,
>  > Marc
>  >
>  > Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
>  > ---
>  > Re-posting patch with two recommended changes:
>  > 1. Dropped the PMC_MSP_UNCACHED configuration item as this was
>  > already available in arch/mips/Kconfig.debug.
>  > 3. Dropped 'else' case to simplify patch to do_watch() in
>  > arch/mips/kernel/traps.c
>  >
>  >  arch/mips/Kconfig           |   78 ++++++++++++++++++++
>  >  arch/mips/Makefile          |    8 ++
>  >  arch/mips/kernel/head.S     |    8 ++
>  >  arch/mips/kernel/traps.c    |    6 +
>  >  include/asm-mips/bootinfo.h |   12 +++
>  >  include/asm-mips/mipsregs.h |   30 +++++++
>  >  include/asm-mips/regops.h   |  168
>  > ++++++++++++++++++++++++++++++++++++++++++++
>  > include/asm-mips/war.h      |   11 ++ 8 files changed, 321 insertions(+)
> 
> My mailer kind of made a mess of things, hope I caught them all.
> 
>  > diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
>  > index 6f57ca4..d7451b1 100644
>  > --- a/arch/mips/kernel/head.S
>  > +++ b/arch/mips/kernel/head.S
>  > @@ -130,10 +130,18 @@
>  >       .endm
>  > 
>  >       /*
>  > +      * Reserverd space not required for PMC boards, although we 
> need to
>  > +      * jump to kernel start.
>  > +      */
>  > +#ifdef CONFIG_PMC_MSP
>  > +     jal     kernel_entry
>  > +#else
>  > +     /*
>  >        * Reserved space for exception handlers.
>  >        * Necessary for machines which link their kernels at KSEG0.
>  >        */
>  >       .fill   0x400
>  > +#endif /* CONFIG_PMC_MSP */
> 
> This is getting kind of ugly.  There are a whole lot of config choices
> that need to use the 'j kernel_entry'.  Do they all have to have their
> own?  I'm not sure what the best way is to handle them all.

I agree but don't know the best way to handle this. I could introduce a
SYS_NO_EXEPT_FILL or similar flag but this seems excessive.

Any other ideas from arch/mips folks?

I'm not sure why the fill is needed before _stext. The comment states
kernels linked against kseg0 require this. We link our kernels to
0x8010_0000 and expect that to be the start of text. We aren't
changing anything else in the startup code.


>  > diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
>  > index c7c945b..ab29fd4 100644
>  > --- a/include/asm-mips/bootinfo.h
>  > +++ b/include/asm-mips/bootinfo.h
>  > @@ -213,6 +213,18 @@
>  >  #define MACH_GROUP_NEC_EMMA2RH 25    /* NEC EMMA2RH (was 23)         */
>  > #define  MACH_NEC_MARKEINS    0       /* NEC EMMA2RH Mark-eins        */
>  > +/*
>  > + * Valid machtype for group PMC-MSP
>  > + */
>  > +#define MACH_GROUP_MSP         23    /* PMC-Sierra MSP 
> boards/CPUs    */
>  > +#define MACH_MSP4200_EVAL       0    /* PMC-Sierra MSP4200 
> Evaluation board */
>  > +#define MACH_MSP4200_GW         1    /* PMC-Sierra MSP4200 Gateway 
> demo board */
>  > +#define MACH_MSP4200_FPGA       2    /* PMC-Sierra MSP4200 Emulation 
> board */
>  > +#define MACH_MSP7120_EVAL       3    /* PMC-Sierra MSP7120 
> Evaluation board *
> /
>  > +#define MACH_MSP7120_GW         4    /* PMC-Sierra MSP7120 
> Residential Gateway board */
>  > +#define MACH_MSP7120_FPGA       5    /* PMC-Sierra MSP7120 Emulation 
> board */
>  > +#define MACH_MSP_OTHER        255    /* PMC-Sierra unknown board 
> type */
>  > +#define CL_SIZE                      COMMAND_LINE_SIZE
> 
> 
> Really I would add MACH_GROUP_MSP after MACH_GROUP_NEC_EMMA2RH,
> perhaps 27 or 28, rather than an interior number.  Especially if
> you are going to put it after MACH_GROUP_NEC_EMMA2RH in the file. ~:^)

Sure we aren't tied to this number. Looking at the numbering more closely,
it looks like numbers aren't reused when they are dropped so it may be
safer in case existing boards are still using 23.

Why do you recommend 27 or higher when apparently 26 hasn't been used?

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 17:09 [PATCH 2/5] mips: PMC MSP71xx mips common Marc St-Jean
@ 2007-02-27 17:38 ` Thiemo Seufer
  2007-02-28 19:32   ` Ralf Baechle
  2007-02-27 18:46 ` Andrew Sharp
  1 sibling, 1 reply; 29+ messages in thread
From: Thiemo Seufer @ 2007-02-27 17:38 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: Andrew Sharp, linux-mips

Marc St-Jean wrote:
[snip]
> >  > +#ifdef CONFIG_PMC_MSP
> >  > +     jal     kernel_entry
> >  > +#else

Maybe introduce a CONFIG_BOOT_RAW (and use it in arch/mips/Makefile
to objcopy the kernel to a raw binary).

> >  > +     /*
> >  >        * Reserved space for exception handlers.
> >  >        * Necessary for machines which link their kernels at KSEG0.
> >  >        */
> >  >       .fill   0x400
> >  > +#endif /* CONFIG_PMC_MSP */
> > 
> > This is getting kind of ugly.  There are a whole lot of config choices
> > that need to use the 'j kernel_entry'.  Do they all have to have their
> > own?  I'm not sure what the best way is to handle them all.
> 
> I agree but don't know the best way to handle this. I could introduce a
> SYS_NO_EXEPT_FILL or similar flag but this seems excessive.
> 
> Any other ideas from arch/mips folks?

Something like

#if LOADADDR == 0xffffffff80000000
	.fill	0x400
#endif

but by defining an appropriate name in arch/mips/Makefile instead of
externalizing the load-y/LOADADDR there.


Thiemo

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 17:09 [PATCH 2/5] mips: PMC MSP71xx mips common Marc St-Jean
  2007-02-27 17:38 ` Thiemo Seufer
@ 2007-02-27 18:46 ` Andrew Sharp
  2007-02-28 19:42   ` Ralf Baechle
  1 sibling, 1 reply; 29+ messages in thread
From: Andrew Sharp @ 2007-02-27 18:46 UTC (permalink / raw)
  To: linux-mips

On Tue, Feb 27, 2007 at 09:09:21AM -0800, Marc St-Jean wrote:
> 
> Andrew Sharp wrote:
> > On Mon, 26 Feb 2007 18:12:55 -0600 Marc St-Jean <stjeanma@pmc-sierra.com> wrote:
> >  > diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
> >  > index c7c945b..ab29fd4 100644
> >  > --- a/include/asm-mips/bootinfo.h
> >  > +++ b/include/asm-mips/bootinfo.h
> >  > @@ -213,6 +213,18 @@
> >  >  #define MACH_GROUP_NEC_EMMA2RH 25    /* NEC EMMA2RH (was 23)         */
> >  > #define  MACH_NEC_MARKEINS    0       /* NEC EMMA2RH Mark-eins        */
> >  > +/*
> >  > + * Valid machtype for group PMC-MSP
> >  > + */
> >  > +#define MACH_GROUP_MSP         23    /* PMC-Sierra MSP 
> > boards/CPUs    */
> >  > +#define MACH_MSP4200_EVAL       0    /* PMC-Sierra MSP4200 
> > Evaluation board */
> >  > +#define MACH_MSP4200_GW         1    /* PMC-Sierra MSP4200 Gateway 
> > demo board */
> >  > +#define MACH_MSP4200_FPGA       2    /* PMC-Sierra MSP4200 Emulation 
> > board */
> >  > +#define MACH_MSP7120_EVAL       3    /* PMC-Sierra MSP7120 
> > Evaluation board *
> > /
> >  > +#define MACH_MSP7120_GW         4    /* PMC-Sierra MSP7120 
> > Residential Gateway board */
> >  > +#define MACH_MSP7120_FPGA       5    /* PMC-Sierra MSP7120 Emulation 
> > board */
> >  > +#define MACH_MSP_OTHER        255    /* PMC-Sierra unknown board 
> > type */
> >  > +#define CL_SIZE                      COMMAND_LINE_SIZE
> > 
> > 
> > Really I would add MACH_GROUP_MSP after MACH_GROUP_NEC_EMMA2RH,
> > perhaps 27 or 28, rather than an interior number.  Especially if
> > you are going to put it after MACH_GROUP_NEC_EMMA2RH in the file. ~:^)
> 
> Sure we aren't tied to this number. Looking at the numbering more closely,
> it looks like numbers aren't reused when they are dropped so it may be
> safer in case existing boards are still using 23.
> 
> Why do you recommend 27 or higher when apparently 26 hasn't been used?

Experience. ~:^)  You never know when a little extra room for expansion
might come in handy.  For example, let's say next year you release a
quad-core SOC (hint-hint), and a line of eval boards.  You would have
room to put them in the file next to your other boards.  But just a
suggestion.

Cheers,

a

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 17:38 ` Thiemo Seufer
@ 2007-02-28 19:32   ` Ralf Baechle
  0 siblings, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-02-28 19:32 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Marc St-Jean, Andrew Sharp, linux-mips

On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:

> Something like
> 
> #if LOADADDR == 0xffffffff80000000
> 	.fill	0x400
> #endif
> 
> but by defining an appropriate name in arch/mips/Makefile instead of
> externalizing the load-y/LOADADDR there.

Basically a good idea but it will fail for 64-bit kernels so the test
would need to be extended to cover XKPHYS as well.  Also R2 processors
which have the c0_ebase registers do no need to reserve space for
exception handlers as they can easily move them elsewhere.

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 18:46 ` Andrew Sharp
@ 2007-02-28 19:42   ` Ralf Baechle
  0 siblings, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-02-28 19:42 UTC (permalink / raw)
  To: Andrew Sharp; +Cc: linux-mips

On Tue, Feb 27, 2007 at 10:46:01AM -0800, Andrew Sharp wrote:

> Experience. ~:^)  You never know when a little extra room for expansion
> might come in handy.  For example, let's say next year you release a
> quad-core SOC (hint-hint), and a line of eval boards.  You would have
> room to put them in the file next to your other boards.  But just a
> suggestion.

Since mips_machtype and mips_machgroup are mostly used to identify systems
within Linux changing would not be the most terrible thing on earth.
There is no requirement for these numbers to be contiguous either.

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-03-16 23:53 Marc St-Jean
@ 2007-03-17  0:46 ` Ralf Baechle
  0 siblings, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-03-17  0:46 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: linux-mips

On Fri, Mar 16, 2007 at 03:53:15PM -0800, Marc St-Jean wrote:

> I have been searching for information on this in various 34k manuals as
> well as Dominic's See MIPS Run 2nd Ed. and have not found this limitation
> stated anywhere.
> 
> Programming the MIPS32 34K Core Family (MD00427) Section 3.5 states:
> "The MIPS MT ASE requires that ll/sc also work between concurrent threads
> on an MT CPU. Each TC is equipped with a CP0 register called LLAddr, which
> remembers the physical address (at least to the enclosing 32-byte block) of
> the target location of any ll/sc sequence. The 34K core detects possible
> non-atomicity by checking every write made by any thread against the LLAddr
> of all other TCs."

These are implementation details for the 34K.  The 34K manual and MIPS MT
ASE documentation are extensions to the MIPS32 Revision 2 architecture.

> Doesn't the fact that a physical address is being compared imply any logical
> address type can be used?

You would be relying on an implementation detail, not the guaranteed
semantics of the instruction here.

Now, for a uniprocessor a _likely_ implementation is based on just the
comparing either the virtual or physical address.  I say likely because
it's the simplest implementation.  And yes, there is at least one
MIPS processor implemetation that does it differently, and where SC
will always fail even on uniprocessors when using uncached memory.

> > So to fix this you'd have to use something like this:
> > 
> >         unsigned long flags;
> >         spinlock_t lock;
> > 
> >         spin_lock_irqsave(&lock, flags);
> >         writel(readl(addr) | mask);
> >         spin_unlock_restore(&lock, flags);
> > 
> > Which of course is considerably slower and heavier weight.
> 
> I don't believe we can use a linux lock as the code running on the other TCs
> is not necessarily a linux driver/thread/process. It does not share linux's
> lock implementation.

In which case I suggest you move this file into an platform-specific
directory and add a big and fat comment to ensure nobody reuses the code.

> MIPS32 34K Processor Core Family Software User's Manual (MD00534)
> Store Conditional Word instruction states:
> "If either of the following events occurs between the execution of LL and
> SC, the SC may succeed or it may fail; the success or failure is not
> predictable. Portable programs should not cause one of these events.
>   -A memory access instruction (load, store, or prefetch) is executed on
>    the processor executing the LL/SC.
>   -The instructions executed starting with the LL and ending with the SC
>    do not lie in a 2048-byte contiguous region of virtual memory. (The
>    region does not have to be aligned, other than the alignment required
>    for instruction words.)"

The MIPS32 spec says for the SC instruction:

[...]
If either of the following events occurs between the execution of LL and SC,
the SC fails:
   • A coherent store is completed by another processor or coherent I/O
     module into the block of synchronizable physical memory containing
     the word. The size and alignment of the block is implementation
     dependent, but it is at least one word and at most the minimum page
     size.
   • An ERET instruction is executed.
[...]
Atomic RMW is provided only for synchronizable memory locations. A
synchronizable memory location is one that is associated with the state and
logic necessary to implement the LL/SC semantics. Whether a memory location
is synchronizable depends on the processor and system configurations, and on
the memory access type used for the location:

   • Uniprocessor atomicity: To provide atomic RMW on a single processor,
     all accesses to the location must be made with memory access type of
     either cached noncoherent or cached coherent. All accesses must be to
     one or the other access type, and they may not be mixed.
   • MP atomicity: To provide atomic RMW among multiple processors, all
     accesses to the location must be made with a memory access type of
     cached coherent.
   • I/O System: To provide atomic RMW with a coherent I/O system, all
     accesses to the location must be made with a memory access type of
     cached coherent. If the I/O system does not use coherent memory
     operations, then atomic RMW cannot be provided with respect to the
     I/O reads and writes.

Restrictions:

The addressed location must have a memory access type of cached noncoherent
or cached coherent; if it does not, the result is UNPREDICTABLE.

The effective address must be naturally-aligned. If either of the 2
least-significant bits of the address is non-zero, an Address Error exception
occurs.
[...]

> For the first of these points, if a failure occurs because of activity
> on another TC, the loop should repeat until success.
> 
> For the second point, the code between custom_reg32_read and
> custom_reg32_write is meant to be very simple. We can live with a
> 2k limit.

The 2k limit did show up in the MIPS architecture I think for MIPS IV,
so either the R8000 or R10000 over 10 years ago.  I'm not aware what the
technical reason for this restriction is.  I was wondering if it was just
future proofing.

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-03-16 23:53 Marc St-Jean
  2007-03-17  0:46 ` Ralf Baechle
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-03-16 23:53 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips



Ralf Baechle wrote:
> On Wed, Mar 07, 2007 at 12:01:34PM -0600, Marc St-Jean wrote:
> 
> Looks fine ...  except this one:
> 
>  > diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
>  > new file mode 100644
>  > index 0000000..375c667
>  > --- /dev/null
>  > +++ b/include/asm-mips/regops.h
>  > @@ -0,0 +1,166 @@
>  > +/*
>  > + * VPE/SMP-safe functions to access registers.  They use ll/sc 
> instructions, so
>  > + * it is your responsibility to ensure these are available on your 
> platform
>  > + * before including this file.
>  > + *
>  > + * In addition, there is a bug on the R10000 chips which has a 
> workaround.  If
>  > + * you are affected by this bug, make sure to define the symbol
>  > + * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header 
> from within
>  > + * linux, you may include <asm/war.h> before including this file to 
> have this
>  > + * defined appropriately for you.

[...]

>  > + */
>  > +
>  > +#ifndef __ASM_REGOPS_H__
>  > +#define __ASM_REGOPS_H__
>  > +
>  > +#ifndef R10000_LLSC_WAR
>  > +#define R10000_LLSC_WAR 0
>  > +#endif
> 
> Better include <asm/war.h> or R10000_LLSC_WAR might have an unexpected 
> value.

Thanks, will do.

>  > +#if R10000_LLSC_WAR == 1
>  > +#define __beqz       "beqzl  "
>  > +#else
>  > +#define __beqz       "beqz   "
>  > +#endif
>  > +
>  > +#ifndef _LINUX_TYPES_H
>  > +typedef unsigned int uint32_t;
>  > +#endif
> 
> Again, include <linux/types.h>.  Including this file first then 
> <linux/types.h>
> will result in a duplicate definition ...

OK.

>  > +/*
>  > + * Sets all the masked bits to the corresponding value bits
>  > + */
>  > +static inline void set_value_reg32( volatile uint32_t * const addr,
>  > +                                     uint32_t const mask,
>  > +                                     uint32_t const value )
>  > +{
>  > +     uint32_t temp;
>  > +
>  > +     __asm__ __volatile__(
>  > +     "       .set    mips3                           \n"
>  > +     "1:     ll      %0, %1  # set_value_reg32       \n"
>  > +     "       and     %0, %2                          \n"
>  > +     "       or      %0, %3                          \n"
>  > +     "       sc      %0, %1                          \n"
>  > +     "       "__beqz"%0, 1b                          \n"
>  > +     "       .set    mips0                           \n"
>  > +     : "=&r" (temp), "=m" (*addr)
>  > +     : "ir" (~mask), "ir" (value), "m" (*addr) );
>  > +}
>  > +
>  > +/*
>  > + * Sets all the masked bits to '1'
>  > + */
>  > +static inline void set_reg32( volatile uint32_t * const addr,
>  > +                             uint32_t const mask )
>  > +{
>  > +     uint32_t temp;
>  > +
>  > +     __asm__ __volatile__(
>  > +     "       .set    mips3                           \n"
>  > +     "1:     ll      %0, %1          # set_reg32     \n"
>  > +     "       or      %0, %2                          \n"
>  > +     "       sc      %0, %1                          \n"
>  > +     "       "__beqz"%0, 1b                          \n"
>  > +     "       .set    mips0                           \n"
>  > +     : "=&r" (temp), "=m" (*addr)
>  > +     : "ir" (mask), "m" (*addr) );
>  > +}
>  > +
>  > +/*
>  > + * Sets all the masked bits to '0'
>  > + */
>  > +static inline void clear_reg32( volatile uint32_t * const addr,
>  > +                             uint32_t const mask )
>  > +{
>  > +     uint32_t temp;
>  > +
>  > +     __asm__ __volatile__(
>  > +     "       .set    mips3                           \n"
>  > +     "1:     ll      %0, %1          # clear_reg32   \n"
>  > +     "       and     %0, %2                          \n"
>  > +     "       sc      %0, %1                          \n"
>  > +     "       "__beqz"%0, 1b                          \n"
>  > +     "       .set    mips0                           \n"
>  > +     : "=&r" (temp), "=m" (*addr)
>  > +     : "ir" (~mask), "m" (*addr) );
>  > +}
>  > +
>  > +/*
>  > + * Toggles all masked bits from '0' to '1' and '1' to '0'
>  > + */
>  > +static inline void toggle_reg32( volatile uint32_t * const addr,
>  > +                             uint32_t const mask )
>  > +{
>  > +     uint32_t temp;
>  > +
>  > +     __asm__ __volatile__(
>  > +     "       .set    mips3                           \n"
>  > +     "1:     ll      %0, %1          # toggle_reg32  \n"
>  > +     "       xor     %0, %2                          \n"
>  > +     "       sc      %0, %1                          \n"
>  > +     "       "__beqz"%0, 1b                          \n"
>  > +     "       .set    mips0                           \n"
>  > +     : "=&r" (temp), "=m" (*addr)
>  > +     : "ir" (mask), "m" (*addr) );
>  > +}
> 
> As I understand you're using the preceeding 4 functions with the address
> pointing to device registers, that is uncached memory?  The operation of
> ll/sc on uncached memory is undefined.

I have been searching for information on this in various 34k manuals as
well as Dominic's See MIPS Run 2nd Ed. and have not found this limitation
stated anywhere.

Programming the MIPS32 34K Core Family (MD00427) Section 3.5 states:
"The MIPS MT ASE requires that ll/sc also work between concurrent threads
on an MT CPU. Each TC is equipped with a CP0 register called LLAddr, which
remembers the physical address (at least to the enclosing 32-byte block) of
the target location of any ll/sc sequence. The 34K core detects possible
non-atomicity by checking every write made by any thread against the LLAddr
of all other TCs."

Doesn't the fact that a physical address is being compared imply any logical
address type can be used?


> So to fix this you'd have to use something like this:
> 
>         unsigned long flags;
>         spinlock_t lock;
> 
>         spin_lock_irqsave(&lock, flags);
>         writel(readl(addr) | mask);
>         spin_unlock_restore(&lock, flags);
> 
> Which of course is considerably slower and heavier weight.

I don't believe we can use a linux lock as the code running on the other TCs
is not necessarily a linux driver/thread/process. It does not share linux's
lock implementation.


>  > +/* For special strange cases only:
>  > + *
>  > + * If you need custom processing within a ll/sc loop, use the 
> following macros
>  > + * VERY CAREFULLY:
>  > + *
>  > + *   uint32_t tmp;                      <-- Define a variable to 
> hold the data
>  > + *
>  > + *   custom_reg32_start(address, tmp);       <-- Reads the address 
> and puts the value
>  > + *                                           in the 'tmp' variable 
> given
>  > + *
>  > + *   < From here on out, you are (basicly) atomic, so don't do 
> anything too
>  > + *   < fancy!
>  > + *   < Also, this code may loop if the end of this block fails to write
>  > + *   < everything back safely due do the other CPU, so do NOT do 
> anything
>  > + *   < with side-effects!
>  > + *
>  > + *   custom_reg32_stop(address, tmp);        <-- Writes back 'tmp' 
> safely.
>  > + *
>  > + */
>  > +#define custom_reg32_read(address, tmp)                              \
>  > +     __asm__ __volatile__(                                   \
>  > +     "       .set    mips3                           \n"     \
>  > +     "1:     ll      %0, %1  #custom_reg32_read      \n"     \
>  > +     "       .set    mips0                           \n"     \
>  > +     : "=r" (tmp), "=m" (*address)                           \
>  > +     : "m" (*address) )
>  > +
>  > +#define custom_reg32_write(address, tmp)                     \
>  > +     __asm__ __volatile__(                                   \
>  > +     "       .set    mips3                           \n"     \
>  > +     "       sc      %0, %1  #custom_reg32_write     \n"     \
>  > +     "       "__beqz"%0, 1b                          \n"     \
>  > +     "       .set    mips0                           \n"     \
>  > +     : "=&r" (tmp), "=m" (*address)                          \
>  > +     : "0" (tmp), "m" (*address) )
>  > +
>  > +#endif  /* __ASM_REGOPS_H__ */
> 
> Same comment as above applies for uncached accesses.
> 
> I used to have functions that expand into ll/sc in the kernel ages ago -
> gcc did generate interesting (for some definition of interesting) but not
> terribly useful code from it.  The chance that something like this is
> happening has grown even further thanks to the more agressive optimizer
> of modern gcc.
> 
> A valid ll/sc sequence also requires that there may not be another
> load or store in between these two instructions.  So for example:

MIPS32 34K Processor Core Family Software User's Manual (MD00534)
Store Conditional Word instruction states:
"If either of the following events occurs between the execution of LL and
SC, the SC may succeed or it may fail; the success or failure is not
predictable. Portable programs should not cause one of these events.
  -A memory access instruction (load, store, or prefetch) is executed on
   the processor executing the LL/SC.
  -The instructions executed starting with the LL and ending with the SC
   do not lie in a 2048-byte contiguous region of virtual memory. (The
   region does not have to be aligned, other than the alignment required
   for instruction words.)"

For the first of these points, if a failure occurs because of activity
on another TC, the loop should repeat until success.

For the second point, the code between custom_reg32_read and
custom_reg32_write is meant to be very simple. We can live with a
2k limit.


> +                       custom_reg32_read(MSP_GPIO_DATA_REGISTER[gpio],
> +                                         tmpdata);
> +                       if (tmpdata & EXTENDED_CLR(gpio))
> +                               tmpdata = EXTENDED_CLR(gpio);
> +                       else
> +                               tmpdata = EXTENDED_SET(gpio);
> +                       custom_reg32_write(MSP_GPIO_DATA_REGISTER[gpio],
> +                                          tmpdata);
> 
> What if gcc just because it feels like it puts tmpdata or gpio into the
> stackframe?  In this particular case there is little register pressure
> so it's unlikely but be afraid, be very afraid ...
> 
>   Ralf

We've been using this for a year with different versions of gcc and
have not encountered any problems. We could declare tmpdata as
"register" and increase the odds of it being allocated into a register.

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-03-07 18:01 Marc St-Jean
@ 2007-03-16  1:58 ` Ralf Baechle
  0 siblings, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-03-16  1:58 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: linux-mips

On Wed, Mar 07, 2007 at 12:01:34PM -0600, Marc St-Jean wrote:

Looks fine ...  except this one:

> diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
> new file mode 100644
> index 0000000..375c667
> --- /dev/null
> +++ b/include/asm-mips/regops.h
> @@ -0,0 +1,166 @@
> +/*
> + * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
> + * it is your responsibility to ensure these are available on your platform
> + * before including this file.
> + *
> + * In addition, there is a bug on the R10000 chips which has a workaround.  If
> + * you are affected by this bug, make sure to define the symbol
> + * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
> + * linux, you may include <asm/war.h> before including this file to have this
> + * defined appropriately for you.
> + *
> + * Copyright 2005 PMC-Sierra, Inc.
> + *
> + *  This program is free software; you can redistribute  it and/or modify it
> + *  under  the terms of  the GNU General  Public License as published by the
> + *  Free Software Foundation;  either version 2 of the  License, or (at your
> + *  option) any later version.
> + *
> + *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
> + *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
> + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
> + *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
> + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
> + *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + *
> + *  You should have received a copy of the  GNU General Public License along
> + *  with this program; if not, write  to the Free Software Foundation, Inc., 675
> + *  Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __ASM_REGOPS_H__
> +#define __ASM_REGOPS_H__
> +
> +#ifndef R10000_LLSC_WAR
> +#define R10000_LLSC_WAR 0
> +#endif

Better include <asm/war.h> or R10000_LLSC_WAR might have an unexpected value.

> +#if R10000_LLSC_WAR == 1
> +#define __beqz	"beqzl	"
> +#else
> +#define __beqz	"beqz	"
> +#endif
> +
> +#ifndef _LINUX_TYPES_H
> +typedef unsigned int uint32_t;
> +#endif

Again, include <linux/types.h>.  Including this file first then <linux/types.h>
will result in a duplicate definition ...

> +/*
> + * Sets all the masked bits to the corresponding value bits
> + */
> +static inline void set_value_reg32( volatile uint32_t * const addr,
> +					uint32_t const mask,
> +					uint32_t const value )
> +{
> +	uint32_t temp;
> +
> +	__asm__ __volatile__(
> +	"	.set	mips3				\n"
> +	"1:	ll	%0, %1	# set_value_reg32	\n"
> +	"	and	%0, %2				\n"
> +	"	or	%0, %3				\n"
> +	"	sc	%0, %1				\n"
> +	"	"__beqz"%0, 1b				\n"
> +	"	.set	mips0				\n"
> +	: "=&r" (temp), "=m" (*addr)
> +	: "ir" (~mask), "ir" (value), "m" (*addr) );
> +}
> +
> +/*
> + * Sets all the masked bits to '1'
> + */
> +static inline void set_reg32( volatile uint32_t * const addr,
> +				uint32_t const mask )
> +{
> +	uint32_t temp;
> +
> +	__asm__ __volatile__(
> +	"	.set	mips3				\n"
> +	"1:	ll	%0, %1		# set_reg32	\n"
> +	"	or	%0, %2				\n"
> +	"	sc	%0, %1				\n"
> +	"	"__beqz"%0, 1b				\n"
> +	"	.set	mips0				\n"
> +	: "=&r" (temp), "=m" (*addr)
> +	: "ir" (mask), "m" (*addr) );
> +}
> +
> +/*
> + * Sets all the masked bits to '0'
> + */
> +static inline void clear_reg32( volatile uint32_t * const addr,
> +				uint32_t const mask )
> +{
> +	uint32_t temp;
> +
> +	__asm__ __volatile__(
> +	"	.set	mips3				\n"
> +	"1:	ll	%0, %1		# clear_reg32	\n"
> +	"	and	%0, %2				\n"
> +	"	sc	%0, %1				\n"
> +	"	"__beqz"%0, 1b				\n"
> +	"	.set	mips0				\n"
> +	: "=&r" (temp), "=m" (*addr)
> +	: "ir" (~mask), "m" (*addr) );
> +}
> +
> +/*
> + * Toggles all masked bits from '0' to '1' and '1' to '0'
> + */
> +static inline void toggle_reg32( volatile uint32_t * const addr,
> +				uint32_t const mask )
> +{
> +	uint32_t temp;
> +
> +	__asm__ __volatile__(
> +	"	.set	mips3				\n"
> +	"1:	ll	%0, %1		# toggle_reg32	\n"
> +	"	xor	%0, %2				\n"
> +	"	sc	%0, %1				\n"
> +	"	"__beqz"%0, 1b				\n"
> +	"	.set	mips0				\n"
> +	: "=&r" (temp), "=m" (*addr)
> +	: "ir" (mask), "m" (*addr) );
> +}

As I understand you're using the preceeding 4 functions with the address
pointing to device registers, that is uncached memory?  The operation of
ll/sc on uncached memory is undefined.

So to fix this you'd have to use something like this:

	unsigned long flags;
	spinlock_t lock;

	spin_lock_irqsave(&lock, flags);
	writel(readl(addr) | mask);
	spin_unlock_restore(&lock, flags);

Which of course is considerably slower and heavier weight.

> +/* For special strange cases only:
> + *
> + * If you need custom processing within a ll/sc loop, use the following macros
> + * VERY CAREFULLY:
> + *
> + *   uint32_t tmp;                      <-- Define a variable to hold the data
> + *
> + *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
> + *						in the 'tmp' variable given
> + *
> + *	< From here on out, you are (basicly) atomic, so don't do anything too
> + *	< fancy!
> + *	< Also, this code may loop if the end of this block fails to write
> + *	< everything back safely due do the other CPU, so do NOT do anything
> + *	< with side-effects!
> + *
> + *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
> + *
> + */
> +#define custom_reg32_read(address, tmp)				\
> +	__asm__ __volatile__(					\
> +	"	.set	mips3				\n"	\
> +	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
> +	"	.set	mips0				\n"	\
> +	: "=r" (tmp), "=m" (*address)				\
> +	: "m" (*address) )
> +
> +#define custom_reg32_write(address, tmp)			\
> +	__asm__ __volatile__(					\
> +	"	.set	mips3				\n"	\
> +	"	sc	%0, %1	#custom_reg32_write	\n"	\
> +	"	"__beqz"%0, 1b				\n"	\
> +	"	.set	mips0				\n"	\
> +	: "=&r" (tmp), "=m" (*address)				\
> +	: "0" (tmp), "m" (*address) )
> +
> +#endif  /* __ASM_REGOPS_H__ */

Same comment as above applies for uncached accesses.

I used to have functions that expand into ll/sc in the kernel ages ago -
gcc did generate interesting (for some definition of interesting) but not
terribly useful code from it.  The chance that something like this is
happening has grown even further thanks to the more agressive optimizer
of modern gcc.

A valid ll/sc sequence also requires that there may not be another
load or store in between these two instructions.  So for example:

+                       custom_reg32_read(MSP_GPIO_DATA_REGISTER[gpio],
+                                         tmpdata);
+                       if (tmpdata & EXTENDED_CLR(gpio))
+                               tmpdata = EXTENDED_CLR(gpio);
+                       else
+                               tmpdata = EXTENDED_SET(gpio);
+                       custom_reg32_write(MSP_GPIO_DATA_REGISTER[gpio],
+                                          tmpdata);

What if gcc just because it feels like it puts tmpdata or gpio into the
stackframe?  In this particular case there is little register pressure
so it's unlikely but be afraid, be very afraid ...

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-03-07 18:01 Marc St-Jean
  2007-03-16  1:58 ` Ralf Baechle
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-03-07 18:01 UTC (permalink / raw)
  To: linux-mips

[PATCH 2/5] mips: PMC MSP71xx mips common

Patch to add mips common support for the PMC-Sierra
MSP71xx devices.

These 5 patches along with the previously posted serial patch
will boot the PMC-Sierra MSP7120 Residential Gateway board.

Thanks,
Marc

Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
---
Re-posting patch with recommended changes:
-Moved 34K errata checking from platfrom patch to an check_errata
function called from check_bugs32().
(arch/mips/kernel/cpu-probe.c, include/asm-mips/cpu.h,
include/asm-mips/mipsregs.h)

 arch/mips/Kconfig            |   87 ++++++++++++++++++++++
 arch/mips/Makefile           |   11 ++
 arch/mips/kernel/cpu-probe.c |   20 +++++
 arch/mips/kernel/head.S      |    5 +
 arch/mips/kernel/traps.c     |    6 +
 include/asm-mips/bootinfo.h  |   12 +++
 include/asm-mips/cpu.h       |    2 
 include/asm-mips/mipsregs.h  |   33 ++++++++
 include/asm-mips/regops.h    |  166 +++++++++++++++++++++++++++++++++++++++++++
 include/asm-mips/war.h       |   11 ++
 10 files changed, 351 insertions(+), 2 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5da6b0d..899c528 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -354,6 +354,7 @@ config MIPS_SIM
 	bool 'MIPS simulator (MIPSsim)'
 	select DMA_NONCOHERENT
 	select IRQ_CPU
+	select BOOT_RAW
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -504,6 +505,27 @@ config MACH_VR41XX
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+	bool "PMC-Sierra MSP chipsets"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select SWAP_IO_SPACE
+	select NO_EXCEPT_FILL
+	select BOOT_RAW
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
+	select IRQ_CPU
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	help
+	  This adds support for the PMC-Sierra family of Multi-Service
+	  Processor System-On-A-Chips.  These parts include a number
+	  of integrated peripherals, interfaces and DSPs in addition to
+	  a variety of MIPS cores.
+
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
 	select DMA_COHERENT
@@ -815,6 +837,55 @@ config TOSHIBA_RBTX4938
 
 endchoice
 
+choice
+	prompt "PMC-Sierra MSP SOC type"
+	depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+	bool "PMC-Sierra MSP4200 Eval Board"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+	bool "PMC-Sierra MSP7120 Eval Board"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_GW
+	bool "PMC-Sierra MSP7120 Residential Gateway"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_FPGA
+	bool "PMC-Sierra MSP7120 FPGA"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+	depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+	bool "Root filesystem embedded in kernel image"
+	select MTD
+	select MTD_BLOCK
+	select MTD_PMC_MSP_RAMROOT
+	select MTD_RAM
+
+endmenu
+
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
@@ -879,6 +950,9 @@ config ARC
 config ARCH_MAY_HAVE_PC_FDC
 	bool
 
+config BOOT_RAW
+	bool
+
 config DMA_COHERENT
 	bool
 
@@ -924,6 +998,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
 
 config GENERIC_ISA_DMA_SUPPORT_BROKEN
 	bool
+	
+config NO_EXCEPT_FILL
+	bool
 
 #
 # Endianess selection.  Sufficiently obscure so many users don't know what to
@@ -971,6 +1048,15 @@ config IRQ_CPU_RM9K
 config IRQ_MV64340
 	bool
 
+config IRQ_MSP_SLP
+	bool
+
+config IRQ_MSP_CIC
+	bool
+
+config MSP_USB
+	bool
+
 config DDB5XXX_COMMON
 	bool
 	select SYS_SUPPORTS_KGDB
@@ -1086,6 +1172,7 @@ config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
+	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 92bca6a..1c38332 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -360,6 +360,14 @@ core-$(CONFIG_MOMENCO_OCELOT_C)	+= arch/mips/momentum/ocelot_c/
 load-$(CONFIG_MOMENCO_OCELOT_C)	+= 0xffffffff80100000
 
 #
+# PMC-Sierra MSP SOCs
+#
+core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)	+= -Iinclude/asm-mips/pmc-sierra/msp71xx \
+					-mno-branch-likely
+load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
+
+#
 # PMC-Sierra Yosemite
 #
 core-$(CONFIG_PMC_YOSEMITE)	+= arch/mips/pmc-sierra/yosemite/
@@ -619,7 +627,8 @@ JIFFIES			= jiffies_64
 endif
 
 AFLAGS		+= $(cflags-y)
-CFLAGS		+= $(cflags-y)
+CFLAGS		+= $(cflags-y) \
+			-D"VMLINUX_LOAD_ADDRESS=$(load-y)"
 
 LDFLAGS			+= -m $(ld-emul)
 
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca4..27366f6 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/threads.h>
 
+#include <asm/addrspace.h>
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/irqflags.h>
@@ -129,16 +130,18 @@
 #endif
 	.endm
 
+#ifndef CONFIG_NO_EXCEPT_FILL
 	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#endif
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
 
-#ifdef CONFIG_MIPS_SIM
+#ifdef CONFIG_BOOT_RAW
 	/*
 	 * Give us a fighting chance of running if execution beings at the
 	 * kernel load address.  This is needed because this platform does
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ab755ea..ce8c9c7 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -165,9 +165,29 @@ static inline void check_wait(void)
 	}
 }
 
+static inline void check_errata(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	switch (c->cputype) {
+	case CPU_34K:
+		/*
+		 * Erratum "RPS May Cause Incorrect Instruction Execution"
+		 * This code only handles VPE0, any SMP/SMTC/RTOS code
+		 * making use of VPE1 will be responsable for that VPE.
+		 */
+		if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
+			write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
+		break;
+	default:
+		break;
+	}
+}
+
 void __init check_bugs32(void)
 {
 	check_wait();
+	check_errata();
 }
 
 /*
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..2c812c2 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -860,6 +861,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	if (board_watchpoint_handler) {
+		(*board_watchpoint_handler)(regs);
+		return;
+	}
+	
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index c7c945b..7fc52c7 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -213,6 +213,18 @@
 #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
 #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
 
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         26	/* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
+#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
+#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
+#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation board */
+#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
+#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
+#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
index d38fdbf..9415dc2 100644
--- a/include/asm-mips/cpu.h
+++ b/include/asm-mips/cpu.h
@@ -107,6 +107,7 @@
  * Definitions for 7:0 on legacy processors
  */
 
+#define PRID_REV_MASK		0x00ff
 
 #define PRID_REV_TX4927		0x0022
 #define PRID_REV_TX4937		0x0030
@@ -123,6 +124,7 @@
 #define PRID_REV_VR4122		0x0070
 #define PRID_REV_VR4181A	0x0070	/* Same as VR4122 */
 #define PRID_REV_VR4130		0x0080
+#define PRID_REV_34K_V1_0_2	0x0022
 
 /*
  * FPU implementation/revision register (CP1 control register 0).
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7..fb3c76e 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
@@ -534,6 +535,9 @@
 #define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
 
+#define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
+
+
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
  */
@@ -1292,10 +1296,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+	int res = 0;
+
+	__asm__ __volatile__(
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+	"	.set	mips32r2					\n"
+	"	.word	0x41610001		# dvpe $1		\n"
+	"	move	%0, $1						\n"
+	"	ehb							\n"
+	"	.set	pop						\n"
+	: "=r" (res));
+
+	instruction_hazard();
+#endif
+
 	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"tlbr\n\t"
 		".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+	if ((res & _ULCAST_(1)))
+		__asm__ __volatile__(
+		"	.set	push						\n"
+		"	.set	noreorder					\n"
+		"	.set	noat						\n"
+		"	.set	mips32r2					\n"
+		"	.word	0x41600021		# evpe			\n"
+		"	ehb							\n"
+		"	.set	pop						\n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 13a3502..74c08e6 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -196,6 +196,14 @@
 #endif
 
 /*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+	defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
 #ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -234,5 +242,8 @@
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR			0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
new file mode 100644
index 0000000..375c667
--- /dev/null
+++ b/include/asm-mips/regops.h
@@ -0,0 +1,166 @@
+/*
+ * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
+ * it is your responsibility to ensure these are available on your platform
+ * before including this file.
+ *
+ * In addition, there is a bug on the R10000 chips which has a workaround.  If
+ * you are affected by this bug, make sure to define the symbol
+ * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
+ * linux, you may include <asm/war.h> before including this file to have this
+ * defined appropriately for you.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz	"beqzl	"
+#else
+#define __beqz	"beqz	"
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int uint32_t;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32( volatile uint32_t * const addr,
+					uint32_t const mask,
+					uint32_t const value )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1	# set_value_reg32	\n"
+	"	and	%0, %2				\n"
+	"	or	%0, %3				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "ir" (value), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# set_reg32	\n"
+	"	or	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# clear_reg32	\n"
+	"	and	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "m" (*addr) );
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# toggle_reg32	\n"
+	"	xor	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/* For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   uint32_t tmp;                      <-- Define a variable to hold the data
+ *
+ *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
+ *						in the 'tmp' variable given
+ *
+ *	< From here on out, you are (basicly) atomic, so don't do anything too
+ *	< fancy!
+ *	< Also, this code may loop if the end of this block fails to write
+ *	< everything back safely due do the other CPU, so do NOT do anything
+ *	< with side-effects!
+ *
+ *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
+ *
+ */
+#define custom_reg32_read(address, tmp)				\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
+	"	.set	mips0				\n"	\
+	: "=r" (tmp), "=m" (*address)				\
+	: "m" (*address) )
+
+#define custom_reg32_write(address, tmp)			\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"	sc	%0, %1	#custom_reg32_write	\n"	\
+	"	"__beqz"%0, 1b				\n"	\
+	"	.set	mips0				\n"	\
+	: "=&r" (tmp), "=m" (*address)				\
+	: "0" (tmp), "m" (*address) )
+
+#endif  /* __ASM_REGOPS_H__ */

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-03-01 20:41 Marc St-Jean
  0 siblings, 0 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-03-01 20:41 UTC (permalink / raw)
  To: linux-mips

[PATCH 2/5] mips: PMC MSP71xx mips common

Patch to add mips common support for the PMC-Sierra
MSP71xx devices.

These 5 patches along with the previously posted serial patch
will boot the PMC-Sierra MSP7120 Residential Gateway board.

Thanks,
Marc

Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
---
Re-posting patch with recommended change:
Added CONFIG_NO_EXCEPT_FILL option and selected in PMC_MSP
to eliminate the .fill for exception handlers.
(arch/mips/Kconfig, arch/mips/kernel/head.S)

 arch/mips/Kconfig           |   87 ++++++++++++++++++++++
 arch/mips/Makefile          |   11 ++
 arch/mips/kernel/head.S     |    5 +
 arch/mips/kernel/traps.c    |    6 +
 include/asm-mips/bootinfo.h |   12 +++
 include/asm-mips/mipsregs.h |   30 +++++++
 include/asm-mips/regops.h   |  168 ++++++++++++++++++++++++++++++++++++++++++++
 include/asm-mips/war.h      |   11 ++
 8 files changed, 328 insertions(+), 2 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5da6b0d..899c528 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -354,6 +354,7 @@ config MIPS_SIM
 	bool 'MIPS simulator (MIPSsim)'
 	select DMA_NONCOHERENT
 	select IRQ_CPU
+	select BOOT_RAW
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -504,6 +505,27 @@ config MACH_VR41XX
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+	bool "PMC-Sierra MSP chipsets"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select SWAP_IO_SPACE
+	select NO_EXCEPT_FILL
+	select BOOT_RAW
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
+	select IRQ_CPU
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	help
+	  This adds support for the PMC-Sierra family of Multi-Service
+	  Processor System-On-A-Chips.  These parts include a number
+	  of integrated peripherals, interfaces and DSPs in addition to
+	  a variety of MIPS cores.
+
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
 	select DMA_COHERENT
@@ -815,6 +837,55 @@ config TOSHIBA_RBTX4938
 
 endchoice
 
+choice
+	prompt "PMC-Sierra MSP SOC type"
+	depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+	bool "PMC-Sierra MSP4200 Eval Board"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+	bool "PMC-Sierra MSP7120 Eval Board"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_GW
+	bool "PMC-Sierra MSP7120 Residential Gateway"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_FPGA
+	bool "PMC-Sierra MSP7120 FPGA"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+	depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+	bool "Root filesystem embedded in kernel image"
+	select MTD
+	select MTD_BLOCK
+	select MTD_PMC_MSP_RAMROOT
+	select MTD_RAM
+
+endmenu
+
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
@@ -879,6 +950,9 @@ config ARC
 config ARCH_MAY_HAVE_PC_FDC
 	bool
 
+config BOOT_RAW
+	bool
+
 config DMA_COHERENT
 	bool
 
@@ -924,6 +998,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
 
 config GENERIC_ISA_DMA_SUPPORT_BROKEN
 	bool
+	
+config NO_EXCEPT_FILL
+	bool
 
 #
 # Endianess selection.  Sufficiently obscure so many users don't know what to
@@ -971,6 +1048,15 @@ config IRQ_CPU_RM9K
 config IRQ_MV64340
 	bool
 
+config IRQ_MSP_SLP
+	bool
+
+config IRQ_MSP_CIC
+	bool
+
+config MSP_USB
+	bool
+
 config DDB5XXX_COMMON
 	bool
 	select SYS_SUPPORTS_KGDB
@@ -1086,6 +1172,7 @@ config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
+	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 92bca6a..1c38332 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -360,6 +360,14 @@ core-$(CONFIG_MOMENCO_OCELOT_C)	+= arch/mips/momentum/ocelot_c/
 load-$(CONFIG_MOMENCO_OCELOT_C)	+= 0xffffffff80100000
 
 #
+# PMC-Sierra MSP SOCs
+#
+core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)	+= -Iinclude/asm-mips/pmc-sierra/msp71xx \
+					-mno-branch-likely
+load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
+
+#
 # PMC-Sierra Yosemite
 #
 core-$(CONFIG_PMC_YOSEMITE)	+= arch/mips/pmc-sierra/yosemite/
@@ -619,7 +627,8 @@ JIFFIES			= jiffies_64
 endif
 
 AFLAGS		+= $(cflags-y)
-CFLAGS		+= $(cflags-y)
+CFLAGS		+= $(cflags-y) \
+			-D"VMLINUX_LOAD_ADDRESS=$(load-y)"
 
 LDFLAGS			+= -m $(ld-emul)
 
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca4..27366f6 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/threads.h>
 
+#include <asm/addrspace.h>
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/irqflags.h>
@@ -129,16 +130,18 @@
 #endif
 	.endm
 
+#ifndef CONFIG_NO_EXCEPT_FILL
 	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#endif
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
 
-#ifdef CONFIG_MIPS_SIM
+#ifdef CONFIG_BOOT_RAW
 	/*
 	 * Give us a fighting chance of running if execution beings at the
 	 * kernel load address.  This is needed because this platform does
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..2c812c2 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -860,6 +861,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	if (board_watchpoint_handler) {
+		(*board_watchpoint_handler)(regs);
+		return;
+	}
+	
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index c7c945b..7fc52c7 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -213,6 +213,18 @@
 #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
 #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
 
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         26	/* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
+#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
+#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
+#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation board */
+#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
+#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
+#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7..bd683b6 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
@@ -1292,10 +1293,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+	int res = 0;
+
+	__asm__ __volatile__(
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+	"	.set	mips32r2					\n"
+	"	.word	0x41610001		# dvpe $1		\n"
+	"	move	%0, $1						\n"
+	"	ehb							\n"
+	"	.set	pop						\n"
+	: "=r" (res));
+
+	instruction_hazard();
+#endif
+
 	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"tlbr\n\t"
 		".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+	if ((res & _ULCAST_(1)))
+		__asm__ __volatile__(
+		"	.set	push						\n"
+		"	.set	noreorder					\n"
+		"	.set	noat						\n"
+		"	.set	mips32r2					\n"
+		"	.word	0x41600021		# evpe			\n"
+		"	ehb							\n"
+		"	.set	pop						\n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 13a3502..74c08e6 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -196,6 +196,14 @@
 #endif
 
 /*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+	defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
 #ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -234,5 +242,8 @@
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR			0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
new file mode 100644
index 0000000..fbfc940
--- /dev/null
+++ b/include/asm-mips/regops.h
@@ -0,0 +1,168 @@
+/*
+ * $Id: regops.h,v 1.2 2006/05/08 22:00:34 ramsayji Exp $
+ *
+ * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
+ * it is your responsibility to ensure these are available on your platform
+ * before including this file.
+ *
+ * In addition, there is a bug on the R10000 chips which has a workaround.  If
+ * you are affected by this bug, make sure to define the symbol
+ * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
+ * linux, you may include <asm/war.h> before including this file to have this
+ * defined appropriately for you.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz	"beqzl	"
+#else
+#define __beqz	"beqz	"
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int uint32_t;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32( volatile uint32_t * const addr,
+					uint32_t const mask,
+					uint32_t const value )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1	# set_value_reg32	\n"
+	"	and	%0, %2				\n"
+	"	or	%0, %3				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "ir" (value), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# set_reg32	\n"
+	"	or	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# clear_reg32	\n"
+	"	and	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "m" (*addr) );
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# toggle_reg32	\n"
+	"	xor	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/* For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   uint32_t tmp;                      <-- Define a variable to hold the data
+ *
+ *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
+ *						in the 'tmp' variable given
+ *
+ *	< From here on out, you are (basicly) atomic, so don't do anything too
+ *	< fancy!
+ *	< Also, this code may loop if the end of this block fails to write
+ *	< everything back safely due do the other CPU, so do NOT do anything
+ *	< with side-effects!
+ *
+ *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
+ *
+ */
+#define custom_reg32_read(address, tmp)				\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
+	"	.set	mips0				\n"	\
+	: "=r" (tmp), "=m" (*address)				\
+	: "m" (*address) )
+
+#define custom_reg32_write(address, tmp)			\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"	sc	%0, %1	#custom_reg32_write	\n"	\
+	"	"__beqz"%0, 1b				\n"	\
+	"	.set	mips0				\n"	\
+	: "=&r" (tmp), "=m" (*address)				\
+	: "0" (tmp), "m" (*address) )
+
+#endif  /* __ASM_REGOPS_H__ */

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-28 22:35 Marc St-Jean
  0 siblings, 0 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-28 22:35 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips



Ralf Baechle wrote:
> On Wed, Feb 28, 2007 at 01:35:32PM -0800, Marc St-Jean wrote:
> 
>  > Ralf Baechle wrote:
>  > > On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:
>  > >
>  > >  > Something like
>  > >  >
>  > >  > #if LOADADDR == 0xffffffff80000000
>  > >  >       .fill   0x400
>  > >  > #endif
>  > >  >
>  > >  > but by defining an appropriate name in arch/mips/Makefile 
> instead of
>  > >  > externalizing the load-y/LOADADDR there.
>  > >
>  > > Basically a good idea but it will fail for 64-bit kernels so the test
>  > > would need to be extended to cover XKPHYS as well.  Also R2 processors
>  > > which have the c0_ebase registers do no need to reserve space for
>  > > exception handlers as they can easily move them elsewhere.
>  > >
>  > >   Ralf
>  >
>  > Hi Ralf,
>  >
>  >  From your description it sounds like not all R2 CPUs have c0_ebase 
> registers?
>  >
>  > I don't know how to check for c0_ebase from the pre-processor, the 
> test below
>  > assumes they all do.
> 
> Sorry for being ambigous.  All R2 processors have ebase.  However Linux
> happens to support older processors as well, that was my point.
> 
>  > How about something like:
>  >
>  > #if (defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) && \
>  >                  VMLINUX_LOAD_ADDRESS == CKSEG0) || \
>  >          ((defined(CONFIG_SYS_HAS_CPU_MIPS64_R1) || 
> defined(CONFIG_SYS_HAS_CPU_MIPS64_R2)) && \
>  >                  VMLINUX_LOAD_ADDRESS == XKPHYS)
>  >       .fill 0x400
>  > #endif
> 
> There are several potencial addresses in XKPHYS, so if anything:
> 
> #if !defined(CONFIG_CPU_MIPSR2) && \
>     ((VMLINUX_LOAD_ADDRESS == CKSEG0) || \
>      (VMLINUX_LOAD_ADDRESS & 0xc7ffffffffffffffUL) == XKPHYS)
> 
> However even where ebase actually exists there might be reasons not to use
> it.  So a config option might be the safe thing to do.
> 
>   Ralf

OK, I'll introduce a CONFIG_NO_EXCEPT_FILL as proposed earlier and select
it in our platform configuration section.

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-28 21:35 Marc St-Jean
  2007-02-28 21:43   ` Uhler, Mike
@ 2007-02-28 22:18 ` Ralf Baechle
  1 sibling, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-02-28 22:18 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips

On Wed, Feb 28, 2007 at 01:35:32PM -0800, Marc St-Jean wrote:

> Ralf Baechle wrote:
> > On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:
> > 
> >  > Something like
> >  >
> >  > #if LOADADDR == 0xffffffff80000000
> >  >       .fill   0x400
> >  > #endif
> >  >
> >  > but by defining an appropriate name in arch/mips/Makefile instead of
> >  > externalizing the load-y/LOADADDR there.
> > 
> > Basically a good idea but it will fail for 64-bit kernels so the test
> > would need to be extended to cover XKPHYS as well.  Also R2 processors
> > which have the c0_ebase registers do no need to reserve space for
> > exception handlers as they can easily move them elsewhere.
> > 
> >   Ralf
> 
> Hi Ralf,
> 
>  From your description it sounds like not all R2 CPUs have c0_ebase registers?
> 
> I don't know how to check for c0_ebase from the pre-processor, the test below
> assumes they all do.

Sorry for being ambigous.  All R2 processors have ebase.  However Linux
happens to support older processors as well, that was my point.

> How about something like:
> 
> #if (defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) && \
>                  VMLINUX_LOAD_ADDRESS == CKSEG0) || \
>          ((defined(CONFIG_SYS_HAS_CPU_MIPS64_R1) || defined(CONFIG_SYS_HAS_CPU_MIPS64_R2)) && \
>                  VMLINUX_LOAD_ADDRESS == XKPHYS)
> 	.fill 0x400
> #endif

There are several potencial addresses in XKPHYS, so if anything:

#if !defined(CONFIG_CPU_MIPSR2) && \
    ((VMLINUX_LOAD_ADDRESS == CKSEG0) || \
     (VMLINUX_LOAD_ADDRESS & 0xc7ffffffffffffffUL) == XKPHYS)

However even where ebase actually exists there might be reasons not to use
it.  So a config option might be the safe thing to do.

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-28 21:43   ` Uhler, Mike
  0 siblings, 0 replies; 29+ messages in thread
From: Uhler, Mike @ 2007-02-28 21:43 UTC (permalink / raw)
  To: Marc St-Jean, Ralf Baechle; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips

All MIPS Release 2 implementations contain the EBase register.

/gmu
---
Michael Uhler, Chief Technology Officer
MIPS Technologies, Inc.   Email: uhler AT mips.com
1225 Charleston Road      Voice:  (650)567-5025
Mountain View, CA 94043
   

> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org 
> [mailto:linux-mips-bounce@linux-mips.org] On Behalf Of Marc St-Jean
> Sent: Wednesday, February 28, 2007 1:36 PM
> To: Ralf Baechle
> Cc: Thiemo Seufer; Andrew Sharp; linux-mips@linux-mips.org
> Subject: Re: [PATCH 2/5] mips: PMC MSP71xx mips common
> 
> 
> 
> Ralf Baechle wrote:
> > On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:
> > 
> >  > Something like
> >  >
> >  > #if LOADADDR == 0xffffffff80000000
> >  >       .fill   0x400
> >  > #endif
> >  >
> >  > but by defining an appropriate name in 
> arch/mips/Makefile instead 
> > of  > externalizing the load-y/LOADADDR there.
> > 
> > Basically a good idea but it will fail for 64-bit kernels 
> so the test 
> > would need to be extended to cover XKPHYS as well.  Also R2 
> processors 
> > which have the c0_ebase registers do no need to reserve space for 
> > exception handlers as they can easily move them elsewhere.
> > 
> >   Ralf
> 
> Hi Ralf,
> 
>  From your description it sounds like not all R2 CPUs have 
> c0_ebase registers?
> 
> I don't know how to check for c0_ebase from the 
> pre-processor, the test below assumes they all do.
> 
> How about something like:
> 
> #if (defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) && \
>                  VMLINUX_LOAD_ADDRESS == CKSEG0) || \
>          ((defined(CONFIG_SYS_HAS_CPU_MIPS64_R1) || 
> defined(CONFIG_SYS_HAS_CPU_MIPS64_R2)) && \
>                  VMLINUX_LOAD_ADDRESS == XKPHYS)
> 	.fill 0x400
> #endif
> 
> Marc
> 
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-28 21:43   ` Uhler, Mike
  0 siblings, 0 replies; 29+ messages in thread
From: Uhler, Mike @ 2007-02-28 21:43 UTC (permalink / raw)
  To: Marc St-Jean, Ralf Baechle; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips

All MIPS Release 2 implementations contain the EBase register.

/gmu
---
Michael Uhler, Chief Technology Officer
MIPS Technologies, Inc.   Email: uhler AT mips.com
1225 Charleston Road      Voice:  (650)567-5025
Mountain View, CA 94043
   

> -----Original Message-----
> From: linux-mips-bounce@linux-mips.org 
> [mailto:linux-mips-bounce@linux-mips.org] On Behalf Of Marc St-Jean
> Sent: Wednesday, February 28, 2007 1:36 PM
> To: Ralf Baechle
> Cc: Thiemo Seufer; Andrew Sharp; linux-mips@linux-mips.org
> Subject: Re: [PATCH 2/5] mips: PMC MSP71xx mips common
> 
> 
> 
> Ralf Baechle wrote:
> > On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:
> > 
> >  > Something like
> >  >
> >  > #if LOADADDR == 0xffffffff80000000
> >  >       .fill   0x400
> >  > #endif
> >  >
> >  > but by defining an appropriate name in 
> arch/mips/Makefile instead 
> > of  > externalizing the load-y/LOADADDR there.
> > 
> > Basically a good idea but it will fail for 64-bit kernels 
> so the test 
> > would need to be extended to cover XKPHYS as well.  Also R2 
> processors 
> > which have the c0_ebase registers do no need to reserve space for 
> > exception handlers as they can easily move them elsewhere.
> > 
> >   Ralf
> 
> Hi Ralf,
> 
>  From your description it sounds like not all R2 CPUs have 
> c0_ebase registers?
> 
> I don't know how to check for c0_ebase from the 
> pre-processor, the test below assumes they all do.
> 
> How about something like:
> 
> #if (defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) && \
>                  VMLINUX_LOAD_ADDRESS == CKSEG0) || \
>          ((defined(CONFIG_SYS_HAS_CPU_MIPS64_R1) || 
> defined(CONFIG_SYS_HAS_CPU_MIPS64_R2)) && \
>                  VMLINUX_LOAD_ADDRESS == XKPHYS)
> 	.fill 0x400
> #endif
> 
> Marc
> 
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-28 21:35 Marc St-Jean
  2007-02-28 21:43   ` Uhler, Mike
  2007-02-28 22:18 ` Ralf Baechle
  0 siblings, 2 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-28 21:35 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips



Ralf Baechle wrote:
> On Tue, Feb 27, 2007 at 05:38:41PM +0000, Thiemo Seufer wrote:
> 
>  > Something like
>  >
>  > #if LOADADDR == 0xffffffff80000000
>  >       .fill   0x400
>  > #endif
>  >
>  > but by defining an appropriate name in arch/mips/Makefile instead of
>  > externalizing the load-y/LOADADDR there.
> 
> Basically a good idea but it will fail for 64-bit kernels so the test
> would need to be extended to cover XKPHYS as well.  Also R2 processors
> which have the c0_ebase registers do no need to reserve space for
> exception handlers as they can easily move them elsewhere.
> 
>   Ralf

Hi Ralf,

 From your description it sounds like not all R2 CPUs have c0_ebase registers?

I don't know how to check for c0_ebase from the pre-processor, the test below
assumes they all do.

How about something like:

#if (defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) && \
                 VMLINUX_LOAD_ADDRESS == CKSEG0) || \
         ((defined(CONFIG_SYS_HAS_CPU_MIPS64_R1) || defined(CONFIG_SYS_HAS_CPU_MIPS64_R2)) && \
                 VMLINUX_LOAD_ADDRESS == XKPHYS)
	.fill 0x400
#endif

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 21:27 Marc St-Jean
@ 2007-02-28 19:52 ` Ralf Baechle
  0 siblings, 0 replies; 29+ messages in thread
From: Ralf Baechle @ 2007-02-28 19:52 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: Thiemo Seufer, Andrew Sharp, linux-mips

On Tue, Feb 27, 2007 at 01:27:35PM -0800, Marc St-Jean wrote:

> I thought without the .fill that the kernel_entry function would be at
> the start of text. Apparently not, a quick test shows a crash with both
> the jal and .fill removed.

kernel_entry is __INIT so will actually end near the end of the the
executable.  That's why the j kernel_entry is needed at all.

  Ralf

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-28  0:04 Marc St-Jean
  0 siblings, 0 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-28  0:04 UTC (permalink / raw)
  To: linux-mips

[PATCH 2/5] mips: PMC MSP71xx mips common

Patch to add mips common support for the PMC-Sierra
MSP71xx devices.

These 5 patches along with the previously posted serial patch
will boot the PMC-Sierra MSP7120 Residential Gateway board.

Thanks,
Marc

Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
---
Re-posting patch with three recommended changes:
1. Added CONFIG_BOOT_RAW and selected in MIPS_SIM and PMC_MSP
to allow jumping to the kernel_entry at start of text.
(arch/mips/Kconfig, arch/mips/kernel/head.S)

2. Defined a VMLINUX_LOAD_ADDRESS flag to eliminate the .fill
for exception handlers.
(arch/mips/Makefile, arch/mips/kernel/head.S)

3. Changed MACH_GROUP_MSP from 23 to 26 follow last entry.
(include/asm-mips/bootinfo.h)

 arch/mips/Kconfig           |   83 +++++++++++++++++++++
 arch/mips/Makefile          |   11 ++
 arch/mips/kernel/head.S     |    4 -
 arch/mips/kernel/traps.c    |    6 +
 include/asm-mips/bootinfo.h |   12 +++
 include/asm-mips/mipsregs.h |   30 +++++++
 include/asm-mips/regops.h   |  168 ++++++++++++++++++++++++++++++++++++++++++++
 include/asm-mips/war.h      |   11 ++
 8 files changed, 323 insertions(+), 2 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5da6b0d..b9f0286 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -354,6 +354,7 @@ config MIPS_SIM
 	bool 'MIPS simulator (MIPSsim)'
 	select DMA_NONCOHERENT
 	select IRQ_CPU
+	select BOOT_RAW
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -504,6 +505,26 @@ config MACH_VR41XX
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+	bool "PMC-Sierra MSP chipsets"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select SWAP_IO_SPACE
+	select BOOT_RAW
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
+	select IRQ_CPU
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	help
+	  This adds support for the PMC-Sierra family of Multi-Service
+	  Processor System-On-A-Chips.  These parts include a number
+	  of integrated peripherals, interfaces and DSPs in addition to
+	  a variety of MIPS cores.
+
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
 	select DMA_COHERENT
@@ -815,6 +836,55 @@ config TOSHIBA_RBTX4938
 
 endchoice
 
+choice
+	prompt "PMC-Sierra MSP SOC type"
+	depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+	bool "PMC-Sierra MSP4200 Eval Board"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+	bool "PMC-Sierra MSP7120 Eval Board"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_GW
+	bool "PMC-Sierra MSP7120 Residential Gateway"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_FPGA
+	bool "PMC-Sierra MSP7120 FPGA"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+	depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+	bool "Root filesystem embedded in kernel image"
+	select MTD
+	select MTD_BLOCK
+	select MTD_PMC_MSP_RAMROOT
+	select MTD_RAM
+
+endmenu
+
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
@@ -879,6 +949,9 @@ config ARC
 config ARCH_MAY_HAVE_PC_FDC
 	bool
 
+config BOOT_RAW
+	bool
+
 config DMA_COHERENT
 	bool
 
@@ -971,6 +1044,15 @@ config IRQ_CPU_RM9K
 config IRQ_MV64340
 	bool
 
+config IRQ_MSP_SLP
+	bool
+
+config IRQ_MSP_CIC
+	bool
+
+config MSP_USB
+	bool
+
 config DDB5XXX_COMMON
 	bool
 	select SYS_SUPPORTS_KGDB
@@ -1086,6 +1168,7 @@ config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
+	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 92bca6a..1c38332 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -360,6 +360,14 @@ core-$(CONFIG_MOMENCO_OCELOT_C)	+= arch/mips/momentum/ocelot_c/
 load-$(CONFIG_MOMENCO_OCELOT_C)	+= 0xffffffff80100000
 
 #
+# PMC-Sierra MSP SOCs
+#
+core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)	+= -Iinclude/asm-mips/pmc-sierra/msp71xx \
+					-mno-branch-likely
+load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
+
+#
 # PMC-Sierra Yosemite
 #
 core-$(CONFIG_PMC_YOSEMITE)	+= arch/mips/pmc-sierra/yosemite/
@@ -619,7 +627,8 @@ JIFFIES			= jiffies_64
 endif
 
 AFLAGS		+= $(cflags-y)
-CFLAGS		+= $(cflags-y)
+CFLAGS		+= $(cflags-y) \
+			-D"VMLINUX_LOAD_ADDRESS=$(load-y)"
 
 LDFLAGS			+= -m $(ld-emul)
 
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca4..b73cf67 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -129,16 +129,18 @@
 #endif
 	.endm
 
+#if VMLINUX_LOAD_ADDRESS == 0xffffffff80000000
 	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#endif
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
 
-#ifdef CONFIG_MIPS_SIM
+#ifdef CONFIG_BOOT_RAW
 	/*
 	 * Give us a fighting chance of running if execution beings at the
 	 * kernel load address.  This is needed because this platform does
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..2c812c2 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -860,6 +861,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	if (board_watchpoint_handler) {
+		(*board_watchpoint_handler)(regs);
+		return;
+	}
+	
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index c7c945b..7fc52c7 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -213,6 +213,18 @@
 #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
 #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
 
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         26	/* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
+#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
+#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
+#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation board */
+#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
+#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
+#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7..bd683b6 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
@@ -1292,10 +1293,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+	int res = 0;
+
+	__asm__ __volatile__(
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+	"	.set	mips32r2					\n"
+	"	.word	0x41610001		# dvpe $1		\n"
+	"	move	%0, $1						\n"
+	"	ehb							\n"
+	"	.set	pop						\n"
+	: "=r" (res));
+
+	instruction_hazard();
+#endif
+
 	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"tlbr\n\t"
 		".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+	if ((res & _ULCAST_(1)))
+		__asm__ __volatile__(
+		"	.set	push						\n"
+		"	.set	noreorder					\n"
+		"	.set	noat						\n"
+		"	.set	mips32r2					\n"
+		"	.word	0x41600021		# evpe			\n"
+		"	ehb							\n"
+		"	.set	pop						\n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 13a3502..74c08e6 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -196,6 +196,14 @@
 #endif
 
 /*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+	defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
 #ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -234,5 +242,8 @@
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR			0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
new file mode 100644
index 0000000..fbfc940
--- /dev/null
+++ b/include/asm-mips/regops.h
@@ -0,0 +1,168 @@
+/*
+ * $Id: regops.h,v 1.2 2006/05/08 22:00:34 ramsayji Exp $
+ *
+ * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
+ * it is your responsibility to ensure these are available on your platform
+ * before including this file.
+ *
+ * In addition, there is a bug on the R10000 chips which has a workaround.  If
+ * you are affected by this bug, make sure to define the symbol
+ * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
+ * linux, you may include <asm/war.h> before including this file to have this
+ * defined appropriately for you.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz	"beqzl	"
+#else
+#define __beqz	"beqz	"
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int uint32_t;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32( volatile uint32_t * const addr,
+					uint32_t const mask,
+					uint32_t const value )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1	# set_value_reg32	\n"
+	"	and	%0, %2				\n"
+	"	or	%0, %3				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "ir" (value), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# set_reg32	\n"
+	"	or	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# clear_reg32	\n"
+	"	and	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "m" (*addr) );
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# toggle_reg32	\n"
+	"	xor	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/* For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   uint32_t tmp;                      <-- Define a variable to hold the data
+ *
+ *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
+ *						in the 'tmp' variable given
+ *
+ *	< From here on out, you are (basicly) atomic, so don't do anything too
+ *	< fancy!
+ *	< Also, this code may loop if the end of this block fails to write
+ *	< everything back safely due do the other CPU, so do NOT do anything
+ *	< with side-effects!
+ *
+ *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
+ *
+ */
+#define custom_reg32_read(address, tmp)				\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
+	"	.set	mips0				\n"	\
+	: "=r" (tmp), "=m" (*address)				\
+	: "m" (*address) )
+
+#define custom_reg32_write(address, tmp)			\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"	sc	%0, %1	#custom_reg32_write	\n"	\
+	"	"__beqz"%0, 1b				\n"	\
+	"	.set	mips0				\n"	\
+	: "=&r" (tmp), "=m" (*address)				\
+	: "0" (tmp), "m" (*address) )
+
+#endif  /* __ASM_REGOPS_H__ */

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-27 21:27 Marc St-Jean
  2007-02-28 19:52 ` Ralf Baechle
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-02-27 21:27 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Andrew Sharp, linux-mips



Thiemo Seufer wrote:
> Marc St-Jean wrote:
>  >
>  >
>  > Thiemo Seufer wrote:
>  > > Marc St-Jean wrote:
>  > > [snip]
>  > >  > >  > +#ifdef CONFIG_PMC_MSP
>  > >  > >  > +     jal     kernel_entry
>  > >  > >  > +#else
>  > >
>  > > Maybe introduce a CONFIG_BOOT_RAW (and use it in arch/mips/Makefile
>  > > to objcopy the kernel to a raw binary).

Thanks, I'll introduce this config option to add the above 'jal kernel_entry'.
Our build system already takes care of doing the objcopy as well as
combining a rootfs, etc. so I'd rather not change the makefile if you
have no objections.


>  > >  > >  > +     /*
>  > >  > >  >        * Reserved space for exception handlers.
>  > >  > >  >        * Necessary for machines which link their kernels at 
> KSEG0.
>  > >  > >  >        */
>  > >  > >  >       .fill   0x400
>  > >  > >  > +#endif /* CONFIG_PMC_MSP */
>  > >  > >
>  > >  > > This is getting kind of ugly.  There are a whole lot of config 
> choices
>  > >  > > that need to use the 'j kernel_entry'.  Do they all have to 
> have their
>  > >  > > own?  I'm not sure what the best way is to handle them all.
>  > >  >
>  > >  > I agree but don't know the best way to handle this. I could 
> introduce a
>  > >  > SYS_NO_EXEPT_FILL or similar flag but this seems excessive.
>  > >  >
>  > >  > Any other ideas from arch/mips folks?
>  > >
>  > > Something like
>  > >
>  > > #if LOADADDR == 0xffffffff80000000
>  > >         .fill   0x400
>  > > #endif
>  > >
>  > > but by defining an appropriate name in arch/mips/Makefile instead of
>  > > externalizing the load-y/LOADADDR there.
>  >
>  > Thanks for the suggestions Thiemo.
>  >
>  > We only need one of these solutions and I think the second one is 
> cleaner.
> 
> You need both as they solve two independent problems. One is rerouting
> the kernel entry, the other saves some space in the image.

I thought without the .fill that the kernel_entry function would be at
the start of text. Apparently not, a quick test shows a crash with both
the jal and .fill removed.


>  > I do have a few questions before respinning the patch:
>  >
>  > 1. Why do you want to create another name, wouldn't there be less 
> confusion
>  > and chance for errors by reusing LOADADDR and ensuring it's the same 
> as what
>  > the linker script uses?
> 
> LOADADDR is a short and thus bad name for a global symbol.
> 
>  > 2. Looking at arch/mips/Makefile there are many boards not using
>  > 0xffffffff80000000. If we introduce this check it seems that all of 
> these
>  > boards will have their _stext changed and it'll affect their "jump" 
> address
>  > from monitor/boot scripts?
> 
> For targets with a raw binary kernel the assumption is that their
> firmware jumps to the start of the image. The .fill translates to nops.
> 
> Targets which don't use 0x80000000 as load address don't need to
> reserve space at the start for exception handlers.

Thanks for clarifying,
Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27 17:59 Marc St-Jean
@ 2007-02-27 20:03 ` Thiemo Seufer
  0 siblings, 0 replies; 29+ messages in thread
From: Thiemo Seufer @ 2007-02-27 20:03 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: Andrew Sharp, linux-mips

Marc St-Jean wrote:
> 
> 
> Thiemo Seufer wrote:
> > Marc St-Jean wrote:
> > [snip]
> >  > >  > +#ifdef CONFIG_PMC_MSP
> >  > >  > +     jal     kernel_entry
> >  > >  > +#else
> > 
> > Maybe introduce a CONFIG_BOOT_RAW (and use it in arch/mips/Makefile
> > to objcopy the kernel to a raw binary).
> > 
> >  > >  > +     /*
> >  > >  >        * Reserved space for exception handlers.
> >  > >  >        * Necessary for machines which link their kernels at KSEG0.
> >  > >  >        */
> >  > >  >       .fill   0x400
> >  > >  > +#endif /* CONFIG_PMC_MSP */
> >  > >
> >  > > This is getting kind of ugly.  There are a whole lot of config choices
> >  > > that need to use the 'j kernel_entry'.  Do they all have to have their
> >  > > own?  I'm not sure what the best way is to handle them all.
> >  >
> >  > I agree but don't know the best way to handle this. I could introduce a
> >  > SYS_NO_EXEPT_FILL or similar flag but this seems excessive.
> >  >
> >  > Any other ideas from arch/mips folks?
> > 
> > Something like
> > 
> > #if LOADADDR == 0xffffffff80000000
> >         .fill   0x400
> > #endif
> > 
> > but by defining an appropriate name in arch/mips/Makefile instead of
> > externalizing the load-y/LOADADDR there.
> 
> Thanks for the suggestions Thiemo.
> 
> We only need one of these solutions and I think the second one is cleaner.

You need both as they solve two independent problems. One is rerouting
the kernel entry, the other saves some space in the image.

> I do have a few questions before respinning the patch:
> 
> 1. Why do you want to create another name, wouldn't there be less confusion
> and chance for errors by reusing LOADADDR and ensuring it's the same as what
> the linker script uses?

LOADADDR is a short and thus bad name for a global symbol.

> 2. Looking at arch/mips/Makefile there are many boards not using
> 0xffffffff80000000. If we introduce this check it seems that all of these
> boards will have their _stext changed and it'll affect their "jump" address
> from monitor/boot scripts?

For targets with a raw binary kernel the assumption is that their
firmware jumps to the start of the image. The .fill translates to nops.

Targets which don't use 0x80000000 as load address don't need to
reserve space at the start for exception handlers.


Thiemo

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-27 17:59 Marc St-Jean
  2007-02-27 20:03 ` Thiemo Seufer
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-02-27 17:59 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Andrew Sharp, linux-mips



Thiemo Seufer wrote:
> Marc St-Jean wrote:
> [snip]
>  > >  > +#ifdef CONFIG_PMC_MSP
>  > >  > +     jal     kernel_entry
>  > >  > +#else
> 
> Maybe introduce a CONFIG_BOOT_RAW (and use it in arch/mips/Makefile
> to objcopy the kernel to a raw binary).
> 
>  > >  > +     /*
>  > >  >        * Reserved space for exception handlers.
>  > >  >        * Necessary for machines which link their kernels at KSEG0.
>  > >  >        */
>  > >  >       .fill   0x400
>  > >  > +#endif /* CONFIG_PMC_MSP */
>  > >
>  > > This is getting kind of ugly.  There are a whole lot of config choices
>  > > that need to use the 'j kernel_entry'.  Do they all have to have their
>  > > own?  I'm not sure what the best way is to handle them all.
>  >
>  > I agree but don't know the best way to handle this. I could introduce a
>  > SYS_NO_EXEPT_FILL or similar flag but this seems excessive.
>  >
>  > Any other ideas from arch/mips folks?
> 
> Something like
> 
> #if LOADADDR == 0xffffffff80000000
>         .fill   0x400
> #endif
> 
> but by defining an appropriate name in arch/mips/Makefile instead of
> externalizing the load-y/LOADADDR there.

Thanks for the suggestions Thiemo.

We only need one of these solutions and I think the second one is cleaner.
I do have a few questions before respinning the patch:

1. Why do you want to create another name, wouldn't there be less confusion
and chance for errors by reusing LOADADDR and ensuring it's the same as what
the linker script uses?

2. Looking at arch/mips/Makefile there are many boards not using
0xffffffff80000000. If we introduce this check it seems that all of these
boards will have their _stext changed and it'll affect their "jump" address
from monitor/boot scripts?

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-27  0:12 Marc St-Jean
@ 2007-02-27  0:43 ` Andrew Sharp
  0 siblings, 0 replies; 29+ messages in thread
From: Andrew Sharp @ 2007-02-27  0:43 UTC (permalink / raw)
  To: linux-mips

On Mon, 26 Feb 2007 18:12:55 -0600 Marc St-Jean <stjeanma@pmc-sierra.com> wrote:
> [PATCH 2/5] mips: PMC MSP71xx mips common
> 
> Patch to add mips common support for the PMC-Sierra
> MSP71xx devices.
> 
> These 5 patches along with the previously posted serial patch
> will boot the PMC-Sierra MSP7120 Residential Gateway board.
> 
> Thanks,
> Marc
> 
> Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
> ---
> Re-posting patch with two recommended changes:
> 1. Dropped the PMC_MSP_UNCACHED configuration item as this was
> already available in arch/mips/Kconfig.debug.
> 3. Dropped 'else' case to simplify patch to do_watch() in
> arch/mips/kernel/traps.c
> 
>  arch/mips/Kconfig           |   78 ++++++++++++++++++++
>  arch/mips/Makefile          |    8 ++
>  arch/mips/kernel/head.S     |    8 ++
>  arch/mips/kernel/traps.c    |    6 +
>  include/asm-mips/bootinfo.h |   12 +++
>  include/asm-mips/mipsregs.h |   30 +++++++
>  include/asm-mips/regops.h   |  168
> ++++++++++++++++++++++++++++++++++++++++++++
> include/asm-mips/war.h      |   11 ++ 8 files changed, 321 insertions(+)

My mailer kind of made a mess of things, hope I caught them all.

> diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
> index 6f57ca4..d7451b1 100644
> --- a/arch/mips/kernel/head.S
> +++ b/arch/mips/kernel/head.S
> @@ -130,10 +130,18 @@
>  	.endm
>  
>  	/*
> +	 * Reserverd space not required for PMC boards, although we need to
> +	 * jump to kernel start.
> +	 */
> +#ifdef CONFIG_PMC_MSP
> +	jal	kernel_entry
> +#else
> +	/*
>  	 * Reserved space for exception handlers.
>  	 * Necessary for machines which link their kernels at KSEG0.
>  	 */
>  	.fill	0x400
> +#endif /* CONFIG_PMC_MSP */

This is getting kind of ugly.  There are a whole lot of config choices
that need to use the 'j kernel_entry'.  Do they all have to have their
own?  I'm not sure what the best way is to handle them all.


> diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
> index c7c945b..ab29fd4 100644
> --- a/include/asm-mips/bootinfo.h
> +++ b/include/asm-mips/bootinfo.h
> @@ -213,6 +213,18 @@
>  #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
> #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
> +/*
> + * Valid machtype for group PMC-MSP
> + */
> +#define MACH_GROUP_MSP         23	/* PMC-Sierra MSP boards/CPUs    */
> +#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
> +#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
> +#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
> +#define MACH_MSP7120_EVAL	   3	/* PMC-Sierra MSP7120 Evaluation board *
/
> +#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
> +#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
> +#define MACH_MSP_OTHER	 255	/* PMC-Sierra unknown board type */
> +#define CL_SIZE			COMMAND_LINE_SIZE


Really I would add MACH_GROUP_MSP after MACH_GROUP_NEC_EMMA2RH,
perhaps 27 or 28, rather than an interior number.  Especially if
you are going to put it after MACH_GROUP_NEC_EMMA2RH in the file. ~:^)


Cheers,

a

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-27  0:12 Marc St-Jean
  2007-02-27  0:43 ` Andrew Sharp
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-02-27  0:12 UTC (permalink / raw)
  To: linux-mips

[PATCH 2/5] mips: PMC MSP71xx mips common

Patch to add mips common support for the PMC-Sierra
MSP71xx devices.

These 5 patches along with the previously posted serial patch
will boot the PMC-Sierra MSP7120 Residential Gateway board.

Thanks,
Marc

Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
---
Re-posting patch with two recommended changes:
1. Dropped the PMC_MSP_UNCACHED configuration item as this was
already available in arch/mips/Kconfig.debug.
3. Dropped 'else' case to simplify patch to do_watch() in
arch/mips/kernel/traps.c

 arch/mips/Kconfig           |   78 ++++++++++++++++++++
 arch/mips/Makefile          |    8 ++
 arch/mips/kernel/head.S     |    8 ++
 arch/mips/kernel/traps.c    |    6 +
 include/asm-mips/bootinfo.h |   12 +++
 include/asm-mips/mipsregs.h |   30 +++++++
 include/asm-mips/regops.h   |  168 ++++++++++++++++++++++++++++++++++++++++++++
 include/asm-mips/war.h      |   11 ++
 8 files changed, 321 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5da6b0d..77fc083 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -504,6 +504,25 @@ config MACH_VR41XX
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+	bool "PMC-Sierra MSP chipsets"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select SWAP_IO_SPACE
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
+	select IRQ_CPU
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	help
+	  This adds support for the PMC-Sierra family of Multi-Service
+	  Processor System-On-A-Chips.  These parts include a number
+	  of integrated peripherals, interfaces and DSPs in addition to
+	  a variety of MIPS cores.
+
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
 	select DMA_COHERENT
@@ -815,6 +834,55 @@ config TOSHIBA_RBTX4938
 
 endchoice
 
+choice
+	prompt "PMC-Sierra MSP SOC type"
+	depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+	bool "PMC-Sierra MSP4200 Eval Board"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+	bool "PMC-Sierra MSP7120 Eval Board"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_GW
+	bool "PMC-Sierra MSP7120 Residential Gateway"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+	
+config PMC_MSP7120_FPGA
+	bool "PMC-Sierra MSP7120 FPGA"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+	
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+	depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+	bool "Root filesystem embedded in kernel image"
+	select MTD
+	select MTD_BLOCK
+	select MTD_PMC_MSP_RAMROOT
+	select MTD_RAM
+	
+endmenu
+
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
@@ -971,6 +1039,15 @@ config IRQ_CPU_RM9K
 config IRQ_MV64340
 	bool
 
+config IRQ_MSP_SLP
+	bool
+
+config IRQ_MSP_CIC
+	bool
+
+config MSP_USB
+	bool
+
 config DDB5XXX_COMMON
 	bool
 	select SYS_SUPPORTS_KGDB
@@ -1086,6 +1163,7 @@ config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
+	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 92bca6a..fc406f7 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -367,6 +367,14 @@ cflags-$(CONFIG_PMC_YOSEMITE)	+= -Iinclude/asm-mips/mach-yosemite
 load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
 
 #
+# PMC-Sierra MSP SOCs
+#
+core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)	+= -Iinclude/asm-mips/pmc-sierra/msp71xx \
+					-mno-branch-likely
+load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
+
+#
 # Qemu simulating MIPS32 4Kc
 #
 core-$(CONFIG_QEMU)		+= arch/mips/qemu/
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca4..d7451b1 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -130,10 +130,18 @@
 	.endm
 
 	/*
+	 * Reserverd space not required for PMC boards, although we need to
+	 * jump to kernel start.
+	 */
+#ifdef CONFIG_PMC_MSP
+	jal	kernel_entry
+#else
+	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#endif /* CONFIG_PMC_MSP */
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..2c812c2 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -860,6 +861,11 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
+	if (board_watchpoint_handler) {
+		(*board_watchpoint_handler)(regs);
+		return;
+	}
+	
 	/*
 	 * We use the watch exception where available to detect stack
 	 * overflows.
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index c7c945b..ab29fd4 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -213,6 +213,18 @@
 #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
 #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
 
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         23	/* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
+#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
+#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
+#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation board */
+#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
+#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
+#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7..bd683b6 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
@@ -1292,10 +1293,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+	int res = 0;
+
+	__asm__ __volatile__(
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+	"	.set	mips32r2					\n"
+	"	.word	0x41610001		# dvpe $1		\n"
+	"	move	%0, $1						\n"
+	"	ehb							\n"
+	"	.set	pop						\n"
+	: "=r" (res));
+
+	instruction_hazard();
+#endif
+
 	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"tlbr\n\t"
 		".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+	if ((res & _ULCAST_(1)))
+		__asm__ __volatile__(
+		"	.set	push						\n"
+		"	.set	noreorder					\n"
+		"	.set	noat						\n"
+		"	.set	mips32r2					\n"
+		"	.word	0x41600021		# evpe			\n"
+		"	ehb							\n"
+		"	.set	pop						\n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 13a3502..74c08e6 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -196,6 +196,14 @@
 #endif
 
 /*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+	defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
 #ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -234,5 +242,8 @@
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR			0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
new file mode 100644
index 0000000..fbfc940
--- /dev/null
+++ b/include/asm-mips/regops.h
@@ -0,0 +1,168 @@
+/*
+ * $Id: regops.h,v 1.2 2006/05/08 22:00:34 ramsayji Exp $
+ *
+ * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
+ * it is your responsibility to ensure these are available on your platform
+ * before including this file.
+ *
+ * In addition, there is a bug on the R10000 chips which has a workaround.  If
+ * you are affected by this bug, make sure to define the symbol
+ * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
+ * linux, you may include <asm/war.h> before including this file to have this
+ * defined appropriately for you.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz	"beqzl	"
+#else
+#define __beqz	"beqz	"
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int uint32_t;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32( volatile uint32_t * const addr,
+					uint32_t const mask,
+					uint32_t const value )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1	# set_value_reg32	\n"
+	"	and	%0, %2				\n"
+	"	or	%0, %3				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "ir" (value), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# set_reg32	\n"
+	"	or	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# clear_reg32	\n"
+	"	and	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "m" (*addr) );
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# toggle_reg32	\n"
+	"	xor	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/* For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   uint32_t tmp;                      <-- Define a variable to hold the data
+ *
+ *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
+ *						in the 'tmp' variable given
+ *
+ *	< From here on out, you are (basicly) atomic, so don't do anything too
+ *	< fancy!
+ *	< Also, this code may loop if the end of this block fails to write
+ *	< everything back safely due do the other CPU, so do NOT do anything
+ *	< with side-effects!
+ *
+ *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
+ *
+ */
+#define custom_reg32_read(address, tmp)				\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
+	"	.set	mips0				\n"	\
+	: "=r" (tmp), "=m" (*address)				\
+	: "m" (*address) )
+
+#define custom_reg32_write(address, tmp)			\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"	sc	%0, %1	#custom_reg32_write	\n"	\
+	"	"__beqz"%0, 1b				\n"	\
+	"	.set	mips0				\n"	\
+	: "=&r" (tmp), "=m" (*address)				\
+	: "0" (tmp), "m" (*address) )
+
+#endif  /* __ASM_REGOPS_H__ */

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-23 21:27 Marc St-Jean
  0 siblings, 0 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-23 21:27 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-mips

Sergei Shtylyov wrote:
> Hello.
> 
> Marc St-Jean wrote:
> 
>  >> > +config PMC_MSP_UNCACHED
>  >> > +     bool "Run uncached"
>  >> > +     select MIPS_UNCACHED
>  >> > +   
>  >> > +endmenu
>  >> > +
> 
>  >>    Erm, was there really a need for separate option?
> 
>  > Are you aware of an existing option to accomplish the same
>  > results? I have not found it.
> 
>     How's that when you're using it! "Run uncached" is in the "Kernel 
> hacking"
> menu.

Hmmm, I can only assume the developer who added this wanted it to be
in a more obvious place under out board settings. I will drop it
from the next submission.

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-23 21:15 Marc St-Jean
  0 siblings, 0 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-23 21:15 UTC (permalink / raw)
  To: David Daney; +Cc: Sergei Shtylyov, linux-mips



David Daney wrote:
> Marc St-Jean wrote:
>  >
>  > Sergei Shtylyov wrote:
>  >> Hello.
>  >>
>  >> Marc St-Jean wrote:
>  >>
>  >>  > [PATCH 2/5] mips: PMC MSP71xx mips common
>  >>
>  >>  > Patch to add mips common support for the PMC-Sierra
>  >>  > MSP71xx devices.
>  >>
>  >>  > These 5 patches along with the previously posted serial patch
>  >>  > will boot the PMC-Sierra MSP7120 Residential Gateway board.
>  >>
>  >>  > Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
>  >>
>  >>  > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>  >>  > index 5da6b0d..d512389 100644
>  >>  > --- a/arch/mips/Kconfig
>  >>  > +++ b/arch/mips/Kconfig
>  >> [...]
>  >>
>  >>  > +menu "Options for PMC-Sierra MSP chipsets"
>  >>  > +     depends on PMC_MSP
>  >>  > +
>  >>  > +config PMC_MSP_EMBEDDED_ROOTFS
>  >>  > +     bool "Root filesystem embedded in kernel image"
>  >>  > +     select MTD
>  >>  > +     select MTD_BLOCK
>  >>  > +     select MTD_PMC_MSP_RAMROOT
>  >>  > +     select MTD_RAM
>  >>  > +
>  >>
>  >>     Hm, why not just use initramfs?
>  >
>  > I investigated this as part of an earlier thread.  Initramfs
>  > is not a read-only "ROM" fs but a compressed writable fs.
>  > Once expanded it will take more memory.
>  >
>  > To lower memory usage for embedded usage of our devices we've
>  > added a method to embedded cramfs/squashfs file systems into
>  > the kernel image.
>  >
> 
> Why not just run the cramfs/squashfs on a standard mdtblock device?

We and our customers do that as well but it's handy to have a single
RAM-based image to download during early development.

MArc

> 
>  > I've made sure it was unobtrusive and that no linker script
>  > changes, etc. were required.
>  >
>  >
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-23 20:53 Marc St-Jean
  2007-02-23 21:02 ` Sergei Shtylyov
@ 2007-02-23 21:02 ` David Daney
  1 sibling, 0 replies; 29+ messages in thread
From: David Daney @ 2007-02-23 21:02 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: Sergei Shtylyov, linux-mips

Marc St-Jean wrote:
> 
> Sergei Shtylyov wrote:
>> Hello.
>>
>> Marc St-Jean wrote:
>>
>>  > [PATCH 2/5] mips: PMC MSP71xx mips common
>>
>>  > Patch to add mips common support for the PMC-Sierra
>>  > MSP71xx devices.
>>
>>  > These 5 patches along with the previously posted serial patch
>>  > will boot the PMC-Sierra MSP7120 Residential Gateway board.
>>
>>  > Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
>>
>>  > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>>  > index 5da6b0d..d512389 100644
>>  > --- a/arch/mips/Kconfig
>>  > +++ b/arch/mips/Kconfig
>> [...]
>>
>>  > +menu "Options for PMC-Sierra MSP chipsets"
>>  > +     depends on PMC_MSP
>>  > +
>>  > +config PMC_MSP_EMBEDDED_ROOTFS
>>  > +     bool "Root filesystem embedded in kernel image"
>>  > +     select MTD
>>  > +     select MTD_BLOCK
>>  > +     select MTD_PMC_MSP_RAMROOT
>>  > +     select MTD_RAM
>>  > +
>>
>>     Hm, why not just use initramfs?
> 
> I investigated this as part of an earlier thread.  Initramfs
> is not a read-only "ROM" fs but a compressed writable fs.
> Once expanded it will take more memory.
> 
> To lower memory usage for embedded usage of our devices we've
> added a method to embedded cramfs/squashfs file systems into
> the kernel image.
> 

Why not just run the cramfs/squashfs on a standard mdtblock device?

> I've made sure it was unobtrusive and that no linker script
> changes, etc. were required.
> 
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-23 20:53 Marc St-Jean
@ 2007-02-23 21:02 ` Sergei Shtylyov
  2007-02-23 21:02 ` David Daney
  1 sibling, 0 replies; 29+ messages in thread
From: Sergei Shtylyov @ 2007-02-23 21:02 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: linux-mips

Hello.

Marc St-Jean wrote:

>> > +config PMC_MSP_UNCACHED
>> > +     bool "Run uncached"
>> > +     select MIPS_UNCACHED
>> > +    
>> > +endmenu
>> > +

>>    Erm, was there really a need for separate option?

> Are you aware of an existing option to accomplish the same
> results? I have not found it.

    How's that when you're using it! "Run uncached" is in the "Kernel hacking" 
menu.

> Marc

WBR, Sergei

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-23 20:53 Marc St-Jean
  2007-02-23 21:02 ` Sergei Shtylyov
  2007-02-23 21:02 ` David Daney
  0 siblings, 2 replies; 29+ messages in thread
From: Marc St-Jean @ 2007-02-23 20:53 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-mips



Sergei Shtylyov wrote:
> Hello.
> 
> Marc St-Jean wrote:
> 
>  > [PATCH 2/5] mips: PMC MSP71xx mips common
> 
>  > Patch to add mips common support for the PMC-Sierra
>  > MSP71xx devices.
> 
>  > These 5 patches along with the previously posted serial patch
>  > will boot the PMC-Sierra MSP7120 Residential Gateway board.
> 
>  > Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
> 
>  > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>  > index 5da6b0d..d512389 100644
>  > --- a/arch/mips/Kconfig
>  > +++ b/arch/mips/Kconfig
> [...]
> 
>  > +menu "Options for PMC-Sierra MSP chipsets"
>  > +     depends on PMC_MSP
>  > +
>  > +config PMC_MSP_EMBEDDED_ROOTFS
>  > +     bool "Root filesystem embedded in kernel image"
>  > +     select MTD
>  > +     select MTD_BLOCK
>  > +     select MTD_PMC_MSP_RAMROOT
>  > +     select MTD_RAM
>  > +
> 
>     Hm, why not just use initramfs?

I investigated this as part of an earlier thread.  Initramfs
is not a read-only "ROM" fs but a compressed writable fs.
Once expanded it will take more memory.

To lower memory usage for embedded usage of our devices we've
added a method to embedded cramfs/squashfs file systems into
the kernel image.

I've made sure it was unobtrusive and that no linker script
changes, etc. were required.


>  > +config PMC_MSP_UNCACHED
>  > +     bool "Run uncached"
>  > +     select MIPS_UNCACHED
>  > +    
>  > +endmenu
>  > +
> 
>     Erm, was there really a need for separate option?

Are you aware of an existing option to accomplish the same
results? I have not found it.


>  > diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
>  > index 18f56a9..610e169 100644
>  > --- a/arch/mips/kernel/traps.c
>  > +++ b/arch/mips/kernel/traps.c
>  > @@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
>  >  extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
>  >       struct mips_fpu_struct *ctx, int has_fpu);
>  > 
>  > +void (*board_watchpoint_handler)(struct pt_regs *regs);
>  >  void (*board_be_init)(void);
>  >  int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
>  >  void (*board_nmi_handler_setup)(void);
>  > @@ -860,13 +861,17 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
>  > 
>  >  asmlinkage void do_watch(struct pt_regs *regs)
>  >  {
>  > -     /*
>  > -      * We use the watch exception where available to detect stack
>  > -      * overflows.
>  > -      */
>  > -     dump_tlb_all();
>  > -     show_regs(regs);
>  > -     panic("Caught WATCH exception - probably caused by stack 
> overflow.");
>  > +     if (board_watchpoint_handler) {
>  > +             (*board_watchpoint_handler)(regs);
>  > +     } else {
>  > +             /*
>  > +              * We use the watch exception where available to detect 
> stack
>  > +              * overflows.
>  > +              */
>  > +             dump_tlb_all();
>  > +             show_regs(regs);
>  > +             panic("Caught WATCH exception - probably caused by 
> stack overflow.");
>  > +     }
>  >  }
> 
>     There was no real need for else and massive change, just add return 
> right
> after calling the handler...

Thanks, will do for the next submission.

Marc

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 2/5] mips: PMC MSP71xx mips common
  2007-02-23 19:56 Marc St-Jean
@ 2007-02-23 20:35 ` Sergei Shtylyov
  0 siblings, 0 replies; 29+ messages in thread
From: Sergei Shtylyov @ 2007-02-23 20:35 UTC (permalink / raw)
  To: Marc St-Jean; +Cc: linux-mips

Hello.

Marc St-Jean wrote:

> [PATCH 2/5] mips: PMC MSP71xx mips common

> Patch to add mips common support for the PMC-Sierra
> MSP71xx devices.

> These 5 patches along with the previously posted serial patch
> will boot the PMC-Sierra MSP7120 Residential Gateway board.

> Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>

> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 5da6b0d..d512389 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
[...]

> +menu "Options for PMC-Sierra MSP chipsets"
> +	depends on PMC_MSP
> +
> +config PMC_MSP_EMBEDDED_ROOTFS
> +	bool "Root filesystem embedded in kernel image"
> +	select MTD
> +	select MTD_BLOCK
> +	select MTD_PMC_MSP_RAMROOT
> +	select MTD_RAM
> +

    Hm, why not just use initramfs?

> +config PMC_MSP_UNCACHED
> +	bool "Run uncached"
> +	select MIPS_UNCACHED
> +	
> +endmenu
> +

    Erm, was there really a need for separate option?

> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index 18f56a9..610e169 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
>  extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
>  	struct mips_fpu_struct *ctx, int has_fpu);
>  
> +void (*board_watchpoint_handler)(struct pt_regs *regs);
>  void (*board_be_init)(void);
>  int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
>  void (*board_nmi_handler_setup)(void);
> @@ -860,13 +861,17 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
>  
>  asmlinkage void do_watch(struct pt_regs *regs)
>  {
> -	/*
> -	 * We use the watch exception where available to detect stack
> -	 * overflows.
> -	 */
> -	dump_tlb_all();
> -	show_regs(regs);
> -	panic("Caught WATCH exception - probably caused by stack overflow.");
> +	if (board_watchpoint_handler) {
> +		(*board_watchpoint_handler)(regs);
> +	} else {
> +		/*
> +		 * We use the watch exception where available to detect stack
> +		 * overflows.
> +		 */
> +		dump_tlb_all();
> +		show_regs(regs);
> +		panic("Caught WATCH exception - probably caused by stack overflow.");
> +	}
>  }

    There was no real need for else and massive change, just add return right 
after calling the handler...

WBR, Sergei

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 2/5] mips: PMC MSP71xx mips common
@ 2007-02-23 19:56 Marc St-Jean
  2007-02-23 20:35 ` Sergei Shtylyov
  0 siblings, 1 reply; 29+ messages in thread
From: Marc St-Jean @ 2007-02-23 19:56 UTC (permalink / raw)
  To: linux-mips

[PATCH 2/5] mips: PMC MSP71xx mips common

Patch to add mips common support for the PMC-Sierra
MSP71xx devices.

These 5 patches along with the previously posted serial patch
will boot the PMC-Sierra MSP7120 Residential Gateway board.

Signed-off-by: Marc St-Jean <Marc_St-Jean@pmc-sierra.com>
---
 arch/mips/Kconfig           |   82 +++++++++++++++++++++
 arch/mips/Makefile          |    8 ++
 arch/mips/kernel/head.S     |    8 ++
 arch/mips/kernel/traps.c    |   19 +++-
 include/asm-mips/bootinfo.h |   12 +++
 include/asm-mips/mipsregs.h |   30 +++++++
 include/asm-mips/regops.h   |  168 ++++++++++++++++++++++++++++++++++++++++++++
 include/asm-mips/war.h      |   11 ++
 8 files changed, 331 insertions(+), 7 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5da6b0d..d512389 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -504,6 +504,25 @@ config MACH_VR41XX
 	select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 	select GENERIC_HARDIRQS_NO__DO_IRQ
 
+config PMC_MSP
+	bool "PMC-Sierra MSP chipsets"
+	depends on EXPERIMENTAL
+	select DMA_NONCOHERENT
+	select SWAP_IO_SPACE
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_KGDB
+	select IRQ_CPU
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	help
+	  This adds support for the PMC-Sierra family of Multi-Service
+	  Processor System-On-A-Chips.  These parts include a number
+	  of integrated peripherals, interfaces and DSPs in addition to
+	  a variety of MIPS cores.
+
 config PMC_YOSEMITE
 	bool "PMC-Sierra Yosemite eval board"
 	select DMA_COHERENT
@@ -815,6 +834,59 @@ config TOSHIBA_RBTX4938
 
 endchoice
 
+choice
+	prompt "PMC-Sierra MSP SOC type"
+	depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+	bool "PMC-Sierra MSP4200 Eval Board"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+	bool "PMC-Sierra MSP4200 VoIP Gateway"
+	select IRQ_MSP_SLP
+	select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+	bool "PMC-Sierra MSP7120 Eval Board"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+
+config PMC_MSP7120_GW
+	bool "PMC-Sierra MSP7120 Residential Gateway"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+	
+config PMC_MSP7120_FPGA
+	bool "PMC-Sierra MSP7120 FPGA"
+	select SYS_SUPPORTS_MULTITHREADING
+	select IRQ_MSP_CIC
+	select HW_HAS_PCI
+	select MSP_USB
+	
+endchoice
+
+menu "Options for PMC-Sierra MSP chipsets"
+	depends on PMC_MSP
+
+config PMC_MSP_EMBEDDED_ROOTFS
+	bool "Root filesystem embedded in kernel image"
+	select MTD
+	select MTD_BLOCK
+	select MTD_PMC_MSP_RAMROOT
+	select MTD_RAM
+
+config PMC_MSP_UNCACHED
+	bool "Run uncached"
+	select MIPS_UNCACHED
+	
+endmenu
+
 source "arch/mips/ddb5xxx/Kconfig"
 source "arch/mips/gt64120/ev64120/Kconfig"
 source "arch/mips/jazz/Kconfig"
@@ -971,6 +1043,15 @@ config IRQ_CPU_RM9K
 config IRQ_MV64340
 	bool
 
+config IRQ_MSP_SLP
+	bool
+
+config IRQ_MSP_CIC
+	bool
+
+config MSP_USB
+	bool
+
 config DDB5XXX_COMMON
 	bool
 	select SYS_SUPPORTS_KGDB
@@ -1086,6 +1167,7 @@ config MIPS_L1_CACHE_SHIFT
 	int
 	default "4" if MACH_DECSTATION || SNI_RM
 	default "7" if SGI_IP27
+	default "4" if PMC_MSP4200_EVAL
 	default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 92bca6a..fc406f7 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -367,6 +367,14 @@ cflags-$(CONFIG_PMC_YOSEMITE)	+= -Iinclude/asm-mips/mach-yosemite
 load-$(CONFIG_PMC_YOSEMITE)	+= 0xffffffff80100000
 
 #
+# PMC-Sierra MSP SOCs
+#
+core-$(CONFIG_PMC_MSP)		+= arch/mips/pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP)	+= -Iinclude/asm-mips/pmc-sierra/msp71xx \
+					-mno-branch-likely
+load-$(CONFIG_PMC_MSP)		+= 0xffffffff80100000
+
+#
 # Qemu simulating MIPS32 4Kc
 #
 core-$(CONFIG_QEMU)		+= arch/mips/qemu/
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 6f57ca4..d7451b1 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -130,10 +130,18 @@
 	.endm
 
 	/*
+	 * Reserverd space not required for PMC boards, although we need to
+	 * jump to kernel start.
+	 */
+#ifdef CONFIG_PMC_MSP
+	jal	kernel_entry
+#else
+	/*
 	 * Reserved space for exception handlers.
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#endif /* CONFIG_PMC_MSP */
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 18f56a9..610e169 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -70,6 +70,7 @@ extern asmlinkage void handle_reserved(void);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 	struct mips_fpu_struct *ctx, int has_fpu);
 
+void (*board_watchpoint_handler)(struct pt_regs *regs);
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
 void (*board_nmi_handler_setup)(void);
@@ -860,13 +861,17 @@ asmlinkage void do_mdmx(struct pt_regs *regs)
 
 asmlinkage void do_watch(struct pt_regs *regs)
 {
-	/*
-	 * We use the watch exception where available to detect stack
-	 * overflows.
-	 */
-	dump_tlb_all();
-	show_regs(regs);
-	panic("Caught WATCH exception - probably caused by stack overflow.");
+	if (board_watchpoint_handler) {
+		(*board_watchpoint_handler)(regs);
+	} else {
+		/*
+		 * We use the watch exception where available to detect stack
+		 * overflows.
+		 */
+		dump_tlb_all();
+		show_regs(regs);
+		panic("Caught WATCH exception - probably caused by stack overflow.");
+	}
 }
 
 asmlinkage void do_mcheck(struct pt_regs *regs)
diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
index c7c945b..ab29fd4 100644
--- a/include/asm-mips/bootinfo.h
+++ b/include/asm-mips/bootinfo.h
@@ -213,6 +213,18 @@
 #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/
 #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/
 
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_GROUP_MSP         23	/* PMC-Sierra MSP boards/CPUs    */
+#define MACH_MSP4200_EVAL       0	/* PMC-Sierra MSP4200 Evaluation board */
+#define MACH_MSP4200_GW         1	/* PMC-Sierra MSP4200 Gateway demo board */
+#define MACH_MSP4200_FPGA       2	/* PMC-Sierra MSP4200 Emulation board */
+#define MACH_MSP7120_EVAL       3	/* PMC-Sierra MSP7120 Evaluation board */
+#define MACH_MSP7120_GW         4	/* PMC-Sierra MSP7120 Residential Gateway board */
+#define MACH_MSP7120_FPGA       5	/* PMC-Sierra MSP7120 Emulation board */
+#define MACH_MSP_OTHER        255	/* PMC-Sierra unknown board type */
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7..bd683b6 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -15,6 +15,7 @@
 
 #include <linux/linkage.h>
 #include <asm/hazards.h>
+#include <asm/war.h>
 
 /*
  * The following macros are especially useful for __asm__
@@ -1292,10 +1293,39 @@ static inline void tlb_probe(void)
 
 static inline void tlb_read(void)
 {
+#if MIPS34K_MISSED_ITLB_WAR
+	int res = 0;
+
+	__asm__ __volatile__(
+	"	.set	push						\n"
+	"	.set	noreorder					\n"
+	"	.set	noat						\n"
+	"	.set	mips32r2					\n"
+	"	.word	0x41610001		# dvpe $1		\n"
+	"	move	%0, $1						\n"
+	"	ehb							\n"
+	"	.set	pop						\n"
+	: "=r" (res));
+
+	instruction_hazard();
+#endif
+
 	__asm__ __volatile__(
 		".set noreorder\n\t"
 		"tlbr\n\t"
 		".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+	if ((res & _ULCAST_(1)))
+		__asm__ __volatile__(
+		"	.set	push						\n"
+		"	.set	noreorder					\n"
+		"	.set	noat						\n"
+		"	.set	mips32r2					\n"
+		"	.word	0x41600021		# evpe			\n"
+		"	ehb							\n"
+		"	.set	pop						\n");
+#endif
 }
 
 static inline void tlb_write_indexed(void)
diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h
index 13a3502..74c08e6 100644
--- a/include/asm-mips/war.h
+++ b/include/asm-mips/war.h
@@ -196,6 +196,14 @@
 #endif
 
 /*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+	defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
 #ifndef ICACHE_REFILLS_WORKAROUND_WAR
@@ -234,5 +242,8 @@
 #ifndef R10000_LLSC_WAR
 #define R10000_LLSC_WAR			0
 #endif
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#define MIPS34K_MISSED_ITLB_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff --git a/include/asm-mips/regops.h b/include/asm-mips/regops.h
new file mode 100644
index 0000000..fbfc940
--- /dev/null
+++ b/include/asm-mips/regops.h
@@ -0,0 +1,168 @@
+/*
+ * $Id: regops.h,v 1.2 2006/05/08 22:00:34 ramsayji Exp $
+ *
+ * VPE/SMP-safe functions to access registers.  They use ll/sc instructions, so
+ * it is your responsibility to ensure these are available on your platform
+ * before including this file.
+ *
+ * In addition, there is a bug on the R10000 chips which has a workaround.  If
+ * you are affected by this bug, make sure to define the symbol
+ * 'R10000_LLSC_WAR' to be non-zero.  If you are using this header from within
+ * linux, you may include <asm/war.h> before including this file to have this
+ * defined appropriately for you.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
+ *  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF USE,
+ *  DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc., 675
+ *  Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz	"beqzl	"
+#else
+#define __beqz	"beqz	"
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int uint32_t;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32( volatile uint32_t * const addr,
+					uint32_t const mask,
+					uint32_t const value )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1	# set_value_reg32	\n"
+	"	and	%0, %2				\n"
+	"	or	%0, %3				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "ir" (value), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# set_reg32	\n"
+	"	or	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# clear_reg32	\n"
+	"	and	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (~mask), "m" (*addr) );
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32( volatile uint32_t * const addr,
+				uint32_t const mask )
+{
+	uint32_t temp;
+
+	__asm__ __volatile__(
+	"	.set	mips3				\n"
+	"1:	ll	%0, %1		# toggle_reg32	\n"
+	"	xor	%0, %2				\n"
+	"	sc	%0, %1				\n"
+	"	"__beqz"%0, 1b				\n"
+	"	.set	mips0				\n"
+	: "=&r" (temp), "=m" (*addr)
+	: "ir" (mask), "m" (*addr) );
+}
+
+/* For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ *   uint32_t tmp;                      <-- Define a variable to hold the data
+ *
+ *   custom_reg32_start(address, tmp);	<-- Reads the address and puts the value
+ *						in the 'tmp' variable given
+ *
+ *	< From here on out, you are (basicly) atomic, so don't do anything too
+ *	< fancy!
+ *	< Also, this code may loop if the end of this block fails to write
+ *	< everything back safely due do the other CPU, so do NOT do anything
+ *	< with side-effects!
+ *
+ *   custom_reg32_stop(address, tmp);	<-- Writes back 'tmp' safely. 
+ *
+ */
+#define custom_reg32_read(address, tmp)				\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"1:	ll	%0, %1	#custom_reg32_read	\n"	\
+	"	.set	mips0				\n"	\
+	: "=r" (tmp), "=m" (*address)				\
+	: "m" (*address) )
+
+#define custom_reg32_write(address, tmp)			\
+	__asm__ __volatile__(					\
+	"	.set	mips3				\n"	\
+	"	sc	%0, %1	#custom_reg32_write	\n"	\
+	"	"__beqz"%0, 1b				\n"	\
+	"	.set	mips0				\n"	\
+	: "=&r" (tmp), "=m" (*address)				\
+	: "0" (tmp), "m" (*address) )
+
+#endif  /* __ASM_REGOPS_H__ */

^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2007-03-17  0:48 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-27 17:09 [PATCH 2/5] mips: PMC MSP71xx mips common Marc St-Jean
2007-02-27 17:38 ` Thiemo Seufer
2007-02-28 19:32   ` Ralf Baechle
2007-02-27 18:46 ` Andrew Sharp
2007-02-28 19:42   ` Ralf Baechle
  -- strict thread matches above, loose matches on Subject: below --
2007-03-16 23:53 Marc St-Jean
2007-03-17  0:46 ` Ralf Baechle
2007-03-07 18:01 Marc St-Jean
2007-03-16  1:58 ` Ralf Baechle
2007-03-01 20:41 Marc St-Jean
2007-02-28 22:35 Marc St-Jean
2007-02-28 21:35 Marc St-Jean
2007-02-28 21:43 ` Uhler, Mike
2007-02-28 21:43   ` Uhler, Mike
2007-02-28 22:18 ` Ralf Baechle
2007-02-28  0:04 Marc St-Jean
2007-02-27 21:27 Marc St-Jean
2007-02-28 19:52 ` Ralf Baechle
2007-02-27 17:59 Marc St-Jean
2007-02-27 20:03 ` Thiemo Seufer
2007-02-27  0:12 Marc St-Jean
2007-02-27  0:43 ` Andrew Sharp
2007-02-23 21:27 Marc St-Jean
2007-02-23 21:15 Marc St-Jean
2007-02-23 20:53 Marc St-Jean
2007-02-23 21:02 ` Sergei Shtylyov
2007-02-23 21:02 ` David Daney
2007-02-23 19:56 Marc St-Jean
2007-02-23 20:35 ` Sergei Shtylyov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.