2008/6/10 James Molloy <jamesmol@transitive.com>:
Cassy Foesch wrote:
> Well, is this something "new" described my OpenBIOS, or is it actually
> something that was originally defined in OpenFirmware?
>
> 2008/6/10 James Molloy <jamesmol@transitive.com
> <mailto:jamesmol@transitive.com>>:
>
>     Cassy Foesch wrote:
>     > This is an OpenBios feature? Or OpenFirmware? Or where are the
>     > specifications written?
>     >
>     > Basically, the OpenFirmware implementation on PearPC is pretty
>     buggy,
>     > and incomplete.  If it does just run twice, then it doesn't look
>     like
>     > there would be any problems with even an inefficient version
>     running.
>     >  It sounds like it works pretty good, and I'll have to examine the
>     > code a little more, but so far, it looks pretty good.
>     >
>     > 2008/6/9 James Molloy <jamesmol@transitive.com
>     <mailto:jamesmol@transitive.com>
>     > <mailto:jamesmol@transitive.com <mailto:jamesmol@transitive.com>>>:
>     >
>     >     /Apologies for the possible repost - I checked the mailing list
>     >     archives
>     >     and my message didn't seem to appear, so I've now subscribed
>     to the
>     >     mailing list to check if it does./
>     >
>     >     Hi,
>     >
>     >     I'm using PearPC to assist me in developing a hobby OS for
>     the PowerPC
>     >     platform (in addition to real hardware) and noticed that PearPC
>     >     doesn't
>     >     expose the "translations" property of the MMU firmware
>     device node.
>     >
>     >     The translations property is documented in the OpenBios PowerPC
>     >     bindings
>     >     document and is aimed at helping the client program
>     replicate the HTAB
>     >     before taking full control of memory management. I took the
>     liberty of
>     >     creating this property myself.
>     >
>     >     As far as I can tell, PearPC doesn't maintain an explicit
>     list of
>     >     mmu->map() calls, so my algorithm searches the HTAB for
>     every page in
>     >     the effective address space and manually constructs a list of
>     >     them. It's
>     >     O(n), but since it's only intended to be called twice (once
>     from the
>     >     getproplen call and once from the getprop call) I don't see that
>     >     as much
>     >     of a handicap. It executes seemingly instantaneously on my
>     Core2Duo
>     >     running the x86_64 JITC cpu.
>     >
>     >     Anyway, let me know if it's not up to coding standard or
>     there are too
>     >     few comments and I'll change them.
>     >
>     >     Cheers,
>     >
>     >     James Molloy
>     >
>     >     Index: src/io/prom/promdt.cc
>     >     ==============================
>     >     =====================================
>     >     RCS file: /cvsroot/pearpc/pearpc/src/io/prom/promdt.cc,v
>     >     retrieving revision 1.29
>     >     diff -u -r1.29 promdt.cc
>     >     --- src/io/prom/promdt.cc    16 Aug 2005 12:26:43 -0000    1.29
>     >     +++ src/io/prom/promdt.cc    8 Jun 2008 09:48:24 -0000
>     >     @@ -1032,6 +1032,95 @@
>     >         }
>     >      }
>     >
>     >     +/*
>     >     + * PromPropMMU: Implements the MMU's "translations" property,
>     >     which allows
>     >     + * client programs to replicate the HTAB contents before
>     taking over
>     >     + * memory management.
>     >     + */
>     >     +PromPropMMU::PromPropMMU(const char *aName)
>     >     +    :PromProp(aName), nValidTranslations(0)
>     >     +{
>     >     +}
>     >     +
>     >     +PromPropMMU::~PromPropMMU()
>     >     +{
>     >     +}
>     >     +
>     >     +uint32 PromPropMMU::getValueLen()
>     >     +{
>     >     +  calculateTranslations();
>     >     +  return nValidTranslations*sizeof(Translation);
>     >     +}
>     >     +
>     >     +uint32 PromPropMMU::getValue(uint32 buf, uint32 buflen)
>     >     +{
>     >     +  calculateTranslations();
>     >     +  if (nValidTranslations*sizeof(Translation) < buflen)
>     >     +  {
>     >     +    buflen = nValidTranslations*sizeof(Translation);
>     >     +  }
>     >     +
>     >     +  // Convert all values to BE.
>     >     +  for (int i = 0; i < nValidTranslations; i++)
>     >     +  {
>     >     +    translations[i].virt =
>     ppc_word_to_BE(translations[i].virt);
>     >     +    translations[i].phys =
>     ppc_word_to_BE(translations[i].phys);
>     >     +    translations[i].size =
>     ppc_word_to_BE(translations[i].size);
>     >     +    translations[i].mode =
>     ppc_word_to_BE(translations[i].mode);
>     >     +  }
>     >     +
>     >     +  uint32 phys;
>     >     +  ppc_prom_effective_to_physical(phys, buf);
>     >     +  ppc_dma_write(phys, (void*)translations, buflen);
>     >     +  return 0;
>     >     +}
>     >     +
>     >     +uint32 PromPropMMU::setValue(uint32 buf, uint32 buflen)
>     >     +{
>     >     +  return -1;
>     >     +}
>     >     +
>     >     +void PromPropMMU::calculateTranslations()
>     >     +{
>     >     +  nValidTranslations = 0;
>     >     +  uint32 phys;
>     >     +  // For every page in the address space, check for a mapping.
>     >     +  for (uint32 i = 0; i <= 0xFFFFF; i++)
>     >     +  {
>     >     +    uint32 ea = i << 12;
>     >     +    if (ppc_prom_effective_to_physical(phys, ea))
>     >     +    {
>     >     +      // A valid translation exists. Add to the
>     translations list.
>     >     +      addTranslation(ea, phys);
>     >     +    }
>     >     +  }
>     >     +}
>     >     +
>     >     +void PromPropMMU::addTranslation(uint32 ea, uint32 phys)
>     >     +{
>     >     +  // Can the given translation be appended to translation
>     >     'nValidTranslations-1'?
>     >     +  if ( (nValidTranslations > 0) &&
>     >     +       (translations[nValidTranslations-1].virt +
>     >     translations[nValidTranslations-1].size == ea) &&
>     >     +       (translations[nValidTranslations-1].phys +
>     >     translations[nValidTranslations-1].size == phys) )
>     >     +  {
>     >     +    // Modify 'nValidTranslations'.
>     >     +    translations[nValidTranslations-1].size += 0x1000;
>     >     +  }
>     >     +  else
>     >     +  {
>     >     +    // Else add a new translation.
>     >     +    translations[nValidTranslations].virt = ea;
>     >     +    translations[nValidTranslations].phys = phys;
>     >     +    translations[nValidTranslations].size = 0x1000;
>     >     +    translations[nValidTranslations].mode = 0x6a;
>     >     +    nValidTranslations++;
>     >     +    if (nValidTranslations == NUM_TRANSLATIONS)
>     >     +    {
>     >     +      IO_PROM_ERR("PromPropMMU::calculateTranslations - too
>     many
>     >     translations.");
>     >     +    }
>     >     +  }
>     >     +}
>     >     +
>     >
>      /*******************************************************************************
>     >      *
>     >      */
>     >     @@ -1111,6 +1200,8 @@
>     >         gPromRoot->addNode(cpus);
>     >         gPromRoot->addNode(kbd);
>     >
>     >     +  mmu->addProp(new PromPropMMU("translations"));
>     >     +
>     >         PromNode *cpu = new PromNode("PowerPC,G4");
>     >         cpus->addNode(cpu);
>     >         cpus->addProp(new PromPropInt("#size-cells", 0));
>     >     Index: src/io/prom/promdt.h
>     >
>     ===================================================================
>     >     RCS file: /cvsroot/pearpc/pearpc/src/io/prom/promdt.h,v
>     >     retrieving revision 1.3
>     >     diff -u -r1.3 promdt.h
>     >     --- src/io/prom/promdt.h    21 May 2004 22:29:43 -0000    1.3
>     >     +++ src/io/prom/promdt.h    8 Jun 2008 09:48:24 -0000
>     >     @@ -272,6 +272,30 @@
>     >         virtual uint32            setValue(uint32 buf, uint32
>     buflen);
>     >      };
>     >
>     >     +#define NUM_TRANSLATIONS 256
>     >     +class PromPropMMU: public PromProp {
>     >     +public:
>     >     +                    PromPropMMU(const char *name);
>     >     +    virtual                ~PromPropMMU();
>     >     +
>     >     +    virtual    uint32            getValueLen();
>     >     +    virtual    uint32            getValue(uint32 buf,
>     uint32 buflen);
>     >     +    virtual uint32            setValue(uint32 buf, uint32
>     buflen);
>     >     +
>     >     +private:
>     >     +  void calculateTranslations();
>     >     +  void addTranslation(uint32 ea, uint32 phys);
>     >     +  struct Translation
>     >     +  {
>     >     +    uint32 virt;
>     >     +    uint32 size;
>     >     +    uint32 phys;
>     >     +    uint32 mode;
>     >     +  };
>     >     +  Translation translations[NUM_TRANSLATIONS];
>     >     +  uint32 nValidTranslations;
>     >     +};
>     >     +
>     >      #define FIND_DEVICE_FIND 0
>     >      #define FIND_DEVICE_OPEN 1
>     >      PromNode *findDevice(const char *aPathName, int type,
>     >     PromInstanceHandle *ret);
>     >
>     >
>     -------------------------------------------------------------------------
>     >     Check out the new SourceForge.net Marketplace.
>     >     It's the best place to buy or sell services for
>     >     just about anything Open Source.
>     >     http://sourceforge.net/services/buy/index.php
>     >     _______________________________________________
>     >     Pearpc-devel mailing list
>     >     Pearpc-devel@lists.sourceforge.net
>     <mailto:Pearpc-devel@lists.sourceforge.net>
>     >     <mailto:Pearpc-devel@lists.sourceforge.net
>     <mailto:Pearpc-devel@lists.sourceforge.net>>
>     >     https://lists.sourceforge.net/lists/listinfo/pearpc-devel
>     >
>     >
>     >
>     >
>     > --
>     > Cassy
>     >
>     ------------------------------------------------------------------------
>     >
>     >
>     -------------------------------------------------------------------------
>     > Check out the new SourceForge.net Marketplace.
>     > It's the best place to buy or sell services for
>     > just about anything Open Source.
>     > http://sourceforge.net/services/buy/index.php
>     >
>     ------------------------------------------------------------------------
>     >
>     > _______________________________________________
>     > Pearpc-devel mailing list
>     > Pearpc-devel@lists.sourceforge.net
>     <mailto:Pearpc-devel@lists.sourceforge.net>
>     > https://lists.sourceforge.net/lists/listinfo/pearpc-devel
>     >
>     Hi Cassy,
>
>     Thanks for the reply. The property is described in the PPC binding for
>     OpenBIOS, available at http://openbios.org/Bindings. To quote from
>     section 5.1.7 - Memory management unit properties:
>
>        To aid a client in "taking over" the translation mechanism and
>     still
>        interact with Open Firmware (via the client interface), the client
>        needs to know what translations have been established by Open
>        Firmware. The following standard translation shall exist within the
>        package to which the "mmu" property of the /chosen package refers.
>
>        "Translations"
>          This property, consisting of sets of translations, defines the
>        currently active translations that have been established by Open
>        Firmware (e.g. using map). Each set has the following format:
>            (virt size phys mode)
>          Each value is encoded as with encode-int
>
>
>     As I said, it seems to run pretty quickly even though it's O(n),
>     however
>     I've only run it on a core 2 duo and a pentium 4, neither of which are
>     particularly slow (the P4 is pushing it though :) )
>
>     Cheers,
>
>     James
>
>     -------------------------------------------------------------------------
>     Check out the new SourceForge.net Marketplace.
>     It's the best place to buy or sell services for
>     just about anything Open Source.
>     http://sourceforge.net/services/buy/index.php
>     _______________________________________________
>     Pearpc-devel mailing list
>     Pearpc-devel@lists.sourceforge.net
>     <mailto:Pearpc-devel@lists.sourceforge.net>
>     https://lists.sourceforge.net/lists/listinfo/pearpc-devel
>
>
>
>
> --
> Cassy
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> Check out the new SourceForge.net Marketplace.
> It's the best place to buy or sell services for
> just about anything Open Source.
> http://sourceforge.net/services/buy/index.php
> ------------------------------------------------------------------------
>
> _______________________________________________
> Pearpc-devel mailing list
> Pearpc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/pearpc-devel
>
Hi,

That's a little difficult to answer, as I don't know the full history of
OpenFirmware/OpenBIOS.

What I /can/ tell you is:

(a) It's defined as a "shall" in the OpenBIOS PPC binding (as I've
already quoted).
(b) It's implemented in OpenFirmware version 3 as used by the Apple
iBook and iMacs.

Further to that I have no real idea what you're asking - sorry.

James

Awesome, that's pretty much what I was trying to get to. If it's implemented in Apple's OpenFirmware, and it's a "shall" in OpenBIOS PPC, then it's likely a "shall" in the original OpenFirmware requirements.

I'll review your code, and get it checked in unless you need to fix anything... so far, it doesn't look like it at first glance.

--
Cassy