Setup command list, command table, FIS and PRDT pointers.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22257 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -113,6 +113,62 @@ typedef struct {
|
||||
} ahci_hba;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8 dsfis[0x1c]; // DMA Setup FIS
|
||||
uint8 res1[0x04];
|
||||
uint8 psfis[0x14]; // PIO Setup FIS
|
||||
uint8 res2[0x0c];
|
||||
uint8 rfis[0x20]; // D2H Register FIS
|
||||
uint8 res3[0x04];
|
||||
uint8 sdbfis[0x08]; // Set Device Bits FIS
|
||||
uint8 ufis[0x40]; // Unknown FIS
|
||||
uint8 res4[0x60];
|
||||
} fis;
|
||||
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint16 prdtl; // physical region description table length;
|
||||
uint16 pmp : 4; // Port Multiplier Port
|
||||
uint16 : 1;
|
||||
uint16 c : 1; // Clear Busy upon R_OK
|
||||
uint16 b : 1; // Build In Self Test
|
||||
uint16 r : 1; // Reset
|
||||
uint16 p : 1; // Prefetchable
|
||||
uint16 w : 1; // Write
|
||||
uint16 a : 1;// ATAPI
|
||||
uint16 cfl : 5; // command FIS length
|
||||
};
|
||||
uint32 prdtl_flags_cfl;
|
||||
};
|
||||
uint32 ctba; // command table desciptor base address (alignment 128 byte)
|
||||
uint32 ctbau; // command table desciptor base address upper
|
||||
uint8 res1[0x10];
|
||||
} command_list_entry;
|
||||
|
||||
#define COMMAND_LIST_ENTRY_COUNT 32
|
||||
|
||||
typedef struct {
|
||||
uint32 dba; // Data Base Address (2-byte aligned)
|
||||
uint32 dbau; // Data Base Address Upper
|
||||
uint32 res;
|
||||
uint32 dbc; // Bytecount (0-based, even, max 4MB)
|
||||
#define DBC_I 0x80000000 /* Interrupt on completition */
|
||||
} prd;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8 cfis[0x40]; // command FIS
|
||||
uint8 acmd[0x20]; // ATAPI command
|
||||
uint8 res[0x20]; // reserved
|
||||
} command_table;
|
||||
|
||||
|
||||
#define PRD_TABLE_ENTRY_COUNT 168
|
||||
|
||||
|
||||
|
||||
extern scsi_sim_interface gAHCISimInterface;
|
||||
extern device_manager_info *gDeviceManager;
|
||||
extern pci_device_module_info *gPCI;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE(a...) dprintf("\33[34mahci:\33[0m " a)
|
||||
#define FLOW(a...) dprintf("ahci: " a)
|
||||
@@ -32,27 +33,35 @@ AHCIPort::Init()
|
||||
{
|
||||
TRACE("AHCIPort::Init port %d\n", fIndex);
|
||||
|
||||
size_t size = 999;
|
||||
size_t size = sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT + sizeof(fis) + sizeof(command_table) + sizeof(prd) * PRD_TABLE_ENTRY_COUNT;
|
||||
|
||||
void *virtAddr;
|
||||
void *physAddr;
|
||||
char *virtAddr;
|
||||
char *physAddr;
|
||||
|
||||
fArea = alloc_mem(&virtAddr, &physAddr, size, 0, "some AHCI port");
|
||||
fArea = alloc_mem((void **)&virtAddr, (void **)&physAddr, size, 0, "some AHCI port");
|
||||
if (fArea < B_OK) {
|
||||
TRACE("failed allocating memory for port %d\n", fIndex);
|
||||
return fArea;
|
||||
}
|
||||
memset(virtAddr, 0, size);
|
||||
|
||||
void *virtClbAddr;
|
||||
void *physClbAddr = physAddr;
|
||||
void *virtFisAddr;
|
||||
void *physFisAddr = (char *)physAddr + 1024;
|
||||
|
||||
|
||||
fRegs->clb = LO32(physClbAddr);
|
||||
fRegs->clbu = HI32(physClbAddr);
|
||||
fRegs->fb = LO32(physFisAddr);
|
||||
fRegs->fbu = HI32(physFisAddr);
|
||||
fCommandList = (command_list_entry *)virtAddr;
|
||||
virtAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT;
|
||||
fFIS = (fis *)virtAddr;
|
||||
virtAddr += sizeof(fis);
|
||||
fCommandTable = (command_table *)virtAddr;
|
||||
virtAddr += sizeof(command_table);
|
||||
fPRDTable = (prd *)virtAddr;
|
||||
|
||||
fRegs->clb = LO32(physAddr);
|
||||
fRegs->clbu = HI32(physAddr);
|
||||
physAddr += sizeof(command_list_entry) * COMMAND_LIST_ENTRY_COUNT;
|
||||
fRegs->fb = LO32(physAddr);
|
||||
fRegs->fbu = HI32(physAddr);
|
||||
physAddr += sizeof(fis);
|
||||
fCommandList[0].ctba = LO32(physAddr);
|
||||
fCommandList[0].ctbau = HI32(physAddr);
|
||||
// prdt follows after command table
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@ private:
|
||||
private:
|
||||
int fIndex;
|
||||
volatile ahci_port * fRegs;
|
||||
area_id fArea;
|
||||
area_id fArea;
|
||||
|
||||
volatile fis * fFIS;
|
||||
volatile command_list_entry * fCommandList;
|
||||
volatile command_table * fCommandTable;
|
||||
volatile prd * fPRDTable;
|
||||
};
|
||||
|
||||
#endif // _AHCI_PORT_H
|
||||
|
||||
@@ -40,7 +40,6 @@ alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *n
|
||||
ERROR("couldn't get mapping for %s\n", name);
|
||||
return B_ERROR;
|
||||
}
|
||||
memset(virtadr, 0, size);
|
||||
if (virt)
|
||||
*virt = virtadr;
|
||||
if (phy)
|
||||
|
||||
Reference in New Issue
Block a user