libpayload: New AHCI, ATA and ATAPI drivers

This adds a new interface for storage devices. A driver for ATA and
ATAPI drives on AHCI host controllers comes along.

The interface is very simple and was designed to match FILO's needs.
It consists of three functions:

  void storage_initialize(void);
  Initializes controllers. Should be called once at startup.

  storage_poll_t storage_probe(size_t dev_num);
     with typedef enum {
            POLL_NO_DEVICE      = -2,
            POLL_ERROR          = -1,
            POLL_NO_MEDIUM      =  0,
            POLL_MEDIUM_PRESENT =  1,
          } storage_poll_t;
  Looks for a drive with number dev_num (drives are counted from
  zero) and polls for a medium in the drive if appropriate.

  int storage_read_blocks512(size_t dev_num,
                             u64 start, size_t count,
                             unsigned char *buf);
  Reads count blocks of 512 bytes from block start of drive dev_num
  into buf.

Change-Id: I1c85796b7f8e379ff3817a61b1837636b57e182b
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: http://review.coreboot.org/1622
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Peter Stuge <peter@stuge.se>
diff --git a/payloads/libpayload/drivers/storage/ahci_private.h b/payloads/libpayload/drivers/storage/ahci_private.h
new file mode 100644
index 0000000..ba1471b
--- /dev/null
+++ b/payloads/libpayload/drivers/storage/ahci_private.h
@@ -0,0 +1,201 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2012 secunet Security Networks AG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _AHCI_PRIVATE_H
+#define _AHCI_PRIVATE_H
+
+#include <stdint.h>
+#include <storage/ata.h>
+#include <storage/atapi.h>
+
+typedef volatile struct {
+	u64 cmdlist_base;
+	u64 frameinfo_base;
+	u32 intr_status;
+	u32 intr_enable;
+	u32 cmd_stat;
+	u32 _reserved0;
+	u32 taskfile_data;
+	u32 signature;
+	u32 sata_status;
+	u32 sata_control;
+	u32 sata_error;
+	u32 sata_active;
+	u32 cmd_issue;
+	u32 sata_notify;
+	u32 fis_based_switch;
+	u32 _reserved1[11];
+	u32 _vendor[4];
+} hba_port_t;
+
+#define HBA_PxIS_TFES	(1 << 30)	/* TFES - Task File Error Status */
+#define HBA_PxIS_HBFS	(1 << 29)	/* HBFS - Host Bus Fatal Error Status */
+#define HBA_PxIS_HBDS	(1 << 28)	/* HBDS - Host Bus Data Error Status */
+#define HBA_PxIS_IFS	(1 << 27)	/* IFS - Interface Fatal Error Status */
+#define HBA_PxIS_FATAL	(HBA_PxIS_TFES | HBA_PxIS_HBFS | \
+				HBA_PxIS_HBDS | HBA_PxIS_IFS)
+#define HBA_PxIS_PCS	(1 <<  6)	/* PCS - Port Connect Change Status */
+
+#define HBA_PxCMD_ICC_SHIFT	28
+#define HBA_PxCMD_ICC_MASK	(0xf << HBA_PxCMD_ICC_SHIFT)
+#define HBA_PxCMD_ICC_ACTIVE	(0x1 << HBA_PxCMD_ICC_SHIFT)
+#define HBA_PxCMD_CR		(1 << 15) /* CR - Command list Running */
+#define HBA_PxCMD_FR		(1 << 14) /* FR - FIS receive Running */
+#define HBA_PxCMD_FRE		(1 <<  4) /* FRE - FIS Receive Enable */
+#define HBA_PxCMD_SUD		(1 <<  1) /* SUD - Spin-Up Device */
+#define HBA_PxCMD_ST		(1 <<  0) /* ST - Start (command processing) */
+
+#define HBA_PxTFD_BSY		(1 <<  7)
+#define HBA_PxTFD_DRQ		(1 <<  3)
+
+#define HBA_PxSSTS_IPM_SHIFT		8
+#define HBA_PxSSTS_IPM_MASK		(0xf << HBA_PxSSTS_IPM_SHIFT)
+#define HBA_PxSSTS_IPM_ACTIVE		(1 << HBA_PxSSTS_IPM_SHIFT)
+#define HBA_PxSSTS_DET_SHIFT		0
+#define HBA_PxSSTS_DET_MASK		(0xf << HBA_PxSSTS_DET_SHIFT)
+#define HBA_PxSSTS_DET_ESTABLISHED	(3 << HBA_PxSSTS_DET_SHIFT)
+
+#define HBA_PxSCTL_DET_SHIFT		0
+#define HBA_PxSCTL_DET_MASK		(0xf << HBA_PxSCTL_DET_SHIFT)
+#define HBA_PxSCTL_DET_COMRESET		(0x1 << HBA_PxSCTL_DET_SHIFT)
+
+#define	HBA_PxSIG_ATA	0x00000101 /* SATA drive */
+#define	HBA_PxSIG_ATAPI	0xeb140101 /* SATAPI drive */
+#define	HBA_PxSIG_SEMB	0xc33c0101 /* Enclosure management bridge */
+#define	HBA_PxSIG_PM	0x96690101 /* Port multiplier */
+
+typedef volatile struct {
+	u32 caps;
+	u32 global_ctrl;
+	u32 intr_status;
+	u32 ports_impl;
+	u32 version;
+	u32 ccc_ctrl;		/* CCC - Command Completion Coalescing */
+	u32 ccc_ports;
+	u32 em_location;	/* EM - Enclosure Management */
+	u32 em_ctrl;
+	u32 ext_caps;
+	u32 handoff_ctrl_stat;
+	u32 _reserved0[13];
+	u32 _reserved_nvmchi[16];
+	u32 _vendor[24];
+	hba_port_t ports[32];
+} hba_ctrl_t;
+
+#define HBA_CAPS_SSS		(1 << 27) /* SSS - Supports Staggered Spin-up */
+#define HBA_CAPS_NCS_SHIFT	8	/* NCS - Number of Command Slots */
+#define HBA_CAPS_NCS_MASK	(0x1f << HBA_CAPS_NCS_SHIFT)
+
+#define HBA_CAPS_DECODE_NCS(caps)	(((caps & HBA_CAPS_NCS_MASK)	\
+					  >> HBA_CAPS_NCS_SHIFT)	\
+					 + 1)
+
+#define HBA_CTRL_AHCI_EN	(1 << 31)
+#define HBA_CTRL_INTR_EN	(1 <<  1)
+#define HBA_CTRL_RESET		(1 <<  0)
+
+
+typedef volatile struct {
+	u8 dma_setup_fis[28];
+	u8 _reserved0[4];
+	u8 pio_setup_fis[20];
+	u8 _reserved1[12];
+	u8 d2h_register_fis[20];
+	u8 _reserved2[4];
+	u8 set_device_bits_fis[8];
+	u8 unknown_fis[64];
+	u8 _reserved3[96];
+} rcvd_fis_t;
+
+typedef volatile struct {
+	u16 cmd;
+	u16 prdt_length;
+	u32 prd_bytes;
+	u64 cmdtable_base;
+	u8 _reserved[16];
+} cmd_t;
+
+#define CMD_PMP_SHIFT	12		/* PMP - Port Multiplier Port */
+#define CMD_PMP_MASK	(0xf << CMD_PMP_SHIFT)
+#define CMD_PMP(x)	((x << CMD_PMP_SHIFT) & CMD_PMP_MASK)
+#define CMD_CBuROK	(1 << 10)	/* C - Clear Busy upon R_OK */
+#define CMD_BIST	(1 <<  9)	/* B - BIST - Built-In Selft Test */
+#define CMD_RESET	(1 <<  8)	/* R - Reset */
+#define CMD_PREFETCH	(1 <<  7)	/* P - Prefetch (PRDTs or ATAPI cmd) */
+#define CMD_WRITE	(1 <<  6)	/* W - Write (host to device) */
+#define CMD_ATAPI	(1 <<  5)	/* A - ATAPI cmd */
+#define CMD_CFL_SHIFT	0		/* CFL - Command FIS Length */
+#define CMD_CFL_MASK	(0xf << CMD_CFL_SHIFT)
+#define CMD_CFL(x)	((((x) >> 2) << CMD_CFL_SHIFT) & CMD_CFL_MASK)
+
+typedef volatile struct {
+	u8 fis[64];
+	u8 atapi_cmd[16];
+	u8 _reserved0[48];
+	struct {
+		u64 data_base;
+		u32 _reserved0;
+		u32 flags;
+	} prdt[8]; /* Can be up to 65,535 prds,
+		      but implementation needs multiple of 128 bytes. */
+} cmdtable_t;
+
+#define BYTES_PER_PRD_SHIFT	20
+#define BYTES_PER_PRD		(4 << 20)
+
+enum {
+	FIS_HOST_TO_DEVICE	= 0x27,
+};
+#define FIS_H2D_CMD	(1 << 7)
+#define FIS_H2D_FIS_LEN	20
+#define FIS_H2D_DEV_LBA	(1 << 6)
+
+#define PRD_TABLE_I		(1 << 31) /* I - Interrupt on Completion */
+#define PRD_TABLE_BYTES_MASK	0x3fffff
+#define PRD_TABLE_BYTES(x)	(((x) - 1) & PRD_TABLE_BYTES_MASK)
+
+typedef struct {
+	union {
+		ata_dev_t ata_dev;
+		atapi_dev_t atapi_dev;
+	};
+
+	hba_ctrl_t *ctrl;
+	hba_port_t *port;
+
+	cmd_t *cmdlist;
+	cmdtable_t *cmdtable;
+	rcvd_fis_t *rcvd_fis;
+
+	u8 *buf, *user_buf;
+	int write_back;
+	size_t buflen;
+} ahci_dev_t;
+
+#endif