Discussion:
[Pearpc-devel] [patch] MMU translations property
James Molloy
2008-06-09 08:29:33 UTC
Permalink
/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);
James Molloy
2008-06-09 15:26:16 UTC
Permalink
/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);
Cassy Foesch
2008-06-09 23:22:45 UTC
Permalink
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.
Post by James Molloy
/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 {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf, uint32 buflen);
+ virtual uint32 setValue(uint32 buf, uint32 buflen);
+
+ 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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
James Molloy
2008-06-10 07:25:55 UTC
Permalink
Post by Cassy Foesch
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.
/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 {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf, uint32 buflen);
+ virtual uint32 setValue(uint32 buf, uint32 buflen);
+
+ 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
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
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
Cassy Foesch
2008-06-10 08:15:34 UTC
Permalink
Well, is this something "new" described my OpenBIOS, or is it actually
something that was originally defined in OpenFirmware?
Post by James Molloy
Post by Cassy Foesch
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.
/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
Post by Cassy Foesch
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
Post by Cassy Foesch
before taking full control of memory management. I took the liberty
of
Post by Cassy Foesch
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
Post by Cassy Foesch
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.");
+ }
+ }
+}
+
/*******************************************************************************
Post by Cassy Foesch
*
*/
@@ -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 {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32 buflen);
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
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
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
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
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
(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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
Aaron Fisher
2008-06-10 08:17:22 UTC
Permalink
can someone please finally take me off this list!?!?!?!? i have asked
at least a dozen times.
thank you!
Post by Cassy Foesch
Well, is this something "new" described my OpenBIOS, or is it
actually something that was originally defined in OpenFirmware?
Post by Cassy Foesch
This is an OpenBios feature? Or OpenFirmware? Or where are the
specifications written?
Basically, the OpenFirmware implementation on PearPC is pretty
buggy,
Post by Cassy Foesch
and incomplete. If it does just run twice, then it doesn't look
like
Post by Cassy Foesch
there would be any problems with even an inefficient version
running.
Post by Cassy Foesch
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.
/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
Post by Cassy Foesch
mailing list to check if it does./
Hi,
I'm using PearPC to assist me in developing a hobby OS for the
PowerPC
Post by Cassy Foesch
platform (in addition to real hardware) and noticed that PearPC doesn't
expose the "translations" property of the MMU firmware device
node.
Post by Cassy Foesch
The translations property is documented in the OpenBios PowerPC bindings
document and is aimed at helping the client program replicate
the HTAB
Post by Cassy Foesch
before taking full control of memory management. I took the
liberty of
Post by Cassy Foesch
creating this property myself.
As far as I can tell, PearPC doesn't maintain an explicit list
of
Post by Cassy Foesch
mmu->map() calls, so my algorithm searches the HTAB for every
page in
Post by Cassy Foesch
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
Post by Cassy Foesch
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
Post by Cassy Foesch
running the x86_64 JITC cpu.
Anyway, let me know if it's not up to coding standard or there
are too
Post by Cassy Foesch
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
Post by Cassy Foesch
+ * 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);
Post by Cassy Foesch
+ translations[i].phys =
ppc_word_to_BE(translations[i].phys);
Post by Cassy Foesch
+ translations[i].size =
ppc_word_to_BE(translations[i].size);
Post by Cassy Foesch
+ translations[i].mode =
ppc_word_to_BE(translations[i].mode);
Post by Cassy Foesch
+ }
+
+ 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.
Post by Cassy Foesch
+ 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
Post by Cassy Foesch
translations.");
+ }
+ }
+}
+
/
*******************************************************************************
Post by Cassy Foesch
*
*/
@@ -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
===================================================================
Post by Cassy Foesch
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);
Post by Cassy Foesch
};
+#define NUM_TRANSLATIONS 256
+class PromPropMMU: public PromProp {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
------------------------------------------------------------------------
-------------------------------------------------------------------------
Post by Cassy Foesch
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
------------------------------------------------------------------------
Post by Cassy Foesch
_______________________________________________
Pearpc-devel mailing list
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
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
(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
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
Jens von der Heydt
2008-06-10 08:24:04 UTC
Permalink
Aaron, just asking to get off the list won't help that much. Simply
use the Newsletter-Tools provided by sourceforge on their homepage.

Jens
Post by Aaron Fisher
can someone please finally take me off this list!?!?!?!? i have
asked at least a dozen times.
thank you!
Post by Cassy Foesch
Well, is this something "new" described my OpenBIOS, or is it
actually something that was originally defined in OpenFirmware?
Post by Cassy Foesch
This is an OpenBios feature? Or OpenFirmware? Or where are the
specifications written?
Basically, the OpenFirmware implementation on PearPC is pretty
buggy,
Post by Cassy Foesch
and incomplete. If it does just run twice, then it doesn't look
like
Post by Cassy Foesch
there would be any problems with even an inefficient version
running.
Post by Cassy Foesch
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.
/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
Post by Cassy Foesch
mailing list to check if it does./
Hi,
I'm using PearPC to assist me in developing a hobby OS for
the PowerPC
Post by Cassy Foesch
platform (in addition to real hardware) and noticed that PearPC doesn't
expose the "translations" property of the MMU firmware device
node.
Post by Cassy Foesch
The translations property is documented in the OpenBios PowerPC bindings
document and is aimed at helping the client program replicate
the HTAB
Post by Cassy Foesch
before taking full control of memory management. I took the
liberty of
Post by Cassy Foesch
creating this property myself.
As far as I can tell, PearPC doesn't maintain an explicit
list of
Post by Cassy Foesch
mmu->map() calls, so my algorithm searches the HTAB for every
page in
Post by Cassy Foesch
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
Post by Cassy Foesch
getproplen call and once from the getprop call) I don't see
that
Post by Cassy Foesch
as much
of a handicap. It executes seemingly instantaneously on my
Core2Duo
Post by Cassy Foesch
running the x86_64 JITC cpu.
Anyway, let me know if it's not up to coding standard or
there are too
Post by Cassy Foesch
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
Post by Cassy Foesch
+ * 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);
Post by Cassy Foesch
+ translations[i].phys =
ppc_word_to_BE(translations[i].phys);
Post by Cassy Foesch
+ translations[i].size =
ppc_word_to_BE(translations[i].size);
Post by Cassy Foesch
+ translations[i].mode =
ppc_word_to_BE(translations[i].mode);
Post by Cassy Foesch
+ }
+
+ 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.
Post by Cassy Foesch
+ 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
Post by Cassy Foesch
translations.");
+ }
+ }
+}
+
/
*******************************************************************************
Post by Cassy Foesch
*
*/
@@ -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
===================================================================
Post by Cassy Foesch
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);
Post by Cassy Foesch
};
+#define NUM_TRANSLATIONS 256
+class PromPropMMU: public PromProp {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
------------------------------------------------------------------------
-------------------------------------------------------------------------
Post by Cassy Foesch
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
------------------------------------------------------------------------
Post by Cassy Foesch
_______________________________________________
Pearpc-devel mailing list
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
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
(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
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
-------------------------------------------------------------------------
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
Aaron Fisher
2008-06-10 08:25:24 UTC
Permalink
tried. doesn't work.

=(
Post by Jens von der Heydt
Aaron, just asking to get off the list won't help that much. Simply
use the Newsletter-Tools provided by sourceforge on their homepage.
Jens
Post by Aaron Fisher
can someone please finally take me off this list!?!?!?!? i have
asked at least a dozen times.
thank you!
Post by Cassy Foesch
Well, is this something "new" described my OpenBIOS, or is it
actually something that was originally defined in OpenFirmware?
Post by Cassy Foesch
This is an OpenBios feature? Or OpenFirmware? Or where are the
specifications written?
Basically, the OpenFirmware implementation on PearPC is pretty
buggy,
Post by Cassy Foesch
and incomplete. If it does just run twice, then it doesn't look
like
Post by Cassy Foesch
there would be any problems with even an inefficient version
running.
Post by Cassy Foesch
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.
/Apologies for the possible repost - I checked the mailing
list
Post by Cassy Foesch
archives
and my message didn't seem to appear, so I've now subscribed
to the
Post by Cassy Foesch
mailing list to check if it does./
Hi,
I'm using PearPC to assist me in developing a hobby OS for
the PowerPC
Post by Cassy Foesch
platform (in addition to real hardware) and noticed that
PearPC
Post by Cassy Foesch
doesn't
expose the "translations" property of the MMU firmware
device node.
Post by Cassy Foesch
The translations property is documented in the OpenBios
PowerPC
Post by Cassy Foesch
bindings
document and is aimed at helping the client program
replicate the HTAB
Post by Cassy Foesch
before taking full control of memory management. I took the
liberty of
Post by Cassy Foesch
creating this property myself.
As far as I can tell, PearPC doesn't maintain an explicit
list of
Post by Cassy Foesch
mmu->map() calls, so my algorithm searches the HTAB for
every page in
Post by Cassy Foesch
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
Post by Cassy Foesch
getproplen call and once from the getprop call) I don't see
that
Post by Cassy Foesch
as much
of a handicap. It executes seemingly instantaneously on my
Core2Duo
Post by Cassy Foesch
running the x86_64 JITC cpu.
Anyway, let me know if it's not up to coding standard or
there are too
Post by Cassy Foesch
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
Post by Cassy Foesch
+++ 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
Post by Cassy Foesch
+ * 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);
Post by Cassy Foesch
+ translations[i].phys =
ppc_word_to_BE(translations[i].phys);
Post by Cassy Foesch
+ translations[i].size =
ppc_word_to_BE(translations[i].size);
Post by Cassy Foesch
+ translations[i].mode =
ppc_word_to_BE(translations[i].mode);
Post by Cassy Foesch
+ }
+
+ 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.
Post by Cassy Foesch
+ 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.
Post by Cassy Foesch
+ 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
Post by Cassy Foesch
translations.");
+ }
+ }
+}
+
/
*******************************************************************************
Post by Cassy Foesch
*
*/
@@ -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
===================================================================
Post by Cassy Foesch
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);
Post by Cassy Foesch
};
+#define NUM_TRANSLATIONS 256
+class PromPropMMU: public PromProp {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf,
uint32 buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
------------------------------------------------------------------------
-------------------------------------------------------------------------
Post by Cassy Foesch
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
------------------------------------------------------------------------
Post by Cassy Foesch
_______________________________________________
Pearpc-devel mailing list
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
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
(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
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
-------------------------------------------------------------------------
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
-------------------------------------------------------------------------
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
James Molloy
2008-06-10 08:46:31 UTC
Permalink
Post by Cassy Foesch
Well, is this something "new" described my OpenBIOS, or is it actually
something that was originally defined in OpenFirmware?
Post by Cassy Foesch
This is an OpenBios feature? Or OpenFirmware? Or where are the
specifications written?
Basically, the OpenFirmware implementation on PearPC is pretty
buggy,
Post by Cassy Foesch
and incomplete. If it does just run twice, then it doesn't look
like
Post by Cassy Foesch
there would be any problems with even an inefficient version
running.
Post by Cassy Foesch
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.
/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
Post by Cassy Foesch
mailing list to check if it does./
Hi,
I'm using PearPC to assist me in developing a hobby OS for
the PowerPC
Post by Cassy Foesch
platform (in addition to real hardware) and noticed that PearPC doesn't
expose the "translations" property of the MMU firmware
device node.
Post by Cassy Foesch
The translations property is documented in the OpenBios PowerPC
bindings
document and is aimed at helping the client program
replicate the HTAB
Post by Cassy Foesch
before taking full control of memory management. I took the
liberty of
Post by Cassy Foesch
creating this property myself.
As far as I can tell, PearPC doesn't maintain an explicit
list of
Post by Cassy Foesch
mmu->map() calls, so my algorithm searches the HTAB for
every page in
Post by Cassy Foesch
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
Post by Cassy Foesch
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
Post by Cassy Foesch
running the x86_64 JITC cpu.
Anyway, let me know if it's not up to coding standard or
there are too
Post by Cassy Foesch
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
Post by Cassy Foesch
+ * 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);
Post by Cassy Foesch
+ translations[i].phys =
ppc_word_to_BE(translations[i].phys);
Post by Cassy Foesch
+ translations[i].size =
ppc_word_to_BE(translations[i].size);
Post by Cassy Foesch
+ translations[i].mode =
ppc_word_to_BE(translations[i].mode);
Post by Cassy Foesch
+ }
+
+ 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.
Post by Cassy Foesch
+ 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
Post by Cassy Foesch
translations.");
+ }
+ }
+}
+
/*******************************************************************************
Post by Cassy Foesch
*
*/
@@ -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
===================================================================
Post by Cassy Foesch
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);
Post by Cassy Foesch
};
+#define NUM_TRANSLATIONS 256
+class PromPropMMU: public PromProp {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf,
uint32 buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
------------------------------------------------------------------------
-------------------------------------------------------------------------
Post by Cassy Foesch
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
------------------------------------------------------------------------
Post by Cassy Foesch
_______________________________________________
Pearpc-devel mailing list
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
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
(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
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
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
Cassy Foesch
2008-06-11 18:02:05 UTC
Permalink
Post by James Molloy
Post by Cassy Foesch
Well, is this something "new" described my OpenBIOS, or is it actually
something that was originally defined in OpenFirmware?
Post by Cassy Foesch
This is an OpenBios feature? Or OpenFirmware? Or where are the
specifications written?
Basically, the OpenFirmware implementation on PearPC is pretty
buggy,
Post by Cassy Foesch
and incomplete. If it does just run twice, then it doesn't look
like
Post by Cassy Foesch
there would be any problems with even an inefficient version
running.
Post by Cassy Foesch
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.
/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
Post by Cassy Foesch
mailing list to check if it does./
Hi,
I'm using PearPC to assist me in developing a hobby OS for
the PowerPC
Post by Cassy Foesch
platform (in addition to real hardware) and noticed that PearPC
doesn't
expose the "translations" property of the MMU firmware
device node.
Post by Cassy Foesch
The translations property is documented in the OpenBios PowerPC
bindings
document and is aimed at helping the client program
replicate the HTAB
Post by Cassy Foesch
before taking full control of memory management. I took the
liberty of
Post by Cassy Foesch
creating this property myself.
As far as I can tell, PearPC doesn't maintain an explicit
list of
Post by Cassy Foesch
mmu->map() calls, so my algorithm searches the HTAB for
every page in
Post by Cassy Foesch
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
Post by Cassy Foesch
getproplen call and once from the getprop call) I don't see
that
Post by Cassy Foesch
Post by Cassy Foesch
as much
of a handicap. It executes seemingly instantaneously on my
Core2Duo
Post by Cassy Foesch
running the x86_64 JITC cpu.
Anyway, let me know if it's not up to coding standard or
there are too
Post by Cassy Foesch
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
Post by Cassy Foesch
+ * 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);
Post by Cassy Foesch
+ translations[i].phys =
ppc_word_to_BE(translations[i].phys);
Post by Cassy Foesch
+ translations[i].size =
ppc_word_to_BE(translations[i].size);
Post by Cassy Foesch
+ translations[i].mode =
ppc_word_to_BE(translations[i].mode);
Post by Cassy Foesch
+ }
+
+ 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.
Post by Cassy Foesch
+ 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
Post by Cassy Foesch
translations.");
+ }
+ }
+}
+
/*******************************************************************************
Post by Cassy Foesch
Post by Cassy Foesch
*
*/
@@ -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
===================================================================
Post by Cassy Foesch
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);
Post by Cassy Foesch
};
+#define NUM_TRANSLATIONS 256
+class PromPropMMU: public PromProp {
+ PromPropMMU(const char *name);
+ virtual ~PromPropMMU();
+
+ virtual uint32 getValueLen();
+ virtual uint32 getValue(uint32 buf,
uint32 buflen);
Post by Cassy Foesch
+ virtual uint32 setValue(uint32 buf, uint32
buflen);
Post by Cassy Foesch
+
+ 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);
-------------------------------------------------------------------------
Post by Cassy Foesch
Post by Cassy Foesch
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
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
--
Cassy
------------------------------------------------------------------------
-------------------------------------------------------------------------
Post by Cassy Foesch
Post by Cassy Foesch
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
------------------------------------------------------------------------
Post by Cassy Foesch
Post by Cassy Foesch
_______________________________________________
Pearpc-devel mailing list
https://lists.sourceforge.net/lists/listinfo/pearpc-devel
Hi Cassy,
Thanks for the reply. The property is described in the PPC binding
for
Post by Cassy Foesch
OpenBIOS, available at http://openbios.org/Bindings. To quote from
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
Post by Cassy Foesch
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
(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
Post by Cassy Foesch
particularly slow (the P4 is pushing it though :) )
Cheers,
James
-------------------------------------------------------------------------
Post by Cassy Foesch
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
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
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.
(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
Loading...