From nobody Thu Jan 30 22:12:31 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) smtp.mailfrom=seabios-bounces@seabios.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from coreboot.org (78.46.105.101 [78.46.105.101]) by mx.zohomail.com with SMTPS id 1736871049225187.54528053473894; Tue, 14 Jan 2025 08:10:49 -0800 (PST) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 457AA20FFC; Tue, 14 Jan 2025 16:10:44 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id E709F20B07 for ; Tue, 14 Jan 2025 16:10:29 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) for ; Tue, 14 Jan 2025 08:10:29 -0800 (PST) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by smtp.gmail.com with ESMTPSA id 00721157ae682-6f546c25dabsm21769127b3.15.2025.01.14.08.10.27 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 14 Jan 2025 08:10:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736871028; x=1737475828; darn=seabios.org; h=content-transfer-encoding:from:content-language:subject:to :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=9LZWZAV5RgiT62/mI+0CRmt5RHyLMd2C7H2jXGgmhbg=; b=U0ZSAGVV1ebZOY9ZNPDBjn3/hk5sT97nejFZ8Y1hPo9CioixSqBpHHWcMyRXlBKsJT qh8Tlu0KgO95klxO++NMI7pW79iqIJDneMWm3wjvbdKMYQCqOxdGaZ7miSwiqdxtmak9 V8MEmEQh3ll6/xi0mJOetmZD3DJlCkgO/uEKg55HJ/5TXVFOI1+JjAgmiDUSSiLaAHRP Gh+3/6dLCbmtiku5g1hmd/VdgCs6zVjqU4VxFUra6gUPWndxMvpkbEPn52wdQHU4zmcn jTKyVWe7dr93jor/0OhJbNJzLbizcDoSv6Q3oVHlLwI2ZKVoOMcUB141/Hatsghl5rel WDCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736871028; x=1737475828; h=content-transfer-encoding:from:content-language:subject:to :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=9LZWZAV5RgiT62/mI+0CRmt5RHyLMd2C7H2jXGgmhbg=; b=ZskXEQNHvYUvomyWMuQGw95/QuadkX992DbuYwIEUJ6qm4Gr55XgFBsclkzOlXH6EX zto1cxy9p4qTJ6bLmiUqLk1sMM5K8PF3tRPuDJplanQbwg5XfPbqpEHtQ4NdkhTPNtdS BlnNRqABvS0dsXrSWy/z/0eMN5X0+lTbVyI3Y3N7Dz9hB376RvSsDvAqml+1yUP70Mzm MhTtgeUY9/kUuFEjBgiy1xrgiOqBPlY7VoTW8q7w7TE+hwQ9vjSucfvGzC61p/FtkMXN HoG9q9wfF6Fxx41JADBtbCLmvby9pcMp0dAYDTXpxqS0befQ2PDgCjDuWHfGde0yS3i4 MiQQ== X-Gm-Message-State: AOJu0YwF6h/GAUYdtv4qWGBbOSrSfynD9HhcatvfXnxrH4mSyeygOTCx 0/L0GZmGfmbh5ubhIUq6GcvGMSOeSfHsg8A5RH63Cu+NUXxYfyEYVdR+62j8 X-Gm-Gg: ASbGncua3mB8lyQg3PwJFp0TjeXZK5LoysP00kMuytbxWLgSzZXdABfJ6ZDTKiIHVoT YTNSrKEPCpF4PE/YI+u57SHkfY8++wwzN0AJv/Begh63bJWQBBt/Ovs79sXw6cS7RWRWceQjlkK r67++yld5/i7W7APZf+zaArh/6LAFLETl/iWhrftxnTiAMiBPk3+ffaTrICNCL7irp18t/mq7Kl i56ZnB946KHEXjyQ2GwHyaeyJXv1mjQn9/uaNJ89dFUCilIvfZI0L+PK0S+yCpJupReRfPVHcvG X/RBOns= X-Google-Smtp-Source: AGHT+IHWSSxldceME/0+RWM5YueS67ll3vigC/XTyQvObBRH7FG3F3AdekbOjFrmIqUnsnQQudTnFw== X-Received: by 2002:a05:690c:3683:b0:6ef:60f4:3d41 with SMTP id 00721157ae682-6f5312277a0mr214757837b3.16.1736871028377; Tue, 14 Jan 2025 08:10:28 -0800 (PST) Message-ID: <0fc6a5b8-4813-2f0c-fa26-fd43133b6494@gmail.com> Date: Tue, 14 Jan 2025 11:10:26 -0500 MIME-Version: 1.0 To: seabios@seabios.org Content-Language: en-US From: Christopher Lentocha Message-ID-Hash: LMMPJ45Q46K7UJ3UTQ37HP5TGVLSE752 X-Message-ID-Hash: LMMPJ45Q46K7UJ3UTQ37HP5TGVLSE752 X-MailFrom: christopherericlentocha@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.6b1 Precedence: list Subject: [SeaBIOS] [PATCH] Fix AHCI Disk Detection when using EDK2 CSM List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-Spamd-Bar: / X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1736871049986019000 Content-Type: text/plain; charset="utf-8"; format="flowed" For whatever reason, when you compile SeaBIOS in Csm16 mode, and use it under EDK2's OvmfPkg, the ATA_CMD_IDENTIFY_PACKET_DEVICE command doesn't work properly, therefore, SeaBIOS detects the "SATA HARDDISK" as a "SATA CDROM" device, in QEMU. Despite the Tianocore developers seem to have removed support for Csm16 some time ago, if we decide to remove Csm16 mode in SeaBIOS in favor of that, at least we have the last commit of Csm16 working properly and not half-broken. In order to fix this bug, I decided to move the "detected as a disk" function to be a goto, so code isn't sloppy, by being copied and pasted 1:1 (though this can be changed back later if needed), and in the detected as CDROM function, when it fails at its point, assume its a harddisk, make sure it is with the ATA_CMD_IDENTIFY_DEVICE (which works fine in my testing) command, and continue from there. Signed-off-by: Christopher Lentocha --- src/hw/ahci.c | 191 ++++++++++++++++++++++++++------------------------ 1 file changed, 101 insertions(+), 90 deletions(-) diff --git a/src/hw/ahci.c b/src/hw/ahci.c index 4f0f640a..e53c26be 100644 --- a/src/hw/ahci.c +++ b/src/hw/ahci.c @@ -501,89 +501,7 @@ static int ahci_port_setup(struct ahci_port_s *port) port->drive.removable =3D (buffer[0] & 0x80) ? 1 : 0; if (!port->atapi) { - // found disk (ata) - port->drive.type =3D DTYPE_AHCI; - port->drive.blksize =3D DISK_SECTOR_SIZE; - port->drive.pchs.cylinder =3D buffer[1]; - port->drive.pchs.head =3D buffer[3]; - port->drive.pchs.sector =3D buffer[6]; - - u64 sectors; - if (buffer[83] & (1 << 10)) // word 83 - lba48 support - sectors =3D *(u64*)&buffer[100]; // word 100-103 - else - sectors =3D *(u32*)&buffer[60]; // word 60 and word 61 - port->drive.sectors =3D sectors; - u64 adjsize =3D sectors >> 11; - char adjprefix =3D 'M'; - if (adjsize >=3D (1 << 16)) { - adjsize >>=3D 10; - adjprefix =3D 'G'; - } - port->desc =3D znprintf(MAXDESCSIZE - , "AHCI/%d: %s ATA-%d Hard-Disk (%u=20 %ciBytes)" - , port->pnr - , ata_extract_model(model, MAXMODEL, buffer) - , ata_extract_version(buffer) - , (u32)adjsize, adjprefix); - port->prio =3D bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0); - - s8 multi_dma =3D -1; - s8 pio_mode =3D -1; - s8 udma_mode =3D -1; - // If bit 2 in word 53 is set, udma information is valid in=20 word 88. - if (buffer[53] & 0x04) { - udma_mode =3D 6; - while ((udma_mode >=3D 0) && - !((buffer[88] & 0x7f) & ( 1 << udma_mode ))) { - udma_mode--; - } - } - // If bit 1 in word 53 is set, multiword-dma and advanced pio modes - // are available in words 63 and 64. - if (buffer[53] & 0x02) { - pio_mode =3D 4; - multi_dma =3D 3; - while ((multi_dma >=3D 0) && - !((buffer[63] & 0x7) & ( 1 << multi_dma ))) { - multi_dma--; - } - while ((pio_mode >=3D 3) && - !((buffer[64] & 0x3) & ( 1 << ( pio_mode - 3 ) ))) { - pio_mode--; - } - } - dprintf(2, "AHCI/%d: supported modes: udma %d, multi-dma %d,=20 pio %d\n", - port->pnr, udma_mode, multi_dma, pio_mode); - - sata_prep_simple(&port->cmd->fis, ATA_CMD_SET_FEATURES); - port->cmd->fis.feature =3D ATA_SET_FEATRUE_TRANSFER_MODE; - // Select used mode. UDMA first, then Multi-DMA followed by - // advanced PIO modes 3 or 4. If non, set default PIO. - if (udma_mode >=3D 0) { - dprintf(1, "AHCI/%d: Set transfer mode to UDMA-%d\n", - port->pnr, udma_mode); - port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_ULTRA_DMA - | udma_mode; - } else if (multi_dma >=3D 0) { - dprintf(1, "AHCI/%d: Set transfer mode to Multi-DMA-%d\n", - port->pnr, multi_dma); - port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_MULTIWORD_DMA - | multi_dma; - } else if (pio_mode >=3D 3) { - dprintf(1, "AHCI/%d: Set transfer mode to PIO-%d\n", - port->pnr, pio_mode); - port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_PIO_FLOW_CTRL - | pio_mode; - } else { - dprintf(1, "AHCI/%d: Set transfer mode to default PIO\n", - port->pnr); - port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_DEFAULT_PIO; - } - rc =3D ahci_command(port, 1, 0, 0, 0); - if (rc < 0) { - dprintf(1, "AHCI/%d: Set transfer mode failed.\n", port->pnr); - } + goto is_ata_disk; } else { // found cdrom (atapi) port->drive.type =3D DTYPE_AHCI_ATAPI; @@ -592,14 +510,107 @@ static int ahci_port_setup(struct ahci_port_s *port) u8 iscd =3D ((buffer[0] >> 8) & 0x1f) =3D=3D 0x05; if (!iscd) { dprintf(1, "AHCI/%d: atapi device isn't a cdrom\n",=20 port->pnr); - return -1; + port->atapi =3D 0; + sata_prep_simple(&port->cmd->fis, ATA_CMD_IDENTIFY_DEVICE); + rc =3D ahci_command(port, 0, 0, buffer, sizeof(buffer)); + if (rc < 0) + return -1; + goto is_ata_disk; + } else { + port->desc =3D znprintf(MAXDESCSIZE + , "DVD/CD [AHCI/%d: %s ATAPI-%d DVD/CD]" + , port->pnr + , ata_extract_model(model, MAXMODEL, buffer) + , ata_extract_version(buffer)); + port->prio =3D bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0); + boot_lchs_find_ata_device(ctrl->pci_tmp, pnr, 0,=20 &(port->drive.lchs)); } - port->desc =3D znprintf(MAXDESCSIZE - , "DVD/CD [AHCI/%d: %s ATAPI-%d DVD/CD]" - , port->pnr - , ata_extract_model(model, MAXMODEL, buffer) - , ata_extract_version(buffer)); - port->prio =3D bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0); + } + return 0; + +is_ata_disk: + // found disk (ata) + port->drive.type =3D DTYPE_AHCI; + port->drive.blksize =3D DISK_SECTOR_SIZE; + port->drive.pchs.cylinder =3D buffer[1]; + port->drive.pchs.head =3D buffer[3]; + port->drive.pchs.sector =3D buffer[6]; + + u64 sectors; + if (buffer[83] & (1 << 10)) // word 83 - lba48 support + sectors =3D *(u64*)&buffer[100]; // word 100-103 + else + sectors =3D *(u32*)&buffer[60]; // word 60 and word 61 + port->drive.sectors =3D sectors; + u64 adjsize =3D sectors >> 11; + char adjprefix =3D 'M'; + if (adjsize >=3D (1 << 16)) { + adjsize >>=3D 10; + adjprefix =3D 'G'; + } + port->desc =3D znprintf(MAXDESCSIZE + , "AHCI/%d: %s ATA-%d Hard-Disk (%u %ciBytes)" + , port->pnr + , ata_extract_model(model, MAXMODEL, buffer) + , ata_extract_version(buffer) + , (u32)adjsize, adjprefix); + port->prio =3D bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0); + + s8 multi_dma =3D -1; + s8 pio_mode =3D -1; + s8 udma_mode =3D -1; + // If bit 2 in word 53 is set, udma information is valid in word 88. + if (buffer[53] & 0x04) { + udma_mode =3D 6; + while ((udma_mode >=3D 0) && + !((buffer[88] & 0x7f) & ( 1 << udma_mode ))) { + udma_mode--; + } + } + // If bit 1 in word 53 is set, multiword-dma and advanced pio modes + // are available in words 63 and 64. + if (buffer[53] & 0x02) { + pio_mode =3D 4; + multi_dma =3D 3; + while ((multi_dma >=3D 0) && + !((buffer[63] & 0x7) & ( 1 << multi_dma ))) { + multi_dma--; + } + while ((pio_mode >=3D 3) && + !((buffer[64] & 0x3) & ( 1 << ( pio_mode - 3 ) ))) { + pio_mode--; + } + } + dprintf(2, "AHCI/%d: supported modes: udma %d, multi-dma %d, pio %d\n", + port->pnr, udma_mode, multi_dma, pio_mode); + + sata_prep_simple(&port->cmd->fis, ATA_CMD_SET_FEATURES); + port->cmd->fis.feature =3D ATA_SET_FEATRUE_TRANSFER_MODE; + // Select used mode. UDMA first, then Multi-DMA followed by + // advanced PIO modes 3 or 4. If non, set default PIO. + if (udma_mode >=3D 0) { + dprintf(1, "AHCI/%d: Set transfer mode to UDMA-%d\n", + port->pnr, udma_mode); + port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_ULTRA_DMA + | udma_mode; + } else if (multi_dma >=3D 0) { + dprintf(1, "AHCI/%d: Set transfer mode to Multi-DMA-%d\n", + port->pnr, multi_dma); + port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_MULTIWORD_DMA + | multi_dma; + } else if (pio_mode >=3D 3) { + dprintf(1, "AHCI/%d: Set transfer mode to PIO-%d\n", + port->pnr, pio_mode); + port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_PIO_FLOW_CTRL + | pio_mode; + } else { + dprintf(1, "AHCI/%d: Set transfer mode to default PIO\n", + port->pnr); + port->cmd->fis.sector_count =3D ATA_TRANSFER_MODE_DEFAULT_PIO; + } + rc =3D ahci_command(port, 1, 0, 0, 0); + if (rc < 0) { + dprintf(1, "AHCI/%d: Set transfer mode failed.\n", port->pnr); } boot_lchs_find_ata_device(ctrl->pci_tmp, pnr, 0, &(port->drive.lchs)); return 0; --=20 2.38.1 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org