This patchset is loosely based on earlier work by BALATON Zoltan <balaton(a)eik.bme.hu>
and provides basic infrastructure to allow OpenBIOS to enable PCI device
bus mastering.
Following on from discussions on the QEMU mailing list, it seems that Apple's OF
enables bus mastering for some PCI devices by default, and as a result some buggy
drivers forget to explicitly enable it and hence these devices fail under QEMU's
emulation.
The first 3 patches add the basic support routines while the last 2 patches enable
bus mastering for the rtl8139 card on Apple PPC machines which is required for
OS X and MorphOS.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland(a)ilande.co.uk>
Mark Cave-Ayland (5):
pci: introduce ob_pci_enable_bus_master() function
pci: introduce ob_pci_is_bus_master_capable() function
pci: add PCI database entry for rtl8139 network card
pci: add rtl8139_config_cb() to configure rtl8139 network cards
ppc: mark PCI slots 0-2 for Apple PPC machies as bus master capable
openbios-devel/arch/ppc/qemu/init.c | 9 ++++---
openbios-devel/drivers/pci.c | 44 +++++++++++++++++++++++++++++++++
openbios-devel/drivers/pci_database.c | 6 +++++
openbios-devel/drivers/pci_database.h | 4 +++
openbios-devel/include/drivers/pci.h | 2 ++
5 files changed, 62 insertions(+), 3 deletions(-)
--
1.7.10.4
On Apr 17, 2016, at 11:05 AM, Mark Cave-Ayland wrote:
> On 17/04/16 15:50, Programmingkid wrote:
>
>> Good news, I found out why replacing '\r' with '\n' works to boot Mac OS 9. It is because there are several words that require that character to be at the end of the line.
>>
>> http://www.complang.tuwien.ac.at/forth/1275.ps
>> This is the specifications to Open Firmware. Just do a search for EOL (End of Line a.k.a '\n'). You will see that several words need it in order to work.
>>
>> They will look like this:
>>
>> dev ( "device-specifier<eol>" -- )
>>
>> The <eol> text is what specifies that '\n' should be at the end of the line.
>
> Really? Interesting. Can you provide a self-contained test case that
> demonstrates that it is in fact the line ending that causes this
> independent of the r-stack manipulation? Bear in mind that OpenBIOS may
> deviate from the specification in its behaviour here.
I implemented another stack that two new words use in place of >r and r> when running code in the bootscript. I see this message with and without the '\r' to '\n' patch:
>> Dictionary space overflow: dicthead=000c3fe4 dictlimit=00080000
this image is not for this platform
This means the implementing another stack did not fix the problem. It appears to make it worse.
Here is the patch:
Index: include/libc/string.h
===================================================================
--- include/libc/string.h (revision 1391)
+++ include/libc/string.h (working copy)
@@ -47,7 +47,7 @@
extern char *strdup( const char *str );
extern int strcasecmp( const char *cs, const char *ct );
extern int strncasecmp( const char *cs, const char *ct, size_t count );
-
+extern char *strstr(char *buffer, const char *search_string);
extern char *strncpy_nopad( char *dest, const char *src, size_t n );
#define _U 0x01 /* upper */
Index: kernel/bootstrap.c
===================================================================
--- kernel/bootstrap.c (revision 1391)
+++ kernel/bootstrap.c (working copy)
@@ -89,7 +89,7 @@
"here", "here!", "dobranch", "do?branch", "unaligned-w@",
"unaligned-w!", "unaligned-l@", "unaligned-l!", "ioc@", "iow@",
"iol@", "ioc!", "iow!", "iol!", "i", "j", "call", "sys-debug",
- "$include", "$encode-file", "(debug", "(debug-off)"
+ "$include", "$encode-file", "(debug", "(debug-off)", "sub_>r", "sub_r>"
};
/*
Index: kernel/forth.c
===================================================================
--- kernel/forth.c (revision 1391)
+++ kernel/forth.c (working copy)
@@ -1848,6 +1848,37 @@
PUSH(rstack[rstackcnt - 2]);
}
+/* The substitute return stack */
+#define MAX_SUB_RSTACK_SIZE 100
+static int sub_return_stack[MAX_SUB_RSTACK_SIZE];
+static int top = 0;
+
+/*
+ * sub_>r ( i -- ) (Substitute R: -- i )
+ */
+
+static void sub_gt_r(void)
+{
+ if (top >= MAX_SUB_RSTACK_SIZE) {
+ printf_console("Stack overflow\n");
+ return;
+ }
+ sub_return_stack[top++] = POP();
+}
+
+/*
+ * sub_r> ( -- i ) (Substitute R: i -- )
+ */
+
+static void sub_r_gt(void)
+{
+ if (top < 0 ) {
+ printf_console("Stack underflow\n");
+ return;
+ }
+ PUSH(sub_return_stack[top--]);
+}
+
/* words[] is a function array of all native code functions used by
* the dictionary, i.e. CFAs and primitives.
* Any change here needs a matching change in the primitive word's
@@ -1963,4 +1994,6 @@
do_encode_file, /* $encode-file */
do_debug_xt, /* (debug */
do_debug_off, /* (debug-off) */
+ sub_gt_r, /* sub_>r */
+ sub_r_gt /* sub_r> */
};
Index: libc/string.c
===================================================================
--- libc/string.c (revision 1391)
+++ libc/string.c (working copy)
@@ -385,3 +385,30 @@
return __res;
}
+// Search for a string within another string
+char *strstr(char *buffer, const char *search_string)
+{
+ if (!*search_string || (strlen(search_string) == 0)) {
+ return buffer;
+ }
+
+ int match_found, index, index2;
+ for (index = 0; index < strlen(buffer); index++) {
+ if (buffer[index] == search_string[0]) {
+ match_found = 1;
+ // see if we have a match
+ for (index2 = 0; index2 < strlen(search_string); index2++) {
+ if (buffer[index + index2] != search_string[index2]) {
+ match_found = 0; // match not found
+ break;
+ }
+ }
+ if(match_found == 1) {
+ return &buffer[index];
+ }
+ }
+ }
+
+ // Could not find search_string in buffer
+ return NULL;
+}
Index: libopenbios/bootinfo_load.c
===================================================================
--- libopenbios/bootinfo_load.c (revision 1391)
+++ libopenbios/bootinfo_load.c (working copy)
@@ -19,6 +19,7 @@
#include "libopenbios/bootinfo_load.h"
#include "libopenbios/ofmem.h"
#include "libc/vsprintf.h"
+#include "libc/string.h"
//#define DEBUG_BOOTINFO
@@ -116,6 +117,60 @@
return LOADER_NOT_SUPPORT;
}
+static void erase_memory(char *memory, int size)
+{
+ int i;
+ for(i = 0; i < size; i++) {
+ memory[i] = ' ';
+ }
+}
+
+// Replace all occurrences of orig_str in buffer with replace_str
+static void replace_string(char *buffer, const char *orig_str, const char *replace_str)
+{
+ char *ptr;
+ int index, new_buf_index = 0;
+ const int max_size = 5000;
+ char *new_buffer = malloc(max_size * sizeof(char));
+ erase_memory(new_buffer, max_size);
+
+ for (index = 0; index < strlen(buffer); index++) {
+ if (buffer[index] == orig_str[0]) {
+ ptr = strstr(buffer + index, orig_str);
+
+ // if we encountered an orig_str in the buffer
+ if (index == (ptr - buffer)) {
+ sprintf(new_buffer + new_buf_index, "%s ", replace_str);
+ new_buf_index += strlen(replace_str) + 1;
+ index += strlen(orig_str);
+ continue;
+ }
+ }
+ new_buffer[new_buf_index++] = buffer[index];
+ }
+
+ // Clear the origial buffer
+ erase_memory(buffer, max_size);
+
+ // copy new_buffer into buffer
+ for (index = 0; index < strlen(new_buffer); index++) {
+ buffer[index] = new_buffer[index];
+ }
+ buffer[index+1] = '\0';
+}
+
+/* Replace >r and r> with sub_>r and sub_r> */
+static void replace_return_stack_words(char *bootscript)
+{
+ const char *find_str1 = ">r";
+ const char *replace_str1 = "sub_>r";
+ const char *find_str2 = "r>";
+ const char *replace_str2 = "sub_r>";
+
+ replace_string(bootscript, find_str1, replace_str1);
+ replace_string(bootscript, find_str2, replace_str2);
+}
+
/*
Parse SGML structure like:
<chrp-boot>
@@ -190,8 +245,11 @@
while (current < size) {
c = base[current++];
+
+ if(c == '\r')
+ c = '\n';
- if (c == '<') {
+ if (c == '<') {
script = 0;
tag = 1;
taglen = 0;
@@ -262,6 +320,7 @@
/* If the payload is bootinfo then we execute it immediately */
if (scriptvalid) {
DPRINTF("bootscript: %s\n", bootscript);
+ replace_return_stack_words(bootscript);
feval(bootscript);
}
else
On 25/06/16 20:34, G 3 wrote:
> I just did a git pull today to this commit:
>
> commit a01aef5d2f96c334d048f43f0d3573a1152b37ca
> Merge: c728876 21a4d96
> Author: Peter Maydell <peter.maydell(a)linaro.org
> <mailto:peter.maydell@linaro.org>>
> Date: Fri Jun 24 11:00:15 2016 +0100
>
> When I tried to run qemu-system-ppc with and without the -bios option,
> all I see is a empty black window. Switching consoles yields a Guest
> hasn't initialized the display yet message. Are you having better luck
> or is this a known issue?
I've just tried this here and everything seems okay for me on Linux? Do
you have a test Linux VM you can use to at least verify whether the
regression is QEMU-wide or just related to a OS X host?
You should be able to find your last good commit in the "git reflog"
history at which point you should be able to do a bisect fairly easily.
ATB,
Mark.
I just did a git pull today to this commit:
commit a01aef5d2f96c334d048f43f0d3573a1152b37ca
Merge: c728876 21a4d96
Author: Peter Maydell <peter.maydell(a)linaro.org>
Date: Fri Jun 24 11:00:15 2016 +0100
When I tried to run qemu-system-ppc with and without the -bios option, all
I see is a empty black window. Switching consoles yields a Guest hasn't
initialized the display yet message. Are you having better luck or is this
a known issue?
A recent attempt to restrict the use of rfi on 64bit cpus in qemu
broke 32bit OpenBIOS when run under a 970.
This patches memory to replace rfi instructions with rfid in the
vector code.
Signed-off-by: Cédric Le Goater <clg(a)kaod.org>
Suggested-by: Alexander Graf <agraf(a)suse.de>
---
Tested on qemu.
Changes since v3 :
- fix pointer comparison
- make comments clearer
Changes since v2 :
- make it nicer
arch/ppc/qemu/ofmem.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
Index: openbios.git/arch/ppc/qemu/ofmem.c
===================================================================
--- openbios.git.orig/arch/ppc/qemu/ofmem.c
+++ openbios.git/arch/ppc/qemu/ofmem.c
@@ -478,6 +478,36 @@ isi_exception(void)
hash_page(nip, phys, mode);
}
+/*
+ * Power ISA 2.x has deleted the rfi instruction and rfid shoud be
+ * used instead on cpus following this instruction set or later.
+ *
+ * OpenBIOS 32bits is compiled to use rfi. But, when it runs on a
+ * Power ISA 2.x cpu (a 970 for instance), we need to replace the rfi
+ * instructions with rfid in the vectors' memory section. Else we
+ * won't go any futher than the first exception ...
+ */
+#define RFI 0x4c000064
+#define RFID 0x4c000024
+
+extern char __vectors[];
+extern char __vectors_end[];
+
+static void patch_rfi(void)
+{
+ uint32_t* ptr;
+ uint32_t* vec_start = (uint32_t*) 0x100UL;
+ uint32_t* vec_end = (uint32_t*) (__vectors_end - __vectors);
+
+ if (!is_ppc64())
+ return;
+
+ for (ptr = vec_start; ptr != vec_end; ptr++) {
+ if (*ptr == RFI)
+ *ptr = RFID;
+ }
+ flush_icache_range((char*) vec_start , (char*) vec_end);
+}
/************************************************************************/
/* init / cleanup */
@@ -532,6 +562,8 @@ setup_mmu(unsigned long ramsize)
memcpy((void *)get_rom_base(), (void *)OF_CODE_START, OF_CODE_SIZE);
+ patch_rfi();
+
/* Enable MMU */
mtmsr(mfmsr() | MSR_IR | MSR_DR);
Hello,
This thread was started on qemu-devel@ but openbios@ seems more appropriate
place now.
On 06/07/2016 10:24 AM, Mark Cave-Ayland wrote:
> On 07/06/16 08:04, Cédric Le Goater wrote:
>
>>>>> 2. I have an old ibook G4 from which I dd'ed the disk. openbios
>>>>> complains for some invalid state. is that supported ?
>>>
>>> Yes, OpenBIOS should boot most things these days (MorphOS is the only
>>> execption I know of where the bootloader won't execute correctly as it
>>> assumes real mode). The above message means that OpenBIOS couldn't find
>>> a bootloader, or it could but was unable to execute it, e.g. due to
>>> incompatible architecture - which OS is your image running?
>>
>> I am pretty sure it is a Mac OS X v10.5. I still have the hardware but it
>> is running Linux now :
>>
>> # cat /proc/cpuinfo
>> processor : 0
>> cpu : 7447A, altivec supported
>> clock : 1333.333000MHz
>> revision : 1.5 (pvr 8003 0105)
>> bogomips : 36.86
>>
>> total bogomips : 36.86
>> timebase : 18432000
>> platform : PowerMac
>> model : PowerBook6,7
>> machine : PowerBook6,7
>> motherboard : PowerBook6,7 MacRISC3 Power Macintosh
>> detected as : 287 (iBook G4)
>> pmac flags : 0000001a
>> L2 cache : 512K unified
>> pmac-generation : NewWorld
>> Memory : 1024 MB
>>
>> # lsprop /proc/device-tree/rom@ff800000/boot-rom@fff00000/
>> reg fff00000 00100000
>> info fff00000 00003f00 000493f0 20050705
>> 815fda85 fff08000 00078001 000493f0
>> 20050705 23765c6c fff80000 00080002
>> 000493f0 20050705 b3364dca fff03f00
>> 00000083 000493f0 20050705 c2b72d61
>> fff03f80 00000084 e24a68ca 15a82001
>> ffffffff fff04000 00004005 6e767261
>> 6d000000 00000000 00000000 00000000
>> [140 bytes total]
>> name "boot-rom"
>> security-modes 6e6f6e65 2c206675 6c6c2c20 636f6d6d
>> 616e642c 206e6f2d 70617373 776f7264
>> image 00080000 (524288)
>> model "Apple PowerBook6,7 4.9.3f0 BootROM built on 07/05/05 at 11:14:11"
>> write-characteristic
>> "flash"
>> hwi-flags 402a1220 (1076498976)
>> BootROM-version "$0004.93f0"
>> BootROM-build-date
>> "07/05/05 at 11:14:11"
>> linux,phandle ff89cb08
>> has-config-block
>>
>>
>>> Have you tried both mac99 and g3beige machines?
>>
>> yes.
>
> (I'm wondering if we should start a new thread here either just on
> qemu-ppc or over on the OpenBIOS list)
doing so on openbios@
> OpenBIOS will read hfs/hfsplus filesystems fine - I wonder if maybe it
> can't locate a suitable partition in the Apple Partition Map?
>
> If you boot to the Forth prompt with -prom-env 'auto-boot?=false' can
> you try the following to see if you can list the disk contents:
>
> dir hd:,\
>
> If that doesn't work it means that the partition auto-detection is
> failing, so try manually forcing the partition number until you find one
> that works e.g.
>
> dir hd:0,\
> dir hd:1,\
> etc.
>
> up until around partition 10? Once you find one that works it should be
> possible to boot that partition directly e.g.
>
> boot hd:1
So it is hd:3 and then, openbios dies directly :
...
IN:
0xfff0d6c8: mr r28,r3
0xfff0d6cc: add r30,r30,r3
0xfff0d6d0: add r31,r31,r3
0xfff0d6d4: b 0xfff0d6a0
IN:
0xfff0d6a0: mr r3,r29
0xfff0d6a4: li r5,0
0xfff0d6a8: mr r6,r30
0xfff0d6ac: bl 0xfff279e8
IN:
0x00000300: .long 0x0
IN:
0x00000700: .long 0x0
which is this loop in bootcode_load() :
...
bootcode = loadbase;
offset = 0;
while(1) {
if (seek_io(fd, offset) == -1)
break;
count = read_io(fd, (void *)bootcode, 512);
offset += count;
bootcode += count;
}
...
How do I add more logging with openbios ?
Thanks,
C.