All of lore.kernel.org
 help / color / mirror / Atom feed
From: BALATON Zoltan <balaton@eik.bme.hu>
To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
	Howard Spoelstra <hsp.cat7@gmail.com>
Subject: [RFC PATCH] WIP macio/cuda: Attempt to add i2c support
Date: Sun, 28 Jun 2020 14:37:51 +0200 (CEST)	[thread overview]
Message-ID: <alpine.BSF.2.22.395.2006281432290.95193@zero.eik.bme.hu> (raw)
In-Reply-To: <681515f214d7b0a8553be509dcba3d8a9085082d.1592315226.git.balaton@eik.bme.hu>


This is a non-working RFC patch attempt to implement i2c bus in CUDA
needed for firmware to access SPD data of installed RAM. The skeleton
is there but actual operation fails because I don't know how this is
supposed to work and the i2c bus state becomes invalid quickly. Also
sending back results may be missing or wrong. Help fixing and
finishing this is welcome, I don't plan to spend more time with this
so just submitted it for whoever picks this up.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
This is still RFC and only for testing but with this the ROM seems to 
detect some RAM now:

cuda_packet_receive length 5
cuda_packet_receive_data [0] 0x01
cuda_packet_receive_data [1] 0x25
cuda_packet_receive_data [2] 0xa0
cuda_packet_receive_data [3] 0x02
cuda_packet_receive_data [4] 0xa1
cuda_receive_packet_cmd handling command COMBINED_FORMAT_IIC
i2c_event start(addr:0x50)
smbus(50): Incoming data
i2c_send send(addr:0x50) data:0x02
smbus(50): Write data 02
i2c_event finish(addr:0x50)
smbus(50): Command 2 len 1
eeprom_write_byte: addr=0x50 cmd=0x02 val=0x00
i2c_event start(addr:0x50)
smbus(50): Read mode
eeprom_receive_byte: addr=0x50 val=0x04
smbus(50): Read data 04
i2c_recv recv(addr:0x50) data:0x04
eeprom_receive_byte: addr=0x50 val=0x0d
smbus(50): Read data 0d
i2c_recv recv(addr:0x50) data:0x0d
eeprom_receive_byte: addr=0x50 val=0x0a
smbus(50): Read data 0a
i2c_recv recv(addr:0x50) data:0x0a
eeprom_receive_byte: addr=0x50 val=0x02
smbus(50): Read data 02
i2c_recv recv(addr:0x50) data:0x02
eeprom_receive_byte: addr=0x50 val=0x40
smbus(50): Read data 40
i2c_recv recv(addr:0x50) data:0x40
i2c_event finish(addr:0x50)
smbus(50): Quick Command 1
cuda_packet_send length 8
cuda_packet_send_data [0] 0x01
cuda_packet_send_data [1] 0x00
cuda_packet_send_data [2] 0x25
cuda_packet_send_data [3] 0x04
cuda_packet_send_data [4] 0x0d
cuda_packet_send_data [5] 0x0a
cuda_packet_send_data [6] 0x02
cuda_packet_send_data [7] 0x40
cuda_delay_set_sr_int
cuda_data_recv recv: 0x01
cuda_delay_set_sr_int
cuda_data_recv recv: 0x00
cuda_delay_set_sr_int
cuda_data_recv recv: 0x25
cuda_delay_set_sr_int
cuda_data_recv recv: 0x04
cuda_delay_set_sr_int
cuda_data_recv recv: 0x0d
cuda_delay_set_sr_int
cuda_data_recv recv: 0x0a
cuda_delay_set_sr_int
cuda_data_recv recv: 0x02
cuda_delay_set_sr_int
cuda_data_recv recv: 0x40
cuda_delay_set_sr_int
cuda_delay_set_sr_int
cuda_delay_set_sr_int
cuda_delay_set_sr_int
cuda_data_send send: 0x01
cuda_delay_set_sr_int
cuda_data_send send: 0x25
cuda_delay_set_sr_int
cuda_data_send send: 0xa2
cuda_delay_set_sr_int
cuda_data_send send: 0x02
cuda_delay_set_sr_int
cuda_data_send send: 0xa3
cuda_delay_set_sr_int
cuda_delay_set_sr_int
cuda_packet_receive length 5
cuda_packet_receive_data [0] 0x01
cuda_packet_receive_data [1] 0x25
cuda_packet_receive_data [2] 0xa2
cuda_packet_receive_data [3] 0x02
cuda_packet_receive_data [4] 0xa3
cuda_receive_packet_cmd handling command COMBINED_FORMAT_IIC
CUDA: COMBINED_FORMAT_IIC: wrong parameters 4
[...]
pci_cfg_write grackle 00:0 @0x80 <- 0xffff8000
pci_cfg_write grackle 00:0 @0x88 <- 0xffff0000
pci_cfg_write grackle 00:0 @0x90 <- 0xffffff7f
pci_cfg_write grackle 00:0 @0x98 <- 0xffff0000

