This patch implements Adler-32 checksum support for compatibility with Mac OS 9. Since OS 9 is the only client known to use the Adler-32 function, we bind the copyright message needed by OS 9 when the function is called.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
--- arch/ppc/qemu/init.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ arch/ppc/qemu/qemu.fs | 13 ++++++++++++ 2 files changed, 68 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 4fe8b72..84a3615 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -680,6 +680,58 @@ static void ffilll(void) } }
+/* + * adler32 ( adler buf len -- checksum ) + * + * Adapted from Mark Adler's original implementation (zlib license) + */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +static void adler32(void) +{ + uint32_t len = (uint32_t)POP(); + char *buf = (char *)POP(); + uint32_t adler = (uint32_t)POP(); + + if (buf == NULL) { + RET(-1); + } + + uint32_t base = 65521; + uint32_t nmax = 5552; + + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + + uint32_t k; + while (len > 0) { + k = (len < nmax ? len : nmax); + len -= k; + + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) { + do { + s1 += *buf++; + s2 += s1; + } while (--k); + } + + s1 %= base; + s2 %= base; + } + + RET(s2 << 16 | s1); +} + void arch_of_init(void) { @@ -945,6 +997,9 @@ arch_of_init(void)
/* Implementation of filll word (required by BootX) */ bind_func("filll", ffilll); + + /* Adler-32 required by Mac OS 9 */ + bind_func("(adler32)", adler32);
bind_func("platform-boot", boot); bind_func("(go)", go); diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs index 458af1b..d2c6a4c 100644 --- a/arch/ppc/qemu/qemu.fs +++ b/arch/ppc/qemu/qemu.fs @@ -93,3 +93,16 @@ variable keyboard-phandle 0 keyboard-phandle ! :noname set-defaults ; PREPOST-initializer + +\ ------------------------------------------------------------------------- +\ Apple copyright hack +\ ------------------------------------------------------------------------- + +: adler32 ( adler buf len -- checksum ) + \ The only OS that calls this is Mac OS 9, so we take this opportunity to + \ patch in the required copyright string. + " /" find-device + " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY PURPOSES ONLY. COPYRIGHT IS HELD BY THE OPENBIOS PROJECT AND ITS CONTRIBUTORS." + encode-string " copyright" property + " (adler32)" evaluate +;
On 26/05/15 17:48, Cormac O'Brien wrote:
Hi Cormac,
This patch implements Adler-32 checksum support for compatibility with Mac OS 9. Since OS 9 is the only client known to use the Adler-32 function, we bind the copyright message needed by OS 9 when the function is called.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
arch/ppc/qemu/init.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ arch/ppc/qemu/qemu.fs | 13 ++++++++++++ 2 files changed, 68 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 4fe8b72..84a3615 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -680,6 +680,58 @@ static void ffilll(void) } }
+/*
- adler32 ( adler buf len -- checksum )
- Adapted from Mark Adler's original implementation (zlib license)
- */
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8);
+static void adler32(void) +{
- uint32_t len = (uint32_t)POP();
- char *buf = (char *)POP();
- uint32_t adler = (uint32_t)POP();
- if (buf == NULL) {
RET(-1);
- }
- uint32_t base = 65521;
- uint32_t nmax = 5552;
- uint32_t s1 = adler & 0xffff;
- uint32_t s2 = (adler >> 16) & 0xffff;
- uint32_t k;
- while (len > 0) {
k = (len < nmax ? len : nmax);
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) {
do {
s1 += *buf++;
s2 += s1;
} while (--k);
}
s1 %= base;
s2 %= base;
- }
- RET(s2 << 16 | s1);
+}
void arch_of_init(void) { @@ -945,6 +997,9 @@ arch_of_init(void)
/* Implementation of filll word (required by BootX) */ bind_func("filll", ffilll);
/* Adler-32 required by Mac OS 9 */
bind_func("(adler32)", adler32);
bind_func("platform-boot", boot); bind_func("(go)", go);
diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs index 458af1b..d2c6a4c 100644 --- a/arch/ppc/qemu/qemu.fs +++ b/arch/ppc/qemu/qemu.fs @@ -93,3 +93,16 @@ variable keyboard-phandle 0 keyboard-phandle ! :noname set-defaults ; PREPOST-initializer
+\ ------------------------------------------------------------------------- +\ Apple copyright hack +\ -------------------------------------------------------------------------
I think this comment is a bit misleading since the adler32 word isn't anything to do with the copyright hack. It's still a valid word, it just so happens that it's a good injection point for a dummy copyright property. Maybe just explain in the comment below that OS 9 does a fixed string comparison on boot which is why we need to do this?
+: adler32 ( adler buf len -- checksum )
- \ The only OS that calls this is Mac OS 9, so we take this opportunity to
- \ patch in the required copyright string.
- " /" find-device
The use of find-device here is likely to cause problems as it's effectively changing the current device package which means when control is returned to the boot script, it won't be in the device it thinks it is.
- " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY PURPOSES ONLY. COPYRIGHT IS HELD BY THE OPENBIOS PROJECT AND ITS CONTRIBUTORS."
- encode-string " copyright" property
In OpenBIOS you should be able to use something like find-package and set-property to set the property directly without having to change to a different package.
And thinking about this more, with an enhanced comment above then stopping the message just after "THIS MESSAGE IS FOR COMPATIBILITY PURPOSES ONLY." should suffice as the context seems fairly clear.
- " (adler32)" evaluate
The normal convention is Forth is to search the dictionary for a word (xt) and then execute it directly rather than directly execing strings in the Forth interpreter.
At compile time you'd go for something like "['] myfunction execute" but since (adler32) is only bound at runtime then you'll need to use $find or similar to find it - there should be several existing examples around in the source for you to study.
ATB,
Mark.
On 26/05/15 17:48, Cormac O'Brien wrote:
This patch implements Adler-32 checksum support for compatibility with Mac OS 9. Since OS 9 is the only client known to use the Adler-32 function, we bind the copyright message needed by OS 9 when the function is called.
Signed-off-by: Cormac O'Brien i.am.cormac.obrien@gmail.com
arch/ppc/qemu/init.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ arch/ppc/qemu/qemu.fs | 13 ++++++++++++ 2 files changed, 68 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 4fe8b72..84a3615 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -680,6 +680,58 @@ static void ffilll(void) } }
+/*
- adler32 ( adler buf len -- checksum )
- Adapted from Mark Adler's original implementation (zlib license)
- */
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8);
+static void adler32(void) +{
- uint32_t len = (uint32_t)POP();
- char *buf = (char *)POP();
- uint32_t adler = (uint32_t)POP();
- if (buf == NULL) {
RET(-1);
- }
- uint32_t base = 65521;
- uint32_t nmax = 5552;
- uint32_t s1 = adler & 0xffff;
- uint32_t s2 = (adler >> 16) & 0xffff;
- uint32_t k;
- while (len > 0) {
k = (len < nmax ? len : nmax);
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) {
do {
s1 += *buf++;
s2 += s1;
} while (--k);
}
s1 %= base;
s2 %= base;
- }
- RET(s2 << 16 | s1);
+}
void arch_of_init(void) { @@ -945,6 +997,9 @@ arch_of_init(void)
/* Implementation of filll word (required by BootX) */ bind_func("filll", ffilll);
/* Adler-32 required by Mac OS 9 */
bind_func("(adler32)", adler32);
bind_func("platform-boot", boot); bind_func("(go)", go);
diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs index 458af1b..d2c6a4c 100644 --- a/arch/ppc/qemu/qemu.fs +++ b/arch/ppc/qemu/qemu.fs @@ -93,3 +93,16 @@ variable keyboard-phandle 0 keyboard-phandle ! :noname set-defaults ; PREPOST-initializer
+\ ------------------------------------------------------------------------- +\ Apple copyright hack +\ -------------------------------------------------------------------------
+: adler32 ( adler buf len -- checksum )
- \ The only OS that calls this is Mac OS 9, so we take this opportunity to
- \ patch in the required copyright string.
- " /" find-device
- " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY PURPOSES ONLY. COPYRIGHT IS HELD BY THE OPENBIOS PROJECT AND ITS CONTRIBUTORS."
- encode-string " copyright" property
- " (adler32)" evaluate
+;
Thinking about this again after some sleep, can we keep this as two separate patches i.e. one for the adler32 and one for the copyright? The reason here is that we know the behaviour of guests can change depending upon this property value, so with two patches we get a definite bisection point should a guest that previously worked starts to fail. It's fairly easy to spin this out as a 2 patch series using git.
One of the things Alex mentioned yesterday was whether or not the copyright patch would affect BootX or not, and so I'd like to see something along the lines of "Tested on both OS 9 and BootX" included in the commit message. Did you manage to test the 2 patches on any other OSs at all?
ATB,
Mark.
[ Sorry for replying to this message, I already deleted the older ones. ]
On Wed, May 27, 2015 at 07:41:16AM +0100, Mark Cave-Ayland wrote:
On 26/05/15 17:48, Cormac O'Brien wrote:
+\ ------------------------------------------------------------------------- +\ Apple copyright hack +\ -------------------------------------------------------------------------
+: adler32 ( adler buf len -- checksum )
- \ The only OS that calls this is Mac OS 9, so we take this opportunity to
- \ patch in the required copyright string.
- " /" find-device
- " Copyright 1983-2001 Apple Computer, Inc. THIS MESSAGE FOR COMPATIBILITY PURPOSES ONLY. COPYRIGHT IS HELD BY THE OPENBIOS PROJECT AND ITS CONTRIBUTORS."
- encode-string " copyright" property
- " (adler32)" evaluate
+;
The "year" part is not checked either, so you could say something like "Copyright IS NOT BY Apple Computer, Inc." and things will work fine.
Thinking about this again after some sleep, can we keep this as two separate patches i.e. one for the adler32 and one for the copyright?
Yes please.
One of the things Alex mentioned yesterday was whether or not the copyright patch would affect BootX or not, and so I'd like to see something along the lines of "Tested on both OS 9 and BootX" included in the commit message. Did you manage to test the 2 patches on any other OSs at all?
The same holds for other changes for OS9, e.g. the RTAS things. That stuff can potentially break Linux as well, oh joy.
Segher