qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mac99 SMP


From: BALATON Zoltan
Subject: Re: mac99 SMP
Date: Fri, 21 Mar 2025 18:38:12 +0100 (CET)

On Fri, 21 Mar 2025, Jd Lyons wrote:
What I have lines up with the real HW:

/* Add CPU-specific properties based on CPU index */
                if (i == 0) {  /* CPU0 */

                        PUSH(0x21); 0x71

It's hard to tell without context but this won't compile because of the bare 0x71 value there. If the device tree should contain that 0x71 value that's what should be pushed not the 0x21. I think the offsets in the device tree are relative to the chip base address where gpio related registers start at 0x50 so in gpio logs a register that shows up as 0x21 is at macio_base+0x50+0x21, that is macio_base_0x71. Therefore 0x2a is macio_base+0x7a and would appear as 0x7a in the device tree or driver sources that list register offsets from chip base address and not from gpio base address within that chip. The Linux kernel source has some defines in linux/arch/powerpc/include/asm/keylargo.h:

/* GPIO registers */
#define KEYLARGO_GPIO_LEVELS0           0x50
#define KEYLARGO_GPIO_LEVELS1           0x54
#define KEYLARGO_GPIO_EXTINT_0          0x58
#define KEYLARGO_GPIO_EXTINT_CNT        18
#define KEYLARGO_GPIO_0                 0x6A
#define KEYLARGO_GPIO_CNT               17

and then defined by those the individual lines:

/* Specific GPIO regs */

#define KL_GPIO_MODEM_RESET             (KEYLARGO_GPIO_0+0x03)
#define KL_GPIO_MODEM_POWER (KEYLARGO_GPIO_0+0x02) /* Pangea */

#define KL_GPIO_SOUND_POWER             (KEYLARGO_GPIO_0+0x05)

/* Hrm... this one is only to be used on Pismo. It seems to also
 * control the timebase enable on other machines. Still to be
 * experimented... --BenH.
 */
#define KL_GPIO_FW_CABLE_POWER          (KEYLARGO_GPIO_0+0x09)
#define KL_GPIO_TB_ENABLE               (KEYLARGO_GPIO_0+0x09)

#define KL_GPIO_ETH_PHY_RESET           (KEYLARGO_GPIO_0+0x10)

#define KL_GPIO_EXTINT_CPU1             (KEYLARGO_GPIO_0+0x0a)
#define KL_GPIO_EXTINT_CPU1_ASSERT      0x04
#define KL_GPIO_EXTINT_CPU1_RELEASE     0x38

#define KL_GPIO_RESET_CPU0              (KEYLARGO_GPIO_EXTINT_0+0x03)
#define KL_GPIO_RESET_CPU1              (KEYLARGO_GPIO_EXTINT_0+0x04)
#define KL_GPIO_RESET_CPU2              (KEYLARGO_GPIO_EXTINT_0+0x0f)
#define KL_GPIO_RESET_CPU3              (KEYLARGO_GPIO_EXTINT_0+0x10)

#define KL_GPIO_PMU_MESSAGE_IRQ         (KEYLARGO_GPIO_EXTINT_0+0x09)
#define KL_GPIO_PMU_MESSAGE_BIT         KEYLARGO_GPIO_INPUT_DATA

#define KL_GPIO_MEDIABAY_IRQ            (KEYLARGO_GPIO_EXTINT_0+0x0e)

#define KL_GPIO_AIRPORT_0               (KEYLARGO_GPIO_EXTINT_0+0x0a)
#define KL_GPIO_AIRPORT_1               (KEYLARGO_GPIO_EXTINT_0+0x0d)
#define KL_GPIO_AIRPORT_2               (KEYLARGO_GPIO_0+0x0d)
#define KL_GPIO_AIRPORT_3               (KEYLARGO_GPIO_0+0x0e)
#define KL_GPIO_AIRPORT_4               (KEYLARGO_GPIO_0+0x0f)

This likely is not a full list, Apple's Darwin sources may have more defines.

0x7a or gpio offset 0x2a can be: 0x50+0x2a, 0x58+0x22 or 0x6a+0x10 and the last one seems to match with KL_GPIO_ETH_PHY_RESET.

This is now getting to be a course on basic programming and maths so maybe find a free tutorial on the basics and complete that first to get this out of the way.

Regards,
BALATON Zoltan

                        fword("encode-int");
                        push_str("soft-reset");
                        fword("property");




                        PUSH(0x23); 0x73
                        fword("encode-int");
                        push_str("timebase-enable");
                        fword("property");
                } else if (i == 1) {  /* CPU1 */
                        PUSH(0x22); 0x72
                        fword("encode-int");
                        push_str("soft-reset");
                        fword("property");



                        PUSH(0x23); 0x73
                        fword("encode-int");
                        push_str("timebase-enable");
                        fword("property");

                        PUSH(0x24); 0x74
                        fword("encode-int");
                        push_str("cpu-interrupt-enable");
                        fword("property");
                }


