1
2/*
3 * Copyright (c) 2016, ETH Zurich.
4 * All rights reserved.
5 *
6 * This file is distributed under the terms in the attached LICENSE file.
7 * If you do not find this file, copies can be found by writing to:
8 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
9 */
10
11#ifndef _BLK_AHCI_
12#define _BLK_AHCI_
13
14#include <barrelfish/barrelfish.h>
15#include <pci/mem.h>
16#include <blk/ahci.h>
17//#include <devif/queue.h>
18
19#include <dev/ahci_hba_dev.h>
20#include <dev/ahci_port_dev.h>
21#include <dev/ata_identify_dev.h>
22
23#include "../dma_mem/dma_mem.h"
24
25#define MAX_AHCI_PORTS 32
26#define MAX_CTBA_SLOTS 32
27
28#define MAX_HBA 32
29#define MAX_BUFFERS 256
30#define MAX_REQUESTS MAX_CTBA_SLOTS
31
32struct __attribute__((__packed__)) region_descriptor {
33    /// Data base address
34    uint64_t dba;
35    uint32_t reserved;
36    /// Byte count and Interrupt bit (31)
37    uint32_t dbc;
38};
39
40struct __attribute__((__packed__)) command_table {
41    /// Command FIS
42    uint8_t cfis[64];
43    /// ATAPI command
44    uint8_t acmd[16];
45    uint8_t reserved[48];
46    /// Physical Descriptior Region Table entries
47    /// Can be up to 65536 entries, we limit this to 248 for now
48    /// (which limits the size of CommandTable to a single page).
49    struct region_descriptor prdt[248];
50};
51
52
53struct ahci_port;
54struct dev_queue;
55
56
57enum RequestStatus {
58    RequestStatus_Unused = 0,
59    RequestStatus_InProgress = 1,
60    RequestStatus_Done = 2
61};
62
63struct dev_queue_request {
64    // TODO change back to regionid_t
65    //regionid_t region_id;
66    uint32_t region_id;
67    struct dma_mem region;
68    uint64_t command_slot;
69
70    genpaddr_t offset;
71    genpaddr_t length;
72    genpaddr_t valid_data;
73    genpaddr_t valid_length;
74
75    errval_t error;
76    enum RequestStatus status;
77};
78
79
80typedef void (*ahci_port_interrupt_handler_fn)(struct ahci_port*, struct dev_queue_request* reqs, size_t slots);
81
82struct ahci_port {
83    bool is_initialized; //< Port is up and running, ready to read/write.
84    ahci_port_t port;
85    struct dma_mem fb;
86    struct dma_mem clb;
87    struct dma_mem ctba_mem[MAX_CTBA_SLOTS];
88    struct command_table* command_table[MAX_CTBA_SLOTS]; //< Points to ctba_mem[i].vaddr
89    size_t ncs; //< Number of command slots actually implemented
90    ahci_port_interrupt_handler_fn interrupt;
91    struct ahci_mgmt_binding *binding;
92    struct dma_mem identify_mem;
93    ata_identify_t identify; //< Points to identify_mem.vaddr, valid after port_identify() is done.
94};
95
96struct ahci_disk {
97    struct device_mem* bar5;
98    ahci_hba_t controller;
99    struct ahci_port ports[MAX_AHCI_PORTS];
100};
101
102
103
104struct dev_queue {
105    struct ahci_port* port;
106    struct dma_mem buffers[MAX_BUFFERS];
107    struct dev_queue_request requests[MAX_REQUESTS];
108};
109
110/* ahci_port_init.h */
111errval_t blk_ahci_ports_init(struct ahci_disk *ad);
112errval_t blk_ahci_port_dma(struct ahci_port *port, uint64_t block, struct dma_mem *buffer, bool write);
113errval_t blk_ahci_port_dma_async(struct ahci_port *port, size_t slot, uint64_t block, lpaddr_t base, size_t length, bool write);
114
115lvaddr_t blk_ahci_get_bar5_vaddr(struct ahci_disk* ad);
116
117#endif // _BLK_AHCI_
118