^^^ these were all 0xffffffff before

pci_cfg_write grackle 00:0 @0x84 <- 0xffffffff
pci_cfg_write grackle 00:0 @0x8c <- 0xffffffff
pci_cfg_write grackle 00:0 @0x94 <- 0xffffffff
pci_cfg_write grackle 00:0 @0x9c <- 0xffffffff
pci_cfg_write grackle 00:0 @0xa0 <- 0x3
pci_cfg_read grackle 00:0 @0xf0 -> 0x12900000
pci_cfg_write grackle 00:0 @0xf0 <- 0x12900005
pci_cfg_read grackle 00:0 @0x8 -> 0x6000140
pci_cfg_read grackle 00:0 @0xf0 -> 0x12900005
pci_cfg_write grackle 00:0 @0xf0 <- 0x12940005
pci_cfg_write grackle 00:0 @0xf0 <- 0x12940005
pci_cfg_write grackle 00:0 @0xf4 <- 0x40010fe4
pci_cfg_write grackle 00:0 @0xf8 <- 0x7302293
pci_cfg_write grackle 00:0 @0xfc <- 0x25302220
pci_cfg_read grackle 00:0 @0xa0 -> 0x3
pci_cfg_write grackle 00:0 @0xa0 <- 0x67000003
pci_cfg_read grackle 00:0 @0xf0 -> 0x12940005
pci_cfg_write grackle 00:0 @0xf0 <- 0x129c0005

In my understanding after an I2C command CUDA should enter in a mode 
whereby reading the SR reg will return bytes from the I2C device but not 
sure what terminates that mode and how to model it correctly so I just 
return the expected number of bytes in this patch to make the ROM go 
further so I can test what else is needed. Then it crashes in screamer.

  hw/misc/macio/cuda.c         | 76 +++++++++++++++++++++++++++++++++++-
  include/hw/misc/macio/cuda.h |  1 +
  2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 5bbc7770fa..3fc9773717 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -28,6 +28,7 @@
  #include "hw/ppc/mac.h"
  #include "hw/qdev-properties.h"
  #include "migration/vmstate.h"
+#include "hw/i2c/i2c.h"
  #include "hw/input/adb.h"
  #include "hw/misc/mos6522.h"
  #include "hw/misc/macio/cuda.h"
@@ -370,6 +371,75 @@ static bool cuda_cmd_set_time(CUDAState *s,
      return true;
  }

