From patchwork Sun Jun 14 18:13:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: BALATON Zoltan X-Patchwork-Id: 11603403 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D94B6912 for ; Sun, 14 Jun 2020 18:34:06 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B8A3520739 for ; Sun, 14 Jun 2020 18:34:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B8A3520739 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=eik.bme.hu Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:37936 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkXSI-0005Q7-2c for patchwork-qemu-devel@patchwork.kernel.org; Sun, 14 Jun 2020 14:34:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48818) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkXLR-0004Eg-Sh; Sun, 14 Jun 2020 14:27:01 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:52077) by eggs.gnu.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkXLQ-0007gh-2A; Sun, 14 Jun 2020 14:27:01 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 641637482C8; Sun, 14 Jun 2020 20:26:44 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id C06B1748DDA; Sun, 14 Jun 2020 20:26:43 +0200 (CEST) Message-Id: <71dbf049654ff55cba40e7b92b73674479223009.1592158400.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [PATCH v4 8/9] WIP RFC macio/cuda: Attempt to add i2c support Date: Sun, 14 Jun 2020 20:13:19 +0200 MIME-Version: 1.0 To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 8% Received-SPF: pass client-ip=2001:738:2001:2001::2001; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Howard Spoelstra , Mark Cave-Ayland , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" 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 --- hw/misc/macio/cuda.c | 65 +++++++++++++++++++++++++++++++++++- include/hw/misc/macio/cuda.h | 1 + 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index e0cc0aac5d..9609828091 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" @@ -369,6 +370,64 @@ 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 addr = in_data[0] >> 1; + int recv = in_data[0] & 1; + + 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; + } else { + for (i = 0; i < in_len - 3; i++) { + data = in_data[3 + i]; + if (i2c_send_recv(s->i2c_bus, (in_data[2] & 1 ? &out_data[i] : + &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 }, @@ -381,6 +440,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, @@ -548,6 +609,7 @@ static void cuda_init(Object *obj) { CUDAState *s = CUDA(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + DeviceState *dev = DEVICE(obj); sysbus_init_child_obj(obj, "mos6522-cuda", &s->mos6522_cuda, sizeof(s->mos6522_cuda), TYPE_MOS6522_CUDA); @@ -556,7 +618,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 5768075ac5..0c798100dc 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;