It’s just I don’t understand how to use it, I’ll have to do some tests and see 
what changes I made that have the Mac OS trying to access these addresses, I 
don’t recall it trying before I added the code for the ‘gpio-parent’

/* --- New code: Add the gpio-parent property --- */
           {
                   phandle_t gpio_node = find_dev("/pci/mac-io/gpio");
                   if (!gpio_node) {
                           printk("Error: GPIO node '/pci/mac-io/gpio' not 
found!\n");
                   } else {
                           PUSH(gpio_node);
                           fword("encode-int");
                           push_str("gpio-parent");
                           fword("property");
                   }


But it also could have been the ’soft-reset’ property too, so I’ll have to test 
what property it was I added.

I still can’t figure out what 0x2a is, but none of it really matters that much 
until I can fully understand the rest of it, and that day may never come, the 
odd thing is Linux never tried to access these reg addr, so I’ll have to figure 
that too.


On Mar 17, 2025, at 9:30 AM, BALATON Zoltan <balaton@eik.bme.hu> wrote:

On Mon, 17 Mar 2025, Jd Lyons wrote:
I can’t find anything pointing to what 0x2a does, best guess, it’s the final 
gate that releases CPI1 from reset or enables it for execution.

OS X doesn’t seem to touch 0x23 or 0x24 at all and only does:

macio_gpio_write addr 0x2a val 0x4
macio_gpio_write addr 0x2a val 0x1

That’s just a wild guess tho in the void of facts about how Mac OS 9 and Linux 
deal with enabling CPU1 for execution.

I don’t really understand what is needed on the Qemu side to enable 0x23/0x24 
if they are in fact what I think they are. I don’t understand how the GPIO 
emulations works at all, or how the CPU pins are routed.

Linux doesn’t seem to touch 0x23/0x24 or 0x2a.

First of all try to find what these offsets are. They seem to be in tha macio 
gpio range so maybe kernel sources have defines with the macio gpio offset 
added which I think is 0x50 so 0x23 is 0x73. This appears in the device tree as 
well. If you look at the functions in qemu/hw/misc/macio/gpio.c this has:

static void macio_gpio_write(void *opaque, hwaddr addr, uint64_t value,
                            unsigned size)
{
   MacIOGPIOState *s = opaque;
   uint8_t ibit;

   trace_macio_gpio_write(addr, value);

   /* Levels regs are read-only */
   if (addr < 8) {
       return;
   }

So first 8 regs are levels for GPIO lines where you can read what level they 
are for lines where direction was set to input. These are GPIOs that are 
controlled by external sources, such as NMI/programmer switch.


   addr -= 8;
   if (addr < 36) {
       value &= ~IN_DATA;

       if (value & OUT_ENABLE) {
           ibit = (value & OUT_DATA) << 1;
       } else {
           ibit = s->gpio_regs[addr] & IN_DATA;
       }

       s->gpio_regs[addr] = value | ibit;
   }
}

Then these regs set the level for GPIO lines that are set to ouptut, these can 
control other devices such as reset a CPU or freeze its timebase. These regs 
are betwen 8 and 44 because 8 is substracted from the offset before it checks 
if it's less than 36 so in hex these offsets are between 0x8 and 0x2c. Assuming 
the first reg corresponds to GPIO0 and so on you should be able to work out 
which GPIO line regs at those offsets should control.

Also try to read my patch that added GPIO for CPU reset and understand how that 
works. The missing piece is I don't know how to stop timebase on a CPU so don't 
know where and how to connect the GPIO. If nobody can tell then you should look 
at the QEMU sources and try to find out. Is there another machine that needs 
something similar? If so you can check there how it's done for that machine.

Regards,
BALATON Zoltan


reply via email to

[Prev in Thread] Current Thread [Next in Thread]