|
From: Cassy F. <pue...@go...> - 2008-06-09 23:22:38
|
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 <jam...@tr...>:
> /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
> Pea...@li...
> https://lists.sourceforge.net/lists/listinfo/pearpc-devel
>
--
Cassy
|