AHCI fixes and debugging improvements
This commit is contained in:
parent
568d7ee600
commit
696101f277
@ -18,5 +18,7 @@ typedef uint64_t uintptr_t;
|
||||
typedef uint64_t size_t;
|
||||
typedef int64_t ssize_t;
|
||||
|
||||
typedef int64_t off_t;
|
||||
|
||||
#endif /* _STDINT_H_ */
|
||||
|
||||
|
@ -23,6 +23,7 @@ src_amd64 = [
|
||||
]
|
||||
|
||||
src_common = [
|
||||
"kern/debug.c",
|
||||
"kern/libc.c",
|
||||
"kern/palloc.c",
|
||||
"kern/printf.c",
|
||||
|
@ -9,6 +9,29 @@
|
||||
* SATA Definitions
|
||||
*/
|
||||
|
||||
typedef struct SATAIdentifyDevice
|
||||
{
|
||||
uint16_t _rsvd0[10]; // 0-9
|
||||
uint8_t serial[20]; // 10-19 - Serial
|
||||
uint16_t _rsvd1[3]; // 20-22
|
||||
uint8_t firmware[8]; // 23-26 - Firmware
|
||||
uint8_t model[40]; // 27-46 - Model
|
||||
uint16_t _rsvd2[16]; // 47-62 X
|
||||
uint16_t dmaMode; // 63 - DMA Mode
|
||||
uint16_t _rsvd3[11]; // 64-74 X
|
||||
uint16_t queueDepth; // 75 - Queue Depth
|
||||
uint16_t sataCap; // 76 - SATA Capabilities
|
||||
uint16_t ncqCap; // 77 - NCQ Capabilities
|
||||
uint16_t _rsvd4[8]; // 78-85
|
||||
uint16_t deviceFlags; // 86 - Device Flags (48-bit Addressing)
|
||||
uint16_t deviceFlags2; // 87 - Device Flags 2 (SMART)
|
||||
uint16_t udmaMode; // 88 - Ultra DMA Mode
|
||||
uint16_t _rsvd5[11]; // 89-99
|
||||
uint64_t lbaSectors; // 100-103 - User Addressable Logical Sectors
|
||||
uint16_t _rsvd6[151]; // 104-254
|
||||
uint16_t chksum; // 255 - Checksum
|
||||
} SATAIdentifyDevice;
|
||||
|
||||
typedef struct SATAFIS_REG_H2D {
|
||||
uint8_t type; // 0x27
|
||||
uint8_t flag;
|
||||
@ -128,7 +151,8 @@ typedef struct AHCIPort
|
||||
|
||||
typedef struct AHCICommandHeader
|
||||
{
|
||||
uint32_t descInfo;
|
||||
uint16_t flag;
|
||||
uint16_t prdtl; // PRDT Length
|
||||
uint32_t cmdStatus;
|
||||
uint64_t ctba;
|
||||
uint64_t _rsvd[2];
|
||||
@ -223,6 +247,7 @@ AHCI_Init(uint32_t bus, uint32_t slot, uint32_t func)
|
||||
ASSERT(sizeof(AHCI) <= PGSIZE);
|
||||
ASSERT(sizeof(AHCICommandList) <= PGSIZE);
|
||||
ASSERT(sizeof(AHCIRecvFIS) <= PGSIZE);
|
||||
ASSERT(sizeof(SATAIdentifyDevice) == 512);
|
||||
|
||||
int deviceIdx = 0;
|
||||
while (deviceList[deviceIdx].device != 0x0) {
|
||||
@ -236,6 +261,26 @@ AHCI_Init(uint32_t bus, uint32_t slot, uint32_t func)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AHCI_DumpPort(AHCI *ahci, int port)
|
||||
{
|
||||
volatile AHCIPort *p = ahci->port[port];
|
||||
|
||||
kprintf("Port %d\n", port);
|
||||
kprintf("CLBA: 0x%016llx\n", p->clba);
|
||||
kprintf("FB: 0x%016llx\n", p->fb);
|
||||
kprintf("IS: 0x%08x\n", p->is);
|
||||
kprintf("IE: 0x%08x\n", p->ie);
|
||||
kprintf("CMD: 0x%08x\n", p->cmd);
|
||||
kprintf("TFD: 0x%08x\n", p->tfd);
|
||||
kprintf("SIG: 0x%08x\n", p->sig);
|
||||
kprintf("SSTS: 0x%08x\n", p->ssts);
|
||||
kprintf("SCTL: 0x%08x\n", p->sctl);
|
||||
kprintf("SERR: 0x%08x\n", p->serr);
|
||||
kprintf("SACT: 0x%08x\n", p->sact);
|
||||
kprintf("CI: 0x%08x\n", p->ci);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
AHCI_IssueCommand(AHCI *ahci, int port, SGArray *sga, void *cfis, int len)
|
||||
{
|
||||
@ -245,7 +290,7 @@ AHCI_IssueCommand(AHCI *ahci, int port, SGArray *sga, void *cfis, int len)
|
||||
volatile AHCIPort *p = ahci->port[port];
|
||||
|
||||
// Copy Command FIS
|
||||
memcpy(&ct->cfis, cfis, len);
|
||||
memcpy((void *)&ct->cfis[0], cfis, len);
|
||||
|
||||
// Convert SGArray into PRDT
|
||||
int i;
|
||||
@ -259,7 +304,8 @@ AHCI_IssueCommand(AHCI *ahci, int port, SGArray *sga, void *cfis, int len)
|
||||
|
||||
// Specify cfis length and prdt entries;
|
||||
// XXX: support multiple commands
|
||||
cl->cmds[0].descInfo = (sga->len << 16) | (len / 4);
|
||||
cl->cmds[0].prdtl = sga->len;
|
||||
cl->cmds[0].flag = len >> 2;
|
||||
|
||||
p->ci = 1;
|
||||
}
|
||||
@ -269,7 +315,8 @@ AHCI_WaitPort(AHCI *ahci, int port)
|
||||
{
|
||||
volatile AHCIPort *p = ahci->port[port];
|
||||
while (1) {
|
||||
if (((p->tfd & AHCIPORT_TFD_BSY) == 0) && (p->ci != 0)) {
|
||||
uint32_t tfd = p->tfd & AHCIPORT_TFD_BSY;
|
||||
if ((tfd == 0) && (p->ci == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -283,7 +330,7 @@ AHCI_IdentifyPort(AHCI *ahci, int port)
|
||||
volatile AHCIPort *p = ahci->port[port];
|
||||
SGArray sga;
|
||||
SATAFIS_REG_H2D fis;
|
||||
uint8_t buf[512];
|
||||
SATAIdentifyDevice ident;
|
||||
|
||||
kprintf("AHCI: Signature %08x\n", p->sig);
|
||||
|
||||
@ -291,12 +338,10 @@ AHCI_IdentifyPort(AHCI *ahci, int port)
|
||||
fis.type = SATAFIS_TYPE_REG_H2D;
|
||||
fis.flag = SATAFIS_REG_H2D_FLAG_COMMAND;
|
||||
fis.command = SATAFIS_CMD_IDENTIFY;
|
||||
fis.count0 = 1;
|
||||
fis.count1 = 0;
|
||||
|
||||
sga.len = 1;
|
||||
// VA2PA
|
||||
sga.entries[0].offset = &buf;
|
||||
sga.entries[0].offset = (uintptr_t)&ident;
|
||||
sga.entries[0].length = 512;
|
||||
|
||||
AHCI_IssueCommand(ahci, port, &sga, &fis, sizeof(fis));
|
||||
@ -304,6 +349,8 @@ AHCI_IdentifyPort(AHCI *ahci, int port)
|
||||
AHCI_WaitPort(ahci, port);
|
||||
|
||||
kprintf("AHCI: Identify Succeeded Port %d\n", port);
|
||||
Debug_PrintHex((const char *)&ident, 512, 0, 512);
|
||||
AHCI_DumpPort(ahci, port);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -334,6 +381,9 @@ AHCI_ResetPort(AHCI *ahci, int port)
|
||||
p->serr = 0xFFFFFFFF;
|
||||
p->serr = 0x00000000;
|
||||
|
||||
p->cmd |= AHCIPORT_CMD_FRE | AHCIPORT_CMD_ST | AHCIPORT_CMD_SUD |
|
||||
AHCIPORT_CMD_POD | AHCIPORT_CMD_ICCACTIVE;
|
||||
|
||||
// Check port
|
||||
uint32_t ssts = p->ssts;
|
||||
if ((ssts & AHCIPORT_SSTS_DETMASK) == AHCIPORT_SSTS_DETNP) {
|
||||
@ -348,6 +398,8 @@ AHCI_ResetPort(AHCI *ahci, int port)
|
||||
kprintf("AHCI: Port %d not enabled\n", port);
|
||||
return;
|
||||
}
|
||||
|
||||
AHCI_IdentifyPort(ahci, port);
|
||||
}
|
||||
|
||||
void
|
||||
@ -363,8 +415,6 @@ AHCI_Reset(AHCI *ahci)
|
||||
{
|
||||
if (ahci->port[port] != 0) {
|
||||
AHCI_ResetPort(ahci, port);
|
||||
// XXX: Skipme if nothing connected
|
||||
AHCI_IdentifyPort(ahci, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
70
sys/kern/debug.c
Normal file
70
sys/kern/debug.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stanford University
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void
|
||||
Debug_PrintHex(const char *data, size_t length, off_t off, size_t limit)
|
||||
{
|
||||
const size_t row_size = 16;
|
||||
bool stop = false;
|
||||
|
||||
size_t row;
|
||||
for (row = 0; !stop; row++) {
|
||||
size_t ix = row * row_size;
|
||||
if (ix >= limit || ix >= length)
|
||||
return;
|
||||
|
||||
kprintf("%08lx ", row * row_size);
|
||||
size_t col;
|
||||
for (col = 0; col < row_size; col++) {
|
||||
size_t ix = row * row_size + col;
|
||||
if ((limit != 0 && ix >= limit) || ix >= length) {
|
||||
stop = true;
|
||||
for (; col < row_size; col++) {
|
||||
kprintf(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
ix += off;
|
||||
|
||||
kprintf("%02X ", (unsigned char)data[ix]);
|
||||
}
|
||||
kprintf(" |");
|
||||
|
||||
for (col = 0; col < row_size; col++) {
|
||||
size_t ix = row * row_size + col;
|
||||
if ((limit != 0 && ix >= limit) || ix >= length) {
|
||||
stop = true;
|
||||
for (; col < row_size; col++) {
|
||||
kprintf(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
ix += off;
|
||||
|
||||
unsigned char c = (unsigned char)data[ix];
|
||||
if (c >= 0x20 && c < 0x7F)
|
||||
kprintf("%c", c);
|
||||
else
|
||||
kprintf(".");
|
||||
}
|
||||
kprintf("|");
|
||||
kprintf("\n");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user