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>:
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>>:
>
>     /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>
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> 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 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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel



--
Cassy