+static bool cuda_cmd_get_set_iic(CUDAState *s,
+                                 const uint8_t *in_data, int in_len,
+                                 uint8_t *out_data, int *out_len)
+{
+    int i;
+
+    qemu_log_mask(LOG_UNIMP, "CUDA: unimplemented GET_SET_IIC %s 0x%x %d\n",
+                  (in_data[0] & 1 ? "read" : "write"), in_data[0] >> 1,
+                  in_len);
+    if (i2c_start_transfer(s->i2c_bus, in_data[0] >> 1, in_data[0] & 1)) {
+        return false;
+    }
+    for (i = 0; i < in_len - 3; i++) {
+        if (i2c_send(s->i2c_bus, in_data[i])) {
+            i2c_end_transfer(s->i2c_bus);
+            return false;
+        }
+    }
+    return true;
+}
+
+static bool cuda_cmd_combined_iic(CUDAState *s,
+                                  const uint8_t *in_data, int in_len,
+                                  uint8_t *out_data, int *out_len)
+{
+    int i;
+
+    if (in_len < 3) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CUDA: COMBINED_FORMAT_IIC too few input bytes\n");
+        return false;
+    }
+    if ((in_data[0] & 0xfe) != (in_data[2] & 0xfe)) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "CUDA: COMBINED_FORMAT_IIC address mismatch\n");
+        return false;
+    }
+
+    uint8_t data = in_data[1];
+    if (i2c_start_transfer(s->i2c_bus, in_data[0] >> 1, in_data[0] & 1) ||
+        i2c_send_recv(s->i2c_bus, &data, in_data[0] & 1)) {
+        return false;
+    }
+    i2c_end_transfer(s->i2c_bus);
+    if (in_data[2] & 1) {
+        if (i2c_start_transfer(s->i2c_bus, in_data[2] >> 1, in_data[2] & 1)) {
+            i2c_end_transfer(s->i2c_bus);
+            return false;
+        }
+        for (i = 0; i < 5; i++) {
+            if (i2c_send_recv(s->i2c_bus, &out_data[i], in_data[2] & 1)) {
+                i2c_end_transfer(s->i2c_bus);
+                return false;
+            }
+        }
+        *out_len = i;
+        i2c_end_transfer(s->i2c_bus);
+    } else {
+        for (i = 0; i < in_len - 3; i++) {
+            data = in_data[3 + i];
+            if (i2c_send_recv(s->i2c_bus, &data, in_data[2] & 1)) {
+                i2c_end_transfer(s->i2c_bus);
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
  static const CudaCommand handlers[] = {
      { CUDA_AUTOPOLL, "AUTOPOLL", cuda_cmd_autopoll },
      { CUDA_SET_AUTO_RATE, "SET_AUTO_RATE",  cuda_cmd_set_autorate },
@@ -382,6 +452,8 @@ static const CudaCommand handlers[] = {
        cuda_cmd_set_power_message },
      { CUDA_GET_TIME, "GET_TIME", cuda_cmd_get_time },
      { CUDA_SET_TIME, "SET_TIME", cuda_cmd_set_time },
+    { CUDA_GET_SET_IIC, "GET_SET_IIC", cuda_cmd_get_set_iic },
+    { CUDA_COMBINED_FORMAT_IIC, "COMBINED_FORMAT_IIC", cuda_cmd_combined_iic },
  };

  static void cuda_receive_packet(CUDAState *s,
@@ -549,6 +621,7 @@ static void cuda_init(Object *obj)
  {
      CUDAState *s = CUDA(obj);
      SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    DeviceState *dev = DEVICE(obj);

      object_initialize_child(obj, "mos6522-cuda", &s->mos6522_cuda,
                              TYPE_MOS6522_CUDA);
@@ -557,7 +630,8 @@ static void cuda_init(Object *obj)
      sysbus_init_mmio(sbd, &s->mem);

      qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
-                        DEVICE(obj), "adb.0");
+                        dev, "adb.0");
+    s->i2c_bus = i2c_init_bus(dev, "i2c");
  }

  static Property cuda_properties[] = {
diff --git a/include/hw/misc/macio/cuda.h b/include/hw/misc/macio/cuda.h
index a8cf0be1ec..6856ed7704 100644
--- a/include/hw/misc/macio/cuda.h
+++ b/include/hw/misc/macio/cuda.h
@@ -79,6 +79,7 @@ typedef struct CUDAState {

      ADBBusState adb_bus;
      MOS6522CUDAState mos6522_cuda;
+    I2CBus *i2c_bus;

      uint32_t tick_offset;
      uint64_t tb_frequency;
-- 
2.21.3



  reply	other threads:[~2020-06-28 12:38 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-16 13:47 [PATCH v5 00/11] Mac Old World ROM experiment BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 05/11] grackle: Set revision in PCI config to match hardware BALATON Zoltan
2020-06-26 12:51   ` Mark Cave-Ayland
2020-06-16 13:47 ` [PATCH v5 09/11] macio: Add dummy screamer register area BALATON Zoltan
2020-06-26 13:12   ` Mark Cave-Ayland
2020-06-28 12:26     ` BALATON Zoltan
2020-06-28 14:08       ` BALATON Zoltan
2020-06-28 14:29         ` BALATON Zoltan
2020-06-28 14:53           ` BALATON Zoltan
2020-06-28 15:04             ` BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 08/11] mac_oldworld: Add machine ID register BALATON Zoltan
2020-06-26 13:07   ` Mark Cave-Ayland
2020-06-16 13:47 ` [PATCH v5 10/11] WIP macio/cuda: Attempt to add i2c support BALATON Zoltan
2020-06-28 12:37   ` BALATON Zoltan [this message]
2020-06-16 13:47 ` [PATCH v5 06/11] mac_oldworld: Rename ppc_heathrow_reset to ppc_heathrow_cpu_reset BALATON Zoltan
2020-06-26 12:55   ` Mark Cave-Ayland
2020-06-26 22:22     ` BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 07/11] mac_oldworld: Map macio to expected address at reset BALATON Zoltan
2020-06-26 13:03   ` Mark Cave-Ayland
2020-06-26 22:25     ` BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 02/11] mac_newworld: Allow loading binary ROM image BALATON Zoltan
2020-06-26 12:42   ` Mark Cave-Ayland
2020-06-16 13:47 ` [PATCH v5 11/11] mac_oldworld: Add SPD data to cover RAM BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 01/11] mac_oldworld: Allow loading binary ROM image BALATON Zoltan
2020-06-26 12:38   ` Mark Cave-Ayland
2020-06-26 21:57     ` BALATON Zoltan
2020-06-16 13:47 ` [PATCH v5 04/11] mac_oldworld: Drop some variables BALATON Zoltan
2020-06-26 12:46   ` Mark Cave-Ayland
2020-06-16 13:47 ` [PATCH v5 03/11] mac_oldworld: Drop a variable, use get_system_memory() directly BALATON Zoltan
2020-06-26 12:42   ` Mark Cave-Ayland
2020-06-26 10:21 ` [PATCH v5 00/11] Mac Old World ROM experiment BALATON Zoltan
2020-06-26 12:23   ` Mark Cave-Ayland
2020-06-28 18:34     ` BALATON Zoltan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.BSF.2.22.395.2006281432290.95193@zero.eik.bme.hu \
    --to=balaton@eik.bme.hu \
    --cc=hsp.cat7@gmail.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.